else
PGSQL_SEARCH_PATHS=$PHP_PDO_PGSQL
fi
-
+
for i in $PGSQL_SEARCH_PATHS; do
for j in include include/pgsql include/postgres include/postgresql ""; do
if test -r "$i/$j/libpq-fe.h"; then
done
for j in $PHP_LIBDIR $PHP_LIBDIR/pgsql $PHP_LIBDIR/postgres $PHP_LIBDIR/postgresql ""; do
- if test -f "$i/$j/libpq.so" || test -f "$i/$j/libpq.a"; then
+ if test -f "$i/$j/libpq.so" || test -f "$i/$j/libpq.a"; then
PGSQL_LIBDIR=$i/$j
fi
done
old_LIBS=$LIBS
old_LDFLAGS=$LDFLAGS
LDFLAGS="-L$PGSQL_LIBDIR $LDFLAGS"
- AC_CHECK_LIB(pq, PQparameterStatus,AC_DEFINE(HAVE_PQPARAMETERSTATUS,1,[PostgreSQL 7.4 or later]), [
- echo "Unable to build the PDO PostgreSQL driver: libpq 7.4+ is required"
- exit 1
- ])
-
- AC_CHECK_LIB(pq, PQprepare,AC_DEFINE(HAVE_PQPREPARE,1,[PostgreSQL 8.0 or later]))
- AC_CHECK_LIB(pq, PQescapeStringConn, AC_DEFINE(HAVE_PQESCAPE_CONN,1,[PostgreSQL 8.1.4 or later]))
- AC_CHECK_LIB(pq, PQescapeByteaConn, AC_DEFINE(HAVE_PQESCAPE_BYTEA_CONN,1,[PostgreSQL 8.1.4 or later]))
- AC_CHECK_LIB(pq, pg_encoding_to_char,AC_DEFINE(HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT,1,[Whether libpq is compiled with --enable-multibyte]))
-
+ AC_CHECK_LIB(pq, PQprepare,, AC_MSG_ERROR([Unable to build the PDO PostgreSQL driver: a newer libpq is required]))
+ AC_CHECK_LIB(pq, PQexecParams,, AC_MSG_ERROR([Unable to build the PDO PostgreSQL driver: a newer libpq is required]))
+ AC_CHECK_LIB(pq, PQescapeStringConn,, AC_MSG_ERROR([Unable to build the PDO PostgreSQL driver: a newer libpq is required]))
+ AC_CHECK_LIB(pq, PQescapeByteaConn,, AC_MSG_ERROR([Unable to build the PDO PostgreSQL driver: a newer libpq is required]))
LIBS=$old_LIBS
LDFLAGS=$old_LDFLAGS
PHP_NEW_EXTENSION(pdo_pgsql, pdo_pgsql.c pgsql_driver.c pgsql_statement.c, $ext_shared,,-I$pdo_cv_inc_path $PDO_PGSQL_CFLAGS)
ifdef([PHP_ADD_EXTENSION_DEP],
[
- PHP_ADD_EXTENSION_DEP(pdo_pgsql, pdo)
+ PHP_ADD_EXTENSION_DEP(pdo_pgsql, pdo)
])
fi
}
AC_DEFINE('HAVE_PDO_PGSQL', 1, 'Have PostgreSQL library');
- AC_DEFINE('HAVE_PQESCAPE_BYTEA_CONN', 1, 'Have PQescapeByteaConn');
- AC_DEFINE('HAVE_PQESCAPE_CONN', 1, 'Have PQescapeConn');
- AC_DEFINE('HAVE_PQPREPARE', 1, 'Have PQprepare');
- ADD_FLAG('CFLAGS_PDO_PGSQL', "/D HAVE_PQPARAMETERSTATUS=1 /D HAVE_PQPROTOCOLVERSION=1 /D HAVE_PGTRANSACTIONSTATUS=1 /D HAVE_PQUNESCAPEBYTEA=1 /D HAVE_PQRESULTERRORFIELD=1 /D HAVE_PQESCAPE_CONN=1 /D HAVE_PQESCAPE_BYTEA_CONN=1");
+
ADD_EXTENSION_DEP('pdo_pgsql', 'pdo');
} else {
WARNING("pdo_pgsql not enabled; libraries and headers not found");
tmp = pemalloc(i + 1, persistent);
memcpy(tmp, message, i);
tmp[i] = '\0';
-
+
return tmp;
}
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
pdo_pgsql_stmt *S = ecalloc(1, sizeof(pdo_pgsql_stmt));
int scrollable;
-#if HAVE_PQPREPARE
int ret;
char *nsql = NULL;
int nsql_len = 0;
int emulate = 0;
-#endif
S->H = H;
stmt->driver_data = S;
efree(S->cursor_name);
}
spprintf(&S->cursor_name, 0, "pdo_crsr_%08x", ++H->stmt_counter);
-#if HAVE_PQPREPARE
emulate = 1;
-#endif
- }
-
-#if HAVE_PQPREPARE
- else if (driver_options) {
+ } else if (driver_options) {
if (pdo_attr_lval(driver_options, PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT, H->disable_native_prepares TSRMLS_CC) == 1 ||
pdo_attr_lval(driver_options, PDO_ATTR_EMULATE_PREPARES, H->emulate_prepares TSRMLS_CC) == 1) {
emulate = 1;
spprintf(&S->stmt_name, 0, "pdo_stmt_%08x", ++H->stmt_counter);
/* that's all for now; we'll defer the actual prepare until the first execute call */
-
+
if (nsql) {
S->query = nsql;
} else {
return 1;
}
-#endif
stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
return 1;
PGresult *res;
long ret = 1;
ExecStatusType qs;
-
+
if (!(res = PQexec(H->server, sql))) {
/* fatal error */
pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
unsigned char *escaped;
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
size_t tmp_len;
-
+
switch (paramtype) {
case PDO_PARAM_LOB:
/* escapedlen returned by PQescapeBytea() accounts for trailing 0 */
-#ifdef HAVE_PQESCAPE_BYTEA_CONN
escaped = PQescapeByteaConn(H->server, (unsigned char *)unquoted, (size_t)unquotedlen, &tmp_len);
-#else
- escaped = PQescapeBytea((unsigned char *)unquoted, (size_t)unquotedlen, &tmp_len);
-#endif
*quotedlen = (int)tmp_len + 1;
*quoted = emalloc(*quotedlen + 1);
memcpy((*quoted)+1, escaped, *quotedlen-2);
default:
*quoted = safe_emalloc(2, unquotedlen, 3);
(*quoted)[0] = '\'';
-#ifndef HAVE_PQESCAPE_CONN
- *quotedlen = PQescapeString(*quoted + 1, unquoted, (size_t)unquotedlen);
-#else
*quotedlen = PQescapeStringConn(H->server, *quoted + 1, unquoted, (size_t)unquotedlen, NULL);
-#endif
(*quoted)[*quotedlen + 1] = '\'';
(*quoted)[*quotedlen + 2] = '\0';
*quotedlen += 2;
case PDO_ATTR_SERVER_INFO: {
int spid = PQbackendPID(H->server);
char *tmp;
- spprintf(&tmp, 0,
- "PID: %d; Client Encoding: %s; Is Superuser: %s; Session Authorization: %s; Date Style: %s",
+ spprintf(&tmp, 0,
+ "PID: %d; Client Encoding: %s; Is Superuser: %s; Session Authorization: %s; Date Style: %s",
spid,
(char*)PQparameterStatus(H->server, "client_encoding"),
(char*)PQparameterStatus(H->server, "is_superuser"),
break;
default:
- return 0;
+ return 0;
}
return 1;
while (zend_hash_get_current_data_ex(Z_ARRVAL_P(pg_rows), (void **) &tmp, &pos) == SUCCESS) {
int query_len;
convert_to_string_ex(tmp);
-
+
if (buffer_len < Z_STRLEN_PP(tmp)) {
buffer_len = Z_STRLEN_PP(tmp);
query = erealloc(query, buffer_len + 2); /* room for \n\0 */
int ret = PQgetCopyData(H->server, &csv, 0);
if (ret == -1) {
break; /* copy done */
- } else if (ret > 0) {
+ } else if (ret > 0) {
add_next_index_stringl(return_value, csv, ret, 1);
PQfreemem(csv);
} else {
if (strpbrk(modestr, "+w")) {
mode = INV_READ|INV_WRITE;
}
-
+
dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
PDO_CONSTRUCT_CHECK;
PDO_DBH_CLEAR_ERR();
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
switch (attr) {
-#if HAVE_PQPREPARE
case PDO_ATTR_EMULATE_PREPARES:
H->emulate_prepares = Z_LVAL_P(val);
return 1;
case PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT:
H->disable_native_prepares = Z_LVAL_P(val);
return 1;
-#endif
-
default:
return 0;
}
H->einfo.errcode = 0;
H->einfo.errmsg = NULL;
-
+
/* PostgreSQL wants params in the connect string to be separated by spaces,
* if the PDO standard semicolons are used, we convert them to spaces
*/
dbh->max_escaped_char_length = 2;
ret = 1;
-
+
cleanup:
dbh->methods = &pgsql_methods;
if (!ret) {
S->result = NULL;
}
-#if HAVE_PQPREPARE
if (S->stmt_name) {
pdo_pgsql_db_handle *H = S->H;
char *q = NULL;
efree(S->query);
S->query = NULL;
}
-#endif
if (S->cursor_name) {
pdo_pgsql_db_handle *H = S->H;
efree(S->cursor_name);
S->cursor_name = NULL;
}
-
+
if(S->cols) {
efree(S->cols);
S->cols = NULL;
PQclear(S->result);
S->result = NULL;
}
-
+
S->current_row = 0;
if (S->cursor_name) {
spprintf(&q, 0, "FETCH FORWARD 0 FROM %s", S->cursor_name);
S->result = PQexec(H->server, q);
efree(q);
- } else
-#if HAVE_PQPREPARE
- if (S->stmt_name) {
+ } else if (S->stmt_name) {
/* using a prepared statement */
if (!S->is_prepared) {
stmt_retry:
/* we deferred the prepare until now, because we didn't
* know anything about the parameter types; now we do */
- S->result = PQprepare(H->server, S->stmt_name, S->query,
+ S->result = PQprepare(H->server, S->stmt_name, S->query,
stmt->bound_params ? zend_hash_num_elements(stmt->bound_params) : 0,
S->param_types);
status = PQresultStatus(S->result);
break;
default: {
char *sqlstate = pdo_pgsql_sqlstate(S->result);
- /* 42P05 means that the prepared statement already existed. this can happen if you use
- * a connection pooling software line pgpool which doesn't close the db-connection once
- * php disconnects. if php dies (no chance to run RSHUTDOWN) during execution it has no
- * chance to DEALLOCATE the prepared statements it has created. so, if we hit a 42P05 we
+ /* 42P05 means that the prepared statement already existed. this can happen if you use
+ * a connection pooling software line pgpool which doesn't close the db-connection once
+ * php disconnects. if php dies (no chance to run RSHUTDOWN) during execution it has no
+ * chance to DEALLOCATE the prepared statements it has created. so, if we hit a 42P05 we
* deallocate it and retry ONCE (thies 2005.12.15)
*/
if (sqlstate && !strcmp(sqlstate, "42P05")) {
S->param_lengths,
S->param_formats,
0);
- } else
-#endif
- {
+ } else {
S->result = PQexec(H->server, stmt->active_query_string);
}
status = PQresultStatus(S->result);
static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
enum pdo_param_event event_type TSRMLS_DC)
{
-#if HAVE_PQPREPARE
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
if (S->stmt_name && param->is_param) {
return 1;
} else {
int len;
-
+
SEPARATE_ZVAL_IF_NOT_REF(¶m->parameter);
Z_TYPE_P(param->parameter) = IS_STRING;
-
+
if ((len = php_stream_copy_to_mem(stm, &Z_STRVAL_P(param->parameter), PHP_STREAM_COPY_ALL, 0)) > 0) {
Z_STRLEN_P(param->parameter) = len;
} else {
}
break;
}
- } else {
-#endif
- if (param->is_param) {
- /* We need to manually convert to a pg native boolean value */
- if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL &&
- ((param->param_type & PDO_PARAM_INPUT_OUTPUT) != PDO_PARAM_INPUT_OUTPUT)) {
- SEPARATE_ZVAL(¶m->parameter);
- param->param_type = PDO_PARAM_STR;
- ZVAL_STRINGL(param->parameter, Z_BVAL_P(param->parameter) ? "t" : "f", 1, 1);
- }
- }
-#if HAVE_PQPREPARE
+ } else if (param->is_param) {
+ /* We need to manually convert to a pg native boolean value */
+ if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL &&
+ ((param->param_type & PDO_PARAM_INPUT_OUTPUT) != PDO_PARAM_INPUT_OUTPUT)) {
+ SEPARATE_ZVAL(¶m->parameter);
+ param->param_type = PDO_PARAM_STR;
+ ZVAL_STRINGL(param->parameter, Z_BVAL_P(param->parameter) ? "t" : "f", 1, 1);
+ }
}
-#endif
return 1;
}
default:
return 0;
}
-
+
spprintf(&q, 0, "FETCH %s FROM %s", ori_str, S->cursor_name);
efree(ori_str);
S->result = PQexec(S->H->server, q);
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
struct pdo_column_data *cols = stmt->columns;
struct pdo_bound_param_data *param;
-
+
if (!S->result) {
return 0;
}
cols[colno].maxlen = PQfsize(S->result, colno);
cols[colno].precision = PQfmod(S->result, colno);
S->cols[colno].pgsql_type = PQftype(S->result, colno);
-
+
switch(S->cols[colno].pgsql_type) {
case BOOLOID:
cols[colno].param_type = PDO_PARAM_BOOL;
break;
-
+
case OIDOID:
/* did the user bind the column as a LOB ? */
if (stmt->bound_columns && (
} else {
*ptr = PQgetvalue(S->result, S->current_row - 1, colno);
*len = PQgetlength(S->result, S->current_row - 1, colno);
-
+
switch(cols[colno].param_type) {
case PDO_PARAM_INT:
*ptr = (char *) &(S->cols[colno].boolval);
*len = sizeof(zend_bool);
break;
-
+
case PDO_PARAM_LOB:
if (S->cols[colno].pgsql_type == OIDOID) {
/* ooo, a real large object */
PGresult *res;
char *q=NULL;
ExecStatusType status;
-
+
if (!S->result) {
return FAILURE;
}
-
+
if (colno >= stmt->column_count) {
return FAILURE;
}
-
+
array_init(return_value);
add_assoc_long(return_value, "pgsql:oid", S->cols[colno].pgsql_type);
spprintf(&q, 0, "SELECT TYPNAME FROM PG_TYPE WHERE OID=%u", S->cols[colno].pgsql_type);
res = PQexec(S->H->server, q);
efree(q);
-
+
status = PQresultStatus(res);
-
+
if (status != PGRES_TUPLES_OK) {
/* Failed to get system catalogue, but return success
* with the data we have collected so far
add_assoc_string(return_value, "native_type", PQgetvalue(res, 0, 0), 1);
done:
- PQclear(res);
+ PQclear(res);
return 1;
}
unsigned _reserved:31;
pdo_pgsql_error_info einfo;
Oid pgoid;
-#if HAVE_PQPREPARE
/* The following two variables have the same purpose. Unfortunately we need
to keep track of two different attributes having the same effect.
It might be worth to deprecate the driver specific one soon. */
int emulate_prepares;
int disable_native_prepares;
-#endif
- unsigned int stmt_counter;
+ unsigned int stmt_counter;
} pdo_pgsql_db_handle;
typedef struct {
int current_row;
pdo_pgsql_column *cols;
char *cursor_name;
-#if HAVE_PQPREPARE
char *stmt_name;
char *query;
char **param_values;
int *param_lengths;
int *param_formats;
Oid *param_types;
-#endif
zend_bool is_prepared;
} pdo_pgsql_stmt;