diff options
Diffstat (limited to 'ext/pgsql')
| -rw-r--r-- | ext/pgsql/config.m4 | 5 | ||||
| -rw-r--r-- | ext/pgsql/config.w32 | 4 | ||||
| -rw-r--r-- | ext/pgsql/pgsql.c | 184 | ||||
| -rw-r--r-- | ext/pgsql/php_pgsql.h | 3 |
4 files changed, 166 insertions, 30 deletions
diff --git a/ext/pgsql/config.m4 b/ext/pgsql/config.m4 index e15344d91..88d0faff1 100644 --- a/ext/pgsql/config.m4 +++ b/ext/pgsql/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.46.2.1 2006/01/05 21:53:19 sniper Exp $ +dnl $Id: config.m4,v 1.46.2.1.2.3 2006/10/06 21:45:10 iliaa Exp $ dnl AC_DEFUN([PHP_PGSQL_CHECK_FUNCTIONS],[ @@ -90,6 +90,9 @@ if test "$PHP_PGSQL" != "no"; then AC_CHECK_LIB(pq, PQputCopyEnd,AC_DEFINE(HAVE_PQPUTCOPYEND,1,[PostgreSQL 7.4 or later])) AC_CHECK_LIB(pq, PQgetCopyData,AC_DEFINE(HAVE_PQGETCOPYDATA,1,[PostgreSQL 7.4 or later])) AC_CHECK_LIB(pq, PQsetErrorVerbosity,AC_DEFINE(HAVE_PQSETERRORVERBOSITY,1,[PostgreSQL 7.4 or later])) + AC_CHECK_LIB(pq, PQftable,AC_DEFINE(HAVE_PQFTABLE,1,[PostgreSQL 7.4 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])) LIBS=$old_LIBS LDFLAGS=$old_LDFLAGS diff --git a/ext/pgsql/config.w32 b/ext/pgsql/config.w32 index 4ac49276f..414bfbd97 100644 --- a/ext/pgsql/config.w32 +++ b/ext/pgsql/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.7 2005/06/05 19:25:01 wez Exp $ +// $Id: config.w32,v 1.7.4.3 2006/10/11 11:00:02 edink Exp $ // vim:ft=javascript ARG_WITH("pgsql", "PostgreSQL support", "no"); @@ -8,7 +8,7 @@ if (PHP_PGSQL != "no") { CHECK_HEADER_ADD_INCLUDE("libpq-fe.h", "CFLAGS_PGSQL", PHP_PGSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\pgsql;" + PHP_PGSQL)) { EXTENSION("pgsql", "pgsql.c"); AC_DEFINE('HAVE_PGSQL', 1, 'Have PostgreSQL library'); - ADD_FLAG("CFLAGS_PGSQL", "/D HAVE_PG_CONFIG_H /D PGSQL_EXPORTS /D HAVE_PQSETNONBLOCKING /D HAVE_PQCMDTUPLES /D HAVE_PQCLIENTENCODING /D HAVE_PQESCAPE /D HAVE_PQPARAMETERSTATUS /D HAVE_PGTRANSACTIONSTATUS /D HAVE_PQEXECPARAMS /D HAVE_PQPREPARE /D HAVE_PQEXECPREPARED /D HAVE_PQRESULTERRORFIELD /D HAVE_PQSENDQUERYPARAMS /D HAVE_PQSENDPREPARE /D HAVE_PQSENDQUERYPREPARED /D HAVE_PQPUTCOPYDATA /D HAVE_PQPUTCOPYEND /D HAVE_PQGETCOPYDATA /D HAVE_PQSETERRORVERBOSITY /D HAVE_PQUNESCAPEBYTEA"); + ADD_FLAG("CFLAGS_PGSQL", "/D HAVE_PG_CONFIG_H /D PGSQL_EXPORTS /D HAVE_PQSETNONBLOCKING /D HAVE_PQCMDTUPLES /D HAVE_PQCLIENTENCODING /D HAVE_PQESCAPE /D HAVE_PQPARAMETERSTATUS /D HAVE_PGTRANSACTIONSTATUS /D HAVE_PQEXECPARAMS /D HAVE_PQPREPARE /D HAVE_PQEXECPREPARED /D HAVE_PQRESULTERRORFIELD /D HAVE_PQSENDQUERYPARAMS /D HAVE_PQSENDPREPARE /D HAVE_PQSENDQUERYPREPARED /D HAVE_PQPUTCOPYDATA /D HAVE_PQPUTCOPYEND /D HAVE_PQGETCOPYDATA /D HAVE_PQSETERRORVERBOSITY /D HAVE_PQUNESCAPEBYTEA /D HAVE_PQFTABLE /D HAVE_PQESCAPE_CONN /D HAVE_PQESCAPE_BYTEA_CONN"); } else { WARNING("pgsql not enabled; libraries and headers not found"); } diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index df233118e..7439d7f3d 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -20,7 +20,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pgsql.c,v 1.331.2.13 2006/04/10 19:51:55 helly Exp $ */ +/* $Id: pgsql.c,v 1.331.2.13.2.9 2006/10/06 21:45:10 iliaa Exp $ */ #include <stdlib.h> @@ -81,6 +81,9 @@ #define CHECK_DEFAULT_LINK(x) if ((x) == -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "No PostgreSQL link opened yet"); } +ZEND_DECLARE_MODULE_GLOBALS(pgsql) +static PHP_GINIT_FUNCTION(pgsql); + /* {{{ pgsql_functions[] */ zend_function_entry pgsql_functions[] = { @@ -151,6 +154,9 @@ zend_function_entry pgsql_functions[] = { PHP_FE(pg_field_type_oid, NULL) PHP_FE(pg_field_prtlen, NULL) PHP_FE(pg_field_is_null,NULL) +#ifdef HAVE_PQFTABLE + PHP_FE(pg_field_table, NULL) +#endif /* async message function */ PHP_FE(pg_get_notify, NULL) PHP_FE(pg_get_pid, NULL) @@ -247,7 +253,11 @@ zend_module_entry pgsql_module_entry = { PHP_RSHUTDOWN(pgsql), PHP_MINFO(pgsql), NO_VERSION_YET, - STANDARD_MODULE_PROPERTIES + PHP_MODULE_GLOBALS(pgsql), + PHP_GINIT(pgsql), + NULL, + NULL, + STANDARD_MODULE_PROPERTIES_EX }; /* }}} */ @@ -257,8 +267,6 @@ ZEND_GET_MODULE(pgsql) static int le_link, le_plink, le_result, le_lofp, le_string; -ZEND_DECLARE_MODULE_GLOBALS(pgsql) - /* {{{ _php_pgsql_trim_message */ static char * _php_pgsql_trim_message(const char *message, int *len) { @@ -445,9 +453,9 @@ STD_PHP_INI_BOOLEAN( "pgsql.log_notice", "0", PHP_INI_ALL, OnUpda PHP_INI_END() /* }}} */ -/* {{{ php_pgsql_init_globals +/* {{{ PHP_GINIT_FUNCTION */ -static void php_pgsql_init_globals(zend_pgsql_globals *pgsql_globals) +static PHP_GINIT_FUNCTION(pgsql) { memset(pgsql_globals, 0, sizeof(zend_pgsql_globals)); /* Initilize notice message hash at MINIT only */ @@ -459,8 +467,6 @@ static void php_pgsql_init_globals(zend_pgsql_globals *pgsql_globals) */ PHP_MINIT_FUNCTION(pgsql) { - ZEND_INIT_MODULE_GLOBALS(pgsql, php_pgsql_init_globals, NULL); - REGISTER_INI_ENTRIES(); le_link = zend_register_list_destructors_ex(_close_pgsql_link, NULL, "pgsql link", module_number); @@ -1694,6 +1700,97 @@ static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC) } /* }}} */ +#ifdef HAVE_PQFTABLE +/* {{{ proto mixed pg_field_table(resource result, int field_number[, bool oid_only]) + Returns the name of the table field belongs to, or table's oid if oid_only is true */ +PHP_FUNCTION(pg_field_table) +{ + zval *result; + pgsql_result_handle *pg_result; + long fnum = -1; + zend_bool return_oid = 0; + Oid oid; + smart_str hash_key = {0}; + char *table_name; + zend_rsrc_list_entry *field_table; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|b!", &result, &fnum, &return_oid) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); + + if (fnum < 0 || fnum >= PQnfields(pg_result->result)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad field offset specified"); + RETURN_FALSE; + } + + oid = PQftable(pg_result->result, fnum); + + if (InvalidOid == oid) { + RETURN_FALSE; + } + + + if (return_oid) { + if (oid > LONG_MAX) { + smart_str oidstr = {0}; + smart_str_append_unsigned(&oidstr, oid); + smart_str_0(&oidstr); + RETURN_STRINGL(oidstr.c, oidstr.len, 0); + } else { + RETURN_LONG((long)oid); + } + } + + /* try to lookup the table name in the resource list */ + smart_str_appends(&hash_key, "pgsql_table_oid_"); + smart_str_append_unsigned(&hash_key, oid); + smart_str_0(&hash_key); + + if (zend_hash_find(&EG(regular_list), hash_key.c, hash_key.len+1, (void **) &field_table) == SUCCESS) { + smart_str_free(&hash_key); + RETURN_STRING((char *)field_table->ptr, 1); + } else { /* Not found, lookup by querying PostgreSQL system tables */ + PGresult *tmp_res; + smart_str querystr = {0}; + zend_rsrc_list_entry new_field_table; + + smart_str_appends(&querystr, "select relname from pg_class where oid="); + smart_str_append_unsigned(&querystr, oid); + smart_str_0(&querystr); + + + if ((tmp_res = PQexec(pg_result->conn, querystr.c)) == NULL || PQresultStatus(tmp_res) != PGRES_TUPLES_OK) { + if (tmp_res) { + PQclear(tmp_res); + } + smart_str_free(&querystr); + smart_str_free(&hash_key); + RETURN_FALSE; + } + + smart_str_free(&querystr); + + if ((table_name = PQgetvalue(tmp_res, 0, 0)) == NULL) { + PQclear(tmp_res); + smart_str_free(&hash_key); + RETURN_FALSE; + } + + Z_TYPE(new_field_table) = le_string; + new_field_table.ptr = estrdup(table_name); + zend_hash_update(&EG(regular_list), hash_key.c, hash_key.len+1, (void *) &new_field_table, sizeof(zend_rsrc_list_entry), NULL); + + smart_str_free(&hash_key); + PQclear(tmp_res); + RETURN_STRING(table_name, 1); + } + +} +/* }}} */ +#endif + #define PHP_PG_FIELD_NAME 1 #define PHP_PG_FIELD_SIZE 2 #define PHP_PG_FIELD_TYPE 3 @@ -2017,7 +2114,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, * single value is an array. Also we'd have to make that one * argument passed by reference. */ - zend_throw_exception(zend_exception_get_default(), "Parameter ctor_params must be an array", 0 TSRMLS_CC); + zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Parameter ctor_params must be an array", 0 TSRMLS_CC); return; } } else { @@ -2032,7 +2129,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, fcc.object_pp = &return_value; if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) { - zend_throw_exception_ex(zend_exception_get_default(), 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name); + zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name); } else { if (retval_ptr) { zval_ptr_dtor(&retval_ptr); @@ -2042,7 +2139,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, efree(fci.params); } } else if (ctor_params) { - zend_throw_exception_ex(zend_exception_get_default(), 0 TSRMLS_CC, "Class %s does not have a constructor hence you cannot use ctor_params", ce->name); + zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Class %s does not have a constructor hence you cannot use ctor_params", ce->name); } } } @@ -3216,12 +3313,13 @@ PHP_FUNCTION(pg_copy_to) if (!pg_delim) { pg_delim = "\t"; } + + ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + if (!pg_null_as) { pg_null_as = safe_estrdup("\\\\N"); } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - query = (char *)emalloc(strlen(query_template) + strlen(table_name) + strlen(pg_null_as) + 1); sprintf(query, "COPY \"%s\" TO STDOUT DELIMITERS '%c' WITH NULL AS '%s'", table_name, *pg_delim, pg_null_as); @@ -3449,37 +3547,67 @@ PHP_FUNCTION(pg_copy_from) /* }}} */ #ifdef HAVE_PQESCAPE -/* {{{ proto string pg_escape_string(string data) +/* {{{ proto string pg_escape_string([resource connection,] string data) Escape string for text/char type */ PHP_FUNCTION(pg_escape_string) { char *from = NULL, *to = NULL; + zval *pgsql_link; +#ifdef HAVE_PQESCAPE_CONN + PGconn *pgsql; +#endif int to_len; int from_len; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", - &from, &from_len) == FAILURE) { + int id = -1; + + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s", &from, &from_len) == SUCCESS) { + pgsql_link = NULL; + id = PGG(default_link); + } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &from, &from_len) == FAILURE) { return; } - to = (char *)safe_emalloc(from_len, 2, 1); - to_len = (int)PQescapeString(to, from, from_len); + to = (char *) safe_emalloc(from_len, 2, 1); + +#ifdef HAVE_PQESCAPE_CONN + if (pgsql_link != NULL || id != -1) { + ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + to_len = (int) PQescapeStringConn(pgsql, to, from, (size_t)from_len, NULL); + } else +#endif + to_len = (int) PQescapeString(to, from, (size_t)from_len); + RETURN_STRINGL(to, to_len, 0); } /* }}} */ -/* {{{ proto string pg_escape_bytea(string data) +/* {{{ proto string pg_escape_bytea([resource connection,] string data) Escape binary for bytea type */ PHP_FUNCTION(pg_escape_bytea) { char *from = NULL, *to = NULL; size_t to_len; - int from_len; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", - &from, &from_len) == FAILURE) { + int from_len, id = -1; +#ifdef HAVE_PQESCAPE_BYTEA_CONN + PGconn *pgsql; +#endif + zval *pgsql_link; + + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s", &from, &from_len) == SUCCESS) { + pgsql_link = NULL; + id = PGG(default_link); + } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &from, &from_len) == FAILURE) { return; } - to = (char *)PQescapeBytea((unsigned char*)from, from_len, &to_len); +#ifdef HAVE_PQESCAPE_BYTEA_CONN + if (pgsql_link != NULL || id != -1) { + ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + to = (char *)PQescapeByteaConn(pgsql, from, (size_t)from_len, &to_len); + } else +#endif + to = (char *)PQescapeBytea((unsigned char*)from, from_len, &to_len); + RETVAL_STRINGL(to, to_len-1, 1); /* to_len includes addtional '\0' */ free(to); } @@ -3899,7 +4027,7 @@ PHP_FUNCTION(pg_send_query_params) int leftover = 0; if (zend_get_parameters_ex(3, &pgsql_link, &query, &pv_param_arr) == FAILURE) { - return; + WRONG_PARAM_COUNT; } if (pgsql_link == NULL && id == -1) { @@ -3989,7 +4117,7 @@ PHP_FUNCTION(pg_send_prepare) int leftover = 0; if (zend_get_parameters_ex(3, &pgsql_link, &stmtname, &query) == FAILURE) { - return; + WRONG_PARAM_COUNT; } if (pgsql_link == NULL && id == -1) { RETURN_FALSE; @@ -4043,7 +4171,7 @@ PHP_FUNCTION(pg_send_execute) int leftover = 0; if (zend_get_parameters_ex(3, &pgsql_link, &stmtname, &pv_param_arr)==FAILURE) { - return; + WRONG_PARAM_COUNT; } if (pgsql_link == NULL && id == -1) { RETURN_FALSE; @@ -5015,7 +5143,11 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con else { unsigned char *tmp; size_t to_len; +#ifdef HAVE_PQESCAPE_BYTEA_CONN + tmp = PQescapeByteaConn(pg_link, Z_STRVAL_PP(val), Z_STRLEN_PP(val), &to_len); +#else tmp = PQescapeBytea(Z_STRVAL_PP(val), Z_STRLEN_PP(val), &to_len); +#endif Z_TYPE_P(new_val) = IS_STRING; Z_STRLEN_P(new_val) = to_len-1; /* PQescapeBytea's to_len includes additional '\0' */ Z_STRVAL_P(new_val) = emalloc(to_len); diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h index 68f110107..0b31b3733 100644 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pgsql.h,v 1.73.2.1 2006/01/01 12:50:12 sniper Exp $ */ +/* $Id: php_pgsql.h,v 1.73.2.1.2.1 2006/05/07 00:28:32 edink Exp $ */ #ifndef PHP_PGSQL_H #define PHP_PGSQL_H @@ -125,6 +125,7 @@ PHP_FUNCTION(pg_field_type); PHP_FUNCTION(pg_field_type_oid); PHP_FUNCTION(pg_field_prtlen); PHP_FUNCTION(pg_field_is_null); +PHP_FUNCTION(pg_field_table); /* async message functions */ PHP_FUNCTION(pg_get_notify); PHP_FUNCTION(pg_get_pid); |
