DCL 3.7.4
Loading...
Searching...
No Matches
PeConnection.cpp
Go to the documentation of this file.
1#line 1 "PeConnection.pgc"
2#include <dcl/Config.h>
3
4/* Processed by ecpg (17.7) */
5/* These include files are added by the preprocessor */
6#include <ecpglib.h>
7#include <ecpgerrno.h>
8#include <sqlca.h>
9/* End of automatic include section */
10
11#include <string.h> // strlen, strncpy
12
13#include <sqlda.h>
14
15#include <dcl/Object.h>
16#if __DCL_HAVE_ALLOC_DEBUG
17#undef __DCL_ALLOC_LEVEL
18#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
19#endif
20
21#include <dcl/Numeric.h>
22#include <dcl/Regex.h>
23#include <dcl/SQLCore.h>
24
25#include "PeConnection.h"
26#include "PeQuery.h"
27#include "PeField.h" // for _getServerInfo
28
29#define __TRACE_THIS 0
30#if __TRACE_THIS
31#define __DCL_TRACE0_N __DCL_TRACE0
32#define __DCL_TRACE1_N __DCL_TRACE1
33#define __DCL_TRACE2_N __DCL_TRACE2
34#define __DCL_TRACE3_N __DCL_TRACE3
35#define __DCL_TRACE4_N __DCL_TRACE4
36#else
37#define __DCL_TRACE0_N(fmt)
38#define __DCL_TRACE1_N(fmt, arg)
39#define __DCL_TRACE2_N(fmt, arg1, arg2)
40#define __DCL_TRACE3_N(fmt, arg1, arg2, arg3)
41#define __DCL_TRACE4_N(fmt, arg1, arg2, arg3, arg4)
42#endif
43
44#undef __THIS_FILE__
45static const char_t __THIS_FILE__[] = __T("dcl/sql/PeConnection.pgc");
46
47__DCL_BEGIN_NAMESPACE
48
49#define __SET_ERROR(_error) \
50 setErrorHandle(_error, 0L, __THIS_FILE__, __LINE__)
51#define __SET_ERROR_HANDLE(_SQLCODE) \
52 setErrorHandle(SQL::eServerError, _SQLCODE, __THIS_FILE__, __LINE__)
53#define __SET_ERROR_MSG(_message) \
54 setErrorMessage(_message, __THIS_FILE__, __LINE__)
55
57
58PeConnection::PeConnection(const wchar_t* pszServerTitle)
59 : Connection(pszServerTitle)
60{
61 Connection::__canTransact = true;
62}
63
65{
66 if (!__connectionID.isEmpty()) {
67 __DCL_TRACE0_N(L"Warning!! The connection was not closed\n");
68 close();
69 }
70}
71
73{
74 delete this;
75}
76
77/*
78_conns에 가능한 프로퍼티
79 USER,
80 PASSWORD,
81 SERVER, -- host name
82 DATABASE
83*/
84
85bool PeConnection::__open(const char* _conns, size_t _connslen)
86{
87 ListedByteStringToByteStringMap map;
88 Connection::splitConnStr(_conns, _connslen, map);
89
90 ByteString _USER = map["USER"];
91 ByteString _PASSWORD = map["PASSWORD"];
92 ByteString _SERVER = map["SERVER"];
93 ByteString _PORT = map["PORT"];
94 ByteString _DATABASE = map["DATABASE"];
95 ByteString _TARGET;
96
97 {
98 ByteStringBuilder sb;
99 if (!_SERVER.isEmpty()) {
100 sb.append("tcp:postgresql://").append(_SERVER);
101 if (!_PORT.isEmpty()) {
102 sb.append(":").append(_PORT);
103 }
104 }
105 if (!_DATABASE.isEmpty()) {
106 if (!sb.isEmpty()) {
107 sb += "/";
108 }
109 sb += _DATABASE;
110 }
111 _TARGET = sb.toByteString();
112 __DCL_TRACE1_N(L"TARGET [%hs]\n", _TARGET.data());
113 }
114
115 ByteString connectionID = ByteString::format("conn_%zx", (size_t)this);
116
117 /* exec sql begin declare section */
118
119
120
121
122
123#line 110 "PeConnection.pgc"
124 char * user = ( _CONST char * ) _USER . data () ;
125
126#line 111 "PeConnection.pgc"
127 char * pass = ( _CONST char * ) _PASSWORD . data () ;
128
129#line 112 "PeConnection.pgc"
130 char * target = ( _CONST char * ) _TARGET . data () ;
131
132#line 113 "PeConnection.pgc"
133 char * connID = ( _CONST char * ) connectionID . data () ;
134/* exec sql end declare section */
135#line 114 "PeConnection.pgc"
136
137
138 { ECPGconnect(__LINE__, 0, target , user , pass , connID, 0); }
139#line 117 "PeConnection.pgc"
140
141
142 if (SQLCODE < 0) {
143 __SET_ERROR_HANDLE(SQLCODE);
144 return false;
145 }
146 __connectionID = connectionID;
147
148 return true;
149}
150
152{
153 if (__connectionID.isEmpty()) {
155 return false;
156 }
157
158 /* exec sql begin declare section */
159
160
161#line 136 "PeConnection.pgc"
162 char * connID = ( _CONST char * ) __connectionID . data () ;
163/* exec sql end declare section */
164#line 137 "PeConnection.pgc"
165
166
167 { ECPGdisconnect(__LINE__, connID);}
168#line 139 "PeConnection.pgc"
169
170 if (SQLCODE < 0) {
171 __SET_ERROR_HANDLE(SQLCODE);
172 return false;
173 }
174
175 __connectionID.clear();
176 return true;
177}
178
184
185typedef struct {
186 StmtType type;
187 const char* pattern;
189
190static STMT_PATTERN sp[] = {
191 { StmtTransBegin, "BEGIN" },
192 { StmtTransEnd, "COMMIT|ROLLBACK|END" },
193 { StmtOther, NULL }
194};
195
196static StmtType __GetStmtType(const char* _sql)
197{
198 for(size_t i = 0; sp[i].type != StmtOther; i++) {
199 try {
200 if (Regex::test(sp[i].pattern, _sql, true))
201 return sp[i].type;
202 }
203 catch(Exception* _e) {
204 _e->destroy();
205 }
206 }
207 return StmtOther;
208}
209
210bool PeConnection::__execute(const char* _sql, size_t _sqllen)
211{
212 // PostgreSQL에서 EXEC SQL EXECUTE IMMEDIATE는 DML만 사용할 수 있다!
213 PGconn* conn = ECPGget_PGconn(__connectionID.data());
214 PGresult* res = PQexec(conn, _sql);
215 ExecStatusType status = PQresultStatus(res);
216 if (status != PGRES_COMMAND_OK) {
217 ByteStringBuilder sb;
218 sb.format("ExecStatusType(%d)", status)
219 .append(PQresultErrorMessage(res));
220 __SET_ERROR_MSG(sb);
221 PQclear(res);
222 return false;
223 }
224 PQclear(res);
225
226 switch(__GetStmtType(_sql)) {
227 case StmtTransBegin :
229 break;
230 case StmtTransEnd :
232 break;
233 case StmtOther :
234 default :
235 ;
236 }
237
238 return true;
239}
240
242{
243 /* exec sql begin declare section */
244
245
246#line 214 "PeConnection.pgc"
247 char * connID = ( _CONST char * ) __connectionID . data () ;
248/* exec sql end declare section */
249#line 215 "PeConnection.pgc"
250
251
252 { ECPGsetconn(__LINE__, connID);}
253#line 217 "PeConnection.pgc"
254
255 if (SQLCODE < 0) {
256 __SET_ERROR_HANDLE(SQLCODE);
257 return false;
258 }
259
260 { ECPGtrans(__LINE__, NULL, "begin work");}
261#line 223 "PeConnection.pgc"
262
263 if (SQLCODE < 0) {
264 __SET_ERROR_HANDLE(SQLCODE);
265 return false;
266 }
267
269 return true;
270}
271
273{
274 /* exec sql begin declare section */
275
276
277#line 236 "PeConnection.pgc"
278 char * connID = ( _CONST char * ) __connectionID . data () ;
279/* exec sql end declare section */
280#line 237 "PeConnection.pgc"
281
282
283 { ECPGsetconn(__LINE__, connID);}
284#line 239 "PeConnection.pgc"
285
286 if (SQLCODE < 0) {
287 __SET_ERROR_HANDLE(SQLCODE);
288 return false;
289 }
290
291 { ECPGtrans(__LINE__, NULL, "commit work");}
292#line 245 "PeConnection.pgc"
293
294 if (SQLCODE < 0) {
295 __SET_ERROR_HANDLE(SQLCODE);
296 return false;
297 }
298
300 return true;
301}
302
304{
305 /* exec sql begin declare section */
306
307
308#line 258 "PeConnection.pgc"
309 char * connID = ( _CONST char * ) __connectionID . data () ;
310/* exec sql end declare section */
311#line 259 "PeConnection.pgc"
312
313
314 { ECPGsetconn(__LINE__, connID);}
315#line 261 "PeConnection.pgc"
316
317 if (SQLCODE < 0) {
318 __SET_ERROR_HANDLE(SQLCODE);
319 return false;
320 }
321
322 { ECPGtrans(__LINE__, NULL, "rollback work");}
323#line 267 "PeConnection.pgc"
324
325 if (SQLCODE < 0) {
326 __SET_ERROR_HANDLE(SQLCODE);
327 return false;
328 }
329
331 return true;
332}
333
335{
336 __DCL_ASSERT(_queryHandleOut != NULL);
337
338 SQL::Query* pNewQuery = new PeQuery(this);
339 if (!pNewQuery) {
341 return false;
342 }
343
344 *_queryHandleOut = pNewQuery;
345 return true;
346}
347
349 SQL::Error _error, long _SQLCODE,
350 const wchar_t* _filename, int _line
351)
352{
353 Connection::setErrorStatus(_error, _filename, _line);
354 if (_SQLCODE == 0 /* ECPG_NO_ERROR */) {
355 __lastErrorMessage.clear();
356 }
357 else {
358 ByteStringBuilder sb;
359 sb.format("SQLCODE(%d) ", _SQLCODE);
360 sb.append(sqlca.sqlerrm.sqlerrmc, sqlca.sqlerrm.sqlerrml);
361 __lastErrorMessage = sb.toByteString();
362 }
363}
364
365bool PeConnection::__getErrorMessage(char* _buf, size_t* _buflen)
366{
367 __DCL_ASSERT(Connection::__errorCode == SQL::eServerError);
368 if (__lastErrorMessage.length() < *_buflen) {
369 *_buflen = __lastErrorMessage.length();
370 *(_buf + *_buflen) = '\0';
371 }
372 strncpy(_buf, __lastErrorMessage.data(), *_buflen);
373 return true;
374}
375
376bool PeConnection::__getServerInfo(char* _buf, size_t* _buflen)
377{
378 PGconn* conn = ECPGget_PGconn(__connectionID.data());
379 int serverVersion = PQserverVersion(conn);
380 int protocolVersion =
381#ifdef LIBPQ_HAS_FULL_PROTOCOL_VERSION
382 PQfullProtocolVersion(conn)
383#else
384 PQprotocolVersion(conn) * 10000
385#endif
386 ;
387 int libVersion = PQlibVersion();
388
389 ByteString s = ByteString::format("PostgreSQL %d.%d/%d.%d/%d.%d/ecpg",
390 serverVersion / 10000, serverVersion % 10000,
391 protocolVersion / 10000, protocolVersion % 10000,
392 libVersion / 10000, libVersion % 10000
393 );
394 if (s.length() < *_buflen) {
395 *_buflen = s.length();
396 *(_buf + *_buflen) = '\0';
397 }
398 strncpy(_buf, s.data(), *_buflen);
399 return true;
400}
401
402__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:312
wchar_t char_t
Definition Config.h:247
#define _CONST
Definition Config.h:325
#define __DCL_TRACE1_N(fmt, arg)
#define __SET_ERROR_MSG(_message)
@ StmtTransEnd
@ StmtOther
@ StmtTransBegin
#define __DCL_TRACE0_N(fmt)
#define __SET_ERROR_HANDLE(_SQLCODE)
#define __DCL_ASSERT(expr)
Definition Object.h:394
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:245
#define __T(str)
Definition Object.h:60
#define __SET_ERROR(_errorCode)
Definition SQLCore.cpp:149
#define __UNSET_STATE(state)
Definition SQLCore.h:483
#define __SET_STATE(state)
Definition SQLCore.h:482
virtual void destroy()
Definition Exception.cpp:74
virtual bool __getServerInfo(char *_buf, size_t *_buflen)
_CONST char * connectionID() const
virtual bool __getErrorMessage(char *_buf, size_t *_buflen)
virtual bool __createQueryInstance(SQL::Query **_queryHandleOut)
virtual bool __execute(const char *_sql, size_t _sqllen)
virtual bool __commitTrans()
virtual bool __startTrans()
void setErrorHandle(SQL::Error _error, long _SQLCODE, const wchar_t *_filename, int _line)
virtual ~PeConnection()
PeConnection(const wchar_t *_serverTitle)
virtual bool __rollbackTrans()
virtual void destroy()
virtual bool __open(const char *_conns, size_t _connslen)
virtual bool __close()
static bool test(const wchar_t *_regex, const wchar_t *_string, bool _icase=false) __DCL_THROWS1(RegexException *)
Definition Regex.cpp:250
_PROTECTED const wchar_t * _filename
Definition SQLCore.h:439
_PROTECTED const wchar_t int _line
Definition SQLCore.h:441
Error
Definition SQLCore.h:19
@ eOutOfMemory
Definition SQLCore.h:24
@ eServerError
Definition SQLCore.h:21
@ eNotConnected
Definition SQLCore.h:33