X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-pq;a=blobdiff_plain;f=src%2Fphp_pq.c;h=bae80fcf245f4215cfaf0be8f59a620926d33265;hp=34c4ffee81fdf754885ceb192b081ee426c1e318;hb=f45475be17b6acdb84137ffd76fe6ea5745886e9;hpb=dad016bcee4340d19f604e51b12d97266dbacefd diff --git a/src/php_pq.c b/src/php_pq.c index 34c4ffe..bae80fc 100644 --- a/src/php_pq.c +++ b/src/php_pq.c @@ -6,7 +6,7 @@ | modification, are permitted provided that the conditions mentioned | | in the accompanying LICENSE file are met. | +--------------------------------------------------------------------+ - | Copyright (c) 2013, Michael Wallner | + | Copyright (c) 2013, Michael Wallner | +--------------------------------------------------------------------+ */ @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -106,9 +107,13 @@ typedef struct php_pq_object { void *intern; } php_pq_object_t; +#define PHP_PQCONN_ASYNC 0x01 +#define PHP_PQCONN_PERSISTENT 0x02 + typedef struct php_pqconn { PGconn *conn; int (*poller)(PGconn *); + php_resource_factory_t factory; HashTable listeners; HashTable eventhandlers; php_pq_callback_t onevent; @@ -157,6 +162,7 @@ typedef struct php_pqres_iterator { typedef struct php_pqres { PGresult *res; php_pqres_iterator_t *iter; + HashTable bound; } php_pqres_t; typedef struct php_pqres_object { @@ -169,6 +175,7 @@ typedef struct php_pqres_object { typedef struct php_pqstm { php_pqconn_object_t *conn; char *name; + HashTable bound; } php_pqstm_t; typedef struct php_pqstm_object { @@ -520,7 +527,15 @@ static void php_pqconn_object_free(void *o TSRMLS_DC) php_pqconn_object_t *obj = o; if (obj->intern) { - PQfinish(obj->intern->conn); + php_pqconn_event_data_t *evdata = PQinstanceData(obj->intern->conn, php_pqconn_event); + + if (evdata) { + efree(evdata); + PQsetInstanceData(obj->intern->conn, php_pqconn_event, NULL); + } + + php_resource_factory_handle_dtor(&obj->intern->factory, obj->intern->conn TSRMLS_CC); + php_resource_factory_dtor(&obj->intern->factory); php_pq_callback_dtor(&obj->intern->onevent); zend_hash_destroy(&obj->intern->listeners); zend_hash_destroy(&obj->intern->eventhandlers); @@ -568,6 +583,8 @@ static void php_pqres_object_free(void *o TSRMLS_DC) obj->intern->iter = NULL; } + zend_hash_destroy(&obj->intern->bound); + efree(obj->intern); obj->intern = NULL; } @@ -582,6 +599,7 @@ static void php_pqstm_object_free(void *o TSRMLS_DC) if (obj->intern) { php_pq_object_delref(obj->intern->conn TSRMLS_CC); efree(obj->intern->name); + zend_hash_destroy(&obj->intern->bound); efree(obj->intern); obj->intern = NULL; } @@ -1586,17 +1604,6 @@ static STATUS php_pqconn_update_socket(zval *this_ptr, php_pqconn_object_t *obj # define TSRMLS_CF(d) #endif -static void php_pqconn_event_register(PGEventRegister *event, php_pqconn_event_data_t *data) -{ - PQsetInstanceData(event->conn, php_pqconn_event, data); -} - -static void php_pqconn_event_conndestroy(PGEventConnDestroy *event, php_pqconn_event_data_t *data) -{ - PQsetInstanceData(event->conn, php_pqconn_event, NULL); - efree(data); -} - static int apply_event(void *p, void *a TSRMLS_DC) { zval **evh = p; @@ -1637,6 +1644,7 @@ static zval *result_instance_zval(PGresult *res TSRMLS_DC) MAKE_STD_ZVAL(rid); r->res = res; + ZEND_INIT_SYMTABLE(&r->bound); rid->type = IS_OBJECT; rid->value.obj = php_pqres_create_object_ex(php_pqres_class_entry, r, NULL TSRMLS_CC); @@ -1678,12 +1686,6 @@ static void php_pqconn_event_resultcreate(PGEventResultCreate *event, php_pqconn static int php_pqconn_event(PGEventId id, void *e, void *data) { switch (id) { - case PGEVT_REGISTER: - php_pqconn_event_register(e, data); - break; - case PGEVT_CONNDESTROY: - php_pqconn_event_conndestroy(e, data); - break; case PGEVT_CONNRESET: php_pqconn_event_connreset(e, data); break; @@ -1726,6 +1728,33 @@ static void php_pqconn_notice_recv(void *p, const PGresult *res) } } +typedef struct php_pqconn_resource_factory_data { + char *dsn; + long flags; +} php_pqconn_resource_factory_data_t; + +static void *php_pqconn_resource_factory_ctor(void *data, void *init_arg TSRMLS_DC) +{ + php_pqconn_resource_factory_data_t *o = init_arg; + + if (o->flags & PHP_PQCONN_ASYNC) { + return PQconnectStart(o->dsn); + } else { + return PQconnectdb(o->dsn); + } +} + +static void php_pqconn_resource_factory_dtor(void *opaque, void *handle TSRMLS_DC) +{ + PQfinish(handle); +} + +static php_resource_factory_ops_t php_pqconn_resource_factory_ops = { + php_pqconn_resource_factory_ctor, + NULL, + php_pqconn_resource_factory_dtor +}; + ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct, 0, 0, 1) ZEND_ARG_INFO(0, dsn) ZEND_ARG_INFO(0, async) @@ -1734,28 +1763,35 @@ static PHP_METHOD(pqconn, __construct) { zend_error_handling zeh; char *dsn_str = ""; int dsn_len = 0; - zend_bool async = 0; + long flags = 0; zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC); - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sb", &dsn_str, &dsn_len, &async)) { + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sl", &dsn_str, &dsn_len, &flags)) { php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - php_pqconn_event_data_t *data = php_pqconn_event_data_init(obj TSRMLS_CC); + php_pqconn_event_data_t *evdata = php_pqconn_event_data_init(obj TSRMLS_CC); + php_pqconn_resource_factory_data_t rfdata = {dsn_str, flags}; obj->intern = ecalloc(1, sizeof(*obj->intern)); zend_hash_init(&obj->intern->listeners, 0, NULL, (dtor_func_t) zend_hash_destroy, 0); zend_hash_init(&obj->intern->eventhandlers, 0, NULL, ZVAL_PTR_DTOR, 0); - - if (async) { - obj->intern->conn = PQconnectStart(dsn_str); + if (flags & PHP_PQCONN_PERSISTENT) { + php_persistent_handle_factory_t *phf = php_persistent_handle_concede(NULL, ZEND_STRL("pq\\Connection"), dsn_str, dsn_len TSRMLS_CC); + php_resource_factory_init(&obj->intern->factory, php_persistent_handle_get_resource_factory_ops(), phf, (void (*)(void*)) php_persistent_handle_abandon); + } else{ + php_resource_factory_init(&obj->intern->factory, &php_pqconn_resource_factory_ops, NULL, NULL); + } + if (flags & PHP_PQCONN_ASYNC) { obj->intern->poller = (int (*)(PGconn*)) PQconnectPoll; - } else { - obj->intern->conn = PQconnectdb(dsn_str); } - PQsetNoticeReceiver(obj->intern->conn, php_pqconn_notice_recv, data); - PQregisterEventProc(obj->intern->conn, php_pqconn_event, "ext-pq", data); + obj->intern->conn = php_resource_factory_handle_ctor(&obj->intern->factory, &rfdata TSRMLS_CC); + + PQregisterEventProc(obj->intern->conn, php_pqconn_event, "ext-pq", evdata); + /* the connection might be persistent, so reset event_proc instance data */ + PQsetInstanceData(obj->intern->conn, php_pqconn_event, evdata); + PQsetNoticeReceiver(obj->intern->conn, php_pqconn_notice_recv, evdata); if (SUCCESS != php_pqconn_update_socket(getThis(), obj TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection failed (%s)", PHP_PQerrorMessage(obj->intern->conn)); @@ -1954,6 +1990,7 @@ static PHP_METHOD(pqconn, exec) { php_pqres_t *r = ecalloc(1, sizeof(*r)); r->res = res; + ZEND_INIT_SYMTABLE(&r->bound); return_value->type = IS_OBJECT; return_value->value.obj = php_pqres_create_object_ex(php_pqres_class_entry, r, NULL TSRMLS_CC); } @@ -1980,6 +2017,7 @@ static PHP_METHOD(pqconn, getResult) { php_pqres_t *r = ecalloc(1, sizeof(*r)); r->res = res; + ZEND_INIT_SYMTABLE(&r->bound); return_value->type = IS_OBJECT; return_value->value.obj = php_pqres_create_object_ex(php_pqres_class_entry, r, NULL TSRMLS_CC); } else { @@ -2159,6 +2197,7 @@ static PHP_METHOD(pqconn, execParams) { php_pqres_t *r = ecalloc(1, sizeof(*r)); r->res = res; + ZEND_INIT_SYMTABLE(&r->bound); return_value->type = IS_OBJECT; return_value->value.obj = php_pqres_create_object_ex(php_pqres_class_entry, r, NULL TSRMLS_CC); } @@ -2298,6 +2337,7 @@ static PHP_METHOD(pqconn, prepare) { php_pq_object_addref(obj TSRMLS_CC); stm->conn = obj; stm->name = estrdup(name_str); + ZEND_INIT_SYMTABLE(&stm->bound); return_value->type = IS_OBJECT; return_value->value.obj = php_pqstm_create_object_ex(php_pqstm_class_entry, stm, NULL TSRMLS_CC); @@ -2366,6 +2406,7 @@ static PHP_METHOD(pqconn, prepareAsync) { php_pq_object_addref(obj TSRMLS_CC); stm->conn = obj; stm->name = estrdup(name_str); + ZEND_INIT_SYMTABLE(&stm->bound); return_value->type = IS_OBJECT; return_value->value.obj = php_pqstm_create_object_ex(php_pqstm_class_entry, stm, NULL TSRMLS_CC); @@ -2768,8 +2809,9 @@ static zend_function_entry php_pqtypes_methods[] = { {0} }; -static zval *php_pqres_iteration(zval *this_ptr, php_pqres_object_t *obj, php_pqres_fetch_t fetch_type, zval ***row TSRMLS_DC) +static STATUS php_pqres_iteration(zval *this_ptr, php_pqres_object_t *obj, php_pqres_fetch_t fetch_type, zval ***row TSRMLS_DC) { + STATUS rv; php_pqres_fetch_t orig_fetch; if (!obj) { @@ -2782,13 +2824,146 @@ static zval *php_pqres_iteration(zval *this_ptr, php_pqres_object_t *obj, php_pq } orig_fetch = obj->intern->iter->fetch_type; obj->intern->iter->fetch_type = fetch_type; - if (SUCCESS == obj->intern->iter->zi.funcs->valid((zend_object_iterator *) obj->intern->iter TSRMLS_CC)) { + if (SUCCESS == (rv = obj->intern->iter->zi.funcs->valid((zend_object_iterator *) obj->intern->iter TSRMLS_CC))) { obj->intern->iter->zi.funcs->get_current_data((zend_object_iterator *) obj->intern->iter, row TSRMLS_CC); obj->intern->iter->zi.funcs->move_forward((zend_object_iterator *) obj->intern->iter TSRMLS_CC); } obj->intern->iter->fetch_type = orig_fetch; - return *row ? **row : NULL; + return rv; +} + +typedef struct php_pqres_col { + char *name; + int num; +} php_pqres_col_t; + +static STATUS column_nn(php_pqres_object_t *obj, zval *zcol, php_pqres_col_t *col TSRMLS_DC) +{ + long index = -1; + char *name = NULL; + + switch (Z_TYPE_P(zcol)) { + default: + convert_to_string(zcol); + /* no break */ + + case IS_STRING: + if (!is_numeric_string(Z_STRVAL_P(zcol), Z_STRLEN_P(zcol), &index, NULL, 0)) { + name = Z_STRVAL_P(zcol); + } + break; + + case IS_LONG: + index = Z_LVAL_P(zcol); + break; + } + + if (name) { + col->name = name; + col->num = PQfnumber(obj->intern->res, name); + } else { + col->name = PQfname(obj->intern->res, index); + col->num = index; + } + + if (!col->name) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to find column at index %ld", index); + return FAILURE; + } + if (col->num == -1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to find column with name '%s'", name); + return FAILURE; + } + return SUCCESS; +} + +static int compare_index(const void *lptr, const void *rptr TSRMLS_DC) +{ + const Bucket *l = *(const Bucket **) lptr; + const Bucket *r = *(const Bucket **) rptr; + + if (l->h < r->h) { + return -1; + } + if (l->h > r->h) { + return 1; + } + return 0; +} + +ZEND_BEGIN_ARG_INFO_EX(ai_pqres_bind, 0, 0, 2) + ZEND_ARG_INFO(0, col) + ZEND_ARG_INFO(1, ref) +ZEND_END_ARG_INFO(); +static PHP_METHOD(pqres, bind) { + zval *zcol, *zref; + + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/z", &zcol, &zref)) { + php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + if (obj->intern) { + php_pqres_col_t col; + + if (SUCCESS == column_nn(obj, zcol, &col TSRMLS_CC)) { + Z_ADDREF_P(zref); + if (SUCCESS == zend_hash_index_update(&obj->intern->bound, col.num, (void *) &zref, sizeof(zval *), NULL)) { + zend_hash_sort(&obj->intern->bound, zend_qsort, compare_index, 0 TSRMLS_CC); + RETVAL_TRUE; + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to bind column %s@%d", col.name, col.num); + RETVAL_FALSE; + } + } else { + RETVAL_FALSE; + } + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "pq\\Result not initialized"); + RETVAL_FALSE; + } + } +} + +static int apply_bound(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key) +{ + zval **zvalue, **zbound = p; + zval **zrow = va_arg(argv, zval **); + + if (SUCCESS == zend_hash_index_find(Z_ARRVAL_PP(zrow), key->h, (void *) &zvalue)) { + zval_dtor(*zbound); + ZVAL_COPY_VALUE(*zbound, *zvalue); + ZVAL_NULL(*zvalue); + zval_ptr_dtor(zvalue); + Z_ADDREF_P(*zbound); + *zvalue = *zbound; + return ZEND_HASH_APPLY_KEEP; + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to find column ad index %lu", key->h); + return ZEND_HASH_APPLY_STOP; + } +} + +ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_bound, 0, 0, 0) +ZEND_END_ARG_INFO(); +static PHP_METHOD(pqres, fetchBound) { + zend_error_handling zeh; + + zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC); + if (SUCCESS == zend_parse_parameters_none()) { + php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + if (obj->intern) { + zval **row = NULL; + + if (SUCCESS == php_pqres_iteration(getThis(), obj, PHP_PQRES_FETCH_ARRAY, &row TSRMLS_CC)) { + if (row) { + zend_hash_apply_with_arguments(&obj->intern->bound TSRMLS_CC, apply_bound, 1, row); + RETVAL_ZVAL(*row, 1, 0); + } + } + } + } + zend_restore_error_handling(&zeh TSRMLS_CC); } ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_row, 0, 0, 0) @@ -2867,55 +3042,22 @@ static PHP_METHOD(pqres, fetchCol) { zend_restore_error_handling(&zeh TSRMLS_CC); } -typedef struct php_pqres_col { - char *name; - int num; -} php_pqres_col_t; - static int apply_to_col(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key) { zval **c = p; php_pqres_object_t *obj = va_arg(argv, php_pqres_object_t *); php_pqres_col_t *col, **cols = va_arg(argv, php_pqres_col_t **); STATUS *rv = va_arg(argv, STATUS *); - long index = -1; - char *name = NULL; - - switch (Z_TYPE_PP(c)) { - default: - convert_to_string(*c); - /* no break */ - case IS_STRING: - if (!is_numeric_string(Z_STRVAL_PP(c), Z_STRLEN_PP(c), &index, NULL, 0)) { - name = Z_STRVAL_PP(c); - } - break; - case IS_LONG: - index = Z_LVAL_PP(c); - break; - } col = *cols; - if (name) { - col->name = name; - col->num = PQfnumber(obj->intern->res, name); + if (SUCCESS == column_nn(obj, *c, col TSRMLS_CC)) { + *rv = SUCCESS; } else { - col->name = PQfname(obj->intern->res, index); - col->num = index; - } - - if (!col->name) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to find column at index %ld", index); *rv = FAILURE; return ZEND_HASH_APPLY_STOP; } - if (col->num == -1) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to find column with name '%s'", name); - *rv = FAILURE; - return ZEND_HASH_APPLY_STOP; - } - ++*cols; + return ZEND_HASH_APPLY_KEEP; } @@ -3071,6 +3213,8 @@ static PHP_METHOD(pqres, count) { } static zend_function_entry php_pqres_methods[] = { + PHP_ME(pqres, bind, ai_pqres_bind, ZEND_ACC_PUBLIC) + PHP_ME(pqres, fetchBound, ai_pqres_fetch_bound, ZEND_ACC_PUBLIC) PHP_ME(pqres, fetchRow, ai_pqres_fetch_row, ZEND_ACC_PUBLIC) PHP_ME(pqres, fetchCol, ai_pqres_fetch_col, ZEND_ACC_PUBLIC) PHP_ME(pqres, count, ai_pqres_count, ZEND_ACC_PUBLIC) @@ -3113,6 +3257,7 @@ static PHP_METHOD(pqstm, __construct) { php_pq_object_addref(conn_obj TSRMLS_CC); stm->conn = conn_obj; stm->name = estrdup(name_str); + ZEND_INIT_SYMTABLE(&stm->bound); obj->intern = stm; } } else { @@ -3121,6 +3266,26 @@ static PHP_METHOD(pqstm, __construct) { } zend_restore_error_handling(&zeh TSRMLS_CC); } +ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_bind, 0, 0, 2) + ZEND_ARG_INFO(0, param_no) + ZEND_ARG_INFO(1, param_ref) +ZEND_END_ARG_INFO(); +static PHP_METHOD(pqstm, bind) { + long param_no; + zval *param_ref; + + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz", ¶m_no, ¶m_ref)) { + php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + if (obj->intern) { + Z_ADDREF_P(param_ref); + zend_hash_index_update(&obj->intern->bound, param_no, (void *) ¶m_ref, sizeof(zval *), NULL); + zend_hash_sort(&obj->intern->bound, zend_qsort, compare_index, 0 TSRMLS_CC); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "pq\\Statement not initialized"); + } + } +} ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec, 0, 0, 0) ZEND_ARG_ARRAY_INFO(0, params, 1) @@ -3140,9 +3305,12 @@ static PHP_METHOD(pqstm, exec) { HashTable zdtor; PGresult *res; + ZEND_INIT_SYMTABLE(&zdtor); + if (zparams) { - ZEND_INIT_SYMTABLE(&zdtor); count = php_pq_params_to_array(Z_ARRVAL_P(zparams), ¶ms, &zdtor TSRMLS_CC); + } else { + count = php_pq_params_to_array(&obj->intern->bound, ¶ms, &zdtor TSRMLS_CC); } res = PQexecPrepared(obj->intern->conn->intern->conn, obj->intern->name, count, (const char *const*) params, NULL, NULL, 0); @@ -3150,9 +3318,7 @@ static PHP_METHOD(pqstm, exec) { if (params) { efree(params); } - if (zparams) { - zend_hash_destroy(&zdtor); - } + zend_hash_destroy(&zdtor); php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); @@ -3161,6 +3327,7 @@ static PHP_METHOD(pqstm, exec) { php_pqres_t *r = ecalloc(1, sizeof(*r)); r->res = res; + ZEND_INIT_SYMTABLE(&r->bound); return_value->type = IS_OBJECT; return_value->value.obj = php_pqres_create_object_ex(php_pqres_class_entry, r, NULL TSRMLS_CC); } @@ -3281,6 +3448,7 @@ static PHP_METHOD(pqstm, desc) { static zend_function_entry php_pqstm_methods[] = { PHP_ME(pqstm, __construct, ai_pqstm_construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) + PHP_ME(pqstm, bind, ai_pqstm_bind, ZEND_ACC_PUBLIC) PHP_ME(pqstm, exec, ai_pqstm_exec, ZEND_ACC_PUBLIC) PHP_ME(pqstm, desc, ai_pqstm_desc, ZEND_ACC_PUBLIC) PHP_ME(pqstm, execAsync, ai_pqstm_exec_async, ZEND_ACC_PUBLIC) @@ -4423,6 +4591,8 @@ static PHP_MINIT_FUNCTION(pq) zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING TSRMLS_CC); zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK TSRMLS_CC); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("ASYNC"), 0x1 TSRMLS_CC); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("PERSISTENT"), 0x2 TSRMLS_CC); memset(&ce, 0, sizeof(ce)); INIT_NS_CLASS_ENTRY(ce, "pq", "Types", php_pqtypes_methods); php_pqtypes_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); @@ -4668,6 +4838,8 @@ static PHP_MINIT_FUNCTION(pq) zend_declare_class_constant_long(php_pqcopy_class_entry, ZEND_STRL("FROM_STDIN"), PHP_PQCOPY_FROM_STDIN TSRMLS_CC); zend_declare_class_constant_long(php_pqcopy_class_entry, ZEND_STRL("TO_STDOUT"), PHP_PQCOPY_TO_STDOUT TSRMLS_CC); + php_persistent_handle_provide(ZEND_STRL("pq\\Connection"), &php_pqconn_resource_factory_ops, NULL, NULL); + /* REGISTER_INI_ENTRIES(); */ @@ -4682,6 +4854,7 @@ static PHP_MSHUTDOWN_FUNCTION(pq) /* uncomment this line if you have INI entries UNREGISTER_INI_ENTRIES(); */ + php_persistent_handle_cleanup(ZEND_STRL("pq\\Connection"), NULL, 0 TSRMLS_CC); return SUCCESS; } /* }}} */ @@ -4690,7 +4863,9 @@ static PHP_MSHUTDOWN_FUNCTION(pq) */ static PHP_MINFO_FUNCTION(pq) { +#ifdef HAVE_PQLIBVERSION int libpq_v; +#endif char libpq_version[10] = "pre-9.1"; php_info_print_table_start(); @@ -4717,10 +4892,17 @@ const zend_function_entry pq_functions[] = { {0} }; +static zend_module_dep pq_module_deps[] = { + ZEND_MOD_REQUIRED("raphf") + ZEND_MOD_END +}; + /* {{{ pq_module_entry */ zend_module_entry pq_module_entry = { - STANDARD_MODULE_HEADER, + STANDARD_MODULE_HEADER_EX, + NULL, + pq_module_deps, "pq", pq_functions, PHP_MINIT(pq),