DCL 4.0
Loading...
Searching...
No Matches
PgConnection.cpp
Go to the documentation of this file.
1/* Processed by ecpg (17.4) */
2/* These include files are added by the preprocessor */
3#include <ecpglib.h>
4#include <ecpgerrno.h>
5#include <sqlca.h>
6/* End of automatic include section */
7
8#line 1 "PgConnection.pgc"
9#include <dcl/Config.h>
10
11#if __DCL_WINDOWS
12 #include <windows.h>
13 #if __DCL_PTHREAD
14 #include <pthread.h>
15 #endif
16#else
17 #include <pthread.h>
18#endif
19
20#include <string.h> // strlen, strncpy
21
22#include <sqlda.h>
23
24#include <dcl/Object.h>
25#if __DCL_HAVE_ALLOC_DEBUG
26#undef __DCL_ALLOC_LEVEL
27#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
28#endif
29
30#include <dcl/Numeric.h>
31#include <dcl/Regex.h>
32#include <dcl/Thread.h>
33
34#include <dcl/SQLCore.h>
35
36#include "PgConnection.h"
37#include "PgQuery.h"
38#include "PgField.h" // for _getServerInfo
39
40#undef __THIS_FILE__
41static const wchar_t __THIS_FILE__[] = __T("dcl/sql/PgConnection.ec");
42
43__DCL_BEGIN_NAMESPACE
44
46
47static volatile long __connectionID__ = 0;
48
49PgConnection::PgConnection(const wchar_t* pszServerTitle)
50 : Connection(pszServerTitle)
51{
52 Connection::__canTransact = true;
53 __connectionID = ByteString::format("con:%ld",
54 Thread::incrementAndGet(__connectionID__));
55}
56
60
62{
63 delete this;
64}
65
66/*
67pszConnectionString에 가능한 프로퍼티
68 USER,
69 PASSWORD,
70 SERVER, -- host name
71 DATABASE
72*/
73
74bool PgConnection::__open(const char* _pszConnString, size_t _n)
75{
76 ListedByteStringToByteStringMap map;
77 Connection::splitConnectionString(_pszConnString, _n, map);
78
79 ByteString strServer = map["SERVER"];
80 ByteString strUser = map["USER"];
81 ByteString strPassword = map["PASSWORD"];
82 ByteString strDatabase = map["DATABASE"];
83
84 ByteStringBuilder sbTarget;
85 if (!strServer.isEmpty()) {
86 sbTarget = strServer;
87 }
88 if (!strDatabase.isEmpty()) {
89 if (!sbTarget.isEmpty()) {
90 sbTarget += "/";
91 }
92 sbTarget += strDatabase;
93 }
94
95 /* exec sql begin declare section */
96
97
98
99
100
101#line 88 "PgConnection.pgc"
102 char * pszUserName = ( _CONST char * ) strUser . data () ;
103
104#line 89 "PgConnection.pgc"
105 char * pszPassword = ( _CONST char * ) strPassword . data () ;
106
107#line 90 "PgConnection.pgc"
108 char * pszTarget = ( _CONST char * ) sbTarget . data () ;
109
110#line 91 "PgConnection.pgc"
111 char * pszConnectionID = NULL ;
112/* exec sql end declare section */
113#line 92 "PgConnection.pgc"
114
115
116 pszConnectionID = (_CONST char*) __connectionID.data();
117
118 { ECPGconnect(__LINE__, 0, pszTarget , pszUserName , pszPassword , pszConnectionID, 0); }
119#line 97 "PgConnection.pgc"
120
121
122 if (SQLCODE < 0) {
123 __SET_ERROR_SQLCODE(SQLCODE);
124 return false;
125 }
126
127 return true;
128}
129
131{
132 /* exec sql begin declare section */
133
134
135#line 111 "PgConnection.pgc"
136 char * pszConnectionID = ( _CONST char * ) __connectionID . data () ;
137/* exec sql end declare section */
138#line 112 "PgConnection.pgc"
139
140
141 { ECPGdisconnect(__LINE__, pszConnectionID);}
142#line 114 "PgConnection.pgc"
143
144 if (SQLCODE < 0)
145 {
146 __SET_ERROR_SQLCODE(SQLCODE);
147 return false;
148 }
149
150 return true;
151}
152
158
159typedef struct {
160 StmtType type;
161 const char* pattern;
163
164static STMT_PATTERN sp[] = {
165 { StmtTransBegin, "BEGIN" },
166 { StmtTransEnd, "COMMIT|ROLLBACK|END" },
167 { StmtOther, NULL }
168};
169
170static StmtType __GetStmtType(const char* _sql)
171{
172 for(size_t i = 0; sp[i].type != StmtOther; i++)
173 {
174 try
175 {
176 if (Regex::test(sp[i].pattern, _sql, true))
177 return sp[i].type;
178 }
179 catch(Exception* p)
180 {
181 p->destroy();
182 }
183 }
184 return StmtOther;
185}
186
187bool PgConnection::__execute(const char* _sql, size_t n)
188{
189 // PostgreSQL에서 EXEC SQL EXECUTE IMMEDIATE는 DML만 사용할 수 있다!
190 PGconn* conn = ECPGget_PGconn(__connectionID.data());
191 PGresult* res = PQexec(conn, _sql);
192 ExecStatusType status = PQresultStatus(res);
193 if (status != PGRES_COMMAND_OK) {
194 ByteStringBuilder sb;
195 sb.format("ExecStatusType(%d)", status)
196 .append(PQresultErrorMessage(res));
197 __SET_ERROR_MSG(sb);
198 PQclear(res);
199 return false;
200 }
201 PQclear(res);
202
203 switch(__GetStmtType(_sql))
204 {
205 case StmtTransBegin :
207 break;
208 case StmtTransEnd :
210 break;
211 case StmtOther :
212 default :
213 ;
214 }
215
216 return true;
217}
218
220{
221 /* exec sql begin declare section */
222
223
224#line 193 "PgConnection.pgc"
225 char * pszConnectionID = ( _CONST char * ) __connectionID . data () ;
226/* exec sql end declare section */
227#line 194 "PgConnection.pgc"
228
229
230 { ECPGsetconn(__LINE__, pszConnectionID);}
231#line 196 "PgConnection.pgc"
232
233 if (SQLCODE < 0)
234 {
235 __SET_ERROR_SQLCODE(SQLCODE);
236 return false;
237 }
238
239 { ECPGtrans(__LINE__, NULL, "begin work");}
240#line 203 "PgConnection.pgc"
241
242 if (SQLCODE < 0)
243 {
244 __SET_ERROR_SQLCODE(SQLCODE);
245 return false;
246 }
247
249
250 return true;
251}
252
254{
255 /* exec sql begin declare section */
256
257
258#line 218 "PgConnection.pgc"
259 char * pszConnectionID = ( _CONST char * ) __connectionID . data () ;
260/* exec sql end declare section */
261#line 219 "PgConnection.pgc"
262
263
264 { ECPGsetconn(__LINE__, pszConnectionID);}
265#line 221 "PgConnection.pgc"
266
267 if (SQLCODE < 0)
268 {
269 __SET_ERROR_SQLCODE(SQLCODE);
270 return false;
271 }
272
273 { ECPGtrans(__LINE__, NULL, "commit work");}
274#line 228 "PgConnection.pgc"
275
276 if (SQLCODE < 0)
277 {
278 __SET_ERROR_SQLCODE(SQLCODE);
279 return false;
280 }
281
283
284 return true;
285}
286
288{
289 /* exec sql begin declare section */
290
291
292#line 243 "PgConnection.pgc"
293 char * pszConnectionID = ( _CONST char * ) __connectionID . data () ;
294/* exec sql end declare section */
295#line 244 "PgConnection.pgc"
296
297
298 { ECPGsetconn(__LINE__, pszConnectionID);}
299#line 246 "PgConnection.pgc"
300
301 if (SQLCODE < 0)
302 {
303 __SET_ERROR_SQLCODE(SQLCODE);
304 return false;
305 }
306
307 { ECPGtrans(__LINE__, NULL, "rollback work");}
308#line 253 "PgConnection.pgc"
309
310 if (SQLCODE < 0)
311 {
312 __SET_ERROR_SQLCODE(SQLCODE);
313 return false;
314 }
315
317
318 return true;
319}
320
322{
323 __DCL_ASSERT(_queryHandleOut != NULL);
324
325 SQL::Query* pNewQuery = new PgQuery(this);
326 if (!pNewQuery)
327 {
329 return false;
330 }
331
332 *_queryHandleOut = pNewQuery;
333 return true;
334}
335
336void PgConnection::setErrorStatus(SQL::Error _error, long _SQLCODE,
337 const wchar_t* _filename, int _line)
338{
339 Connection::setErrorStatus(_error, _filename, _line);
340 if (_SQLCODE == 0 /* ECPG_NO_ERROR */) {
341 __lastErrorMessage.clear();
342 }
343 else {
344 ByteStringBuilder sb;
345 sb.format("SQLCODE(%d) ", _SQLCODE);
346 sb.append(sqlca.sqlerrm.sqlerrmc, sqlca.sqlerrm.sqlerrml);
347 __lastErrorMessage = sb.toByteString();
348 }
349}
350
351bool PgConnection::__getErrorMessage(char* _buf, size_t* _buflen)
352{
353 __DCL_ASSERT(Connection::__errorCode == SQL::eServerError);
354 if (__lastErrorMessage.length() < *_buflen)
355 *_buflen = __lastErrorMessage.length();
356 strncpy(_buf, __lastErrorMessage.data(), *_buflen);
357 return true;
358}
359
360bool PgConnection::__getServerInfo(char* _buf, size_t* _buflen)
361{
362 PgQuery* pQuery = new PgQuery(this);
363 if (pQuery == NULL) {
365 return false;
366 }
367
368 bool localTrans = false;
370 __startTrans();
371 localTrans = true;
372 }
373
374 const char* _sql = "select version()";
375 for ( ; ; ) {
376 if (!pQuery->prepare(_sql, ByteString::length(_sql), 0))
377 break;
378
379 if (!pQuery->execute())
380 break;
381
382 if (!pQuery->fetch())
383 break;
384
385 if (pQuery->eof()) {
387 break;
388 }
389
390 PgField* pField = NULL;
391 if (!pQuery->__getField(0, (SQL::Field**)&pField))
392 break;
393
394 if (pField->isNull()) {
396 break;
397 }
398
399 if (!pField->__getData(_buf, _buflen, SQL::typeText))
400 break;
401
402 pQuery->__destroy();
403 pQuery = NULL;
404
405 if (localTrans) {
407 }
408 return true;
409 }
410
411 if (pQuery) {
412 pQuery->__destroy();
413 }
414
415 if (localTrans) {
417 }
418 return false;
419}
420
421__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:340
#define _CONST
Definition Config.h:353
@ StmtTransEnd
@ StmtOther
@ StmtTransBegin
#define __DCL_ASSERT(expr)
Definition Object.h:371
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:228
#define __T(str)
Definition Object.h:44
#define __SET_ERROR_SQLCODE(SQLCODE)
#define __SET_ERROR(_error)
#define __SET_ERROR_MSG(_message)
#define __UNSET_STATE(state)
Definition SQLCore.h:431
#define __SET_STATE(state)
Definition SQLCore.h:430
void CharsetConvertException *size_t n
Definition SQLField.cpp:253
virtual void destroy()
Definition Exception.cpp:74
PgConnection(const wchar_t *_serverTitle)
virtual bool __execute(const char *pszSQL, size_t n)
virtual bool __getErrorMessage(char *_buf, size_t *_buflen)
virtual bool __open(const char *_pszConnString, size_t _n)
virtual bool __getServerInfo(char *_buf, size_t *_buflen)
virtual bool __createQueryInstance(SQL::Query **_queryHandleOut)
virtual bool __rollbackTrans()
virtual bool __close()
virtual ~PgConnection()
virtual bool __startTrans()
virtual bool __commitTrans()
void setErrorStatus(SQL::Error _error, long _SQLCODE, const wchar_t *_filename, int _line)
virtual void destroy()
virtual bool __getData(void *_pv, size_t *_size, SQL::DataType _dataType)
Definition PgField.cpp:270
virtual bool isNull() const
Definition PgField.cpp:227
virtual bool __getField(size_t _index, SQL::Field **_fieldHandleOut)
Definition PgQuery.cpp:496
virtual void __destroy()
Definition PgQuery.cpp:85
static bool test(const wchar_t *_regex, const wchar_t *_string, bool _icase=false) __DCL_THROWS1(RegexException *)
Definition Regex.cpp:252
Connection(const wchar_t *_serverTitle)
Definition SQLCore.cpp:653
bool inState(unsigned int uState) const
Definition SQLCore.inl:99
__PROTECTED const wchar_t int _line
Definition SQLCore.h:390
__PROTECTED const wchar_t * _filename
Definition SQLCore.h:390
@ typeText
Definition SQLCore.h:75
Error
Definition SQLCore.h:19
@ eOutOfMemory
Definition SQLCore.h:24
@ eServerError
Definition SQLCore.h:21
@ eNotAvailable
Definition SQLCore.h:38
static long incrementAndGet(volatile long &_n)