This source file includes following definitions.
- _pdo_pgsql_trim_message
- _pdo_pgsql_escape_credentials
- _pdo_pgsql_error
- _pdo_pgsql_notice
- pdo_pgsql_fetch_error_func
- pgsql_lob_write
- pgsql_lob_read
- pgsql_lob_close
- pgsql_lob_flush
- pgsql_lob_seek
- pdo_pgsql_create_lob_stream
- pgsql_handle_closer
- pgsql_handle_preparer
- pgsql_handle_doer
- pgsql_handle_quoter
- pdo_pgsql_last_insert_id
- pdo_pgsql_get_attribute
- pdo_pgsql_check_liveness
- pgsql_handle_in_transaction
- pdo_pgsql_transaction_cmd
- pgsql_handle_begin
- pgsql_handle_commit
- pgsql_handle_rollback
- PHP_METHOD
- PHP_METHOD
- PHP_METHOD
- PHP_METHOD
- PHP_METHOD
- PHP_METHOD
- PHP_METHOD
- PHP_METHOD
- PHP_METHOD
- pdo_pgsql_get_driver_methods
- pdo_pgsql_set_attr
- pdo_pgsql_handle_factory
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "php.h"
28 #include "php_ini.h"
29 #include "ext/standard/info.h"
30 #include "ext/standard/php_string.h"
31 #include "main/php_network.h"
32 #include "pdo/php_pdo.h"
33 #include "pdo/php_pdo_driver.h"
34 #include "pdo/php_pdo_error.h"
35 #include "ext/standard/file.h"
36
37 #undef PACKAGE_BUGREPORT
38 #undef PACKAGE_NAME
39 #undef PACKAGE_STRING
40 #undef PACKAGE_TARNAME
41 #undef PACKAGE_VERSION
42 #include "pg_config.h"
43 #include "php_pdo_pgsql.h"
44 #include "php_pdo_pgsql_int.h"
45 #include "zend_exceptions.h"
46
47 static char * _pdo_pgsql_trim_message(const char *message, int persistent)
48 {
49 register int i = strlen(message)-1;
50 char *tmp;
51
52 if (i>1 && (message[i-1] == '\r' || message[i-1] == '\n') && message[i] == '.') {
53 --i;
54 }
55 while (i>0 && (message[i] == '\r' || message[i] == '\n')) {
56 --i;
57 }
58 ++i;
59 tmp = pemalloc(i + 1, persistent);
60 memcpy(tmp, message, i);
61 tmp[i] = '\0';
62
63 return tmp;
64 }
65
66 static char * _pdo_pgsql_escape_credentials(char *str TSRMLS_DC)
67 {
68 int len;
69
70 if (str) {
71 return php_addcslashes(str, strlen(str), &len, 0, "\\'", sizeof("\\'") TSRMLS_CC);
72 }
73
74 return NULL;
75 }
76
77 int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *sqlstate, const char *msg, const char *file, int line TSRMLS_DC)
78 {
79 pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
80 pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code;
81 pdo_pgsql_error_info *einfo = &H->einfo;
82 char *errmsg = PQerrorMessage(H->server);
83
84 einfo->errcode = errcode;
85 einfo->file = file;
86 einfo->line = line;
87
88 if (einfo->errmsg) {
89 pefree(einfo->errmsg, dbh->is_persistent);
90 einfo->errmsg = NULL;
91 }
92
93 if (sqlstate == NULL || strlen(sqlstate) >= sizeof(pdo_error_type)) {
94 strcpy(*pdo_err, "HY000");
95 }
96 else {
97 strcpy(*pdo_err, sqlstate);
98 }
99
100 if (msg) {
101 einfo->errmsg = estrdup(msg);
102 }
103 else if (errmsg) {
104 einfo->errmsg = _pdo_pgsql_trim_message(errmsg, dbh->is_persistent);
105 }
106
107 if (!dbh->methods) {
108 zend_throw_exception_ex(php_pdo_get_exception(), einfo->errcode TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
109 *pdo_err, einfo->errcode, einfo->errmsg);
110 }
111
112 return errcode;
113 }
114
115
116 static void _pdo_pgsql_notice(pdo_dbh_t *dbh, const char *message)
117 {
118
119 }
120
121
122 static int pdo_pgsql_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
123 {
124 pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
125 pdo_pgsql_error_info *einfo = &H->einfo;
126
127 if (einfo->errcode) {
128 add_next_index_long(info, einfo->errcode);
129 add_next_index_string(info, einfo->errmsg, 1);
130 }
131
132 return 1;
133 }
134
135
136
137 static size_t pgsql_lob_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC)
138 {
139 struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stream->abstract;
140 return lo_write(self->conn, self->lfd, (char*)buf, count);
141 }
142
143 static size_t pgsql_lob_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
144 {
145 struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stream->abstract;
146 return lo_read(self->conn, self->lfd, buf, count);
147 }
148
149 static int pgsql_lob_close(php_stream *stream, int close_handle TSRMLS_DC)
150 {
151 struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stream->abstract;
152 pdo_dbh_t *dbh = self->dbh;
153
154 if (close_handle) {
155 lo_close(self->conn, self->lfd);
156 }
157 efree(self);
158 php_pdo_dbh_delref(dbh TSRMLS_CC);
159 return 0;
160 }
161
162 static int pgsql_lob_flush(php_stream *stream TSRMLS_DC)
163 {
164 return 0;
165 }
166
167 static int pgsql_lob_seek(php_stream *stream, off_t offset, int whence,
168 off_t *newoffset TSRMLS_DC)
169 {
170 struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stream->abstract;
171 int pos = lo_lseek(self->conn, self->lfd, offset, whence);
172 *newoffset = pos;
173 return pos >= 0 ? 0 : -1;
174 }
175
176 php_stream_ops pdo_pgsql_lob_stream_ops = {
177 pgsql_lob_write,
178 pgsql_lob_read,
179 pgsql_lob_close,
180 pgsql_lob_flush,
181 "pdo_pgsql lob stream",
182 pgsql_lob_seek,
183 NULL,
184 NULL,
185 NULL
186 };
187
188 php_stream *pdo_pgsql_create_lob_stream(pdo_dbh_t *dbh, int lfd, Oid oid TSRMLS_DC)
189 {
190 php_stream *stm;
191 struct pdo_pgsql_lob_self *self = ecalloc(1, sizeof(*self));
192 pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
193
194 self->dbh = dbh;
195 self->lfd = lfd;
196 self->oid = oid;
197 self->conn = H->server;
198
199 stm = php_stream_alloc(&pdo_pgsql_lob_stream_ops, self, 0, "r+b");
200
201 if (stm) {
202 php_pdo_dbh_addref(dbh TSRMLS_CC);
203 return stm;
204 }
205
206 efree(self);
207 return NULL;
208 }
209
210
211 static int pgsql_handle_closer(pdo_dbh_t *dbh TSRMLS_DC)
212 {
213 pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
214 if (H) {
215 if (H->server) {
216 PQfinish(H->server);
217 H->server = NULL;
218 }
219 if (H->einfo.errmsg) {
220 pefree(H->einfo.errmsg, dbh->is_persistent);
221 H->einfo.errmsg = NULL;
222 }
223 pefree(H, dbh->is_persistent);
224 dbh->driver_data = NULL;
225 }
226 return 0;
227 }
228
229
230 static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC)
231 {
232 pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
233 pdo_pgsql_stmt *S = ecalloc(1, sizeof(pdo_pgsql_stmt));
234 int scrollable;
235 int ret;
236 char *nsql = NULL;
237 int nsql_len = 0;
238 int emulate = 0;
239 int execute_only = 0;
240
241 S->H = H;
242 stmt->driver_data = S;
243 stmt->methods = &pgsql_stmt_methods;
244
245 scrollable = pdo_attr_lval(driver_options, PDO_ATTR_CURSOR,
246 PDO_CURSOR_FWDONLY TSRMLS_CC) == PDO_CURSOR_SCROLL;
247
248 if (scrollable) {
249 if (S->cursor_name) {
250 efree(S->cursor_name);
251 }
252 spprintf(&S->cursor_name, 0, "pdo_crsr_%08x", ++H->stmt_counter);
253 emulate = 1;
254 } else if (driver_options) {
255 if (pdo_attr_lval(driver_options, PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT, H->disable_native_prepares TSRMLS_CC) == 1) {
256 php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated, use PDO::ATTR_EMULATE_PREPARES instead");
257 emulate = 1;
258 }
259 if (pdo_attr_lval(driver_options, PDO_ATTR_EMULATE_PREPARES, H->emulate_prepares TSRMLS_CC) == 1) {
260 emulate = 1;
261 }
262 if (pdo_attr_lval(driver_options, PDO_PGSQL_ATTR_DISABLE_PREPARES, H->disable_prepares TSRMLS_CC) == 1) {
263 execute_only = 1;
264 }
265 } else {
266 emulate = H->disable_native_prepares || H->emulate_prepares;
267 execute_only = H->disable_prepares;
268 }
269
270 if (!emulate && PQprotocolVersion(H->server) > 2) {
271 stmt->supports_placeholders = PDO_PLACEHOLDER_NAMED;
272 stmt->named_rewrite_template = "$%d";
273 ret = pdo_parse_params(stmt, (char*)sql, sql_len, &nsql, &nsql_len TSRMLS_CC);
274
275 if (ret == 1) {
276
277 sql = nsql;
278 } else if (ret == -1) {
279
280 strcpy(dbh->error_code, stmt->error_code);
281 return 0;
282 }
283
284 if (!execute_only) {
285
286
287 spprintf(&S->stmt_name, 0, "pdo_stmt_%08x", ++H->stmt_counter);
288 }
289
290 if (nsql) {
291 S->query = nsql;
292 } else {
293 S->query = estrdup(sql);
294 }
295
296 return 1;
297 }
298
299 stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
300 return 1;
301 }
302
303 static long pgsql_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
304 {
305 pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
306 PGresult *res;
307 long ret = 1;
308 ExecStatusType qs;
309
310 if (!(res = PQexec(H->server, sql))) {
311
312 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
313 return -1;
314 }
315 qs = PQresultStatus(res);
316 if (qs != PGRES_COMMAND_OK && qs != PGRES_TUPLES_OK) {
317 pdo_pgsql_error(dbh, qs, pdo_pgsql_sqlstate(res));
318 PQclear(res);
319 return -1;
320 }
321 H->pgoid = PQoidValue(res);
322 ret = (qs == PGRES_COMMAND_OK) ? atol(PQcmdTuples(res)) : 0L;
323 PQclear(res);
324
325 return ret;
326 }
327
328 static int pgsql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype TSRMLS_DC)
329 {
330 unsigned char *escaped;
331 pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
332 size_t tmp_len;
333
334 switch (paramtype) {
335 case PDO_PARAM_LOB:
336
337 escaped = PQescapeByteaConn(H->server, (unsigned char *)unquoted, (size_t)unquotedlen, &tmp_len);
338 *quotedlen = (int)tmp_len + 1;
339 *quoted = emalloc(*quotedlen + 1);
340 memcpy((*quoted)+1, escaped, *quotedlen-2);
341 (*quoted)[0] = '\'';
342 (*quoted)[*quotedlen-1] = '\'';
343 (*quoted)[*quotedlen] = '\0';
344 PQfreemem(escaped);
345 break;
346 default:
347 *quoted = safe_emalloc(2, unquotedlen, 3);
348 (*quoted)[0] = '\'';
349 *quotedlen = PQescapeStringConn(H->server, *quoted + 1, unquoted, (size_t)unquotedlen, NULL);
350 (*quoted)[*quotedlen + 1] = '\'';
351 (*quoted)[*quotedlen + 2] = '\0';
352 *quotedlen += 2;
353 }
354 return 1;
355 }
356
357 static char *pdo_pgsql_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC)
358 {
359 pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
360 char *id = NULL;
361
362 if (name == NULL) {
363 if (H->pgoid == InvalidOid) {
364 return NULL;
365 }
366 *len = spprintf(&id, 0, "%ld", (long) H->pgoid);
367 } else {
368 PGresult *res;
369 ExecStatusType status;
370 const char *q[1];
371 q[0] = name;
372 res = PQexecParams(H->server, "SELECT CURRVAL($1)", 1, NULL, q, NULL, NULL, 0);
373 status = PQresultStatus(res);
374
375 if (res && (status == PGRES_TUPLES_OK)) {
376 id = estrdup((char *)PQgetvalue(res, 0, 0));
377 *len = PQgetlength(res, 0, 0);
378 } else {
379 pdo_pgsql_error(dbh, status, pdo_pgsql_sqlstate(res));
380 }
381
382 if (res) {
383 PQclear(res);
384 }
385 }
386 return id;
387 }
388
389 static int pdo_pgsql_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC)
390 {
391 pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
392
393 switch (attr) {
394 case PDO_ATTR_EMULATE_PREPARES:
395 ZVAL_BOOL(return_value, H->emulate_prepares);
396 break;
397
398 case PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT:
399 php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated, use PDO::ATTR_EMULATE_PREPARES instead");
400 ZVAL_BOOL(return_value, H->disable_native_prepares);
401 break;
402
403 case PDO_PGSQL_ATTR_DISABLE_PREPARES:
404 ZVAL_BOOL(return_value, H->disable_prepares);
405 break;
406
407 case PDO_ATTR_CLIENT_VERSION:
408 ZVAL_STRING(return_value, PG_VERSION, 1);
409 break;
410
411 case PDO_ATTR_SERVER_VERSION:
412 if (PQprotocolVersion(H->server) >= 3) {
413 ZVAL_STRING(return_value, (char*)PQparameterStatus(H->server, "server_version"), 1);
414 } else
415 {
416 PGresult *res = PQexec(H->server, "SELECT VERSION()");
417 if (res && PQresultStatus(res) == PGRES_TUPLES_OK) {
418 ZVAL_STRING(return_value, (char *)PQgetvalue(res, 0, 0), 1);
419 }
420
421 if (res) {
422 PQclear(res);
423 }
424 }
425 break;
426
427 case PDO_ATTR_CONNECTION_STATUS:
428 switch (PQstatus(H->server)) {
429 case CONNECTION_STARTED:
430 ZVAL_STRINGL(return_value, "Waiting for connection to be made.", sizeof("Waiting for connection to be made.")-1, 1);
431 break;
432
433 case CONNECTION_MADE:
434 case CONNECTION_OK:
435 ZVAL_STRINGL(return_value, "Connection OK; waiting to send.", sizeof("Connection OK; waiting to send.")-1, 1);
436 break;
437
438 case CONNECTION_AWAITING_RESPONSE:
439 ZVAL_STRINGL(return_value, "Waiting for a response from the server.", sizeof("Waiting for a response from the server.")-1, 1);
440 break;
441
442 case CONNECTION_AUTH_OK:
443 ZVAL_STRINGL(return_value, "Received authentication; waiting for backend start-up to finish.", sizeof("Received authentication; waiting for backend start-up to finish.")-1, 1);
444 break;
445 #ifdef CONNECTION_SSL_STARTUP
446 case CONNECTION_SSL_STARTUP:
447 ZVAL_STRINGL(return_value, "Negotiating SSL encryption.", sizeof("Negotiating SSL encryption.")-1, 1);
448 break;
449 #endif
450 case CONNECTION_SETENV:
451 ZVAL_STRINGL(return_value, "Negotiating environment-driven parameter settings.", sizeof("Negotiating environment-driven parameter settings.")-1, 1);
452 break;
453
454 case CONNECTION_BAD:
455 default:
456 ZVAL_STRINGL(return_value, "Bad connection.", sizeof("Bad connection.")-1, 1);
457 break;
458 }
459 break;
460
461 case PDO_ATTR_SERVER_INFO: {
462 int spid = PQbackendPID(H->server);
463 char *tmp;
464 spprintf(&tmp, 0,
465 "PID: %d; Client Encoding: %s; Is Superuser: %s; Session Authorization: %s; Date Style: %s",
466 spid,
467 (char*)PQparameterStatus(H->server, "client_encoding"),
468 (char*)PQparameterStatus(H->server, "is_superuser"),
469 (char*)PQparameterStatus(H->server, "session_authorization"),
470 (char*)PQparameterStatus(H->server, "DateStyle"));
471 ZVAL_STRING(return_value, tmp, 0);
472 }
473 break;
474
475 default:
476 return 0;
477 }
478
479 return 1;
480 }
481
482
483 static int pdo_pgsql_check_liveness(pdo_dbh_t *dbh TSRMLS_DC)
484 {
485 pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
486 if (PQstatus(H->server) == CONNECTION_BAD) {
487 PQreset(H->server);
488 }
489 return (PQstatus(H->server) == CONNECTION_OK) ? SUCCESS : FAILURE;
490 }
491
492
493 static int pgsql_handle_in_transaction(pdo_dbh_t *dbh TSRMLS_DC)
494 {
495 pdo_pgsql_db_handle *H;
496
497 H = (pdo_pgsql_db_handle *)dbh->driver_data;
498
499 return PQtransactionStatus(H->server) > PQTRANS_IDLE;
500 }
501
502 static int pdo_pgsql_transaction_cmd(const char *cmd, pdo_dbh_t *dbh TSRMLS_DC)
503 {
504 pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
505 PGresult *res;
506 int ret = 1;
507
508 res = PQexec(H->server, cmd);
509
510 if (PQresultStatus(res) != PGRES_COMMAND_OK) {
511 pdo_pgsql_error(dbh, PQresultStatus(res), pdo_pgsql_sqlstate(res));
512 ret = 0;
513 }
514
515 PQclear(res);
516 return ret;
517 }
518
519 static int pgsql_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
520 {
521 return pdo_pgsql_transaction_cmd("BEGIN", dbh TSRMLS_CC);
522 }
523
524 static int pgsql_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
525 {
526 int ret = pdo_pgsql_transaction_cmd("COMMIT", dbh TSRMLS_CC);
527
528
529
530 if (!ret) {
531 dbh->in_txn = pgsql_handle_in_transaction(dbh TSRMLS_CC);
532 }
533
534 return ret;
535 }
536
537 static int pgsql_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
538 {
539 return pdo_pgsql_transaction_cmd("ROLLBACK", dbh TSRMLS_CC);
540 }
541
542
543
544 static PHP_METHOD(PDO, pgsqlCopyFromArray)
545 {
546 pdo_dbh_t *dbh;
547 pdo_pgsql_db_handle *H;
548
549 zval *pg_rows;
550
551 char *table_name, *pg_delim = NULL, *pg_null_as = NULL, *pg_fields = NULL;
552 int table_name_len, pg_delim_len = 0, pg_null_as_len = 0, pg_fields_len;
553 char *query;
554
555 PGresult *pgsql_result;
556 ExecStatusType status;
557
558 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s/a|sss",
559 &table_name, &table_name_len, &pg_rows,
560 &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) == FAILURE) {
561 return;
562 }
563
564 if (!zend_hash_num_elements(Z_ARRVAL_P(pg_rows))) {
565 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot copy from an empty array");
566 RETURN_FALSE;
567 }
568
569 dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
570 PDO_CONSTRUCT_CHECK;
571 PDO_DBH_CLEAR_ERR();
572
573
574 if (pg_fields) {
575 spprintf(&query, 0, "COPY %s (%s) FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));
576 } else {
577 spprintf(&query, 0, "COPY %s FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));
578 }
579
580
581 H = (pdo_pgsql_db_handle *)dbh->driver_data;
582
583 while ((pgsql_result = PQgetResult(H->server))) {
584 PQclear(pgsql_result);
585 }
586 pgsql_result = PQexec(H->server, query);
587
588 efree(query);
589 query = NULL;
590
591 if (pgsql_result) {
592 status = PQresultStatus(pgsql_result);
593 } else {
594 status = (ExecStatusType) PQstatus(H->server);
595 }
596
597 if (status == PGRES_COPY_IN && pgsql_result) {
598 int command_failed = 0;
599 int buffer_len = 0;
600 zval **tmp;
601 HashPosition pos;
602
603 PQclear(pgsql_result);
604 zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(pg_rows), &pos);
605 while (zend_hash_get_current_data_ex(Z_ARRVAL_P(pg_rows), (void **) &tmp, &pos) == SUCCESS) {
606 int query_len;
607 convert_to_string_ex(tmp);
608
609 if (buffer_len < Z_STRLEN_PP(tmp)) {
610 buffer_len = Z_STRLEN_PP(tmp);
611 query = erealloc(query, buffer_len + 2);
612 }
613 memcpy(query, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
614 query_len = Z_STRLEN_PP(tmp);
615 if (query[query_len - 1] != '\n') {
616 query[query_len++] = '\n';
617 }
618 query[query_len] = '\0';
619 if (PQputCopyData(H->server, query, query_len) != 1) {
620 efree(query);
621 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
622 PDO_HANDLE_DBH_ERR();
623 RETURN_FALSE;
624 }
625 zend_hash_move_forward_ex(Z_ARRVAL_P(pg_rows), &pos);
626 }
627 if (query) {
628 efree(query);
629 }
630
631 if (PQputCopyEnd(H->server, NULL) != 1) {
632 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
633 PDO_HANDLE_DBH_ERR();
634 RETURN_FALSE;
635 }
636
637 while ((pgsql_result = PQgetResult(H->server))) {
638 if (PGRES_COMMAND_OK != PQresultStatus(pgsql_result)) {
639 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result));
640 command_failed = 1;
641 }
642 PQclear(pgsql_result);
643 }
644
645 PDO_HANDLE_DBH_ERR();
646 RETURN_BOOL(!command_failed);
647 } else {
648 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result));
649 PQclear(pgsql_result);
650 PDO_HANDLE_DBH_ERR();
651 RETURN_FALSE;
652 }
653 }
654
655
656
657
658 static PHP_METHOD(PDO, pgsqlCopyFromFile)
659 {
660 pdo_dbh_t *dbh;
661 pdo_pgsql_db_handle *H;
662
663 char *table_name, *filename, *pg_delim = NULL, *pg_null_as = NULL, *pg_fields = NULL;
664 int table_name_len, filename_len, pg_delim_len = 0, pg_null_as_len = 0, pg_fields_len;
665 char *query;
666 PGresult *pgsql_result;
667 ExecStatusType status;
668 php_stream *stream;
669
670 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sp|sss",
671 &table_name, &table_name_len, &filename, &filename_len,
672 &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) == FAILURE) {
673 return;
674 }
675
676
677 dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
678 PDO_CONSTRUCT_CHECK;
679 PDO_DBH_CLEAR_ERR();
680
681 stream = php_stream_open_wrapper_ex(filename, "rb", ENFORCE_SAFE_MODE, NULL, FG(default_context));
682 if (!stream) {
683 pdo_pgsql_error_msg(dbh, PGRES_FATAL_ERROR, "Unable to open the file");
684 PDO_HANDLE_DBH_ERR();
685 RETURN_FALSE;
686 }
687
688
689 if (pg_fields) {
690 spprintf(&query, 0, "COPY %s (%s) FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));
691 } else {
692 spprintf(&query, 0, "COPY %s FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));
693 }
694
695 H = (pdo_pgsql_db_handle *)dbh->driver_data;
696
697 while ((pgsql_result = PQgetResult(H->server))) {
698 PQclear(pgsql_result);
699 }
700 pgsql_result = PQexec(H->server, query);
701
702 efree(query);
703
704 if (pgsql_result) {
705 status = PQresultStatus(pgsql_result);
706 } else {
707 status = (ExecStatusType) PQstatus(H->server);
708 }
709
710 if (status == PGRES_COPY_IN && pgsql_result) {
711 char *buf;
712 int command_failed = 0;
713 size_t line_len = 0;
714
715 PQclear(pgsql_result);
716 while ((buf = php_stream_get_line(stream, NULL, 0, &line_len)) != NULL) {
717 if (PQputCopyData(H->server, buf, line_len) != 1) {
718 efree(buf);
719 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
720 php_stream_close(stream);
721 PDO_HANDLE_DBH_ERR();
722 RETURN_FALSE;
723 }
724 efree(buf);
725 }
726 php_stream_close(stream);
727
728 if (PQputCopyEnd(H->server, NULL) != 1) {
729 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
730 PDO_HANDLE_DBH_ERR();
731 RETURN_FALSE;
732 }
733
734 while ((pgsql_result = PQgetResult(H->server))) {
735 if (PGRES_COMMAND_OK != PQresultStatus(pgsql_result)) {
736 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result));
737 command_failed = 1;
738 }
739 PQclear(pgsql_result);
740 }
741
742 PDO_HANDLE_DBH_ERR();
743 RETURN_BOOL(!command_failed);
744 } else {
745 php_stream_close(stream);
746 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result));
747 PQclear(pgsql_result);
748 PDO_HANDLE_DBH_ERR();
749 RETURN_FALSE;
750 }
751 }
752
753
754
755
756
757 static PHP_METHOD(PDO, pgsqlCopyToFile)
758 {
759 pdo_dbh_t *dbh;
760 pdo_pgsql_db_handle *H;
761
762 char *table_name, *pg_delim = NULL, *pg_null_as = NULL, *pg_fields = NULL, *filename = NULL;
763 int table_name_len, pg_delim_len = 0, pg_null_as_len = 0, pg_fields_len, filename_len;
764 char *query;
765
766 PGresult *pgsql_result;
767 ExecStatusType status;
768
769 php_stream *stream;
770
771 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sp|sss",
772 &table_name, &table_name_len, &filename, &filename_len,
773 &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) == FAILURE) {
774 return;
775 }
776
777 dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
778 PDO_CONSTRUCT_CHECK;
779 PDO_DBH_CLEAR_ERR();
780
781 H = (pdo_pgsql_db_handle *)dbh->driver_data;
782
783 stream = php_stream_open_wrapper_ex(filename, "wb", ENFORCE_SAFE_MODE, NULL, FG(default_context));
784 if (!stream) {
785 pdo_pgsql_error_msg(dbh, PGRES_FATAL_ERROR, "Unable to open the file for writing");
786 PDO_HANDLE_DBH_ERR();
787 RETURN_FALSE;
788 }
789
790 while ((pgsql_result = PQgetResult(H->server))) {
791 PQclear(pgsql_result);
792 }
793
794
795 if (pg_fields) {
796 spprintf(&query, 0, "COPY %s (%s) TO STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));
797 } else {
798 spprintf(&query, 0, "COPY %s TO STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));
799 }
800 pgsql_result = PQexec(H->server, query);
801 efree(query);
802
803 if (pgsql_result) {
804 status = PQresultStatus(pgsql_result);
805 } else {
806 status = (ExecStatusType) PQstatus(H->server);
807 }
808
809 if (status == PGRES_COPY_OUT && pgsql_result) {
810 PQclear(pgsql_result);
811 while (1) {
812 char *csv = NULL;
813 int ret = PQgetCopyData(H->server, &csv, 0);
814
815 if (ret == -1) {
816 break;
817 } else if (ret > 0) {
818 if (php_stream_write(stream, csv, ret) != ret) {
819 pdo_pgsql_error_msg(dbh, PGRES_FATAL_ERROR, "Unable to write to file");
820 PQfreemem(csv);
821 php_stream_close(stream);
822 PDO_HANDLE_DBH_ERR();
823 RETURN_FALSE;
824 } else {
825 PQfreemem(csv);
826 }
827 } else {
828 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
829 php_stream_close(stream);
830 PDO_HANDLE_DBH_ERR();
831 RETURN_FALSE;
832 }
833 }
834 php_stream_close(stream);
835
836 while ((pgsql_result = PQgetResult(H->server))) {
837 PQclear(pgsql_result);
838 }
839 RETURN_TRUE;
840 } else {
841 php_stream_close(stream);
842 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result));
843 PQclear(pgsql_result);
844 PDO_HANDLE_DBH_ERR();
845 RETURN_FALSE;
846 }
847 }
848
849
850
851
852 static PHP_METHOD(PDO, pgsqlCopyToArray)
853 {
854 pdo_dbh_t *dbh;
855 pdo_pgsql_db_handle *H;
856
857 char *table_name, *pg_delim = NULL, *pg_null_as = NULL, *pg_fields = NULL;
858 int table_name_len, pg_delim_len = 0, pg_null_as_len = 0, pg_fields_len;
859 char *query;
860
861 PGresult *pgsql_result;
862 ExecStatusType status;
863
864 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sss",
865 &table_name, &table_name_len,
866 &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) == FAILURE) {
867 return;
868 }
869
870 dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
871 PDO_CONSTRUCT_CHECK;
872 PDO_DBH_CLEAR_ERR();
873
874 H = (pdo_pgsql_db_handle *)dbh->driver_data;
875
876 while ((pgsql_result = PQgetResult(H->server))) {
877 PQclear(pgsql_result);
878 }
879
880
881 if (pg_fields) {
882 spprintf(&query, 0, "COPY %s (%s) TO STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));
883 } else {
884 spprintf(&query, 0, "COPY %s TO STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));
885 }
886 pgsql_result = PQexec(H->server, query);
887 efree(query);
888
889 if (pgsql_result) {
890 status = PQresultStatus(pgsql_result);
891 } else {
892 status = (ExecStatusType) PQstatus(H->server);
893 }
894
895 if (status == PGRES_COPY_OUT && pgsql_result) {
896 PQclear(pgsql_result);
897 array_init(return_value);
898
899 while (1) {
900 char *csv = NULL;
901 int ret = PQgetCopyData(H->server, &csv, 0);
902 if (ret == -1) {
903 break;
904 } else if (ret > 0) {
905 add_next_index_stringl(return_value, csv, ret, 1);
906 PQfreemem(csv);
907 } else {
908 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
909 PDO_HANDLE_DBH_ERR();
910 RETURN_FALSE;
911 }
912 }
913
914 while ((pgsql_result = PQgetResult(H->server))) {
915 PQclear(pgsql_result);
916 }
917 } else {
918 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result));
919 PQclear(pgsql_result);
920 PDO_HANDLE_DBH_ERR();
921 RETURN_FALSE;
922 }
923 }
924
925
926
927
928
929 static PHP_METHOD(PDO, pgsqlLOBCreate)
930 {
931 pdo_dbh_t *dbh;
932 pdo_pgsql_db_handle *H;
933 Oid lfd;
934
935 dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
936 PDO_CONSTRUCT_CHECK;
937 PDO_DBH_CLEAR_ERR();
938
939 H = (pdo_pgsql_db_handle *)dbh->driver_data;
940 lfd = lo_creat(H->server, INV_READ|INV_WRITE);
941
942 if (lfd != InvalidOid) {
943 char *buf;
944 spprintf(&buf, 0, "%lu", (long) lfd);
945 RETURN_STRING(buf, 0);
946 }
947
948 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
949 PDO_HANDLE_DBH_ERR();
950 RETURN_FALSE;
951 }
952
953
954
955
956 static PHP_METHOD(PDO, pgsqlLOBOpen)
957 {
958 pdo_dbh_t *dbh;
959 pdo_pgsql_db_handle *H;
960 Oid oid;
961 int lfd;
962 char *oidstr;
963 int oidstrlen;
964 char *modestr = "rb";
965 int modestrlen;
966 int mode = INV_READ;
967 char *end_ptr;
968
969 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s",
970 &oidstr, &oidstrlen, &modestr, &modestrlen)) {
971 RETURN_FALSE;
972 }
973
974 oid = (Oid)strtoul(oidstr, &end_ptr, 10);
975 if (oid == 0 && (errno == ERANGE || errno == EINVAL)) {
976 RETURN_FALSE;
977 }
978
979 if (strpbrk(modestr, "+w")) {
980 mode = INV_READ|INV_WRITE;
981 }
982
983 dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
984 PDO_CONSTRUCT_CHECK;
985 PDO_DBH_CLEAR_ERR();
986
987 H = (pdo_pgsql_db_handle *)dbh->driver_data;
988
989 lfd = lo_open(H->server, oid, mode);
990
991 if (lfd >= 0) {
992 php_stream *stream = pdo_pgsql_create_lob_stream(dbh, lfd, oid TSRMLS_CC);
993 if (stream) {
994 php_stream_to_zval(stream, return_value);
995 return;
996 }
997 } else {
998 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
999 }
1000
1001 PDO_HANDLE_DBH_ERR();
1002 RETURN_FALSE;
1003 }
1004
1005
1006
1007
1008 static PHP_METHOD(PDO, pgsqlLOBUnlink)
1009 {
1010 pdo_dbh_t *dbh;
1011 pdo_pgsql_db_handle *H;
1012 Oid oid;
1013 char *oidstr, *end_ptr;
1014 int oidlen;
1015
1016 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
1017 &oidstr, &oidlen)) {
1018 RETURN_FALSE;
1019 }
1020
1021 oid = (Oid)strtoul(oidstr, &end_ptr, 10);
1022 if (oid == 0 && (errno == ERANGE || errno == EINVAL)) {
1023 RETURN_FALSE;
1024 }
1025
1026 dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
1027 PDO_CONSTRUCT_CHECK;
1028 PDO_DBH_CLEAR_ERR();
1029
1030 H = (pdo_pgsql_db_handle *)dbh->driver_data;
1031
1032 if (1 == lo_unlink(H->server, oid)) {
1033 RETURN_TRUE;
1034 }
1035
1036 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
1037 PDO_HANDLE_DBH_ERR();
1038 RETURN_FALSE;
1039 }
1040
1041
1042
1043
1044 static PHP_METHOD(PDO, pgsqlGetNotify)
1045 {
1046 pdo_dbh_t *dbh;
1047 pdo_pgsql_db_handle *H;
1048 long result_type = PDO_FETCH_USE_DEFAULT;
1049 long ms_timeout = 0;
1050 PGnotify *pgsql_notify;
1051
1052 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll",
1053 &result_type, &ms_timeout)) {
1054 RETURN_FALSE;
1055 }
1056
1057 dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
1058 PDO_CONSTRUCT_CHECK;
1059
1060 if (result_type == PDO_FETCH_USE_DEFAULT) {
1061 result_type = dbh->default_fetch_type;
1062 }
1063
1064 if (result_type != PDO_FETCH_BOTH && result_type != PDO_FETCH_ASSOC && result_type != PDO_FETCH_NUM) {
1065 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid result type");
1066 RETURN_FALSE;
1067 }
1068
1069 if (ms_timeout < 0) {
1070 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid timeout");
1071 RETURN_FALSE;
1072 }
1073
1074 H = (pdo_pgsql_db_handle *)dbh->driver_data;
1075
1076 PQconsumeInput(H->server);
1077 pgsql_notify = PQnotifies(H->server);
1078
1079 if (ms_timeout && !pgsql_notify) {
1080 php_pollfd_for_ms(PQsocket(H->server), PHP_POLLREADABLE, ms_timeout);
1081
1082 PQconsumeInput(H->server);
1083 pgsql_notify = PQnotifies(H->server);
1084 }
1085
1086 if (!pgsql_notify) {
1087 RETURN_FALSE;
1088 }
1089
1090 array_init(return_value);
1091 if (result_type == PDO_FETCH_NUM || result_type == PDO_FETCH_BOTH) {
1092 add_index_string(return_value, 0, pgsql_notify->relname, 1);
1093 add_index_long(return_value, 1, pgsql_notify->be_pid);
1094 if (pgsql_notify->extra && pgsql_notify->extra[0]) {
1095 add_index_string(return_value, 2, pgsql_notify->extra, 1);
1096 }
1097 }
1098 if (result_type == PDO_FETCH_ASSOC || result_type == PDO_FETCH_BOTH) {
1099 add_assoc_string(return_value, "message", pgsql_notify->relname, 1);
1100 add_assoc_long(return_value, "pid", pgsql_notify->be_pid);
1101 if (pgsql_notify->extra && pgsql_notify->extra[0]) {
1102 add_assoc_string(return_value, "payload", pgsql_notify->extra, 1);
1103 }
1104 }
1105
1106 PQfreemem(pgsql_notify);
1107 }
1108
1109
1110
1111
1112 static PHP_METHOD(PDO, pgsqlGetPid)
1113 {
1114 pdo_dbh_t *dbh;
1115 pdo_pgsql_db_handle *H;
1116
1117 dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
1118 PDO_CONSTRUCT_CHECK;
1119
1120 H = (pdo_pgsql_db_handle *)dbh->driver_data;
1121
1122 RETURN_LONG(PQbackendPID(H->server));
1123 }
1124
1125
1126
1127 static const zend_function_entry dbh_methods[] = {
1128 PHP_ME(PDO, pgsqlLOBCreate, NULL, ZEND_ACC_PUBLIC)
1129 PHP_ME(PDO, pgsqlLOBOpen, NULL, ZEND_ACC_PUBLIC)
1130 PHP_ME(PDO, pgsqlLOBUnlink, NULL, ZEND_ACC_PUBLIC)
1131 PHP_ME(PDO, pgsqlCopyFromArray, NULL, ZEND_ACC_PUBLIC)
1132 PHP_ME(PDO, pgsqlCopyFromFile, NULL, ZEND_ACC_PUBLIC)
1133 PHP_ME(PDO, pgsqlCopyToArray, NULL, ZEND_ACC_PUBLIC)
1134 PHP_ME(PDO, pgsqlCopyToFile, NULL, ZEND_ACC_PUBLIC)
1135 PHP_ME(PDO, pgsqlGetNotify, NULL, ZEND_ACC_PUBLIC)
1136 PHP_ME(PDO, pgsqlGetPid, NULL, ZEND_ACC_PUBLIC)
1137 PHP_FE_END
1138 };
1139
1140 static const zend_function_entry *pdo_pgsql_get_driver_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC)
1141 {
1142 switch (kind) {
1143 case PDO_DBH_DRIVER_METHOD_KIND_DBH:
1144 return dbh_methods;
1145 default:
1146 return NULL;
1147 }
1148 }
1149
1150 static int pdo_pgsql_set_attr(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
1151 {
1152 pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
1153
1154 switch (attr) {
1155 case PDO_ATTR_EMULATE_PREPARES:
1156 H->emulate_prepares = Z_LVAL_P(val);
1157 return 1;
1158 case PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT:
1159 php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated, use PDO::ATTR_EMULATE_PREPARES instead");
1160 H->disable_native_prepares = Z_LVAL_P(val);
1161 return 1;
1162 case PDO_PGSQL_ATTR_DISABLE_PREPARES:
1163 H->disable_prepares = Z_LVAL_P(val);
1164 return 1;
1165 default:
1166 return 0;
1167 }
1168 }
1169
1170 static struct pdo_dbh_methods pgsql_methods = {
1171 pgsql_handle_closer,
1172 pgsql_handle_preparer,
1173 pgsql_handle_doer,
1174 pgsql_handle_quoter,
1175 pgsql_handle_begin,
1176 pgsql_handle_commit,
1177 pgsql_handle_rollback,
1178 pdo_pgsql_set_attr,
1179 pdo_pgsql_last_insert_id,
1180 pdo_pgsql_fetch_error_func,
1181 pdo_pgsql_get_attribute,
1182 pdo_pgsql_check_liveness,
1183 pdo_pgsql_get_driver_methods,
1184 NULL,
1185 pgsql_handle_in_transaction,
1186 };
1187
1188 static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC)
1189 {
1190 pdo_pgsql_db_handle *H;
1191 int ret = 0;
1192 char *conn_str, *p, *e;
1193 char *tmp_user, *tmp_pass;
1194 long connect_timeout = 30;
1195
1196 H = pecalloc(1, sizeof(pdo_pgsql_db_handle), dbh->is_persistent);
1197 dbh->driver_data = H;
1198
1199 H->einfo.errcode = 0;
1200 H->einfo.errmsg = NULL;
1201
1202
1203
1204
1205 e = (char *) dbh->data_source + strlen(dbh->data_source);
1206 p = (char *) dbh->data_source;
1207 while ((p = memchr(p, ';', (e - p)))) {
1208 *p = ' ';
1209 }
1210
1211 if (driver_options) {
1212 connect_timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, 30 TSRMLS_CC);
1213 }
1214
1215
1216 tmp_user = _pdo_pgsql_escape_credentials(dbh->username TSRMLS_CC);
1217 tmp_pass = _pdo_pgsql_escape_credentials(dbh->password TSRMLS_CC);
1218
1219
1220 if (tmp_user && tmp_pass) {
1221 spprintf(&conn_str, 0, "%s user='%s' password='%s' connect_timeout=%ld", dbh->data_source, tmp_user, tmp_pass, connect_timeout);
1222 } else if (tmp_user) {
1223 spprintf(&conn_str, 0, "%s user='%s' connect_timeout=%ld", dbh->data_source, tmp_user, connect_timeout);
1224 } else if (tmp_pass) {
1225 spprintf(&conn_str, 0, "%s password='%s' connect_timeout=%ld", dbh->data_source, tmp_pass, connect_timeout);
1226 } else {
1227 spprintf(&conn_str, 0, "%s connect_timeout=%ld", (char *) dbh->data_source, connect_timeout);
1228 }
1229
1230 H->server = PQconnectdb(conn_str);
1231
1232 if (tmp_user) {
1233 efree(tmp_user);
1234 }
1235 if (tmp_pass) {
1236 efree(tmp_pass);
1237 }
1238
1239 efree(conn_str);
1240
1241 if (PQstatus(H->server) != CONNECTION_OK) {
1242 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, PHP_PDO_PGSQL_CONNECTION_FAILURE_SQLSTATE);
1243 goto cleanup;
1244 }
1245
1246 PQsetNoticeProcessor(H->server, (void(*)(void*,const char*))_pdo_pgsql_notice, (void *)&dbh);
1247
1248 H->attached = 1;
1249 H->pgoid = -1;
1250
1251 dbh->methods = &pgsql_methods;
1252 dbh->alloc_own_columns = 1;
1253 dbh->max_escaped_char_length = 2;
1254
1255 ret = 1;
1256
1257 cleanup:
1258 dbh->methods = &pgsql_methods;
1259 if (!ret) {
1260 pgsql_handle_closer(dbh TSRMLS_CC);
1261 }
1262
1263 return ret;
1264 }
1265
1266
1267 pdo_driver_t pdo_pgsql_driver = {
1268 PDO_DRIVER_HEADER(pgsql),
1269 pdo_pgsql_handle_factory
1270 };
1271
1272
1273
1274
1275
1276
1277
1278
1279