From 60f1c75340bc24e1d2e11a71906b683c76b6293f Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Sun, 20 Jan 2013 13:49:35 +0100 Subject: [PATCH] foreach (new pq\Connection(DSN)->exec(QUERY) as $k=>$v) works --- CREDITS | 2 + EXPERIMENTAL | 0 config.m4 | 37 +++ php_pq.h | 1 + src/php_pq.c | 741 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/php_pq.h | 65 +++++ 6 files changed, 846 insertions(+) create mode 100644 CREDITS create mode 100644 EXPERIMENTAL create mode 100644 config.m4 create mode 120000 php_pq.h create mode 100644 src/php_pq.c create mode 100644 src/php_pq.h diff --git a/CREDITS b/CREDITS new file mode 100644 index 0000000..e8db872 --- /dev/null +++ b/CREDITS @@ -0,0 +1,2 @@ +pq +Michael Wallner diff --git a/EXPERIMENTAL b/EXPERIMENTAL new file mode 100644 index 0000000..e69de29 diff --git a/config.m4 b/config.m4 new file mode 100644 index 0000000..b3d0f88 --- /dev/null +++ b/config.m4 @@ -0,0 +1,37 @@ +PHP_ARG_WITH(pq, for pq support, +[ --with-pq Include pq support]) + +if test "$PHP_PQ" != "no"; then + SEARCH_PATH="/usr/local /usr /opt" + if test "$PHP_PQ" != "yes"; then + SEARCH_PATH="$PHP_PQ $SEARCH_PATH" + fi + for i in $SEARCH_PATH; do + AC_MSG_CHECKING(for $i/include/libpq-events.h) + if test -f "$i/include/libpq-events.h"; then + PQ_DIR=$i + AC_MSG_RESULT(yep) + break + fi + AC_MSG_RESULT(nope) + done + + if test -z "$PQ_DIR"; then + AC_MSG_FAILURE(could not find include/libpq-events.h) + fi + PHP_ADD_INCLUDE($PQ_DIR/include) + + PQ_SYM=PQregisterEventProc + PHP_CHECK_LIBRARY(pq, $PQ_SYM, [ + LDFLAGS="$save_LDFLAGS" + PHP_ADD_LIBRARY_WITH_PATH(pq, $PQ_DIR/$PHP_LIBDIR, PQ_SHARED_LIBADD) + PHP_SUBST(PQ_SHARED_LIBADD) + ],[ + AC_MSG_ERROR(could not find $PQ_SYM in -lpq) + ],[ + -L$PQ_DIR/$PHP_LIBDIR + ]) + + PQ_SRC="src/php_pq.c" + PHP_NEW_EXTENSION(pq, $PQ_SRC, $ext_shared) +fi diff --git a/php_pq.h b/php_pq.h new file mode 120000 index 0000000..6b88c69 --- /dev/null +++ b/php_pq.h @@ -0,0 +1 @@ +src/php_pq.h \ No newline at end of file diff --git a/src/php_pq.c b/src/php_pq.c new file mode 100644 index 0000000..64cd734 --- /dev/null +++ b/src/php_pq.c @@ -0,0 +1,741 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2012 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "php.h" +#include "ext/standard/info.h" +#include "php_pq.h" +#include + +typedef int STATUS; /* SUCCESS/FAILURE */ + +/* +ZEND_DECLARE_MODULE_GLOBALS(pq) +*/ + +const zend_function_entry pq_functions[] = { + {0} +}; + +/* {{{ pq_module_entry + */ +zend_module_entry pq_module_entry = { + STANDARD_MODULE_HEADER, + "pq", + pq_functions, + PHP_MINIT(pq), + PHP_MSHUTDOWN(pq), + NULL,/*PHP_RINIT(pq),*/ + NULL,/*PHP_RSHUTDOWN(pq),*/ + PHP_MINFO(pq), + PHP_PQ_EXT_VERSION, + STANDARD_MODULE_PROPERTIES +}; +/* }}} */ + +#ifdef COMPILE_DL_PQ +ZEND_GET_MODULE(pq) +#endif + +/* {{{ PHP_INI + */ +/* Remove comments and fill if you need to have entries in php.ini +PHP_INI_BEGIN() + STD_PHP_INI_ENTRY("pq.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_pq_globals, pq_globals) + STD_PHP_INI_ENTRY("pq.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_pq_globals, pq_globals) +PHP_INI_END() +*/ +/* }}} */ + +/* {{{ php_pq_init_globals + */ +/* Uncomment this function if you have INI entries +static void php_pq_init_globals(zend_pq_globals *pq_globals) +{ + pq_globals->global_value = 0; + pq_globals->global_string = NULL; +} +*/ +/* }}} */ + +static zend_class_entry *php_pqconn_class_entry; +static zend_class_entry *php_pqres_class_entry; + +static zend_object_handlers php_pqconn_object_handlers; +static zend_object_handlers php_pqres_object_handlers; + +typedef struct php_pqconn_object { + zend_object zo; + PGconn *conn; + int (*poller)(PGconn *); + unsigned blocking:1; +} php_pqconn_object_t; + +typedef struct php_pqres_object { + zend_object zo; + PGresult *res; +} php_pqres_object_t; + +typedef enum php_pqres_fetch { + PHP_PQRES_FETCH_ARRAY, + PHP_PQRES_FETCH_ASSOC, + PHP_PQRES_FETCH_OBJECT +} php_pqres_fetch_t; + +static void php_pqconn_object_free(void *o TSRMLS_DC) +{ + php_pqconn_object_t *obj = o; + + if (obj->conn) { + PQfinish(obj->conn); + obj->conn = NULL; + } + zend_object_std_dtor((zend_object *) o TSRMLS_CC); + efree(obj); +} + +static void php_pqres_object_free(void *o TSRMLS_DC) +{ + php_pqres_object_t *obj = o; + + if (obj->res) { + PQclear(obj->res); + obj->res = NULL; + } + zend_object_std_dtor((zend_object *) o TSRMLS_CC); + efree(obj); +} + +static zend_object_value php_pqconn_create_object_ex(zend_class_entry *ce, PGconn *conn, php_pqconn_object_t **ptr TSRMLS_DC) +{ + zend_object_value ov; + php_pqconn_object_t *o; + + o = ecalloc(1, sizeof(*o)); + zend_object_std_init((zend_object *) o, ce TSRMLS_CC); + object_properties_init((zend_object *) o, ce); + + if (ptr) { + *ptr = o; + } + + if (conn) { + o->conn = conn; + o->blocking = !PQisnonblocking(o->conn); + } + + ov.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqconn_object_free, NULL TSRMLS_CC); + ov.handlers = &php_pqconn_object_handlers; + + return ov; +} + +static zend_object_value php_pqres_create_object_ex(zend_class_entry *ce, PGresult *res, php_pqres_object_t **ptr TSRMLS_DC) +{ + zend_object_value ov; + php_pqres_object_t *o; + + o = ecalloc(1, sizeof(*o)); + zend_object_std_init((zend_object *) o, ce TSRMLS_CC); + object_properties_init((zend_object *) o, ce); + + if (ptr) { + *ptr = o; + } + + if (res) { + o->res = res; + } + + ov.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqres_object_free, NULL TSRMLS_CC); + ov.handlers = &php_pqres_object_handlers; + + return ov; +} + +static zend_object_value php_pqconn_create_object(zend_class_entry *class_type TSRMLS_DC) +{ + return php_pqconn_create_object_ex(class_type, NULL, NULL TSRMLS_CC); +} + +static zend_object_value php_pqres_create_object(zend_class_entry *class_type TSRMLS_DC) +{ + return php_pqres_create_object_ex(class_type, NULL, NULL TSRMLS_CC); +} + +static HashTable php_pqconn_object_prophandlers; +static HashTable php_pqres_object_prophandlers; + +typedef void (*php_pq_object_prophandler_func_t)(void *o, zval *return_value TSRMLS_DC); + +typedef struct php_pq_object_prophandler { + php_pq_object_prophandler_func_t read; + php_pq_object_prophandler_func_t write; +} php_pq_object_prophandler_t; + +static void php_pqconn_object_read_status(void *o, zval *return_value TSRMLS_DC) +{ + php_pqconn_object_t *obj = o; + + RETVAL_LONG(PQstatus(obj->conn)); +} + +static void php_pqconn_object_read_transaction_status(void *o, zval *return_value TSRMLS_DC) +{ + php_pqconn_object_t *obj = o; + + RETVAL_LONG(PQtransactionStatus(obj->conn)); +} + +static void php_pqconn_object_read_socket(void *o, zval *return_value TSRMLS_DC) +{ + php_pqconn_object_t *obj = o; + php_stream *stream; + int socket = PQsocket(obj->conn); + + if ((stream = php_stream_fopen_from_fd(socket, "r+b", NULL))) { + php_stream_to_zval(stream, return_value); + } else { + RETVAL_NULL(); + } +} + +static void php_pqconn_object_read_error_message(void *o, zval *return_value TSRMLS_DC) +{ + php_pqconn_object_t *obj = o; + char *error = PQerrorMessage(obj->conn); + + if (error) { + RETVAL_STRING(error, 1); + } else { + RETVAL_NULL(); + } +} + +static void php_pqres_object_read_status(void *o, zval *return_value TSRMLS_DC) +{ + php_pqres_object_t *obj = o; + + RETVAL_LONG(PQresultStatus(obj->res)); +} + +static void php_pqres_object_read_error_message(void *o, zval *return_value TSRMLS_DC) +{ + php_pqres_object_t *obj = o; + char *error = PQresultErrorMessage(obj->res); + + if (error) { + RETVAL_STRING(error, 1); + } else { + RETVAL_NULL(); + } +} + +static void php_pqres_object_read_num_rows(void *o, zval *return_value TSRMLS_DC) +{ + php_pqres_object_t *obj = o; + + RETVAL_LONG(PQntuples(obj->res)); +} + +static void php_pqres_object_read_num_cols(void *o, zval *return_value TSRMLS_DC) +{ + php_pqres_object_t *obj = o; + + RETVAL_LONG(PQnfields(obj->res)); +} + +static void php_pqres_object_read_affected_rows(void *o, zval *return_value TSRMLS_DC) +{ + php_pqres_object_t *obj = o; + + RETVAL_LONG(atoi(PQcmdTuples(obj->res))); +} + +static zval *php_pqconn_object_read_prop(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) +{ + php_pqconn_object_t *obj = zend_object_store_get_object(object TSRMLS_CC); + php_pq_object_prophandler_t *handler; + zval *return_value; + + if (!obj->conn) { + zend_error(E_WARNING, "Connection not initialized"); + } else if (SUCCESS == zend_hash_find(&php_pqconn_object_prophandlers, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void *) &handler)) { + if (type == BP_VAR_R) { + ALLOC_ZVAL(return_value); + Z_SET_REFCOUNT_P(return_value, 0); + Z_UNSET_ISREF_P(return_value); + + handler->read(obj, return_value TSRMLS_CC); + } else { + zend_error(E_ERROR, "Cannot access pq\\Connection properties by reference or array key/index"); + return_value = NULL; + } + } else { + return_value = zend_get_std_object_handlers()->read_property(object, member, type, key TSRMLS_CC); + } + + return return_value; +} + +static void php_pqconn_object_write_prop(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) +{ + php_pqconn_object_t *obj = zend_object_store_get_object(object TSRMLS_CC); + php_pq_object_prophandler_t *handler; + + if (zend_hash_find(&php_pqconn_object_prophandlers, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void *) &handler)) { + if (handler->write) { + handler->write(obj, value TSRMLS_CC); + } + } else { + zend_get_std_object_handlers()->write_property(object, member, value, key TSRMLS_CC); + } +} + +static zval *php_pqres_object_read_prop(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) +{ + php_pqres_object_t *obj = zend_object_store_get_object(object TSRMLS_CC); + php_pq_object_prophandler_t *handler; + zval *return_value; + + if (!obj->res) { + zend_error(E_WARNING, "Result not initialized"); + } else if (SUCCESS == zend_hash_find(&php_pqres_object_prophandlers, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void *) &handler)) { + if (type == BP_VAR_R) { + ALLOC_ZVAL(return_value); + Z_SET_REFCOUNT_P(return_value, 0); + Z_UNSET_ISREF_P(return_value); + + handler->read(obj, return_value TSRMLS_CC); + } else { + zend_error(E_ERROR, "Cannot access pq\\Result properties by reference or array key/index"); + return_value = NULL; + } + } else { + return_value = zend_get_std_object_handlers()->read_property(object, member, type, key TSRMLS_CC); + } + + return return_value; +} + +static void php_pqres_object_write_prop(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) +{ + php_pqres_object_t *obj = zend_object_store_get_object(object TSRMLS_CC); + php_pq_object_prophandler_t *handler; + + if (!obj->res) { + zend_error(E_WARNING, "Result not initialized"); + } else if (zend_hash_find(&php_pqres_object_prophandlers, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void *) &handler)) { + if (handler->write) { + handler->write(obj, value TSRMLS_CC); + } + } else { + zend_get_std_object_handlers()->write_property(object, member, value, key TSRMLS_CC); + } +} + +typedef struct php_pqres_iterator { + zend_object_iterator zi; + zval *current_val; + unsigned index; +} php_pqres_iterator_t; + +static zend_object_iterator_funcs php_pqres_iterator_funcs; + +static zend_object_iterator *php_pqres_iterator_init(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) +{ + php_pqres_iterator_t *iter; + + iter = ecalloc(1, sizeof(*iter)); + iter->zi.funcs = &php_pqres_iterator_funcs; + iter->zi.data = object; + Z_ADDREF_P(object); + + return (zend_object_iterator *) iter; +} + +static void php_pqres_iterator_dtor(zend_object_iterator *i TSRMLS_DC) +{ + php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; + + if (iter->current_val) { + zval_ptr_dtor(&iter->current_val); + } + zval_ptr_dtor((zval **) &iter->zi.data); + efree(iter); +} + +static STATUS php_pqres_iterator_valid(zend_object_iterator *i TSRMLS_DC) +{ + php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; + php_pqres_object_t *obj = zend_object_store_get_object(iter->zi.data TSRMLS_CC); + + if (PQresultStatus(obj->res) != PGRES_TUPLES_OK) { + return FAILURE; + } + if (PQntuples(obj->res) <= iter->index) { + return FAILURE; + } + + return SUCCESS; +} + +static zval *php_pqres_row_to_zval(PGresult *res, unsigned row) +{ + zval *data; + int c, cols; + + MAKE_STD_ZVAL(data); + array_init(data); + + for (c = 0, cols = PQnfields(res); c < cols; ++c) { + if (PQgetisnull(res, row, c)) { + add_index_null(data, c); + add_assoc_null(data, PQfname(res, c)); + } else { + char *val = PQgetvalue(res, row, c); + int len = PQgetlength(res, row, c); + + add_index_stringl(data, c, val, len ,1); + add_assoc_stringl(data, PQfname(res, c), val, len, 1); + } + } + + return data; +} + +static void php_pqres_iterator_current(zend_object_iterator *i, zval ***data_ptr TSRMLS_DC) +{ + php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; + php_pqres_object_t *obj = zend_object_store_get_object(iter->zi.data TSRMLS_CC); + + if (iter->current_val) { + zval_ptr_dtor(&iter->current_val); + } + iter->current_val = php_pqres_row_to_zval(obj->res, iter->index); + *data_ptr = &iter->current_val; +} + +static int php_pqres_iterator_key(zend_object_iterator *i, char **key_str, uint *key_len, ulong *key_num TSRMLS_DC) +{ + php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; + + *key_num = (ulong) iter->index; + + return HASH_KEY_IS_LONG; +} + +static void php_pqres_iterator_next(zend_object_iterator *i TSRMLS_DC) +{ + php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; + + ++iter->index; +} + +static void php_pqres_iterator_rewind(zend_object_iterator *i TSRMLS_DC) +{ + php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; + + iter->index = 0; +} + +static zend_object_iterator_funcs php_pqres_iterator_funcs = { + php_pqres_iterator_dtor, + /* check for end of iteration (FAILURE or SUCCESS if data is valid) */ + php_pqres_iterator_valid, + /* fetch the item data for the current element */ + php_pqres_iterator_current, + /* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) (optional, may be NULL) */ + php_pqres_iterator_key, + /* step forwards to next element */ + php_pqres_iterator_next, + /* rewind to start of data (optional, may be NULL) */ + php_pqres_iterator_rewind, + /* invalidate current value/key (optional, may be NULL) */ + NULL +}; + +ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct, 0, 0, 1) + ZEND_ARG_INFO(0, dsn) + ZEND_ARG_INFO(0, block) +ZEND_END_ARG_INFO(); +static PHP_METHOD(pqconn, __construct) { + zend_error_handling zeh; + char *dsn_str; + int dsn_len; + zend_bool block = 1; + + zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &dsn_str, &dsn_len, &block)) { + php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + if (obj->conn) { + PQfinish(obj->conn); + } + if ((obj->blocking = block)) { + obj->conn = PQconnectdb(dsn_str); + } else { + obj->conn = PQconnectStart(dsn_str); + obj->poller = (int (*)(PGconn*)) PQconnectPoll; + } + + if (CONNECTION_BAD == PQstatus(obj->conn)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection failed: %s", PQerrorMessage(obj->conn)); + } + } + zend_restore_error_handling(&zeh TSRMLS_CC); +} + +ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset, 0, 0, 0) +ZEND_END_ARG_INFO(); +static PHP_METHOD(pqconn, reset) { + if (SUCCESS == zend_parse_parameters_none()) { + php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + if (obj->conn) { + if (obj->blocking) { + PQreset(obj->conn); + RETURN_TRUE; /* probably ;) */ + } if (PQresetStart(obj->conn)) { + obj->poller = (int (*)(PGconn*)) PQresetPoll; + RETURN_TRUE; + } + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection not initialized"); + } + RETURN_FALSE; + } +} + +ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_poll, 0, 0, 0) +ZEND_END_ARG_INFO(); +static PHP_METHOD(pqconn, poll) { + if (SUCCESS == zend_parse_parameters_none()) { + php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + if (obj->conn) { + if (obj->poller) { + RETURN_LONG(obj->poller(obj->conn)); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "No asynchronous operation active"); + } + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection not initialized"); + } + RETURN_FALSE; + } +} + +ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec, 0, 0, 1) + ZEND_ARG_INFO(0, query) +ZEND_END_ARG_INFO(); +static PHP_METHOD(pqconn, exec) { + zend_error_handling zeh; + char *query_str; + int query_len; + + zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &query_str, &query_len)) { + php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + if (obj->conn) { + PGresult *res = PQexec(obj->conn, query_str); + + if (res) { + return_value->type = IS_OBJECT; + return_value->value.obj = php_pqres_create_object_ex(php_pqres_class_entry, res, NULL TSRMLS_CC); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not execute query: %s", PQerrorMessage(obj->conn)); + } + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection not initialized"); + } + } + zend_restore_error_handling(&zeh TSRMLS_CC); +} + +static zend_function_entry pqconn_methods[] = { + PHP_ME(pqconn, __construct, ai_pqconn_construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) + PHP_ME(pqconn, reset, ai_pqconn_reset, ZEND_ACC_PUBLIC) + PHP_ME(pqconn, poll, ai_pqconn_poll, ZEND_ACC_PUBLIC) + PHP_ME(pqconn, exec, ai_pqconn_exec, ZEND_ACC_PUBLIC) + {0} +}; + +ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch, 0, 0, 0) + ZEND_ARG_INFO(0, fetch_type) + ZEND_ARG_INFO(0, fetch_info) +ZEND_END_ARG_INFO(); +static PHP_METHOD(pqres, fetchRow) { + zend_error_handling zeh; + long fetch_type = PHP_PQRES_FETCH_OBJECT; + zval *fetch_info = NULL; + + zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lz", &fetch_type, &fetch_info)) { + + } + zend_restore_error_handling(&zeh TSRMLS_CC); +} + +static zend_function_entry pqres_methods[] = { + PHP_ME(pqres, fetchRow, ai_pqres_fetch, ZEND_ACC_PUBLIC) + {0} +}; + +/* {{{ PHP_MINIT_FUNCTION + */ +PHP_MINIT_FUNCTION(pq) +{ + zend_class_entry ce = {0}; + php_pq_object_prophandler_t ph = {0}; + + zend_hash_init(&php_pqconn_object_prophandlers, 1, NULL, NULL, 1); + INIT_NS_CLASS_ENTRY(ce, "pq", "Connection", pqconn_methods); + php_pqconn_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + php_pqconn_class_entry->create_object = php_pqconn_create_object; + memcpy(&php_pqconn_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + php_pqconn_object_handlers.read_property = php_pqconn_object_read_prop; + php_pqconn_object_handlers.write_property = php_pqconn_object_write_prop; + + zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("status"), CONNECTION_BAD, ZEND_ACC_PUBLIC TSRMLS_CC); + ph.read = php_pqconn_object_read_status; + zend_hash_add(&php_pqconn_object_prophandlers, "status", sizeof("status"), (void *) &ph, sizeof(ph), NULL); + + zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN, ZEND_ACC_PUBLIC TSRMLS_CC); + ph.read = php_pqconn_object_read_transaction_status; + zend_hash_add(&php_pqconn_object_prophandlers, "transactionStatus", sizeof("transactionStatus"), (void *) &ph, sizeof(ph), NULL); + + zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("socket"), ZEND_ACC_PUBLIC TSRMLS_CC); + ph.read = php_pqconn_object_read_socket; + zend_hash_add(&php_pqconn_object_prophandlers, "socket", sizeof("socket"), (void *) &ph, sizeof(ph), NULL); + + zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC); + ph.read = php_pqconn_object_read_error_message; + zend_hash_add(&php_pqconn_object_prophandlers, "errorMessage", sizeof("errorMessage"), (void *) &ph, sizeof(ph), NULL); + + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("MADE"), CONNECTION_MADE TSRMLS_CC); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE TSRMLS_CC); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK TSRMLS_CC); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP TSRMLS_CC); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("SETENV"), CONNECTION_SETENV TSRMLS_CC); + + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE TSRMLS_CC); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE TSRMLS_CC); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS TSRMLS_CC); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR TSRMLS_CC); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN TSRMLS_CC); + + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED TSRMLS_CC); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING TSRMLS_CC); + 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_hash_init(&php_pqres_object_prophandlers, 1, NULL, NULL, 1); + memset(&ce, 0, sizeof(ce)); + INIT_NS_CLASS_ENTRY(ce, "pq", "Result", pqres_methods); + php_pqres_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + php_pqres_class_entry->create_object = php_pqres_create_object; + php_pqres_class_entry->iterator_funcs.funcs = &php_pqres_iterator_funcs; + php_pqres_class_entry->get_iterator = php_pqres_iterator_init; + + memcpy(&php_pqres_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + php_pqres_object_handlers.read_property = php_pqres_object_read_prop; + php_pqres_object_handlers.write_property = php_pqres_object_write_prop; + + zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("status"), ZEND_ACC_PUBLIC TSRMLS_CC); + ph.read = php_pqres_object_read_status; + zend_hash_add(&php_pqres_object_prophandlers, "status", sizeof("status"), (void *) &ph, sizeof(ph), NULL); + + zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC); + ph.read = php_pqres_object_read_error_message; + zend_hash_add(&php_pqres_object_prophandlers, "errorMessage", sizeof("errorMessage"), (void *) &ph, sizeof(ph), NULL); + + zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + ph.read = php_pqres_object_read_num_rows; + zend_hash_add(&php_pqres_object_prophandlers, "numRows", sizeof("numRows"), (void *) &ph, sizeof(ph), NULL); + + zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + ph.read = php_pqres_object_read_num_cols; + zend_hash_add(&php_pqres_object_prophandlers, "numCols", sizeof("numCols"), (void *) &ph, sizeof(ph), NULL); + + zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + ph.read = php_pqres_object_read_affected_rows; + zend_hash_add(&php_pqres_object_prophandlers, "affectedRows", sizeof("affectedRows"), (void *) &ph, sizeof(ph), NULL); + + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_IN"), PGRES_COPY_IN TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE TSRMLS_CC); + + /* + REGISTER_INI_ENTRIES(); + */ + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MSHUTDOWN_FUNCTION + */ +PHP_MSHUTDOWN_FUNCTION(pq) +{ + /* uncomment this line if you have INI entries + UNREGISTER_INI_ENTRIES(); + */ + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MINFO_FUNCTION + */ +PHP_MINFO_FUNCTION(pq) +{ + php_info_print_table_start(); + php_info_print_table_header(2, "pq support", "enabled"); + php_info_print_table_end(); + + /* Remove comments if you have entries in php.ini + DISPLAY_INI_ENTRIES(); + */ +} +/* }}} */ + + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/src/php_pq.h b/src/php_pq.h new file mode 100644 index 0000000..cd7b3ab --- /dev/null +++ b/src/php_pq.h @@ -0,0 +1,65 @@ +/* + +--------------------------------------------------------------------+ + | PECL :: pq | + +--------------------------------------------------------------------+ + | Redistribution and use in source and binary forms, with or without | + | modification, are permitted provided that the conditions mentioned | + | in the accompanying LICENSE file are met. | + +--------------------------------------------------------------------+ + | Copyright (c) 20013, Michael Wallner | + +--------------------------------------------------------------------+ +*/ + + +#ifndef PHP_PQ_H +#define PHP_PQ_H + +#define PHP_PQ_EXT_VERSION "0.1.0" + +int pq_module_number; +zend_module_entry pq_module_entry; +#define phpext_pq_ptr &pq_module_entry + +#ifdef PHP_WIN32 +# define PHP_PQ_API __declspec(dllexport) +#elif defined(__GNUC__) && __GNUC__ >= 4 +# define PHP_PQ_API __attribute__ ((visibility("default"))) +#else +# define PHP_PQ_API +#endif + +#ifdef ZTS +# include "TSRM.h" +#endif + +PHP_MINIT_FUNCTION(pq); +PHP_MSHUTDOWN_FUNCTION(pq); +PHP_RINIT_FUNCTION(pq); +PHP_RSHUTDOWN_FUNCTION(pq); +PHP_MINFO_FUNCTION(pq); + + +/* +ZEND_BEGIN_MODULE_GLOBALS(pq) + long global_value; + char *global_string; +ZEND_END_MODULE_GLOBALS(pq) + +#ifdef ZTS +#define PQ_G(v) TSRMG(pq_globals_id, zend_pq_globals *, v) +#else +#define PQ_G(v) (pq_globals.v) +#endif +*/ + +#endif /* PHP_PQ_H */ + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */