package.xml 0000644 0000765 0000024 00000027042 14560227740 012017 0 ustar mike staff
pq
pecl.php.net
PostgreSQL client library (libpq) binding
Documents: https://mdref.m6w6.name/pq
Highlights:
* Nearly complete support for asynchronous usage:
https://mdref.m6w6.name/pq/Connection/%3A%20Asynchronous%20Usage
* Extended type support by pg_type:
https://mdref.m6w6.name/pq/Types/%3A%20Overview
* Fetching simple multi-dimensional array maps:
https://mdref.m6w6.name/pq/Result/map
* Working Gateway implementation:
https://mdref.m6w6.name/pq-gateway
Michael Wallner
mike
mike@php.net
yes
Chris Wright
daverandom
daverandom@php.net
yes
Remi Collet
remi
remi@php.net
yes
2024-02-05
2.2.3
2.1.0
stable
stable
BSD-2-Clause
* Fix incompatible pointer types (32-bit) (see hg issue #52)
7.0.0
1.10.0
raphf
pecl.php.net
2.0.0
raphf
pq
pq-2.2.3/scripts/gen_pq_type.sh 0000755 0000765 0000024 00000000115 14560227740 015312 0 ustar mike staff #!/bin/sh
CWD=$(dirname $0)
$CWD/php_pq_type-pg11.php >$CWD/../php_pq_type.h
pq-2.2.3/scripts/php_pq_type.awk 0000755 0000765 0000024 00000002032 14560227740 015500 0 ustar mike staff #!/usr/bin/awk -f
BEGIN {
printf "#ifndef PHP_PQ_TYPE\n"
printf "# define PHP_PQ_TYPE(t,o)\n"
printf "#endif\n"
}
END {
printf "#ifndef PHP_PQ_TYPE_IS_ARRAY\n"
printf "# define PHP_PQ_TYPE_IS_ARRAY(oid) (\\\n\t\t0 \\\n"
for (oid in arrays) {
printf "\t||\t((oid) == %d) \\\n", oid
}
printf ")\n#endif\n"
printf "#ifndef PHP_PQ_TYPE_OF_ARRAY\n"
printf "# define PHP_PQ_TYPE_OF_ARRAY(oid) ("
for (oid in arrays) {
printf "\\\n\t(oid) == %d ? %s : ", oid, arrays[oid]
}
printf "0 \\\n)\n#endif\n"
printf "#ifndef PHP_PQ_DELIM_OF_ARRAY\n"
printf "# define PHP_PQ_DELIM_OF_ARRAY(oid) ("
for (oid in delims) {
printf "\\\n\t(oid) == %d ? '%s' : ", oid, delims[oid]
}
printf "\\\n\t0 \\\n)\n#endif\n"
}
/^DATA/ {
oid = $4
name = toupper($6)
adelim = $15
atypoid = $17
if (sub("^_", "", name)) {
arrays[oid] = atypoid
name = name "ARRAY"
}
delims[oid] = adelim
printf "#ifndef PHP_PQ_OID_%s\n", name
printf "# define PHP_PQ_OID_%s %d\n", name, oid
printf "#endif\n"
printf "PHP_PQ_TYPE(\"%s\", %d)\n", name, oid
}
pq-2.2.3/src/php_pq_callback.c 0000644 0000765 0000024 00000007576 14560227740 015032 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include
#include
#include "php_pq_callback.h"
void php_pq_callback_dtor(php_pq_callback_t *cb)
{
if (cb->recursion) {
php_pq_callback_dtor(cb->recursion);
efree(cb->recursion);
cb->recursion = NULL;
}
if (cb->fci.size > 0) {
zend_fcall_info_args_clear(&cb->fci, 1);
zval_ptr_dtor(&cb->fci.function_name);
if (cb->fci.object) {
zval tmp;
ZVAL_OBJ(&tmp, cb->fci.object);
zval_ptr_dtor(&tmp);
}
cb->fci.size = 0;
}
}
void php_pq_callback_addref(php_pq_callback_t *cb)
{
Z_TRY_ADDREF(cb->fci.function_name);
if (cb->fci.object) {
#ifdef GC_ADDREF
GC_ADDREF(cb->fci.object);
#else
++GC_REFCOUNT(cb->fci.object);
#endif
}
}
zval *php_pq_callback_to_zval(php_pq_callback_t *cb, zval *tmp)
{
php_pq_callback_addref(cb);
if (cb->fci.object) {
zval zo;
array_init_size(tmp, 2);
ZVAL_OBJ(&zo, cb->fci.object);
add_next_index_zval(tmp, &zo);
add_next_index_zval(tmp, &cb->fci.function_name);
return tmp;
}
return &cb->fci.function_name;
}
zval *php_pq_callback_to_zval_no_addref(php_pq_callback_t *cb, zval *tmp)
{
if (cb->fci.object) {
zval zo;
array_init_size(tmp, 2);
ZVAL_OBJ(&zo, cb->fci.object);
add_next_index_zval(tmp, &zo);
add_next_index_zval(tmp, &cb->fci.function_name);
return tmp;
}
return &cb->fci.function_name;
}
zend_bool php_pq_callback_is_locked(php_pq_callback_t *cb)
{
/* TODO: fixed in php7?
if (php_pq_callback_is_enabled(cb)) {
const zend_function *closure;
const zend_execute_data *ex;
if (Z_TYPE_P(cb->fci.function_name) != IS_OBJECT) {
return 0;
}
closure = zend_get_closure_method_def(cb->fci.function_name);
if (closure->type != ZEND_USER_FUNCTION) {
return 0;
}
for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) {
if (ex->op_array == &closure->op_array) {
return 1;
}
}
}
if (!php_pq_callback_is_recurrent(cb)) {
return 0;
}
return php_pq_callback_is_locked(cb->recursion);
*/
return 0;
}
void php_pq_callback_recurse(php_pq_callback_t *old, php_pq_callback_t *new)
{
if (php_pq_callback_is_locked(old)) {
php_pq_callback_recurse_ex(old, new);
} else {
php_pq_callback_dtor(old);
if (php_pq_callback_is_enabled(new)) {
php_pq_callback_addref(new);
memcpy(old, new, sizeof(*old));
new->fci.size = 0;
}
}
}
extern zend_bool php_pq_callback_is_enabled(php_pq_callback_t *cb)
{
return cb && cb->fci.size > 0;
}
extern zend_bool php_pq_callback_is_recurrent(php_pq_callback_t *cb)
{
return cb && cb->recursion != NULL;
}
extern void php_pq_callback_disable(php_pq_callback_t *cb)
{
if (php_pq_callback_is_enabled(cb)) {
php_pq_callback_recurse_ex(cb, NULL);
}
}
extern void php_pq_callback_recurse_ex(php_pq_callback_t *old, php_pq_callback_t *new)
{
php_pq_callback_t *tmp = emalloc(sizeof(*tmp));
if (new) {
memcpy(tmp, old, sizeof(*tmp));
memcpy(old, new, sizeof(*old));
old->recursion = tmp;
php_pq_callback_addref(old);
php_pq_callback_disable(tmp);
} else {
memcpy(tmp, old, sizeof(*tmp));
memset(old, 0, sizeof(*old));
old->recursion = tmp;
}
}
/*
* 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
*/
pq-2.2.3/src/php_pq_callback.h 0000644 0000765 0000024 00000003421 14560227740 015020 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifndef PHP_PQ_CALLBACK_H
#define PHP_PQ_CALLBACK_H
#include
typedef struct php_pq_callback {
zend_fcall_info fci;
zend_fcall_info_cache fcc;
struct php_pq_callback *recursion;
} php_pq_callback_t;
#define PHP_PQ_CALLBACK_INIT {{0},{0},NULL}
extern void php_pq_callback_dtor(php_pq_callback_t *cb);
extern void php_pq_callback_addref(php_pq_callback_t *cb);
extern zval *php_pq_callback_to_zval(php_pq_callback_t *cb, zval *tmp);
extern zval *php_pq_callback_to_zval_no_addref(php_pq_callback_t *cb, zval *tmp);
extern zend_bool php_pq_callback_is_locked(php_pq_callback_t *cb);
extern void php_pq_callback_recurse(php_pq_callback_t *old, php_pq_callback_t *new);
extern zend_bool php_pq_callback_is_enabled(php_pq_callback_t *cb);
extern void php_pq_callback_disable(php_pq_callback_t *cb);
extern void php_pq_callback_recurse_ex(php_pq_callback_t *old, php_pq_callback_t *new);
extern zend_bool php_pq_callback_is_recurrent(php_pq_callback_t *cb);
#endif
/*
* 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
*/
pq-2.2.3/src/php_pqcancel.c 0000644 0000765 0000024 00000013357 14560227740 014356 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include
#include
#include "php_pq.h"
#include "php_pq_misc.h"
#include "php_pq_object.h"
#include "php_pqexc.h"
#include "php_pqcancel.h"
zend_class_entry *php_pqcancel_class_entry;
static zend_object_handlers php_pqcancel_object_handlers;
static HashTable php_pqcancel_object_prophandlers;
static void php_pqcancel_object_free(zend_object *o)
{
php_pqcancel_object_t *obj = PHP_PQ_OBJ(NULL, o);
#if DBG_GC
fprintf(stderr, "FREE cancel(#%d) %p (conn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->conn->zo.handle, obj->intern->conn);
#endif
if (obj->intern) {
PQfreeCancel(obj->intern->cancel);
php_pq_object_delref(obj->intern->conn);
efree(obj->intern);
obj->intern = NULL;
}
php_pq_object_dtor(o);
}
php_pqcancel_object_t *php_pqcancel_create_object_ex(zend_class_entry *ce, php_pqcancel_t *intern)
{
return php_pq_object_create(ce, intern, sizeof(php_pqcancel_object_t),
&php_pqcancel_object_handlers, &php_pqcancel_object_prophandlers);
}
static zend_object *php_pqcancel_create_object(zend_class_entry *class_type)
{
return &php_pqcancel_create_object_ex(class_type, NULL)->zo;
}
static void php_pqcancel_object_read_connection(void *o, zval *return_value)
{
php_pqcancel_object_t *obj = o;
php_pq_object_to_zval(obj->intern->conn, return_value);
}
static void php_pqcancel_object_gc_connection(void *o, zval *return_value)
{
php_pqcancel_object_t *obj = o;
zval zconn;
php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn);
add_next_index_zval(return_value, &zconn);
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_construct, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, connection, pq\\Connection, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqcancel, __construct) {
zend_error_handling zeh;
zval *zconn;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zconn, php_pqconn_class_entry);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *conn_obj = PHP_PQ_OBJ(zconn, NULL);
if (!conn_obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
PGcancel *cancel = PQgetCancel(conn_obj->intern->conn);
if (!cancel) {
throw_exce(EX_RUNTIME, "Failed to acquire cancel (%s)", PHP_PQerrorMessage(conn_obj->intern->conn));
} else {
php_pqcancel_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
obj->intern = ecalloc(1, sizeof(*obj->intern));
obj->intern->cancel = cancel;
php_pq_object_addref(conn_obj);
obj->intern->conn = conn_obj;
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_cancel, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqcancel, cancel) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqcancel_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Cancel not initialized");
} else {
char err[256] = {0};
if (!PQcancel(obj->intern->cancel, err, sizeof(err))) {
throw_exce(EX_RUNTIME, "Failed to request cancellation (%s)", err);
}
}
}
}
static zend_function_entry php_pqcancel_methods[] = {
PHP_ME(pqcancel, __construct, ai_pqcancel_construct, ZEND_ACC_PUBLIC)
PHP_ME(pqcancel, cancel, ai_pqcancel_cancel, ZEND_ACC_PUBLIC)
{0}
};
PHP_MSHUTDOWN_FUNCTION(pqcancel)
{
zend_hash_destroy(&php_pqcancel_object_prophandlers);
return SUCCESS;
}
PHP_MINIT_FUNCTION(pqcancel)
{
zend_class_entry ce = {0};
php_pq_object_prophandler_t ph = {0};
INIT_NS_CLASS_ENTRY(ce, "pq", "Cancel", php_pqcancel_methods);
php_pqcancel_class_entry = zend_register_internal_class_ex(&ce, NULL);
php_pqcancel_class_entry->create_object = php_pqcancel_create_object;
memcpy(&php_pqcancel_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
php_pqcancel_object_handlers.offset = XtOffsetOf(php_pqcancel_object_t, zo);
php_pqcancel_object_handlers.free_obj = php_pqcancel_object_free;
php_pqcancel_object_handlers.read_property = php_pq_object_read_prop;
php_pqcancel_object_handlers.write_property = php_pq_object_write_prop;
php_pqcancel_object_handlers.clone_obj = NULL;
php_pqcancel_object_handlers.get_property_ptr_ptr = php_pq_object_get_prop_ptr_null;
php_pqcancel_object_handlers.get_gc = php_pq_object_get_gc;
php_pqcancel_object_handlers.get_properties = php_pq_object_properties;
php_pqcancel_object_handlers.get_debug_info = php_pq_object_debug_info;
zend_hash_init(&php_pqcancel_object_prophandlers, 1, NULL, php_pq_object_prophandler_dtor, 1);
zend_declare_property_null(php_pqcancel_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC);
ph.read = php_pqcancel_object_read_connection;
ph.gc = php_pqcancel_object_gc_connection;
zend_hash_str_add_mem(&php_pqcancel_object_prophandlers, ZEND_STRL("connection"), (void *) &ph, sizeof(ph));
return SUCCESS;
}
/*
* 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
*/
pq-2.2.3/src/php_pqcancel.h 0000644 0000765 0000024 00000002462 14560227740 014356 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifndef PHP_PQCANCEL_H
#define PHP_PQCANCEL_H
#include "php_pqconn.h"
typedef struct php_pqcancel {
PGcancel *cancel;
php_pqconn_object_t *conn;
} php_pqcancel_t;
typedef struct php_pqcancel_object {
PHP_PQ_OBJ_DECL(php_pqcancel_t *)
} php_pqcancel_object_t;
extern zend_class_entry *php_pqcancel_class_entry;
extern php_pqcancel_object_t *php_pqcancel_create_object_ex(zend_class_entry *ce, php_pqcancel_t *intern);
extern PHP_MINIT_FUNCTION(pqcancel);
extern PHP_MSHUTDOWN_FUNCTION(pqcancel);
#endif
/*
* 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
*/
pq-2.2.3/src/php_pqconn.c 0000644 0000765 0000024 00000210364 14560227740 014063 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include
#include
#include
#include
#include "php_pq.h"
#include "php_pq_misc.h"
#include "php_pq_object.h"
#include "php_pqexc.h"
#include "php_pqconn.h"
#include "php_pqconn_event.h"
#include "php_pqres.h"
#include "php_pqstm.h"
#include "php_pqtxn.h"
#include "php_pqcur.h"
zend_class_entry *php_pqconn_class_entry;
static zend_object_handlers php_pqconn_object_handlers;
static HashTable php_pqconn_object_prophandlers;
static void php_pq_callback_hash_dtor(zval *p)
{
php_pq_callback_dtor(Z_PTR_P(p));
efree(Z_PTR_P(p));
}
/*
static void php_pqconn_del_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, unsigned long id)
{
zval **evhs;
if (SUCCESS == zend_hash_find(&obj->intern->eventhandlers, type_str, type_len + 1, (void *) &evhs)) {
zend_hash_index_del(Z_ARRVAL_PP(evhs), id);
}
}
*/
static zend_long php_pqconn_add_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, php_pq_callback_t *cb)
{
zend_long h;
zval *zevhs;
if (!(zevhs = zend_hash_str_find(&obj->intern->eventhandlers, type_str, type_len))) {
HashTable *evhs;
zval tmp;
ALLOC_HASHTABLE(evhs);
zend_hash_init(evhs, 1, NULL, php_pq_callback_hash_dtor, 0);
ZVAL_ARR(&tmp, evhs);
zevhs = zend_hash_str_add(&obj->intern->eventhandlers, type_str, type_len, &tmp);
}
php_pq_callback_addref(cb);
h = zend_hash_next_free_element(Z_ARRVAL_P(zevhs));
zend_hash_index_update_mem(Z_ARRVAL_P(zevhs), h, (void *) cb, sizeof(*cb));
return h;
}
static void php_pqconn_object_free(zend_object *o)
{
php_pqconn_object_t *obj = PHP_PQ_OBJ(NULL, o);
#if DBG_GC
fprintf(stderr, "FREE conn(#%d) %p\n", obj->zo.handle, obj);
#endif
if (obj->intern) {
php_pq_callback_dtor(&obj->intern->onevent);
php_resource_factory_handle_dtor(&obj->intern->factory, obj->intern->conn);
php_resource_factory_dtor(&obj->intern->factory);
zend_hash_destroy(&obj->intern->listeners);
zend_hash_destroy(&obj->intern->statements);
zend_hash_destroy(&obj->intern->converters);
zend_hash_destroy(&obj->intern->eventhandlers);
efree(obj->intern);
obj->intern = NULL;
}
php_pq_object_dtor(o);
}
php_pqconn_object_t *php_pqconn_create_object_ex(zend_class_entry *ce, php_pqconn_t *intern)
{
return php_pq_object_create(ce, intern, sizeof(php_pqconn_object_t),
&php_pqconn_object_handlers, &php_pqconn_object_prophandlers);
}
static zend_object *php_pqconn_create_object(zend_class_entry *class_type)
{
return &php_pqconn_create_object_ex(class_type, NULL)->zo;
}
static void php_pqconn_object_read_status(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
RETVAL_LONG(PQstatus(obj->intern->conn));
}
static void php_pqconn_object_read_transaction_status(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
RETVAL_LONG(PQtransactionStatus(obj->intern->conn));
}
static void php_pqconn_object_read_error_message(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
char *error = PHP_PQerrorMessage(obj->intern->conn);
if (error) {
RETVAL_STRING(error);
} else {
RETVAL_NULL();
}
}
static int apply_notify_listener(zval *p, void *arg)
{
php_pq_callback_t *listener = Z_PTR_P(p);
PGnotify *nfy = arg;
zval zpid, zchannel, zmessage;
ZVAL_LONG(&zpid, nfy->be_pid);
ZVAL_STRING(&zchannel, nfy->relname);
ZVAL_STRING(&zmessage, nfy->extra);
zend_fcall_info_argn(&listener->fci, 3, &zchannel, &zmessage, &zpid);
zend_fcall_info_call(&listener->fci, &listener->fcc, NULL, NULL);
zend_fcall_info_args_clear(&listener->fci, 0);
zval_ptr_dtor(&zchannel);
zval_ptr_dtor(&zmessage);
zval_ptr_dtor(&zpid);
return ZEND_HASH_APPLY_KEEP;
}
static int apply_notify_listeners(zval *p, int argc, va_list argv, zend_hash_key *key)
{
HashTable *listeners = Z_ARRVAL_P(p);
PGnotify *nfy = va_arg(argv, PGnotify *);
if (0 == fnmatch(key->key->val, nfy->relname, 0)) {
zend_hash_apply_with_argument(listeners, apply_notify_listener, nfy);
}
return ZEND_HASH_APPLY_KEEP;
}
void php_pqconn_notify_listeners(php_pqconn_object_t *obj)
{
PGnotify *nfy;
while ((nfy = PQnotifies(obj->intern->conn))) {
zend_hash_apply_with_arguments(&obj->intern->listeners, apply_notify_listeners, 1, nfy);
PQfreemem(nfy);
}
}
static void php_pqconn_object_read_busy(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
RETVAL_BOOL(PQisBusy(obj->intern->conn));
}
static void php_pqconn_object_read_encoding(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
RETVAL_STRING(pg_encoding_to_char(PQclientEncoding(obj->intern->conn)));
}
static void php_pqconn_object_write_encoding(void *o, zval *value)
{
php_pqconn_object_t *obj = o;
zend_string *zenc = zval_get_string(value);
if (0 > PQsetClientEncoding(obj->intern->conn, zenc->val)) {
php_error(E_NOTICE, "Unrecognized encoding '%s'", zenc->val);
}
zend_string_release(zenc);
}
static void php_pqconn_object_read_unbuffered(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
RETVAL_BOOL(obj->intern->unbuffered);
}
static void php_pqconn_object_write_unbuffered(void *o, zval *value)
{
php_pqconn_object_t *obj = o;
obj->intern->unbuffered = z_is_true(value);
}
static void php_pqconn_object_read_nonblocking(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
RETVAL_BOOL(PQisnonblocking(obj->intern->conn));
}
static void php_pqconn_object_write_nonblocking(void *o, zval *value)
{
php_pqconn_object_t *obj = o;
PQsetnonblocking(obj->intern->conn, z_is_true(value));
}
static void php_pqconn_object_read_db(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
char *db = PQdb(obj->intern->conn);
if (db) {
RETVAL_STRING(db);
} else {
RETVAL_EMPTY_STRING();
}
}
static void php_pqconn_object_read_user(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
char *user = PQuser(obj->intern->conn);
if (user) {
RETVAL_STRING(user);
} else {
RETVAL_EMPTY_STRING();
}
}
static void php_pqconn_object_read_pass(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
char *pass = PQpass(obj->intern->conn);
if (pass) {
RETVAL_STRING(pass);
} else {
RETVAL_EMPTY_STRING();
}
}
static void php_pqconn_object_read_host(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
char *host = PQhost(obj->intern->conn);
if (host) {
RETVAL_STRING(host);
} else {
RETVAL_EMPTY_STRING();
}
}
static void php_pqconn_object_read_port(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
char *port = PQport(obj->intern->conn);
if (port) {
RETVAL_STRING(port);
} else {
RETVAL_EMPTY_STRING();
}
}
#if HAVE_PQCONNINFO
static void php_pqconn_object_read_params(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
PQconninfoOption *ptr, *params = PQconninfo(obj->intern->conn);
array_init(return_value);
if (params) {
for (ptr = params; ptr->keyword; ++ptr) {
if (ptr->val) {
add_assoc_string(return_value, ptr->keyword, ptr->val);
} else {
add_assoc_null(return_value, ptr->keyword);
}
}
PQconninfoFree(params);
}
}
#endif
static void php_pqconn_object_read_options(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
char *options = PQoptions(obj->intern->conn);
if (options) {
RETVAL_STRING(options);
} else {
RETVAL_EMPTY_STRING();
}
}
static int apply_read_callback_ex(zval *p, void *arg)
{
HashTable *rv = arg;
zval zcb;
zend_hash_next_index_insert(rv, php_pq_callback_to_zval(Z_PTR_P(p), &zcb));
return ZEND_HASH_APPLY_KEEP;
}
static int apply_read_callbacks(zval *p, int argc, va_list argv, zend_hash_key *key)
{
HashTable *evhs = Z_ARRVAL_P(p), *rv = va_arg(argv, HashTable *);
zval entry, *entry_ptr;
array_init_size(&entry, zend_hash_num_elements(evhs));
if (key->key->len) {
entry_ptr = zend_hash_add(rv, key->key, &entry);
} else {
entry_ptr = zend_hash_index_update(rv, key->h, &entry);
}
zend_hash_apply_with_argument(evhs, apply_read_callback_ex, Z_ARRVAL_P(entry_ptr));
return ZEND_HASH_APPLY_KEEP;
}
static void php_pqconn_object_read_event_handlers(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
array_init(return_value);
zend_hash_apply_with_arguments(&obj->intern->eventhandlers, apply_read_callbacks, 1, Z_ARRVAL_P(return_value));
}
static void php_pqconn_object_gc_event_handlers(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
zval *evhs;
ZEND_HASH_FOREACH_VAL(&obj->intern->eventhandlers, evhs)
{
zval *evh;
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(evhs), evh)
{
zval zcb;
add_next_index_zval(return_value, php_pq_callback_to_zval_no_addref(Z_PTR_P(evh), &zcb));
}
ZEND_HASH_FOREACH_END();
}
ZEND_HASH_FOREACH_END();
}
static void php_pqconn_object_read_listeners(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
array_init(return_value);
zend_hash_apply_with_arguments(&obj->intern->listeners, apply_read_callbacks, 1, Z_ARRVAL_P(return_value));
}
static void php_pqconn_object_gc_listeners(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
zval *listeners;
ZEND_HASH_FOREACH_VAL(&obj->intern->listeners, listeners)
{
zval *listener;
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(listeners), listener)
{
zval zcb;
add_next_index_zval(return_value, php_pq_callback_to_zval_no_addref(Z_PTR_P(listener), &zcb));
}
ZEND_HASH_FOREACH_END();
}
ZEND_HASH_FOREACH_END();
}
static void php_pqconn_object_read_converters(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
array_init(return_value);
zend_hash_copy(Z_ARRVAL_P(return_value), &obj->intern->converters, zval_add_ref);
}
static void php_pqconn_object_gc_converters(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
zval *converter;
ZEND_HASH_FOREACH_VAL(&obj->intern->converters, converter)
{
add_next_index_zval(return_value, converter);
}
ZEND_HASH_FOREACH_END();
}
static void php_pqconn_object_read_def_fetch_type(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
RETVAL_LONG(obj->intern->default_fetch_type);
}
static void php_pqconn_object_write_def_fetch_type(void *o, zval *value)
{
php_pqconn_object_t *obj = o;
obj->intern->default_fetch_type = zval_get_long(value) & 0x3; /* two bits only */
}
static void php_pqconn_object_read_def_txn_isolation(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
RETVAL_LONG(obj->intern->default_txn_isolation);
}
static void php_pqconn_object_write_def_txn_isolation(void *o, zval *value)
{
php_pqconn_object_t *obj = o;
obj->intern->default_txn_isolation = zval_get_long(value) & 0x3; /* two bits only */
}
static void php_pqconn_object_read_def_txn_readonly(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
RETVAL_BOOL(obj->intern->default_txn_readonly);
}
static void php_pqconn_object_write_def_txn_readonly(void *o, zval *value)
{
php_pqconn_object_t *obj = o;
obj->intern->default_txn_readonly = z_is_true(value);
}
static void php_pqconn_object_read_def_txn_deferrable(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
RETVAL_BOOL(obj->intern->default_txn_deferrable);
}
static void php_pqconn_object_write_def_txn_deferrable(void *o, zval *value)
{
php_pqconn_object_t *obj = o;
obj->intern->default_txn_deferrable = zend_is_true(value);
}
static void php_pqconn_object_read_def_auto_conv(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
RETVAL_LONG(obj->intern->default_auto_convert);
}
static void php_pqconn_object_write_def_auto_conv(void *o, zval *value)
{
php_pqconn_object_t *obj = o;
obj->intern->default_auto_convert = zval_get_long(value) & PHP_PQRES_CONV_ALL;
}
#ifdef HAVE_PQLIBVERSION
static void php_pqconn_object_read_lib_version(void *o, zval *return_value)
{
char ver[16];
php_pq_version_to_string(PQlibVersion(), ver, sizeof(ver));
RETVAL_STRING(ver);
}
#endif
#ifdef HAVE_PQPROTOCOLVERSION
static void php_pqconn_object_read_protocol_version(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
RETVAL_LONG(PQprotocolVersion(obj->intern->conn));
}
#endif
#ifdef HAVE_PQSERVERVERSION
static void php_pqconn_object_read_server_version(void *o, zval *return_value)
{
php_pqconn_object_t *obj = o;
char ver[16];
php_pq_version_to_string(PQserverVersion(obj->intern->conn), ver, sizeof(ver));
RETVAL_STRING(ver);
}
#endif
static ZEND_RESULT_CODE php_pqconn_update_socket(zval *zobj, php_pqconn_object_t *obj)
{
zval zsocket, zmember;
php_stream *stream;
ZEND_RESULT_CODE retval;
int socket;
if (!obj) {
obj = PHP_PQ_OBJ(zobj, NULL);
}
ZVAL_STRINGL(&zmember, "socket", sizeof("socket")-1);
if ((CONNECTION_BAD != PQstatus(obj->intern->conn))
&& (-1 < (socket = PQsocket(obj->intern->conn)))
&& (stream = php_stream_fopen_from_fd(socket, "r+b", NULL))) {
stream->flags |= PHP_STREAM_FLAG_NO_CLOSE;
php_stream_to_zval(stream, &zsocket);
retval = SUCCESS;
} else {
ZVAL_NULL(&zsocket);
retval = FAILURE;
}
#if PHP_VERSION_ID >= 80000
zend_std_write_property(Z_OBJ_P(zobj), Z_STR(zmember), &zsocket, NULL);
#else
zend_std_write_property(zobj, &zmember, &zsocket, NULL);
#endif
zval_ptr_dtor(&zsocket);
zval_ptr_dtor(&zmember);
return retval;
}
static void *php_pqconn_resource_factory_ctor(void *data, void *init_arg)
{
php_pqconn_resource_factory_data_t *o = init_arg;
PGconn *conn = NULL;;
if (o->flags & PHP_PQCONN_ASYNC) {
conn = PQconnectStart(o->dsn);
} else {
conn = PQconnectdb(o->dsn);
}
if (conn) {
PQregisterEventProc(conn, php_pqconn_event, "ext-pq", NULL);
}
return conn;
}
static void php_pqconn_resource_factory_dtor(void *opaque, void *handle)
{
php_pqconn_event_data_t *evdata = PQinstanceData(handle, php_pqconn_event);
/* we don't care for anything, except free'ing evdata */
if (evdata) {
PQsetInstanceData(handle, php_pqconn_event, NULL);
memset(evdata, 0, sizeof(*evdata));
efree(evdata);
}
PQfinish(handle);
}
static php_resource_factory_ops_t php_pqconn_resource_factory_ops = {
php_pqconn_resource_factory_ctor,
NULL,
php_pqconn_resource_factory_dtor
};
php_resource_factory_ops_t *php_pqconn_get_resource_factory_ops(void)
{
return &php_pqconn_resource_factory_ops;
}
static void php_pqconn_wakeup(php_persistent_handle_factory_t *f, void **handle)
{
PGresult *res = PQexec(*handle, "");
php_pqres_clear(res);
if (CONNECTION_OK != PQstatus(*handle)) {
PQreset(*handle);
}
}
static inline PGresult *unlisten(PGconn *conn, const char *channel_str, size_t channel_len)
{
char *quoted_channel = PQescapeIdentifier(conn, channel_str, channel_len);
PGresult *res = NULL;
if (quoted_channel) {
smart_str cmd = {0};
smart_str_appends(&cmd, "UNLISTEN ");
smart_str_appends(&cmd, quoted_channel);
smart_str_0(&cmd);
res = php_pq_exec(conn, smart_str_v(&cmd));
smart_str_free(&cmd);
PQfreemem(quoted_channel);
}
return res;
}
static int apply_unlisten(zval *p, int argc, va_list argv, zend_hash_key *key)
{
php_pqconn_object_t *obj = va_arg(argv, php_pqconn_object_t *);
PGresult *res = unlisten(obj->intern->conn, key->key->val, key->key->len);
if (res) {
php_pqres_clear(res);
}
return ZEND_HASH_APPLY_REMOVE;
}
static void php_pqconn_retire(php_persistent_handle_factory_t *f, void **handle)
{
php_pqconn_event_data_t *evdata = PQinstanceData(*handle, php_pqconn_event);
PGcancel *cancel;
PGresult *res;
/* go away */
PQsetInstanceData(*handle, php_pqconn_event, NULL);
/* ignore notices */
PQsetNoticeReceiver(*handle, php_pqconn_notice_ignore, NULL);
/* cancel async queries */
if (PQisBusy(*handle) && (cancel = PQgetCancel(*handle))) {
char err[256] = {0};
PQcancel(cancel, err, sizeof(err));
PQfreeCancel(cancel);
}
/* clean up async results */
while ((res = PQgetResult(*handle))) {
php_pqres_clear(res);
}
/* clean up transaction & session */
switch (PQtransactionStatus(*handle)) {
case PQTRANS_IDLE:
res = PQexec(*handle, "RESET ALL");
break;
default:
res = PQexec(*handle, "ROLLBACK; RESET ALL");
break;
}
if (res) {
php_pqres_clear(res);
}
if (evdata) {
/* clean up notify listeners */
zend_hash_apply_with_arguments(&evdata->obj->intern->listeners, apply_unlisten, 1, evdata->obj);
/* release instance data */
efree(evdata);
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct, 0, 0, 1)
ZEND_ARG_INFO(0, dsn)
ZEND_ARG_INFO(0, flags)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, __construct) {
zend_error_handling zeh;
char *dsn_str = "";
size_t dsn_len = 0;
zend_long flags = 0;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|sl", &dsn_str, &dsn_len, &flags);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (obj->intern) {
throw_exce(EX_BAD_METHODCALL, "pq\\Connection already initialized");
} else {
php_pqconn_event_data_t *evdata = php_pqconn_event_data_init(obj);
php_pqconn_resource_factory_data_t rfdata = {dsn_str, flags};
obj->intern = ecalloc(1, sizeof(*obj->intern));
obj->intern->default_auto_convert = PHP_PQRES_CONV_ALL;
zend_hash_init(&obj->intern->listeners, 0, NULL, ZVAL_PTR_DTOR, 0);
zend_hash_init(&obj->intern->statements, 0, NULL, NULL, 0);
zend_hash_init(&obj->intern->converters, 0, NULL, ZVAL_PTR_DTOR, 0);
zend_hash_init(&obj->intern->eventhandlers, 0, NULL, ZVAL_PTR_DTOR, 0);
if (flags & PHP_PQCONN_PERSISTENT) {
zend_string *dsn = zend_string_init(dsn_str, dsn_len, 0);
php_persistent_handle_factory_t *phf = php_persistent_handle_concede(NULL, PHP_PQ_G->connection.name, dsn, php_pqconn_wakeup, php_pqconn_retire);
php_persistent_handle_resource_factory_init(&obj->intern->factory, phf);
zend_string_release(dsn);
} 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;
}
obj->intern->conn = php_resource_factory_handle_ctor(&obj->intern->factory, &rfdata);
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)) {
throw_exce(EX_CONNECTION_FAILED, "Connection failed (%s)", PHP_PQerrorMessage(obj->intern->conn));
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, reset) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
PQreset(obj->intern->conn);
if (CONNECTION_OK != PQstatus(obj->intern->conn)) {
throw_exce(EX_CONNECTION_FAILED, "Connection reset failed: (%s)", PHP_PQerrorMessage(obj->intern->conn));
}
php_pqconn_notify_listeners(obj);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset_async, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, resetAsync) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
if (!PQresetStart(obj->intern->conn)) {
throw_exce(EX_IO, "Failed to start connection reset (%s)", PHP_PQerrorMessage(obj->intern->conn));
} else {
obj->intern->poller = (int (*)(PGconn*)) PQresetPoll;
}
php_pqconn_notify_listeners(obj);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unlisten, 0, 0, 1)
ZEND_ARG_INFO(0, channel)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, unlisten)
{
zend_error_handling zeh;
char *channel_str;
size_t channel_len;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &channel_str, &channel_len);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else if (SUCCESS == zend_hash_str_del(&obj->intern->listeners, channel_str, channel_len)) {
PGresult *res = unlisten(obj->intern->conn, channel_str, channel_len);
if (res) {
php_pqres_success(res);
php_pqres_clear(res);
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unlisten_async, 0, 0, 1)
ZEND_ARG_INFO(0, channel)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, unlistenAsync) {
zend_error_handling zeh;
char *channel_str;
size_t channel_len;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &channel_str, &channel_len);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
char *quoted_channel = PQescapeIdentifier(obj->intern->conn, channel_str, channel_len);
if (!quoted_channel) {
throw_exce(EX_ESCAPE, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj->intern->conn));
} else {
smart_str cmd = {0};
smart_str_appends(&cmd, "UNLISTEN ");
smart_str_appends(&cmd, quoted_channel);
smart_str_0(&cmd);
if (!PQsendQuery(obj->intern->conn, smart_str_v(&cmd))) {
throw_exce(EX_IO, "Failed to uninstall listener (%s)", PHP_PQerrorMessage(obj->intern->conn));
} else {
obj->intern->poller = PQconsumeInput;
zend_hash_str_del(&obj->intern->listeners, channel_str, channel_len);
}
smart_str_free(&cmd);
PQfreemem(quoted_channel);
php_pqconn_notify_listeners(obj);
}
}
}
}
static void php_pqconn_add_listener(php_pqconn_object_t *obj, const char *channel_str, size_t channel_len, php_pq_callback_t *listener)
{
zval *existing;
php_pq_callback_addref(listener);
if ((existing = zend_hash_str_find(&obj->intern->listeners, channel_str, channel_len))) {
zend_hash_next_index_insert_mem(Z_ARRVAL_P(existing), (void *) listener, sizeof(*listener));
} else {
zval tmp;
HashTable *ht;
ALLOC_HASHTABLE(ht);
zend_hash_init(ht, 0, NULL, php_pq_callback_hash_dtor, 0);
zend_hash_next_index_insert_mem(ht, (void *) listener, sizeof(*listener));
ZVAL_ARR(&tmp, ht);
zend_hash_str_add(&obj->intern->listeners, channel_str, channel_len, &tmp);
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen, 0, 0, 2)
ZEND_ARG_INFO(0, channel)
ZEND_ARG_INFO(0, callable)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, listen) {
zend_error_handling zeh;
char *channel_str = NULL;
size_t channel_len = 0;
php_pq_callback_t listener = PHP_PQ_CALLBACK_INIT;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "sf", &channel_str, &channel_len, &listener.fci, &listener.fcc);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
char *quoted_channel = PQescapeIdentifier(obj->intern->conn, channel_str, channel_len);
if (!quoted_channel) {
throw_exce(EX_ESCAPE, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj->intern->conn));
} else {
PGresult *res;
smart_str cmd = {0};
smart_str_appends(&cmd, "LISTEN ");
smart_str_appends(&cmd, quoted_channel);
smart_str_0(&cmd);
res = php_pq_exec(obj->intern->conn, smart_str_v(&cmd));
smart_str_free(&cmd);
PQfreemem(quoted_channel);
if (!res) {
throw_exce(EX_RUNTIME, "Failed to install listener (%s)", PHP_PQerrorMessage(obj->intern->conn));
} else {
if (SUCCESS == php_pqres_success(res)) {
obj->intern->poller = PQconsumeInput;
php_pqconn_add_listener(obj, channel_str, channel_len, &listener);
}
php_pqres_clear(res);
}
php_pqconn_notify_listeners(obj);
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen_async, 0, 0, 0)
ZEND_ARG_INFO(0, channel)
ZEND_ARG_INFO(0, callable)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, listenAsync) {
zend_error_handling zeh;
char *channel_str = NULL;
size_t channel_len = 0;
php_pq_callback_t listener = PHP_PQ_CALLBACK_INIT;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "sf", &channel_str, &channel_len, &listener.fci, &listener.fcc);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
char *quoted_channel = PQescapeIdentifier(obj->intern->conn, channel_str, channel_len);
if (!quoted_channel) {
throw_exce(EX_ESCAPE, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj->intern->conn));
} else {
smart_str cmd = {0};
smart_str_appends(&cmd, "LISTEN ");
smart_str_appends(&cmd, quoted_channel);
smart_str_0(&cmd);
if (!PQsendQuery(obj->intern->conn, smart_str_v(&cmd))) {
throw_exce(EX_IO, "Failed to install listener (%s)", PHP_PQerrorMessage(obj->intern->conn));
} else {
obj->intern->poller = PQconsumeInput;
php_pqconn_add_listener(obj, channel_str, channel_len, &listener);
}
smart_str_free(&cmd);
PQfreemem(quoted_channel);
php_pqconn_notify_listeners(obj);
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify, 0, 0, 2)
ZEND_ARG_INFO(0, channel)
ZEND_ARG_INFO(0, message)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, notify) {
zend_error_handling zeh;
char *channel_str, *message_str;
size_t channel_len, message_len;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &channel_str, &channel_len, &message_str, &message_len);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
PGresult *res;
char *params[2] = {channel_str, message_str};
res = php_pq_exec_params(obj->intern->conn, "select pg_notify($1, $2)", 2, NULL, (const char *const*) params, NULL, NULL, 0);
if (!res) {
throw_exce(EX_RUNTIME, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj->intern->conn));
} else {
php_pqres_success(res);
php_pqres_clear(res);
}
php_pqconn_notify_listeners(obj);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify_async, 0, 0, 2)
ZEND_ARG_INFO(0, channel)
ZEND_ARG_INFO(0, message)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, notifyAsync) {
zend_error_handling zeh;
char *channel_str, *message_str;
size_t channel_len, message_len;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &channel_str, &channel_len, &message_str, &message_len);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
char *params[2] = {channel_str, message_str};
if (!PQsendQueryParams(obj->intern->conn, "select pg_notify($1, $2)", 2, NULL, (const char *const*) params, NULL, NULL, 0)) {
throw_exce(EX_IO, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj->intern->conn));
} else {
obj->intern->poller = PQconsumeInput;
}
php_pqconn_notify_listeners(obj);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_poll, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, poll) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else if (!obj->intern->poller) {
throw_exce(EX_RUNTIME, "No asynchronous operation active");
} else {
if (obj->intern->poller == PQconsumeInput) {
RETVAL_LONG(obj->intern->poller(obj->intern->conn) * PGRES_POLLING_OK);
} else {
RETVAL_LONG(obj->intern->poller(obj->intern->conn));
}
php_pqconn_notify_listeners(obj);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_flush, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, flush) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else if (!obj->intern->poller) {
throw_exce(EX_RUNTIME, "No asynchronous operation active");
} else {
switch (PQflush(obj->intern->conn)) {
case -1:
default:
throw_exce(EX_RUNTIME, "Failed to flush connection: %s", PHP_PQerrorMessage(obj->intern->conn));
break;
case 0:
RETVAL_TRUE;
break;
case 1:
RETVAL_FALSE;
break;
}
}
}
}
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;
size_t query_len;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &query_str, &query_len);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
PGresult *res = php_pq_exec(obj->intern->conn, query_str);
if (!res) {
throw_exce(EX_RUNTIME, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn));
} else if (SUCCESS == php_pqres_success(res)) {
php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), return_value);
} else {
php_pqres_clear(res);
}
php_pqconn_notify_listeners(obj);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_get_result, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, getResult) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
PGresult *res = PQgetResult(obj->intern->conn);
php_pq_object_t *res_obj;
if (res && (res_obj = PQresultInstanceData(res, php_pqconn_event))) {
php_pq_object_to_zval_no_addref(res_obj, return_value);
} else {
RETVAL_NULL();
}
php_pqconn_notify_listeners(obj);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_async, 0, 0, 1)
ZEND_ARG_INFO(0, query)
ZEND_ARG_INFO(0, callable)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, execAsync) {
zend_error_handling zeh;
php_pq_callback_t resolver = PHP_PQ_CALLBACK_INIT;
char *query_str;
size_t query_len;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s|f", &query_str, &query_len, &resolver.fci, &resolver.fcc);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else if (!PQsendQuery(obj->intern->conn, query_str)) {
throw_exce(EX_IO, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn));
#if HAVE_PQSETSINGLEROWMODE
} else if (obj->intern->unbuffered && !PQsetSingleRowMode(obj->intern->conn)) {
throw_exce(EX_RUNTIME, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn));
#endif
} else {
php_pq_callback_recurse(&obj->intern->onevent, &resolver);
obj->intern->poller = PQconsumeInput;
php_pqconn_notify_listeners(obj);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params, 0, 0, 2)
ZEND_ARG_INFO(0, query)
ZEND_ARG_ARRAY_INFO(0, params, 0)
ZEND_ARG_ARRAY_INFO(0, types, 1)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, execParams) {
zend_error_handling zeh;
char *query_str;
size_t query_len;
zval *zparams;
zval *ztypes = NULL;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "sa/|a/!", &query_str, &query_len, &zparams, &ztypes);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
PGresult *res;
php_pq_params_t *params;
params = php_pq_params_init(&obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, Z_ARRVAL_P(zparams));
res = php_pq_exec_params(obj->intern->conn, query_str, params->param.count, params->type.oids, (const char *const*) params->param.strings, NULL, NULL, 0);
php_pq_params_free(¶ms);
if (!res) {
throw_exce(EX_RUNTIME, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn));
} else {
if (SUCCESS == php_pqres_success(res)) {
php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), return_value);
} else {
php_pqres_clear(res);
}
php_pqconn_notify_listeners(obj);
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params_async, 0, 0, 2)
ZEND_ARG_INFO(0, query)
ZEND_ARG_ARRAY_INFO(0, params, 0)
ZEND_ARG_ARRAY_INFO(0, types, 1)
ZEND_ARG_INFO(0, callable)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, execParamsAsync) {
zend_error_handling zeh;
php_pq_callback_t resolver = PHP_PQ_CALLBACK_INIT;
char *query_str;
size_t query_len;
zval *zparams;
zval *ztypes = NULL;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "sa/|a/!f", &query_str, &query_len, &zparams, &ztypes, &resolver.fci, &resolver.fcc);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
int rc;
php_pq_params_t *params;
params = php_pq_params_init(&obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, Z_ARRVAL_P(zparams));
rc = PQsendQueryParams(obj->intern->conn, query_str, params->param.count, params->type.oids, (const char *const*) params->param.strings, NULL, NULL, 0);
php_pq_params_free(¶ms);
if (!rc) {
throw_exce(EX_IO, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn));
#if HAVE_PQSETSINGLEROWMODE
} else if (obj->intern->unbuffered && !PQsetSingleRowMode(obj->intern->conn)) {
throw_exce(EX_RUNTIME, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn));
#endif
} else {
php_pq_callback_recurse(&obj->intern->onevent, &resolver);
obj->intern->poller = PQconsumeInput;
php_pqconn_notify_listeners(obj);
}
}
}
zend_restore_error_handling(&zeh);
}
ZEND_RESULT_CODE php_pqconn_prepare(zval *object, php_pqconn_object_t *obj, const char *name, const char *query, php_pq_params_t *params)
{
PGresult *res;
ZEND_RESULT_CODE rv;
if (!obj) {
obj = PHP_PQ_OBJ(object, NULL);
}
res = php_pq_prepare(obj->intern->conn, name, query, params->type.count, params->type.oids);
if (!res) {
rv = FAILURE;
throw_exce(EX_RUNTIME, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj->intern->conn));
} else {
rv = php_pqres_success(res);
php_pqres_clear(res);
php_pqconn_notify_listeners(obj);
}
return rv;
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare, 0, 0, 2)
ZEND_ARG_INFO(0, name)
ZEND_ARG_INFO(0, query)
ZEND_ARG_ARRAY_INFO(0, types, 1)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, prepare) {
zend_error_handling zeh;
zval *ztypes = NULL;
char *name_str, *query_str;
size_t name_len, *query_len;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "ss|a/!", &name_str, &name_len, &query_str, &query_len, &ztypes);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
php_pq_params_t *params = php_pq_params_init(&obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, NULL);
if (SUCCESS != php_pqconn_prepare(getThis(), obj, name_str, query_str, params)) {
php_pq_params_free(¶ms);
} else {
php_pqstm_t *stm = php_pqstm_init(obj, name_str, query_str, params);
RETVAL_OBJ(&php_pqstm_create_object_ex(php_pqstm_class_entry, stm)->zo);
}
}
}
}
ZEND_RESULT_CODE php_pqconn_prepare_async(zval *object, php_pqconn_object_t *obj, const char *name, const char *query, php_pq_params_t *params)
{
ZEND_RESULT_CODE rv;
if (!obj) {
obj = PHP_PQ_OBJ(object, NULL);
}
if (!PQsendPrepare(obj->intern->conn, name, query, params->type.count, params->type.oids)) {
rv = FAILURE;
throw_exce(EX_IO, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj->intern->conn));
} else {
rv = SUCCESS;
obj->intern->poller = PQconsumeInput;
php_pqconn_notify_listeners(obj);
}
return rv;
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare_async, 0, 0, 2)
ZEND_ARG_INFO(0, name)
ZEND_ARG_INFO(0, query)
ZEND_ARG_ARRAY_INFO(0, types, 1)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, prepareAsync) {
zend_error_handling zeh;
zval *ztypes = NULL;
char *name_str, *query_str;
size_t name_len, *query_len;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "ss|a/!", &name_str, &name_len, &query_str, &query_len, &ztypes);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
php_pq_params_t *params = php_pq_params_init(&obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, NULL);
if (SUCCESS != php_pqconn_prepare_async(getThis(), obj, name_str, query_str, params)) {
php_pq_params_free(¶ms);
} else {
php_pqstm_t *stm = php_pqstm_init(obj, name_str, query_str, params);
RETVAL_OBJ(&php_pqstm_create_object_ex(php_pqstm_class_entry, stm)->zo);
}
}
}
}
ZEND_RESULT_CODE php_pqconn_declare(zval *object, php_pqconn_object_t *obj, const char *decl)
{
PGresult *res;
ZEND_RESULT_CODE rv;
if (!obj) {
obj = PHP_PQ_OBJ(object, NULL);
}
res = php_pq_exec(obj->intern->conn, decl);
if (!res) {
rv = FAILURE;
throw_exce(EX_RUNTIME, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj->intern->conn));
} else {
rv = php_pqres_success(res);
php_pqres_clear(res);
php_pqconn_notify_listeners(obj);
}
return rv;
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_declare, 0, 0, 3)
ZEND_ARG_INFO(0, name)
ZEND_ARG_INFO(0, flags)
ZEND_ARG_INFO(0, query)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, declare) {
zend_error_handling zeh;
char *name_str, *query_str;
size_t name_len, query_len;
zend_long flags;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "sls", &name_str, &name_len, &flags, &query_str, &query_len);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
int query_offset;
char *decl = php_pqcur_declare_str(name_str, name_len, flags, query_str, query_len, &query_offset);
if (SUCCESS != php_pqconn_declare(getThis(), obj, decl)) {
efree(decl);
} else {
php_pqcur_t *cur = php_pqcur_init(obj, name_str, decl, query_offset, flags);
RETVAL_OBJ(&php_pqcur_create_object_ex(php_pqcur_class_entry, cur)->zo);
}
}
}
}
ZEND_RESULT_CODE php_pqconn_declare_async(zval *object, php_pqconn_object_t *obj, const char *decl)
{
ZEND_RESULT_CODE rv;
if (!obj) {
obj = PHP_PQ_OBJ(object, NULL);
}
if (!PQsendQuery(obj->intern->conn, decl)) {
rv = FAILURE;
throw_exce(EX_IO, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj->intern->conn));
} else {
rv = SUCCESS;
obj->intern->poller = PQconsumeInput;
php_pqconn_notify_listeners(obj);
}
return rv;
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_declare_async, 0, 0, 2)
ZEND_ARG_INFO(0, name)
ZEND_ARG_INFO(0, flags)
ZEND_ARG_INFO(0, query)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, declareAsync) {
zend_error_handling zeh;
char *name_str, *query_str;
size_t name_len, query_len;
zend_long flags;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "sls", &name_str, &name_len, &flags, &query_str, &query_len);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
int query_offset;
char *decl = php_pqcur_declare_str(name_str, name_len, flags, query_str, query_len, &query_offset);
if (SUCCESS != php_pqconn_declare_async(getThis(), obj, decl)) {
efree(decl);
} else {
php_pqcur_t *cur = php_pqcur_init(obj, name_str, decl, query_offset, flags);
RETVAL_OBJ(&php_pqcur_create_object_ex(php_pqcur_class_entry, cur)->zo);
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote, 0, 0, 1)
ZEND_ARG_INFO(0, string)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, quote) {
char *str;
size_t len;
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &len)) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
char *quoted = PQescapeLiteral(obj->intern->conn, str, len);
if (!quoted) {
php_error_docref(NULL, E_WARNING, "Failed to quote string (%s)", PHP_PQerrorMessage(obj->intern->conn));
RETVAL_FALSE;
} else {
RETVAL_STRING(quoted);
PQfreemem(quoted);
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote_name, 0, 0, 1)
ZEND_ARG_INFO(0, type)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, quoteName) {
char *str;
size_t len;
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &len)) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
char *quoted = PQescapeIdentifier(obj->intern->conn, str, len);
if (!quoted) {
php_error_docref(NULL, E_WARNING, "Failed to quote name (%s)", PHP_PQerrorMessage(obj->intern->conn));
RETVAL_FALSE;
} else {
RETVAL_STRING(quoted);
PQfreemem(quoted);
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_escape_bytea, 0, 0, 1)
ZEND_ARG_INFO(0, bytea)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, escapeBytea) {
char *str;
size_t len;
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &len)) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
size_t escaped_len;
char *escaped_str = (char *) PQescapeByteaConn(obj->intern->conn, (unsigned char *) str, len, &escaped_len);
if (!escaped_str) {
php_error_docref(NULL, E_WARNING, "Failed to escape bytea (%s)", PHP_PQerrorMessage(obj->intern->conn));
RETVAL_FALSE;
} else {
RETVAL_STRINGL(escaped_str, escaped_len - 1);
PQfreemem(escaped_str);
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unescape_bytea, 0, 0, 1)
ZEND_ARG_INFO(0, bytea)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, unescapeBytea) {
char *str;
size_t len;
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &len)) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
size_t unescaped_len;
char *unescaped_str = (char *) PQunescapeBytea((unsigned char *)str, &unescaped_len);
if (!unescaped_str) {
php_error_docref(NULL, E_WARNING, "Failed to unescape bytea (%s)", PHP_PQerrorMessage(obj->intern->conn));
RETVAL_FALSE;
} else {
RETVAL_STRINGL(unescaped_str, unescaped_len);
PQfreemem(unescaped_str);
}
}
}
}
ZEND_RESULT_CODE php_pqconn_start_transaction(zval *zconn, php_pqconn_object_t *conn_obj, long isolation, zend_bool readonly, zend_bool deferrable)
{
ZEND_RESULT_CODE rv = FAILURE;
if (!conn_obj) {
conn_obj = PHP_PQ_OBJ(zconn, NULL);
}
if (!conn_obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
PGresult *res;
smart_str cmd = {0};
const char *il = php_pq_isolation_level(&isolation);
smart_str_appends(&cmd, "START TRANSACTION ISOLATION LEVEL ");
smart_str_appends(&cmd, il);
smart_str_appends(&cmd, ", READ ");
smart_str_appends(&cmd, readonly ? "ONLY" : "WRITE");
smart_str_appends(&cmd, ",");
smart_str_appends(&cmd, deferrable ? "" : " NOT");
smart_str_appends(&cmd, " DEFERRABLE");
smart_str_0(&cmd);
res = php_pq_exec(conn_obj->intern->conn, smart_str_v(&cmd));
if (!res) {
throw_exce(EX_RUNTIME, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj->intern->conn));
} else {
rv = php_pqres_success(res);
php_pqres_clear(res);
php_pqconn_notify_listeners(conn_obj);
}
smart_str_free(&cmd);
}
return rv;
}
ZEND_RESULT_CODE php_pqconn_start_transaction_async(zval *zconn, php_pqconn_object_t *conn_obj, long isolation, zend_bool readonly, zend_bool deferrable)
{
ZEND_RESULT_CODE rv = FAILURE;
if (!conn_obj) {
conn_obj = PHP_PQ_OBJ(zconn, NULL);
}
if (!conn_obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
smart_str cmd = {0};
const char *il = php_pq_isolation_level(&isolation);
smart_str_appends(&cmd, "START TRANSACTION ISOLATION LEVEL ");
smart_str_appends(&cmd, il);
smart_str_appends(&cmd, ", READ ");
smart_str_appends(&cmd, readonly ? "ONLY" : "WRITE");
smart_str_appends(&cmd, ",");
smart_str_appends(&cmd, deferrable ? "" : "NOT ");
smart_str_appends(&cmd, " DEFERRABLE");
smart_str_0(&cmd);
if (!PQsendQuery(conn_obj->intern->conn, smart_str_v(&cmd))) {
throw_exce(EX_IO, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj->intern->conn));
} else {
rv = SUCCESS;
conn_obj->intern->poller = PQconsumeInput;
php_pqconn_notify_listeners(conn_obj);
}
smart_str_free(&cmd);
}
return rv;
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction, 0, 0, 0)
ZEND_ARG_INFO(0, isolation)
ZEND_ARG_INFO(0, readonly)
ZEND_ARG_INFO(0, deferrable)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, startTransaction) {
zend_error_handling zeh;
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
zend_long isolation = obj->intern ? obj->intern->default_txn_isolation : PHP_PQTXN_READ_COMMITTED;
zend_bool readonly = obj->intern ? obj->intern->default_txn_readonly : 0;
zend_bool deferrable = obj->intern ? obj->intern->default_txn_deferrable : 0;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|lbb", &isolation, &readonly, &deferrable);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
rv = php_pqconn_start_transaction(getThis(), obj, isolation, readonly, deferrable);
if (SUCCESS == rv) {
php_pqtxn_t *txn = ecalloc(1, sizeof(*txn));
php_pq_object_addref(obj);
txn->conn = obj;
txn->open = 1;
txn->isolation = isolation;
txn->readonly = readonly;
txn->deferrable = deferrable;
RETVAL_OBJ(&php_pqtxn_create_object_ex(php_pqtxn_class_entry, txn)->zo);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction_async, 0, 0, 0)
ZEND_ARG_INFO(0, isolation)
ZEND_ARG_INFO(0, readonly)
ZEND_ARG_INFO(0, deferrable)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, startTransactionAsync) {
zend_error_handling zeh;
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
zend_long isolation = obj->intern ? obj->intern->default_txn_isolation : PHP_PQTXN_READ_COMMITTED;
zend_bool readonly = obj->intern ? obj->intern->default_txn_readonly : 0;
zend_bool deferrable = obj->intern ? obj->intern->default_txn_deferrable : 0;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|lbb", &isolation, &readonly, &deferrable);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
rv = php_pqconn_start_transaction_async(getThis(), obj, isolation, readonly, deferrable);
if (SUCCESS == rv) {
php_pqtxn_t *txn = ecalloc(1, sizeof(*txn));
php_pq_object_addref(obj);
txn->conn = obj;
txn->open = 1;
txn->isolation = isolation;
txn->readonly = readonly;
txn->deferrable = deferrable;
RETVAL_OBJ(&php_pqtxn_create_object_ex(php_pqtxn_class_entry, txn)->zo);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_trace, 0, 0, 0)
ZEND_ARG_INFO(0, stdio_stream)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, trace) {
zval *zstream = NULL;
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &zstream)) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
if (!zstream) {
PQuntrace(obj->intern->conn);
RETVAL_TRUE;
} else {
FILE *fp;
php_stream *stream = NULL;
php_stream_from_zval(stream, zstream);
if (SUCCESS != php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void *) &fp, REPORT_ERRORS)) {
RETVAL_FALSE;
} else {
stream->flags |= PHP_STREAM_FLAG_NO_CLOSE;
PQtrace(obj->intern->conn, fp);
RETVAL_TRUE;
}
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_off, 0, 0, 1)
ZEND_ARG_INFO(0, type)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, off) {
zend_error_handling zeh;
zend_string *type;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "S", &type);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
RETURN_BOOL(SUCCESS == zend_hash_del(&obj->intern->eventhandlers, type));
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_on, 0, 0, 2)
ZEND_ARG_INFO(0, type)
ZEND_ARG_INFO(0, callable)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, on) {
zend_error_handling zeh;
char *type_str;
size_t type_len;
php_pq_callback_t cb = PHP_PQ_CALLBACK_INIT;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "sf", &type_str, &type_len, &cb.fci, &cb.fcc);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
RETVAL_LONG(php_pqconn_add_eventhandler(obj, type_str, type_len, &cb));
}
}
}
struct apply_set_converter_arg {
HashTable *ht;
zval *zconv;
unsigned add:1;
};
static int apply_set_converter(zval *zoid, void *a)
{
zend_long oid = zval_get_long(zoid);
struct apply_set_converter_arg *arg = a;
if (arg->add) {
Z_ADDREF_P(arg->zconv);
zend_hash_index_update(arg->ht, oid, arg->zconv);
} else {
zend_hash_index_del(arg->ht, oid);
}
return ZEND_HASH_APPLY_KEEP;
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_set_converter, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, converter, pq\\Converter, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, setConverter) {
ZEND_RESULT_CODE rv;
zend_error_handling zeh;
zval *zcnv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zcnv, php_pqconv_class_entry);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
zval tmp, zoids;
struct apply_set_converter_arg arg = {NULL};
ZVAL_NULL(&zoids);
php_pq_call_method(zcnv, "converttypes", 0, &zoids);
ZVAL_DUP(&tmp, &zoids);
convert_to_array(&tmp);
arg.ht = &obj->intern->converters;
arg.zconv = zcnv;
arg.add = 1;
zend_hash_apply_with_argument(Z_ARRVAL(tmp), apply_set_converter, &arg);
zval_ptr_dtor(&tmp);
zval_ptr_dtor(&zoids);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unset_converter, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, converter, pq\\Converter, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqconn, unsetConverter) {
ZEND_RESULT_CODE rv;
zend_error_handling zeh;
zval *zcnv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zcnv, php_pqconv_class_entry);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
zval tmp, zoids;
struct apply_set_converter_arg arg = {NULL};
ZVAL_NULL(&zoids);
php_pq_call_method(zcnv, "converttypes", 0, &zoids);
ZVAL_DUP(&tmp, &zoids);
convert_to_array(&tmp);
arg.ht = &obj->intern->converters;
arg.zconv = zcnv;
arg.add = 0;
zend_hash_apply_with_argument(Z_ARRVAL(tmp), apply_set_converter, &arg);
zval_ptr_dtor(&tmp);
zval_ptr_dtor(&zoids);
}
}
}
static zend_function_entry php_pqconn_methods[] = {
PHP_ME(pqconn, __construct, ai_pqconn_construct, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, reset, ai_pqconn_reset, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, resetAsync, ai_pqconn_reset_async, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, poll, ai_pqconn_poll, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, flush, ai_pqconn_flush, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, exec, ai_pqconn_exec, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, execAsync, ai_pqconn_exec_async, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, execParams, ai_pqconn_exec_params, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, execParamsAsync, ai_pqconn_exec_params_async, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, prepare, ai_pqconn_prepare, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, prepareAsync, ai_pqconn_prepare_async, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, declare, ai_pqconn_declare, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, declareAsync, ai_pqconn_declare_async, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, unlisten, ai_pqconn_unlisten, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, unlistenAsync, ai_pqconn_unlisten_async, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, listen, ai_pqconn_listen, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, listenAsync, ai_pqconn_listen_async, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, notify, ai_pqconn_notify, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, notifyAsync, ai_pqconn_notify_async, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, getResult, ai_pqconn_get_result, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, quote, ai_pqconn_quote, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, quoteName, ai_pqconn_quote_name, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, escapeBytea, ai_pqconn_escape_bytea, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, unescapeBytea, ai_pqconn_unescape_bytea, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, startTransaction, ai_pqconn_start_transaction, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, startTransactionAsync, ai_pqconn_start_transaction_async, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, trace, ai_pqconn_trace, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, off, ai_pqconn_off, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, on, ai_pqconn_on, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, setConverter, ai_pqconn_set_converter, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, unsetConverter, ai_pqconn_unset_converter, ZEND_ACC_PUBLIC)
{0}
};
PHP_MSHUTDOWN_FUNCTION(pqconn)
{
php_persistent_handle_cleanup(PHP_PQ_G->connection.name, NULL);
zend_string_release(PHP_PQ_G->connection.name);
zend_hash_destroy(&php_pqconn_object_prophandlers);
return SUCCESS;
}
PHP_MINIT_FUNCTION(pqconn)
{
zend_class_entry ce = {0};
php_pq_object_prophandler_t ph = {0};
INIT_NS_CLASS_ENTRY(ce, "pq", "Connection", php_pqconn_methods);
php_pqconn_class_entry = zend_register_internal_class_ex(&ce, NULL);
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.offset = XtOffsetOf(php_pqconn_object_t, zo);
php_pqconn_object_handlers.free_obj = php_pqconn_object_free;
php_pqconn_object_handlers.read_property = php_pq_object_read_prop;
php_pqconn_object_handlers.write_property = php_pq_object_write_prop;
php_pqconn_object_handlers.clone_obj = NULL;
php_pqconn_object_handlers.get_property_ptr_ptr = php_pq_object_get_prop_ptr_null;
php_pqconn_object_handlers.get_gc = php_pq_object_get_gc;
php_pqconn_object_handlers.get_properties = php_pq_object_properties;
php_pqconn_object_handlers.get_debug_info = php_pq_object_debug_info;
zend_hash_init(&php_pqconn_object_prophandlers, 23, NULL, php_pq_object_prophandler_dtor, 1);
zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("status"), CONNECTION_BAD, ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_status;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "status", sizeof("status")-1, (void *) &ph, sizeof(ph));
zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN, ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_transaction_status;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "transactionStatus", sizeof("transactionStatus")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("socket"), ZEND_ACC_PUBLIC);
ph.read = NULL; /* forward to std prophandler */
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "socket", sizeof("socket")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_error_message;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "errorMessage", sizeof("errorMessage")-1, (void *) &ph, sizeof(ph));
zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_busy;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "busy", sizeof("busy")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_encoding;
ph.write = php_pqconn_object_write_encoding;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "encoding", sizeof("encoding")-1, (void *) &ph, sizeof(ph));
ph.write = NULL;
zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_unbuffered;
ph.write = php_pqconn_object_write_unbuffered;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "unbuffered", sizeof("unbuffered")-1, (void *) &ph, sizeof(ph));
ph.write = NULL;
zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("nonblocking"), 0, ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_nonblocking;
ph.write = php_pqconn_object_write_nonblocking;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "nonblocking", sizeof("nonblocking")-1, (void *) &ph, sizeof(ph));
ph.write = NULL;
zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("db"), ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_db;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "db", sizeof("db")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("user"), ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_user;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "user", sizeof("user")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("pass"), ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_pass;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "pass", sizeof("pass")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("host"), ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_host;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "host", sizeof("host")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("port"), ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_port;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "port", sizeof("port")-1, (void *) &ph, sizeof(ph));
#if HAVE_PQCONNINFO
zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("params"), ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_params;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "params", sizeof("params")-1, (void *) &ph, sizeof(ph));
#endif
zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("options"), ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_options;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "options", sizeof("options")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("eventHandlers"), ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_event_handlers;
ph.gc = php_pqconn_object_gc_event_handlers;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "eventHandlers", sizeof("eventHandlers")-1, (void *) &ph, sizeof(ph));
ph.gc = NULL;
zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("listeners"), ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_listeners;
ph.gc = php_pqconn_object_gc_listeners;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "listeners", sizeof("listeners")-1, (void *) &ph, sizeof(ph));
ph.gc = NULL;
zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("converters"), ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_converters;
ph.gc = php_pqconn_object_gc_converters;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "converters", sizeof("converters")-1, (void *) &ph, sizeof(ph));
ph.gc = NULL;
zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultFetchType"), 0, ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_def_fetch_type;
ph.write = php_pqconn_object_write_def_fetch_type;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "defaultFetchType", sizeof("defaultFetchType")-1, (void *) &ph, sizeof(ph));
ph.write = NULL;
zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultTransactionIsolation"), 0, ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_def_txn_isolation;
ph.write = php_pqconn_object_write_def_txn_isolation;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "defaultTransactionIsolation", sizeof("defaultTransactionIsolation")-1, (void *) &ph, sizeof(ph));
ph.write = NULL;
zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("defaultTransactionReadonly"), 0, ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_def_txn_readonly;
ph.write = php_pqconn_object_write_def_txn_readonly;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "defaultTransactionReadonly", sizeof("defaultTransactionReadonly")-1, (void *) &ph, sizeof(ph));
ph.write = NULL;
zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("defaultTransactionDeferrable"), 0, ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_def_txn_deferrable;
ph.write = php_pqconn_object_write_def_txn_deferrable;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "defaultTransactionDeferrable", sizeof("defaultTransactionDeferrable")-1, (void *) &ph, sizeof(ph));
ph.write = NULL;
zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultAutoConvert"), PHP_PQRES_CONV_ALL, ZEND_ACC_PUBLIC);
ph.read = php_pqconn_object_read_def_auto_conv;
ph.write = php_pqconn_object_write_def_auto_conv;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "defaultAutoConvert", sizeof("defaultAutoConvert")-1, (void *) &ph, sizeof(ph));
ph.write = NULL;
#ifdef HAVE_PQLIBVERSION
zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("libraryVersion"), ZEND_ACC_PUBLIC|ZEND_ACC_READONLY);
ph.read = php_pqconn_object_read_lib_version;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, ZEND_STRL("libraryVersion"), (void *) &ph, sizeof(ph));
#endif
#ifdef HAVE_PQPROTOCOLVERSION
zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("protocolVersion"), ZEND_ACC_PUBLIC|ZEND_ACC_READONLY);
ph.read = php_pqconn_object_read_protocol_version;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, ZEND_STRL("protocolVersion"), (void *) &ph, sizeof(ph));
#endif
#ifdef HAVE_PQSERVERVERSION
zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("serverVersion"), ZEND_ACC_PUBLIC|ZEND_ACC_READONLY);
ph.read = php_pqconn_object_read_server_version;
zend_hash_str_add_mem(&php_pqconn_object_prophandlers, ZEND_STRL("serverVersion"), (void *) &ph, sizeof(ph));
#endif
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("OK"), CONNECTION_OK);
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("BAD"), CONNECTION_BAD);
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("STARTED"), CONNECTION_STARTED);
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("MADE"), CONNECTION_MADE);
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE);
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK);
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP);
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("SETENV"), CONNECTION_SETENV);
#ifdef HAVE_CONNECTION_CHECK_WRITABLE
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("CHECK_WRITABLE"), CONNECTION_CHECK_WRITABLE);
#endif
#ifdef HAVE_CONNECTION_CONSUME
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("CONSUME"), CONNECTION_CONSUME);
#endif
#ifdef HAVE_CONNECTION_GSS_STARTUP
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("GSS_STARTUP"), CONNECTION_GSS_STARTUP);
#endif
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE);
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE);
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS);
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR);
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN);
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED);
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING);
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING);
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK);
zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_NOTICE"), ZEND_STRL("notice"));
zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_RESULT"), ZEND_STRL("result"));
zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_RESET"), ZEND_STRL("reset"));
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("ASYNC"), 0x1);
zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("PERSISTENT"), 0x2);
PHP_PQ_G->connection.name = zend_string_init(ZEND_STRL("pq\\Connection"), 1);
return php_persistent_handle_provide(PHP_PQ_G->connection.name, php_pqconn_get_resource_factory_ops(), NULL, NULL);
}
/*
* 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
*/
pq-2.2.3/src/php_pqconn_event.c 0000644 0000765 0000024 00000013046 14560227740 015262 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include
#include
#include
#include "php_pq.h"
#include "php_pq_misc.h"
#include "php_pq_object.h"
#include "php_pqconn_event.h"
#include "php_pqstm.h"
#include "php_pqres.h"
static int apply_event(zval *p, void *a)
{
php_pq_callback_t *cb = Z_PTR_P(p);
zval *args = a;
zval rv;
ZVAL_NULL(&rv);
zend_fcall_info_args(&cb->fci, args);
zend_fcall_info_call(&cb->fci, &cb->fcc, &rv, NULL);
zend_fcall_info_args_clear(&cb->fci, 0);
zval_ptr_dtor(&rv);
return ZEND_HASH_APPLY_KEEP;
}
static inline PGresult *relisten(PGconn *conn, const char *channel_str, size_t channel_len)
{
char *quoted_channel = PQescapeIdentifier(conn, channel_str, channel_len);
PGresult *res = NULL;
if (quoted_channel) {
smart_str cmd = {0};
smart_str_appends(&cmd, "LISTEN ");
smart_str_appends(&cmd, quoted_channel);
smart_str_0(&cmd);
res = php_pq_exec(conn, smart_str_v(&cmd));
smart_str_free(&cmd);
PQfreemem(quoted_channel);
}
return res;
}
static int apply_relisten(zval *p, int argc, va_list argv, zend_hash_key *key)
{
php_pqconn_object_t *obj = va_arg(argv, php_pqconn_object_t *);
PGresult *res = relisten(obj->intern->conn, key->key->val, key->key->len);
if (res) {
php_pqres_clear(res);
}
return ZEND_HASH_APPLY_KEEP;
}
static int apply_reprepare(zval *p, int argc, va_list argv, zend_hash_key *key)
{
php_pqconn_object_t *obj = va_arg(argv, php_pqconn_object_t *);
php_pqstm_t *stm = Z_PTR_P(p);
php_pqconn_prepare(NULL, obj, stm->name, stm->query, stm->params);
return ZEND_HASH_APPLY_KEEP;
}
static void php_pqconn_event_connreset(PGEventConnReset *event)
{
php_pqconn_event_data_t *data = PQinstanceData(event->conn, php_pqconn_event);
if (data) {
zval *zevhs;
/* restore listeners */
zend_hash_apply_with_arguments(&data->obj->intern->listeners, apply_relisten, 1, data->obj);
/* restore statements */
zend_hash_apply_with_arguments(&data->obj->intern->statements, apply_reprepare, 1, data->obj);
/* eventhandler */
if ((zevhs = zend_hash_str_find(&data->obj->intern->eventhandlers, ZEND_STRL("reset")))) {
zval args, connection;
array_init(&args);
php_pq_object_to_zval(data->obj, &connection);
add_next_index_zval(&args, &connection);
zend_hash_apply_with_argument(Z_ARRVAL_P(zevhs), apply_event, &args);
zval_ptr_dtor(&args);
}
}
}
static void php_pqconn_event_resultcreate(PGEventResultCreate *event)
{
php_pqconn_event_data_t *data = PQinstanceData(event->conn, php_pqconn_event);
if (data) {
php_pqres_object_t *obj = php_pqres_init_instance_data(event->result, data->obj);
zval *zevhs;
/* event listener */
if ((zevhs = zend_hash_str_find(&data->obj->intern->eventhandlers, ZEND_STRL("result")))) {
zval args, connection, res;
array_init(&args);
php_pq_object_to_zval(data->obj, &connection);
add_next_index_zval(&args, &connection);
php_pq_object_to_zval(obj, &res);
add_next_index_zval(&args, &res);
zend_hash_apply_with_argument(Z_ARRVAL_P(zevhs), apply_event, &args);
zval_ptr_dtor(&args);
}
/* async callback */
if (php_pq_callback_is_enabled(&data->obj->intern->onevent)) {
zval res;
php_pq_object_to_zval(obj, &res);
zend_fcall_info_argn(&data->obj->intern->onevent.fci, 1, &res);
zend_fcall_info_call(&data->obj->intern->onevent.fci, &data->obj->intern->onevent.fcc, NULL, NULL);
zval_ptr_dtor(&res);
}
}
}
static void php_pqconn_event_resultdestroy(PGEventResultDestroy *event)
{
php_pqres_object_t *obj = PQresultInstanceData(event->result, php_pqconn_event);
if (obj) {
obj->intern->res = NULL;
assert(GC_REFCOUNT(&obj->zo));
php_pq_object_delref(obj);
}
}
int php_pqconn_event(PGEventId id, void *e, void *data)
{
switch (id) {
case PGEVT_CONNRESET:
php_pqconn_event_connreset(e);
break;
case PGEVT_RESULTCREATE:
php_pqconn_event_resultcreate(e);
break;
case PGEVT_RESULTDESTROY:
php_pqconn_event_resultdestroy(e);
break;
default:
break;
}
return 1;
}
php_pqconn_event_data_t *php_pqconn_event_data_init(php_pqconn_object_t *obj)
{
php_pqconn_event_data_t *data = emalloc(sizeof(*data));
data->obj = obj;
data->res = NULL;
return data;
}
void php_pqconn_notice_recv(void *p, const PGresult *res)
{
php_pqconn_event_data_t *data = p;
if (data) {
zval *zevhs;
if ((zevhs = zend_hash_str_find(&data->obj->intern->eventhandlers, ZEND_STRL("notice")))) {
zval args, connection;
array_init(&args);
php_pq_object_to_zval(data->obj, &connection);
add_next_index_zval(&args, &connection);
add_next_index_string(&args, PHP_PQresultErrorMessage(res));
zend_hash_apply_with_argument(Z_ARRVAL_P(zevhs), apply_event, &args);
zval_ptr_dtor(&args);
}
}
}
void php_pqconn_notice_ignore(void *p, const PGresult *res)
{
}
/*
* 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
*/
pq-2.2.3/src/php_pqconn_event.h 0000644 0000765 0000024 00000002521 14560227740 015263 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifndef PHP_PQCONN_EVENT_H
#define PHP_PQCONN_EVENT_H
#include
#include "php_pqconn.h"
#include "php_pqres.h"
typedef struct php_pqconn_event_data {
php_pqconn_object_t *obj;
php_pqres_object_t *res;
} php_pqconn_event_data_t;
extern php_pqconn_event_data_t *php_pqconn_event_data_init(php_pqconn_object_t *obj);
extern void php_pqconn_notice_recv(void *p, const PGresult *res);
extern void php_pqconn_notice_ignore(void *p, const PGresult *res);
extern int php_pqconn_event(PGEventId id, void *e, void *data);
#endif
/*
* 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
*/
pq-2.2.3/src/php_pqconn.h 0000644 0000765 0000024 00000005567 14560227740 014077 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifndef PHP_PQCONN_H
#define PHP_PQCONN_H
#define PHP_PQCONN_ASYNC 0x01
#define PHP_PQCONN_PERSISTENT 0x02
#include
#include "php_pq_object.h"
#include "php_pq_callback.h"
#include "php_pq_object.h"
#include "php_pq_params.h"
typedef struct php_pqconn {
PGconn *conn;
int (*poller)(PGconn *);
php_resource_factory_t factory;
HashTable listeners;
HashTable statements;
HashTable converters;
HashTable eventhandlers;
php_pq_callback_t onevent;
unsigned unbuffered:1;
unsigned default_fetch_type:2;
unsigned default_txn_isolation:2;
unsigned default_txn_readonly:1;
unsigned default_txn_deferrable:1;
unsigned default_auto_convert:16;
} php_pqconn_t;
typedef struct php_pqconn_object {
PHP_PQ_OBJ_DECL(php_pqconn_t *)
} php_pqconn_object_t;
typedef struct php_pqconn_resource_factory_data {
char *dsn;
unsigned long flags;
} php_pqconn_resource_factory_data_t;
extern php_resource_factory_ops_t *php_pqconn_get_resource_factory_ops(void);
extern zend_class_entry *php_pqconn_class_entry;
extern php_pqconn_object_t *php_pqconn_create_object_ex(zend_class_entry *ce, php_pqconn_t *intern);
extern void php_pqconn_notify_listeners(php_pqconn_object_t *obj);
extern ZEND_RESULT_CODE php_pqconn_prepare(zval *object, php_pqconn_object_t *obj, const char *name, const char *query, php_pq_params_t *params);
extern ZEND_RESULT_CODE php_pqconn_prepare_async(zval *object, php_pqconn_object_t *obj, const char *name, const char *query, php_pq_params_t *params);
extern ZEND_RESULT_CODE php_pqconn_start_transaction(zval *zconn, php_pqconn_object_t *conn_obj, long isolation, zend_bool readonly, zend_bool deferrable);
extern ZEND_RESULT_CODE php_pqconn_start_transaction_async(zval *zconn, php_pqconn_object_t *conn_obj, long isolation, zend_bool readonly, zend_bool deferrable);
extern ZEND_RESULT_CODE php_pqconn_declare(zval *object, php_pqconn_object_t *obj, const char *decl);
extern ZEND_RESULT_CODE php_pqconn_declare_async(zval *object, php_pqconn_object_t *obj, const char *decl);
extern PHP_MINIT_FUNCTION(pqconn);
extern PHP_MSHUTDOWN_FUNCTION(pqconn);
#endif
/*
* 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
*/
pq-2.2.3/src/php_pqcopy.c 0000644 0000765 0000024 00000026621 14560227740 014101 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include
#include
#include
#include "php_pq.h"
#include "php_pq_misc.h"
#include "php_pq_object.h"
#include "php_pqexc.h"
#include "php_pqres.h"
#include "php_pqconn.h"
#include "php_pqcopy.h"
zend_class_entry *php_pqcopy_class_entry;
static zend_object_handlers php_pqcopy_object_handlers;
static HashTable php_pqcopy_object_prophandlers;
static void php_pqcopy_object_free(zend_object *o)
{
php_pqcopy_object_t *obj = PHP_PQ_OBJ(NULL, o);
#if DBG_GC
fprintf(stderr, "FREE copy(#%d) %p (conn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->conn->zo.handle, obj->intern->conn);
#endif
if (obj->intern) {
efree(obj->intern->expression);
efree(obj->intern->options);
php_pq_object_delref(obj->intern->conn);
efree(obj->intern);
obj->intern = NULL;
}
php_pq_object_dtor(o);
}
php_pqcopy_object_t *php_pqcopy_create_object_ex(zend_class_entry *ce, php_pqcopy_t *intern)
{
return php_pq_object_create(ce, intern, sizeof(php_pqcopy_object_t),
&php_pqcopy_object_handlers, &php_pqcopy_object_prophandlers);
}
static zend_object *php_pqcopy_create_object(zend_class_entry *class_type)
{
return &php_pqcopy_create_object_ex(class_type, NULL)->zo;
}
static void php_pqcopy_object_read_connection(void *o, zval *return_value)
{
php_pqcopy_object_t *obj = o;
php_pq_object_to_zval(obj->intern->conn, return_value);
}
static void php_pqcopy_object_gc_connection(void *o, zval *return_value)
{
php_pqcopy_object_t *obj = o;
zval zconn;
php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn);
add_next_index_zval(return_value, &zconn);
}
static void php_pqcopy_object_read_direction(void *o, zval *return_value)
{
php_pqcopy_object_t *obj = o;
RETVAL_LONG(obj->intern->direction);
}
static void php_pqcopy_object_read_expression(void *o, zval *return_value)
{
php_pqcopy_object_t *obj = o;
RETURN_STRING(obj->intern->expression);
}
static void php_pqcopy_object_read_options(void *o, zval *return_value)
{
php_pqcopy_object_t *obj = o;
RETURN_STRING(obj->intern->options);
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_construct, 0, 0, 3)
ZEND_ARG_OBJ_INFO(0, connection, pq\\Connection, 0)
ZEND_ARG_INFO(0, expression)
ZEND_ARG_INFO(0, direction)
ZEND_ARG_INFO(0, options)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqcopy, __construct) {
zend_error_handling zeh;
zval *zconn;
char *expr_str, *opt_str = "";
size_t expr_len, opt_len = 0;
zend_long direction;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "Osl|s", &zconn, php_pqconn_class_entry, &expr_str, &expr_len, &direction, &opt_str, &opt_len);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *conn_obj = PHP_PQ_OBJ(zconn, NULL);
if (!conn_obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
php_pqcopy_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
smart_str cmd = {0};
PGresult *res;
smart_str_appends(&cmd, "COPY ");
smart_str_appendl(&cmd, expr_str, expr_len);
switch (direction) {
case PHP_PQCOPY_FROM_STDIN:
smart_str_appends(&cmd, " FROM STDIN ");
break;
case PHP_PQCOPY_TO_STDOUT:
smart_str_appends(&cmd, " TO STDOUT ");
break;
default:
throw_exce(EX_RUNTIME, "Invalid COPY direction, expected one of FROM_STDIN (%d) TO_STDOUT (%d), got %ld", PHP_PQCOPY_FROM_STDIN, PHP_PQCOPY_TO_STDOUT, direction);
smart_str_free(&cmd);
return;
}
smart_str_appendl(&cmd, opt_str, opt_len);
smart_str_0(&cmd);
res = php_pq_exec(conn_obj->intern->conn, smart_str_v(&cmd));
if (!res) {
throw_exce(EX_RUNTIME, "Failed to start %s (%s)", smart_str_v(&cmd), PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
if (SUCCESS == php_pqres_success(res)) {
obj->intern = ecalloc(1, sizeof(*obj->intern));
obj->intern->direction = direction;
obj->intern->expression = estrdup(expr_str);
obj->intern->options = estrdup(opt_str);
obj->intern->conn = conn_obj;
php_pq_object_addref(conn_obj);
}
php_pqres_clear(res);
}
smart_str_free(&cmd);
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_put, 0, 0, 1)
ZEND_ARG_INFO(0, data)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqcopy, put) {
zend_error_handling zeh;
char *data_str;
size_t data_len;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &data_str, &data_len);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqcopy_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\COPY not initialized");
} else if (obj->intern->direction != PHP_PQCOPY_FROM_STDIN) {
throw_exce(EX_BAD_METHODCALL, "pq\\COPY was not initialized with FROM_STDIN");
} else {
if (1 != PQputCopyData(obj->intern->conn->intern->conn, data_str, data_len)) {
throw_exce(EX_RUNTIME, "Failed to put COPY data (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
}
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_end, 0, 0, 0)
ZEND_ARG_INFO(0, error)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqcopy, end) {
zend_error_handling zeh;
char *error_str = NULL;
size_t error_len = 0;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|s!", &error_str, &error_len);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqcopy_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\COPY not intitialized");
} else if (obj->intern->direction != PHP_PQCOPY_FROM_STDIN) {
throw_exce(EX_BAD_METHODCALL, "pq\\COPY was not intitialized with FROM_STDIN");
} else {
if (1 != PQputCopyEnd(obj->intern->conn->intern->conn, error_str)) {
throw_exce(EX_RUNTIME, "Failed to end COPY (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
PGresult *res = PQgetResult(obj->intern->conn->intern->conn);
if (!res) {
throw_exce(EX_RUNTIME, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
php_pqres_success(res);
php_pqres_clear(res);
}
}
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_get, 0, 0, 1)
ZEND_ARG_INFO(1, data)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqcopy, get) {
zend_error_handling zeh;
zval *zdata;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "z", &zdata);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqcopy_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\COPY not initialized");
} else if (obj->intern->direction != PHP_PQCOPY_TO_STDOUT) {
throw_exce(EX_RUNTIME, "pq\\COPY was not intialized with TO_STDOUT");
} else {
PGresult *res;
char *buffer = NULL;
int bytes = PQgetCopyData(obj->intern->conn->intern->conn, &buffer, 0);
switch (bytes) {
case -2:
throw_exce(EX_RUNTIME, "Failed to fetch COPY data (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
break;
case -1:
res = PQgetResult(obj->intern->conn->intern->conn);
if (!res) {
throw_exce(EX_RUNTIME, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
php_pqres_success(res);
php_pqres_clear(res);
RETVAL_FALSE;
}
break;
default:
ZVAL_DEREF(zdata);
zval_dtor(zdata);
if (buffer) {
ZVAL_STRINGL(zdata, buffer, bytes);
} else {
ZVAL_EMPTY_STRING(zdata);
}
RETVAL_TRUE;
break;
}
if (buffer) {
PQfreemem(buffer);
}
}
}
}
static zend_function_entry php_pqcopy_methods[] = {
PHP_ME(pqcopy, __construct, ai_pqcopy_construct, ZEND_ACC_PUBLIC)
PHP_ME(pqcopy, put, ai_pqcopy_put, ZEND_ACC_PUBLIC)
PHP_ME(pqcopy, end, ai_pqcopy_end, ZEND_ACC_PUBLIC)
PHP_ME(pqcopy, get, ai_pqcopy_get, ZEND_ACC_PUBLIC)
{0}
};
PHP_MSHUTDOWN_FUNCTION(pqcopy)
{
zend_hash_destroy(&php_pqcopy_object_prophandlers);
return SUCCESS;
}
PHP_MINIT_FUNCTION(pqcopy)
{
zend_class_entry ce = {0};
php_pq_object_prophandler_t ph = {0};
INIT_NS_CLASS_ENTRY(ce, "pq", "COPY", php_pqcopy_methods);
php_pqcopy_class_entry = zend_register_internal_class_ex(&ce, NULL);
php_pqcopy_class_entry->create_object = php_pqcopy_create_object;
memcpy(&php_pqcopy_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
php_pqcopy_object_handlers.offset = XtOffsetOf(php_pqcopy_object_t, zo);
php_pqcopy_object_handlers.free_obj = php_pqcopy_object_free;
php_pqcopy_object_handlers.read_property = php_pq_object_read_prop;
php_pqcopy_object_handlers.write_property = php_pq_object_write_prop;
php_pqcopy_object_handlers.clone_obj = NULL;
php_pqcopy_object_handlers.get_property_ptr_ptr = php_pq_object_get_prop_ptr_null;
php_pqcopy_object_handlers.get_gc = php_pq_object_get_gc;
php_pqcopy_object_handlers.get_properties = php_pq_object_properties;
php_pqcopy_object_handlers.get_debug_info = php_pq_object_debug_info;
zend_hash_init(&php_pqcopy_object_prophandlers, 4, NULL, php_pq_object_prophandler_dtor, 1);
zend_declare_property_null(php_pqcopy_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC);
ph.read = php_pqcopy_object_read_connection;
ph.gc = php_pqcopy_object_gc_connection;
zend_hash_str_add_mem(&php_pqcopy_object_prophandlers, "connection", sizeof("connection")-1, (void *) &ph, sizeof(ph));
ph.gc = NULL;
zend_declare_property_null(php_pqcopy_class_entry, ZEND_STRL("expression"), ZEND_ACC_PUBLIC);
ph.read = php_pqcopy_object_read_expression;
zend_hash_str_add_mem(&php_pqcopy_object_prophandlers, "expression", sizeof("expression")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqcopy_class_entry, ZEND_STRL("direction"), ZEND_ACC_PUBLIC);
ph.read = php_pqcopy_object_read_direction;
zend_hash_str_add_mem(&php_pqcopy_object_prophandlers, "direction", sizeof("direction")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqcopy_class_entry, ZEND_STRL("options"), ZEND_ACC_PUBLIC);
ph.read = php_pqcopy_object_read_options;
zend_hash_str_add_mem(&php_pqcopy_object_prophandlers, "options", sizeof("options")-1, (void *) &ph, sizeof(ph));
zend_declare_class_constant_long(php_pqcopy_class_entry, ZEND_STRL("FROM_STDIN"), PHP_PQCOPY_FROM_STDIN);
zend_declare_class_constant_long(php_pqcopy_class_entry, ZEND_STRL("TO_STDOUT"), PHP_PQCOPY_TO_STDOUT);
return SUCCESS;
}
/*
* 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
*/
pq-2.2.3/src/php_pqcopy.h 0000644 0000765 0000024 00000003046 14560227740 014102 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifndef PHP_PQCOPY_H
#define PHP_PQCOPY_H
#include "php_pqconn.h"
typedef enum php_pqcopy_direction {
PHP_PQCOPY_FROM_STDIN,
PHP_PQCOPY_TO_STDOUT
} php_pqcopy_direction_t;
typedef enum php_pqcopy_status {
PHP_PQCOPY_FAIL,
PHP_PQCOPY_CONT,
PHP_PQCOPY_DONE
} php_pqcopy_status_t;
typedef struct php_pqcopy {
php_pqcopy_direction_t direction;
char *expression;
char *options;
php_pqconn_object_t *conn;
} php_pqcopy_t;
typedef struct php_pqcopy_object {
PHP_PQ_OBJ_DECL(php_pqcopy_t *)
} php_pqcopy_object_t;
extern zend_class_entry *php_pqcopy_class_entry;
extern php_pqcopy_object_t *php_pqcopy_create_object_ex(zend_class_entry *ce, php_pqcopy_t *intern);
extern PHP_MINIT_FUNCTION(pqcopy);
extern PHP_MSHUTDOWN_FUNCTION(pqcopy);
#endif
/*
* 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
*/
pq-2.2.3/src/php_pqcur.c 0000644 0000765 0000024 00000035624 14560227740 013723 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include
#include
#include "php_pq.h"
#include "php_pq_misc.h"
#include "php_pq_object.h"
#include "php_pqexc.h"
#include "php_pqconn.h"
#include "php_pqres.h"
#include "php_pqcur.h"
zend_class_entry *php_pqcur_class_entry;
static zend_object_handlers php_pqcur_object_handlers;
static HashTable php_pqcur_object_prophandlers;
static void cur_close(php_pqcur_object_t *obj, zend_bool async, zend_bool silent)
{
if (obj->intern->open && obj->intern->conn->intern) {
PGresult *res;
smart_str cmd = {0};
smart_str_appends(&cmd, "CLOSE ");
smart_str_appends(&cmd, obj->intern->name);
smart_str_0(&cmd);
if (async) {
if (PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd))) {
obj->intern->conn->intern->poller = PQconsumeInput;
php_pqconn_notify_listeners(obj->intern->conn);
} else if (!silent) {
throw_exce(EX_IO, "Failed to close cursor (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
}
} else {
if ((res = php_pq_exec(obj->intern->conn->intern->conn, smart_str_v(&cmd)))) {
php_pqres_clear(res);
} else if (!silent) {
throw_exce(EX_RUNTIME, "Failed to close cursor (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
}
}
smart_str_free(&cmd);
obj->intern->open = 0;
}
}
static void cur_open(INTERNAL_FUNCTION_PARAMETERS, zend_bool async)
{
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
php_pqcur_object_t *obj;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (rv == FAILURE) {
return;
}
obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Cursor not initialized");
return;
} else if (obj->intern->open) {
return;
}
if (async) {
rv = php_pqconn_declare_async(NULL, obj->intern->conn, obj->intern->decl);
} else {
rv = php_pqconn_declare(NULL, obj->intern->conn, obj->intern->decl);
}
if (rv == SUCCESS) {
obj->intern->open = 1;
}
}
static void cur_fetch_or_move(INTERNAL_FUNCTION_PARAMETERS, const char *action, zend_bool async)
{
char *spec_str = "1";
size_t spec_len = 1;
ZEND_RESULT_CODE rv;
php_pq_callback_t resolver = PHP_PQ_CALLBACK_INIT;
zend_error_handling zeh;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), async ? "|sf" : "|s", &spec_str, &spec_len, &resolver.fci, &resolver.fcc);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqcur_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Cursor not initialized");
} else {
smart_str cmd = {0};
smart_str_appends(&cmd, *action == 'f' ? "FETCH " : "MOVE ");
smart_str_appendl(&cmd, spec_str, spec_len);
smart_str_appends(&cmd, " FROM ");
smart_str_appends(&cmd, obj->intern->name);
smart_str_0(&cmd);
if (async) {
int rc = PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd));
if (!rc) {
throw_exce(EX_IO, "Failed to %s cursor (%s)", *action == 'f' ? "fetch from" : "move in", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
#if HAVE_PQSETSINGLEROWMODE
} else if (obj->intern->conn->intern->unbuffered && !PQsetSingleRowMode(obj->intern->conn->intern->conn)) {
throw_exce(EX_RUNTIME, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
#endif
} else {
php_pq_callback_recurse(&obj->intern->conn->intern->onevent, &resolver);
obj->intern->conn->intern->poller = PQconsumeInput;
}
} else {
PGresult *res = php_pq_exec(obj->intern->conn->intern->conn, smart_str_v(&cmd));
if (!res) {
throw_exce(EX_RUNTIME, "Failed to %s cursor (%s)", *action == 'f' ? "fetch from" : "move in", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else if (SUCCESS == php_pqres_success(res)) {
php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), return_value);
}
}
smart_str_free(&cmd);
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
static void php_pqcur_object_free(zend_object *o)
{
php_pqcur_object_t *obj = PHP_PQ_OBJ(NULL, o);
#if DBG_GC
fprintf(stderr, "FREE cur(#%d) %p (conn: %p)\n", obj->zo.handle, obj, obj->intern->conn);
#endif
if (obj->intern) {
cur_close(obj, 0, 1);
php_pq_object_delref(obj->intern->conn);
efree(obj->intern->decl);
efree(obj->intern->name);
efree(obj->intern);
obj->intern = NULL;
}
php_pq_object_dtor(o);
}
php_pqcur_object_t *php_pqcur_create_object_ex(zend_class_entry *ce, php_pqcur_t *intern)
{
return php_pq_object_create(ce, intern, sizeof(php_pqcur_object_t),
&php_pqcur_object_handlers, &php_pqcur_object_prophandlers);
}
static zend_object *php_pqcur_create_object(zend_class_entry *class_type)
{
return &php_pqcur_create_object_ex(class_type, NULL)->zo;
}
static void php_pqcur_object_read_name(void *o, zval *return_value)
{
php_pqcur_object_t *obj = o;
RETVAL_STRING(obj->intern->name);
}
static void php_pqcur_object_read_connection(void *o, zval *return_value)
{
php_pqcur_object_t *obj = o;
php_pq_object_to_zval(obj->intern->conn, return_value);
}
static void php_pqcur_object_gc_connection(void *o, zval *return_value)
{
php_pqcur_object_t *obj = o;
zval zconn;
php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn);
add_next_index_zval(return_value, &zconn);
}
static void php_pqcur_object_read_query(void *o, zval *return_value)
{
php_pqcur_object_t *obj = o;
RETVAL_STRING(obj->intern->decl + obj->intern->query_offset);
}
static void php_pqcur_object_read_flags(void *o, zval *return_value)
{
php_pqcur_object_t *obj = o;
RETVAL_LONG(obj->intern->flags);
}
char *php_pqcur_declare_str(const char *name_str, size_t name_len, unsigned flags, const char *query_str, size_t query_len, int *query_offset)
{
size_t decl_len = name_len + query_len + sizeof("DECLARE BINARY INSENSITIVE NO SCROLL CURSOR WITH HOLD FOR ");
char *decl_str;
decl_str = emalloc(decl_len);
decl_len = slprintf(decl_str, decl_len, "DECLARE %s %s %s %s CURSOR %s FOR %s",
name_str,
(flags & PHP_PQ_DECLARE_BINARY) ? "BINARY" : "",
(flags & PHP_PQ_DECLARE_INSENSITIVE) ? "INSENSITIVE" : "",
(flags & PHP_PQ_DECLARE_NO_SCROLL) ? "NO SCROLL" :
(flags & PHP_PQ_DECLARE_SCROLL) ? "SCROLL" : "",
(flags & PHP_PQ_DECLARE_WITH_HOLD) ? "WITH HOLD" : "",
query_str
);
if (query_offset) {
/* sizeof() includes the terminating null byte, so no need for spaces in the string literals */
*query_offset = sizeof("DECLARE")
+ (name_len + 1)
+ ((flags & PHP_PQ_DECLARE_BINARY) ? sizeof("BINARY") : 1)
+ ((flags & PHP_PQ_DECLARE_INSENSITIVE) ? sizeof("INSENSITIVE") : 1)
+ ((flags & PHP_PQ_DECLARE_NO_SCROLL) ? sizeof("NO SCROLL") :
(flags & PHP_PQ_DECLARE_SCROLL) ? sizeof("SCROLL") : 1)
+ sizeof("CURSOR")
+ ((flags & PHP_PQ_DECLARE_WITH_HOLD) ? sizeof("WITH HOLD") : 1)
+ sizeof("FOR");
}
return decl_str;
}
php_pqcur_t *php_pqcur_init(php_pqconn_object_t *conn, const char *name, char *decl, int query_offset, long flags)
{
php_pqcur_t *cur = ecalloc(1, sizeof(*cur));
php_pq_object_addref(conn);
cur->conn = conn;
cur->name = estrdup(name);
cur->decl = decl;
cur->query_offset = query_offset;
cur->flags = flags;
cur->open = 1;
return cur;
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqcur___construct, 0, 0, 4)
ZEND_ARG_OBJ_INFO(0, connection, pq\\Connection, 0)
ZEND_ARG_INFO(0, name)
ZEND_ARG_INFO(0, flags)
ZEND_ARG_INFO(0, query)
ZEND_ARG_INFO(0, async)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqcur, __construct) {
zend_error_handling zeh;
char *name_str, *query_str;
size_t name_len, query_len;
zend_long flags;
zval *zconn;
ZEND_RESULT_CODE rv;
zend_bool async = 0;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "Osls|b", &zconn, php_pqconn_class_entry, &name_str, &name_len, &flags, &query_str, &query_len, &async);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqcur_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
php_pqconn_object_t *conn_obj = PHP_PQ_OBJ(zconn, NULL);
if (obj->intern) {
throw_exce(EX_BAD_METHODCALL, "pq\\Cursor already initialized");
} if (!conn_obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
int query_offset;
char *decl = php_pqcur_declare_str(name_str, name_len, flags, query_str, query_len, &query_offset);
if (async) {
rv = php_pqconn_declare_async(zconn, conn_obj, decl);
} else {
rv = php_pqconn_declare(zconn, conn_obj, decl);
}
if (SUCCESS != rv) {
efree(decl);
} else {
obj->intern = php_pqcur_init(conn_obj, name_str, decl, query_offset, flags);
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqcur_open, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqcur, open)
{
cur_open(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqcur_openAsync, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqcur, openAsync)
{
cur_open(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqcur_close, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqcur, close)
{
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (rv == SUCCESS) {
php_pqcur_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Cursor not initialized");
} else {
cur_close(obj, 0, 0);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqcur_closeAsync, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqcur, closeAsync)
{
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (rv == SUCCESS) {
php_pqcur_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Cursor not initialized");
} else {
cur_close(obj, 1, 0);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqcur_fetch, 0, 0, 1)
ZEND_ARG_INFO(0, spec)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqcur, fetch)
{
cur_fetch_or_move(INTERNAL_FUNCTION_PARAM_PASSTHRU, "fetch", 0);
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqcur_move, 0, 0, 0)
ZEND_ARG_INFO(0, spec)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqcur, move)
{
cur_fetch_or_move(INTERNAL_FUNCTION_PARAM_PASSTHRU, "move", 0);
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqcur_fetchAsync, 0, 0, 0)
ZEND_ARG_INFO(0, spec)
ZEND_ARG_INFO(0, callback)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqcur, fetchAsync)
{
cur_fetch_or_move(INTERNAL_FUNCTION_PARAM_PASSTHRU, "fetch", 1);
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqcur_moveAsync, 0, 0, 0)
ZEND_ARG_INFO(0, spec)
ZEND_ARG_INFO(0, callback)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqcur, moveAsync)
{
cur_fetch_or_move(INTERNAL_FUNCTION_PARAM_PASSTHRU, "move", 1);
}
static zend_function_entry php_pqcur_methods[] = {
PHP_ME(pqcur, __construct, ai_pqcur___construct, ZEND_ACC_PUBLIC)
PHP_ME(pqcur, open, ai_pqcur_open, ZEND_ACC_PUBLIC)
PHP_ME(pqcur, openAsync, ai_pqcur_openAsync, ZEND_ACC_PUBLIC)
PHP_ME(pqcur, close, ai_pqcur_close, ZEND_ACC_PUBLIC)
PHP_ME(pqcur, closeAsync, ai_pqcur_closeAsync, ZEND_ACC_PUBLIC)
PHP_ME(pqcur, fetch, ai_pqcur_fetch, ZEND_ACC_PUBLIC)
PHP_ME(pqcur, move, ai_pqcur_move, ZEND_ACC_PUBLIC)
PHP_ME(pqcur, fetchAsync, ai_pqcur_fetchAsync, ZEND_ACC_PUBLIC)
PHP_ME(pqcur, moveAsync, ai_pqcur_moveAsync, ZEND_ACC_PUBLIC)
{0}
};
PHP_MSHUTDOWN_FUNCTION(pqcur)
{
zend_hash_destroy(&php_pqcur_object_prophandlers);
return SUCCESS;
}
PHP_MINIT_FUNCTION(pqcur)
{
zend_class_entry ce = {0};
php_pq_object_prophandler_t ph = {0};
INIT_NS_CLASS_ENTRY(ce, "pq", "Cursor", php_pqcur_methods);
php_pqcur_class_entry = zend_register_internal_class_ex(&ce, NULL);
php_pqcur_class_entry->create_object = php_pqcur_create_object;
memcpy(&php_pqcur_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
php_pqcur_object_handlers.offset = XtOffsetOf(php_pqcur_object_t, zo);
php_pqcur_object_handlers.free_obj = php_pqcur_object_free;
php_pqcur_object_handlers.read_property = php_pq_object_read_prop;
php_pqcur_object_handlers.write_property = php_pq_object_write_prop;
php_pqcur_object_handlers.clone_obj = NULL;
php_pqcur_object_handlers.get_property_ptr_ptr = php_pq_object_get_prop_ptr_null;
php_pqcur_object_handlers.get_gc = php_pq_object_get_gc;
php_pqcur_object_handlers.get_properties = php_pq_object_properties;
php_pqcur_object_handlers.get_debug_info = php_pq_object_debug_info;
zend_hash_init(&php_pqcur_object_prophandlers, 4, NULL, php_pq_object_prophandler_dtor, 1);
zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("BINARY"), PHP_PQ_DECLARE_BINARY);
zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("INSENSITIVE"), PHP_PQ_DECLARE_INSENSITIVE);
zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("WITH_HOLD"), PHP_PQ_DECLARE_WITH_HOLD);
zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("SCROLL"), PHP_PQ_DECLARE_SCROLL);
zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("NO_SCROLL"), PHP_PQ_DECLARE_NO_SCROLL);
zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("name"), ZEND_ACC_PUBLIC);
ph.read = php_pqcur_object_read_name;
zend_hash_str_add_mem(&php_pqcur_object_prophandlers, "name", sizeof("name")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC);
ph.read = php_pqcur_object_read_connection;
ph.gc = php_pqcur_object_gc_connection;
zend_hash_str_add_mem(&php_pqcur_object_prophandlers, "connection", sizeof("connection")-1, (void *) &ph, sizeof(ph));
ph.gc = NULL;
zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("query"), ZEND_ACC_PUBLIC);
ph.read = php_pqcur_object_read_query;
zend_hash_str_add_mem(&php_pqcur_object_prophandlers, "query", sizeof("query")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("flags"), ZEND_ACC_PUBLIC);
ph.read = php_pqcur_object_read_flags;
zend_hash_str_add_mem(&php_pqcur_object_prophandlers, "flags", sizeof("flags")-1, (void *) &ph, sizeof(ph));
return SUCCESS;
}
/*
* 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
*/
pq-2.2.3/src/php_pqcur.h 0000644 0000765 0000024 00000003446 14560227740 013725 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifndef PHP_PQCUR_H
#define PHP_PQCUR_H
#include "php_pqconn.h"
#define PHP_PQ_DECLARE_BINARY 0x01
#define PHP_PQ_DECLARE_INSENSITIVE 0x02
#define PHP_PQ_DECLARE_WITH_HOLD 0x04
#define PHP_PQ_DECLARE_SCROLL 0x10
#define PHP_PQ_DECLARE_NO_SCROLL 0x20
typedef struct php_pqcur {
php_pqconn_object_t *conn;
char *name;
char *decl;
unsigned open:1;
int query_offset;
long flags;
} php_pqcur_t;
typedef struct php_pqcur_object {
PHP_PQ_OBJ_DECL(php_pqcur_t *)
} php_pqcur_object_t;
extern zend_class_entry *php_pqcur_class_entry;
extern php_pqcur_object_t *php_pqcur_create_object_ex(zend_class_entry *ce, php_pqcur_t *intern);
extern char *php_pqcur_declare_str(const char *name_str, size_t name_len, unsigned flags, const char *query_str, size_t query_len, int *query_offset);
extern php_pqcur_t *php_pqcur_init(php_pqconn_object_t *conn, const char *name, char *decl, int query_offset, long flags);
extern PHP_MINIT_FUNCTION(pqcur);
extern PHP_MSHUTDOWN_FUNCTION(pqcur);
#endif
/*
* 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
*/
pq-2.2.3/src/php_pqexc.c 0000644 0000765 0000024 00000011141 14560227740 013675 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include
#include
#include
#include "php_pq.h"
#include "php_pq_object.h"
#include "php_pqexc.h"
static zend_class_entry *php_pqexc_interface_class_entry;
static zend_class_entry *php_pqexc_invalid_argument_class_entry;
static zend_class_entry *php_pqexc_runtime_class_entry;
static zend_class_entry *php_pqexc_bad_methodcall_class_entry;
static zend_class_entry *php_pqexc_domain_class_entry;
static zend_function_entry php_pqexc_methods[] = {
{0}
};
zend_class_entry *exce(php_pqexc_type_t type)
{
switch (type) {
default:
case EX_INVALID_ARGUMENT:
return php_pqexc_invalid_argument_class_entry;
case EX_RUNTIME:
case EX_CONNECTION_FAILED:
case EX_IO:
case EX_ESCAPE:
return php_pqexc_runtime_class_entry;
case EX_UNINITIALIZED:
case EX_BAD_METHODCALL:
return php_pqexc_bad_methodcall_class_entry;
case EX_DOMAIN:
case EX_SQL:
return php_pqexc_domain_class_entry;
}
}
zend_object *throw_exce(php_pqexc_type_t type, const char *fmt, ...)
{
char *msg;
zend_object *zexc;
va_list argv;
va_start(argv, fmt);
vspprintf(&msg, 0, fmt, argv);
va_end(argv);
zexc = zend_throw_exception(exce(type), msg, type);
efree(msg);
return zexc;
}
PHP_MINIT_FUNCTION(pqexc)
{
zend_class_entry ce = {0};
INIT_NS_CLASS_ENTRY(ce, "pq", "Exception", php_pqexc_methods);
php_pqexc_interface_class_entry = zend_register_internal_interface(&ce);
zend_class_implements(php_pqexc_interface_class_entry, 1, zend_ce_throwable);
zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("INVALID_ARGUMENT"), EX_INVALID_ARGUMENT);
zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("RUNTIME"), EX_RUNTIME);
zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("CONNECTION_FAILED"), EX_CONNECTION_FAILED);
zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("IO"), EX_IO);
zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("ESCAPE"), EX_ESCAPE);
zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("BAD_METHODCALL"), EX_BAD_METHODCALL);
zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("UNINITIALIZED"), EX_UNINITIALIZED);
zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("DOMAIN"), EX_DOMAIN);
zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("SQL"), EX_SQL);
memset(&ce, 0, sizeof(ce));
INIT_NS_CLASS_ENTRY(ce, "pq\\Exception", "InvalidArgumentException", php_pqexc_methods);
php_pqexc_invalid_argument_class_entry = zend_register_internal_class_ex(&ce, spl_ce_InvalidArgumentException);
zend_class_implements(php_pqexc_invalid_argument_class_entry, 1, php_pqexc_interface_class_entry);
memset(&ce, 0, sizeof(ce));
INIT_NS_CLASS_ENTRY(ce, "pq\\Exception", "RuntimeException", php_pqexc_methods);
php_pqexc_runtime_class_entry = zend_register_internal_class_ex(&ce, spl_ce_RuntimeException);
zend_class_implements(php_pqexc_runtime_class_entry, 1, php_pqexc_interface_class_entry);
memset(&ce, 0, sizeof(ce));
INIT_NS_CLASS_ENTRY(ce, "pq\\Exception", "BadMethodCallException", php_pqexc_methods);
php_pqexc_bad_methodcall_class_entry = zend_register_internal_class_ex(&ce, spl_ce_BadMethodCallException);
zend_class_implements(php_pqexc_bad_methodcall_class_entry, 1, php_pqexc_interface_class_entry);
memset(&ce, 0, sizeof(ce));
INIT_NS_CLASS_ENTRY(ce, "pq\\Exception", "DomainException", php_pqexc_methods);
php_pqexc_domain_class_entry = zend_register_internal_class_ex(&ce, spl_ce_DomainException);
zend_class_implements(php_pqexc_domain_class_entry, 1, php_pqexc_interface_class_entry);
zend_declare_property_null(php_pqexc_domain_class_entry, ZEND_STRL("sqlstate"), ZEND_ACC_PUBLIC);
return SUCCESS;
}
/*
* 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
*/
pq-2.2.3/src/php_pqexc.h 0000644 0000765 0000024 00000002306 14560227740 013705 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifndef PHP_PQEXC_H
#define PHP_PQEXC_H
typedef enum php_pqexc_type {
EX_INVALID_ARGUMENT,
EX_RUNTIME,
EX_CONNECTION_FAILED,
EX_IO,
EX_ESCAPE,
EX_BAD_METHODCALL,
EX_UNINITIALIZED,
EX_DOMAIN,
EX_SQL
} php_pqexc_type_t;
extern zend_class_entry *exce(php_pqexc_type_t type);
extern zend_object *throw_exce(php_pqexc_type_t type, const char *fmt, ...);
extern PHP_MINIT_FUNCTION(pqexc);
#endif
/*
* 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
*/
pq-2.2.3/src/php_pqlob.c 0000644 0000765 0000024 00000037512 14560227740 013704 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include
#include
#include
#include "php_pq.h"
#include "php_pq_misc.h"
#include "php_pq_object.h"
#include "php_pqexc.h"
#include "php_pqlob.h"
zend_class_entry *php_pqlob_class_entry;
static zend_object_handlers php_pqlob_object_handlers;
static HashTable php_pqlob_object_prophandlers;
static void php_pqlob_object_free(zend_object *o)
{
php_pqlob_object_t *obj = PHP_PQ_OBJ(NULL, o);
#if DBG_GC
fprintf(stderr, "FREE lob(#%d) %p (txn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->txn->zo.handle, obj->intern->txn);
#endif
if (obj->intern) {
if (obj->intern->lofd) {
lo_close(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd);
}
/* invalidate the stream */
if (obj->intern->stream) {
zend_list_delete(obj->intern->stream->res);
obj->intern->stream = NULL;
}
php_pq_object_delref(obj->intern->txn);
efree(obj->intern);
obj->intern = NULL;
}
php_pq_object_dtor(o);
}
php_pqlob_object_t *php_pqlob_create_object_ex(zend_class_entry *ce, php_pqlob_t *intern)
{
return php_pq_object_create(ce, intern, sizeof(php_pqlob_object_t),
&php_pqlob_object_handlers, &php_pqlob_object_prophandlers);
}
static zend_object *php_pqlob_create_object(zend_class_entry *class_type)
{
return &php_pqlob_create_object_ex(class_type, NULL)->zo;
}
static void php_pqlob_object_read_transaction(void *o, zval *return_value)
{
php_pqlob_object_t *obj = o;
php_pq_object_to_zval(obj->intern->txn, return_value);
}
static void php_pqlob_object_gc_transaction(void *o, zval *return_value)
{
php_pqlob_object_t *obj = o;
zval ztxn;
php_pq_object_to_zval_no_addref(obj->intern->txn, &ztxn);
add_next_index_zval(return_value, &ztxn);
}
static void php_pqlob_object_read_oid(void *o, zval *return_value)
{
php_pqlob_object_t *obj = o;
RETVAL_LONG(obj->intern->loid);
}
static void php_pqlob_object_update_stream(php_pqlob_object_t *obj, zval *zstream);
static void php_pqlob_object_read_stream(void *o, zval *return_value)
{
php_pqlob_object_t *obj = o;
zval zstream;
if (!obj->intern->stream) {
php_pqlob_object_update_stream(obj, &zstream);
} else {
php_stream_to_zval(obj->intern->stream, &zstream);
}
RETVAL_ZVAL(&zstream, 1, 0);
}
#if PHP_VERSION_ID < 70400
static size_t php_pqlob_stream_write(php_stream *stream, const char *buffer, size_t length)
#else
static ssize_t php_pqlob_stream_write(php_stream *stream, const char *buffer, size_t length)
#endif
{
php_pqlob_object_t *obj = stream->abstract;
ssize_t written = 0;
if (obj) {
written = lo_write(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd, buffer, length);
if (written < 0) {
php_error_docref(NULL, E_WARNING, "Failed to write to LOB with oid=%u (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn));
}
php_pqconn_notify_listeners(obj->intern->txn->intern->conn);
}
#if PHP_VERSION_ID < 70400
return (written < 0 ? 0 : written);
#else
return written;
#endif
}
#if PHP_VERSION_ID < 70400
static size_t php_pqlob_stream_read(php_stream *stream, char *buffer, size_t length)
#else
static ssize_t php_pqlob_stream_read(php_stream *stream, char *buffer, size_t length)
#endif
{
php_pqlob_object_t *obj = stream->abstract;
ssize_t read = 0;
if (obj) {
if (!buffer && !length) {
if (lo_tell(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd) == lo_lseek(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd, 0, SEEK_CUR)) {
return EOF;
}
} else {
read = lo_read(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd, buffer, length);
if (read < 0) {
php_error_docref(NULL, E_WARNING, "Failed to read from LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn));
}
}
php_pqconn_notify_listeners(obj->intern->txn->intern->conn);
}
#if PHP_VERSION_ID < 70400
return (read < 0 ? 0 : read);
#else
return read;
#endif
}
static ZEND_RESULT_CODE php_pqlob_stream_close(php_stream *stream, int close_handle)
{
return SUCCESS;
}
static int php_pqlob_stream_flush(php_stream *stream)
{
return SUCCESS;
}
static ZEND_RESULT_CODE php_pqlob_stream_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffset)
{
ZEND_RESULT_CODE rv = FAILURE;
php_pqlob_object_t *obj = stream->abstract;
if (obj) {
int position = lo_lseek(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd, offset, whence);
if (position < 0) {
php_error_docref(NULL, E_WARNING, "Failed to seek offset in LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn));
rv = FAILURE;
} else {
*newoffset = position;
rv = SUCCESS;
}
php_pqconn_notify_listeners(obj->intern->txn->intern->conn);
}
return rv;
}
static php_stream_ops php_pqlob_stream_ops = {
/* stdio like functions - these are mandatory! */
php_pqlob_stream_write,
php_pqlob_stream_read,
php_pqlob_stream_close,
php_pqlob_stream_flush,
"pq\\LOB stream",
/* these are optional */
php_pqlob_stream_seek,
NULL, /* cast */
NULL, /* stat */
NULL, /* set_option */
};
static void php_pqlob_object_update_stream(php_pqlob_object_t *obj, zval *zstream)
{
zval zobj, zmember;
ZVAL_STRINGL(&zmember, "stream", sizeof("stream")-1);
obj->intern->stream = php_stream_alloc(&php_pqlob_stream_ops, obj, NULL, "r+b");
obj->intern->stream->flags |= PHP_STREAM_FLAG_NO_FCLOSE;
php_stream_to_zval(obj->intern->stream, zstream);
#if PHP_VERSION_ID >= 80000
zend_std_write_property(&obj->zo, Z_STR(zmember), zstream, NULL);
#else
ZVAL_OBJ(&zobj, &obj->zo);
zend_std_write_property(&zobj, &zmember, zstream, NULL);
#endif
zval_ptr_dtor(&zmember);
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_construct, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, transaction, pq\\Transaction, 0)
ZEND_ARG_INFO(0, oid)
ZEND_ARG_INFO(0, mode)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqlob, __construct) {
zend_error_handling zeh;
zval *ztxn;
zend_long mode = INV_WRITE|INV_READ, loid = InvalidOid;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "O|ll", &ztxn, php_pqtxn_class_entry, &loid, &mode);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqlob_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
php_pqtxn_object_t *txn_obj = PHP_PQ_OBJ(ztxn, NULL);
if (obj->intern) {
throw_exce(EX_BAD_METHODCALL, "pq\\LOB already initialized");
} else if (!txn_obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized");
} else if (!txn_obj->intern->open) {
throw_exce(EX_RUNTIME, "pq\\Transation already closed");
} else {
if (loid == InvalidOid) {
loid = lo_creat(txn_obj->intern->conn->intern->conn, mode);
}
if (loid == InvalidOid) {
throw_exce(EX_RUNTIME, "Failed to create large object with mode '%s' (%s)", php_pq_strmode(mode), PHP_PQerrorMessage(txn_obj->intern->conn->intern->conn));
} else {
int lofd = lo_open(txn_obj->intern->conn->intern->conn, loid, mode);
if (lofd < 0) {
throw_exce(EX_RUNTIME, "Failed to open large object with oid=%u with mode '%s' (%s)", loid, php_pq_strmode(mode), PHP_PQerrorMessage(txn_obj->intern->conn->intern->conn));
} else {
obj->intern = ecalloc(1, sizeof(*obj->intern));
obj->intern->lofd = lofd;
obj->intern->loid = loid;
php_pq_object_addref(txn_obj);
obj->intern->txn = txn_obj;
}
}
php_pqconn_notify_listeners(txn_obj->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_write, 0, 0, 1)
ZEND_ARG_INFO(0, data)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqlob, write) {
zend_error_handling zeh;
char *data_str;
size_t data_len;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &data_str, &data_len);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqlob_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\LOB not initialized");
} else {
int written = lo_write(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd, data_str, data_len);
if (written < 0) {
throw_exce(EX_RUNTIME, "Failed to write to LOB with oid=%u (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn));
} else {
RETVAL_LONG(written);
}
php_pqconn_notify_listeners(obj->intern->txn->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_read, 0, 0, 0)
ZEND_ARG_INFO(0, length)
ZEND_ARG_INFO(1, read)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqlob, read) {
zend_error_handling zeh;
zend_long length = 0x1000;
zval *zread = NULL;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|lz!", &length, &zread);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqlob_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\LOB not initialized");
} else {
zend_string *buffer = zend_string_alloc(length, 0);
int read = lo_read(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd, &buffer->val[0], length);
if (read < 0) {
zend_string_release(buffer);
throw_exce(EX_RUNTIME, "Failed to read from LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn));
} else {
if (zread) {
ZVAL_DEREF(zread);
zval_dtor(zread);
ZVAL_LONG(zread, read);
}
buffer->val[buffer->len = read] = '\0';
RETVAL_STR(buffer);
}
php_pqconn_notify_listeners(obj->intern->txn->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_seek, 0, 0, 1)
ZEND_ARG_INFO(0, offset)
ZEND_ARG_INFO(0, whence)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqlob, seek) {
zend_error_handling zeh;
zend_long offset, whence = SEEK_SET;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &offset, &whence);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqlob_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\LOB not initialized");
} else {
int position = lo_lseek(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd, offset, whence);
if (position < 0) {
throw_exce(EX_RUNTIME, "Failed to seek offset in LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn));
} else {
RETVAL_LONG(position);
}
php_pqconn_notify_listeners(obj->intern->txn->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_tell, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqlob, tell) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqlob_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\LOB not initialized");
} else {
int position = lo_tell(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd);
if (position < 0) {
throw_exce(EX_RUNTIME, "Failed to tell offset in LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn));
} else {
RETVAL_LONG(position);
}
php_pqconn_notify_listeners(obj->intern->txn->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_truncate, 0, 0, 0)
ZEND_ARG_INFO(0, length)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqlob, truncate) {
zend_error_handling zeh;
zend_long length = 0;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &length);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqlob_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\LOB not initialized");
} else {
int rc = lo_truncate(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd, length);
if (rc != 0) {
throw_exce(EX_RUNTIME, "Failed to truncate LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn));
}
php_pqconn_notify_listeners(obj->intern->txn->intern->conn);
}
}
}
static zend_function_entry php_pqlob_methods[] = {
PHP_ME(pqlob, __construct, ai_pqlob_construct, ZEND_ACC_PUBLIC)
PHP_ME(pqlob, write, ai_pqlob_write, ZEND_ACC_PUBLIC)
PHP_ME(pqlob, read, ai_pqlob_read, ZEND_ACC_PUBLIC)
PHP_ME(pqlob, seek, ai_pqlob_seek, ZEND_ACC_PUBLIC)
PHP_ME(pqlob, tell, ai_pqlob_tell, ZEND_ACC_PUBLIC)
PHP_ME(pqlob, truncate, ai_pqlob_truncate, ZEND_ACC_PUBLIC)
{0}
};
PHP_MSHUTDOWN_FUNCTION(pqlob)
{
zend_hash_destroy(&php_pqlob_object_prophandlers);
return SUCCESS;
}
PHP_MINIT_FUNCTION(pqlob)
{
zend_class_entry ce = {0};
php_pq_object_prophandler_t ph = {0};
INIT_NS_CLASS_ENTRY(ce, "pq", "LOB", php_pqlob_methods);
php_pqlob_class_entry = zend_register_internal_class_ex(&ce, NULL);
php_pqlob_class_entry->create_object = php_pqlob_create_object;
memcpy(&php_pqlob_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
php_pqlob_object_handlers.offset = XtOffsetOf(php_pqlob_object_t, zo);
php_pqlob_object_handlers.free_obj = php_pqlob_object_free;
php_pqlob_object_handlers.read_property = php_pq_object_read_prop;
php_pqlob_object_handlers.write_property = php_pq_object_write_prop;
php_pqlob_object_handlers.clone_obj = NULL;
php_pqlob_object_handlers.get_property_ptr_ptr = php_pq_object_get_prop_ptr_null;
php_pqlob_object_handlers.get_gc = php_pq_object_get_gc;
php_pqlob_object_handlers.get_properties = php_pq_object_properties;
php_pqlob_object_handlers.get_debug_info = php_pq_object_debug_info;
zend_hash_init(&php_pqlob_object_prophandlers, 3, NULL, php_pq_object_prophandler_dtor, 1);
zend_declare_property_null(php_pqlob_class_entry, ZEND_STRL("transaction"), ZEND_ACC_PUBLIC);
ph.read = php_pqlob_object_read_transaction;
ph.gc = php_pqlob_object_gc_transaction;
zend_hash_str_add_mem(&php_pqlob_object_prophandlers, "transaction", sizeof("transaction")-1, (void *) &ph, sizeof(ph));
ph.gc = NULL;
zend_declare_property_long(php_pqlob_class_entry, ZEND_STRL("oid"), InvalidOid, ZEND_ACC_PUBLIC);
ph.read = php_pqlob_object_read_oid;
zend_hash_str_add_mem(&php_pqlob_object_prophandlers, "oid", sizeof("oid")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqlob_class_entry, ZEND_STRL("stream"), ZEND_ACC_PUBLIC);
ph.read = php_pqlob_object_read_stream;
zend_hash_str_add_mem(&php_pqlob_object_prophandlers, "stream", sizeof("stream")-1, (void *) &ph, sizeof(ph));
zend_declare_class_constant_long(php_pqlob_class_entry, ZEND_STRL("INVALID_OID"), InvalidOid);
zend_declare_class_constant_long(php_pqlob_class_entry, ZEND_STRL("R"), INV_READ);
zend_declare_class_constant_long(php_pqlob_class_entry, ZEND_STRL("W"), INV_WRITE);
zend_declare_class_constant_long(php_pqlob_class_entry, ZEND_STRL("RW"), INV_READ|INV_WRITE);
return SUCCESS;
}
/*
* 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
*/
pq-2.2.3/src/php_pqlob.h 0000644 0000765 0000024 00000002440 14560227740 013701 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifndef PHP_PQLOB_H
#define PHP_PQLOB_H
#include "php_pqtxn.h"
typedef struct php_pqlob {
int lofd;
Oid loid;
php_stream *stream;
php_pqtxn_object_t *txn;
} php_pqlob_t;
typedef struct php_pqlob_object {
PHP_PQ_OBJ_DECL(php_pqlob_t *)
} php_pqlob_object_t;
extern zend_class_entry *php_pqlob_class_entry;
extern php_pqlob_object_t *php_pqlob_create_object_ex(zend_class_entry *ce, php_pqlob_t *intern);
extern PHP_MINIT_FUNCTION(pqlob);
extern PHP_MSHUTDOWN_FUNCTION(pqlob);
#endif
/*
* 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
*/
pq-2.2.3/src/php_pq_misc.c 0000644 0000765 0000024 00000027501 14560227740 014217 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include
#include
#include
#include
#include
#include "php_pq.h"
#include "php_pqexc.h"
#include "php_pq_misc.h"
#include "php_pqconn_event.h"
#undef PHP_PQ_TYPE
#include "php_pq_type.h"
/* convert version to string */
extern void php_pq_version_to_string(int version, char *buffer, int len) {
if (version < 100000) {
slprintf(buffer, len, "%d.%d.%d", version/10000, version/100%100, version%100);
} else { /* since version 10 */
slprintf(buffer, len, "%d.%d", version/10000, version%100);
}
}
/* clear result object associated with a result handle */
void php_pqres_clear(PGresult *r) {
php_pq_object_t *o = PQresultInstanceData(r, php_pqconn_event);
if (o) {
php_pq_object_delref(o);
} else {
PQclear(r);
}
}
/* clear any asynchronous results */
void php_pqconn_clear(PGconn *conn) {
PGresult *r;
php_pqconn_event_data_t *evdata = PQinstanceData(conn, php_pqconn_event);
while ((r = PQgetResult(conn))) {
php_pqres_clear(r);
}
if (evdata && evdata->obj) {
if (php_pq_callback_is_enabled(&evdata->obj->intern->onevent)) {
if (php_pq_callback_is_locked(&evdata->obj->intern->onevent)) {
php_pq_callback_disable(&evdata->obj->intern->onevent);
} else {
php_pq_callback_dtor(&evdata->obj->intern->onevent);
}
}
}
}
/* safe wrappers to clear any asynchronous wrappers before querying synchronously */
PGresult *php_pq_exec(PGconn *conn, const char *query) {
php_pqconn_clear(conn);
return PQexec(conn, query);
}
PGresult *php_pq_exec_params(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const * paramValues, const int *paramLengths, const int *paramFormats, int resultFormat) {
php_pqconn_clear(conn);
return PQexecParams(conn, command, nParams, paramTypes, paramValues, paramLengths, paramFormats, resultFormat);
}
PGresult *php_pq_prepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes) {
php_pqconn_clear(conn);
return PQprepare(conn, stmtName, query, nParams, paramTypes);
}
PGresult *php_pq_exec_prepared(PGconn *conn, const char *stmtName, int nParams, const char *const * paramValues, const int *paramLengths, const int *paramFormats, int resultFormat) {
php_pqconn_clear(conn);
return PQexecPrepared(conn, stmtName, nParams, paramValues, paramLengths, paramFormats, resultFormat);
}
char *php_pq_rtrim(char *e)
{
size_t l = strlen(e);
while (l-- > 0 && e[l] == '\n') {
e[l] = '\0';
}
return e;
}
const char *php_pq_strmode(long mode)
{
switch (mode & (INV_READ|INV_WRITE)) {
case INV_READ|INV_WRITE:
return "rw";
case INV_READ:
return "r";
case INV_WRITE:
return "w";
default:
return "-";
}
}
static inline int compare_index(zend_ulong l, zend_ulong r)
{
if (l < r) {
return -1;
}
if (l > r) {
return 1;
}
return 0;
}
#if PHP_VERSION_ID >= 80000
int php_pq_compare_index(Bucket *lptr, Bucket *rptr)
{
return compare_index(lptr->h, rptr->h);
}
#else
int php_pq_compare_index(const void *lptr, const void *rptr) {
return compare_index(((const Bucket *) lptr)->h, ((const Bucket *) rptr)->h);
}
#endif
void php_pq_hash_ptr_dtor(zval *p)
{
efree(Z_PTR_P(p));
}
zend_class_entry *php_pqdt_class_entry;
#if PHP_VERSION_ID >= 80100
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_pqdt_jsonserialize, 0, 0, IS_MIXED, 0)
ZEND_END_ARG_INFO()
#else
#define ai_pqdt_jsonserialize ai_pqdt_to_string
#endif
#if PHP_VERSION_ID >= 80200
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_pqdt_to_string, 0, 0, IS_STRING, 0)
#else
ZEND_BEGIN_ARG_INFO_EX(ai_pqdt_to_string, 0, 0, 0)
#endif
ZEND_END_ARG_INFO();
static PHP_METHOD(pqdt, __toString)
{
zval rv, tmp;
ZVAL_NULL(&rv);
php_pq_call_method(getThis(), "format", 1, &rv, php_pq_read_property(getThis(), "format", &tmp));
RETVAL_ZVAL(&rv, 1, 1);
}
#if PHP_VERSION_ID >= 80100
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(ai_pqdt_create_from_format, 0, 2, DateTime, MAY_BE_FALSE)
#else
ZEND_BEGIN_ARG_INFO_EX(ai_pqdt_create_from_format, 0, 0, 2)
#endif
ZEND_ARG_INFO(0, format)
ZEND_ARG_INFO(0, datetime)
#if PHP_VERSION_ID >= 70200
ZEND_ARG_OBJ_INFO(0, object, DateTimeZone, 1)
#else
ZEND_ARG_INFO(0, timezone)
#endif
ZEND_END_ARG_INFO();
static PHP_METHOD(pqdt, createFromFormat)
{
zend_error_handling zeh;
char *fmt_str, *dt_str;
size_t fmt_len, dt_len;
zval *ztz = NULL;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "ss|O", &fmt_str, &fmt_len, &dt_str, &dt_len, &ztz, php_date_get_timezone_ce());
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqdt_from_string(return_value, fmt_str, dt_str, dt_len, "Y-m-d H:i:s.uO", ztz);
}
}
static zend_function_entry php_pqdt_methods[] = {
PHP_ME(pqdt, createFromFormat, ai_pqdt_create_from_format, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(pqdt, __toString, ai_pqdt_to_string, ZEND_ACC_PUBLIC)
PHP_MALIAS(pqdt, jsonSerialize, __toString, ai_pqdt_jsonserialize, ZEND_ACC_PUBLIC)
{0}
};
zval *php_pqdt_from_string(zval *zv, char *input_fmt, char *dt_str, size_t dt_len, const char *output_fmt, zval *ztimezone)
{
php_date_obj *dobj;
php_date_instantiate(php_pqdt_class_entry, zv);
dobj = php_date_obj_from_obj(Z_OBJ_P(zv));
if (!php_date_initialize(dobj, dt_str, dt_len, input_fmt, ztimezone, 1)) {
zval_dtor(zv);
ZVAL_NULL(zv);
} else if (output_fmt) {
zval fmt;
ZVAL_STRING(&fmt, output_fmt);
php_pq_update_property(zv, "format", &fmt);
zval_ptr_dtor(&fmt);
}
return zv;
}
zend_string *php_pqdt_to_string(zval *zdt, const char *format)
{
zval rv;
ZVAL_NULL(&rv);
if (php_pq_cast_object(zdt, IS_STRING, &rv)) {
return Z_STR(rv);
} else if (instanceof_function(Z_OBJCE_P(zdt), php_date_get_date_ce())) {
zval rv, zfmt;
ZVAL_NULL(&rv);
ZVAL_STRING(&zfmt, format);
php_pq_call_method(zdt, "format", 1, &rv, &zfmt);
zval_ptr_dtor(&zfmt);
if (Z_TYPE(rv) == IS_STRING) {
return Z_STR(rv);
}
zval_ptr_dtor(&rv);
}
return NULL;
}
zend_class_entry *php_pqconv_class_entry;
ZEND_BEGIN_ARG_INFO_EX(ai_pqconv_convert_types, 0, 0, 0)
ZEND_END_ARG_INFO();
ZEND_BEGIN_ARG_INFO_EX(ai_pqconv_convert_from_string, 0, 0, 2)
ZEND_ARG_INFO(0, data)
ZEND_ARG_INFO(0, type)
ZEND_END_ARG_INFO();
ZEND_BEGIN_ARG_INFO_EX(ai_pqconv_convert_to_string, 0, 0, 2)
ZEND_ARG_INFO(0, data)
ZEND_ARG_INFO(0, type)
ZEND_END_ARG_INFO();
zend_function_entry php_pqconv_methods[] = {
PHP_ABSTRACT_ME(pqconv, convertTypes, ai_pqconv_convert_types)
PHP_ABSTRACT_ME(pqconv, convertFromString, ai_pqconv_convert_from_string)
PHP_ABSTRACT_ME(pqconv, convertToString, ai_pqconv_convert_to_string)
{0}
};
PHP_MINIT_FUNCTION(pq_misc)
{
zend_class_entry *json, ce = {0};
INIT_NS_CLASS_ENTRY(ce, "pq", "Converter", php_pqconv_methods);
php_pqconv_class_entry = zend_register_internal_interface(&ce);
memset(&ce, 0, sizeof(ce));
INIT_NS_CLASS_ENTRY(ce ,"pq", "DateTime", php_pqdt_methods);
php_pqdt_class_entry = zend_register_internal_class_ex(&ce, php_date_get_date_ce());
zend_declare_property_stringl(php_pqdt_class_entry, ZEND_STRL("format"), ZEND_STRL("Y-m-d H:i:s.uO"), ZEND_ACC_PUBLIC);
/* stop reading this file right here! */
if ((json = zend_hash_str_find_ptr(CG(class_table), ZEND_STRL("jsonserializable")))) {
zend_class_implements(php_pqdt_class_entry, 1, json);
}
return SUCCESS;
}
typedef struct _HashTableList {
zval arr;
struct _HashTableList *parent;
} HashTableList;
typedef struct _ArrayParserState {
const char *ptr, *end;
HashTableList *list;
php_pqres_t *res;
Oid typ;
unsigned quotes:1;
unsigned escaped:1;
} ArrayParserState;
static char caa(ArrayParserState *a, const char *any, unsigned advance)
{
const char *p = any;
do {
if (*p == *a->ptr) {
a->ptr += advance;
return *p;
}
} while (*++p);
php_error_docref(NULL, E_WARNING, "Failed to parse array: expected one of '%s', got '%c'", any, *a->ptr); \
return 0;
}
static ZEND_RESULT_CODE add_element(ArrayParserState *a, const char *start)
{
zval zelem;
zend_string *zstr = zend_string_init(start, a->ptr - start, 0);
if (a->quotes) {
php_stripslashes(zstr);
ZVAL_STR(&zelem, zstr);
} else if (!zend_string_equals_literal(zstr, "NULL")) {
ZVAL_STR(&zelem, zstr);
} else {
zend_string_release(zstr);
ZVAL_NULL(&zelem);
}
if (!ZVAL_IS_NULL(&zelem)) {
php_pqres_typed_zval(a->res, a->typ, &zelem);
}
add_next_index_zval(&a->list->arr, &zelem);
return SUCCESS;
}
static ZEND_RESULT_CODE parse_array(ArrayParserState *a);
static ZEND_RESULT_CODE parse_element(ArrayParserState *a, char delim)
{
const char *el;
switch (*a->ptr) {
case '{':
return parse_array(a);
case '}':
return SUCCESS;
case '"':
a->quotes = 1;
++a->ptr;
break;
}
for (el = a->ptr; a->ptr < a->end; ++a->ptr) {
switch (*a->ptr) {
case '\\':
a->escaped = !a->escaped;
break;
case '"':
if (a->escaped) {
a->escaped = 0;
} else if (a->quotes) {
if (SUCCESS != add_element(a, el)) {
return FAILURE;
}
a->quotes = 0;
++a->ptr;
return SUCCESS;
} else {
php_error_docref(NULL, E_WARNING, "Failed to parse element, unexpected quote: '%.*s'", (int) (a->ptr - el), el);
return FAILURE;
}
break;
default:
if (delim != *a->ptr) {
a->escaped = 0;
break;
}
/* no break */
case '}':
if (!a->quotes) {
return add_element(a, el);
}
break;
}
}
php_error_docref(NULL, E_WARNING, "Failed to parse element, reached end of input");
return FAILURE;
}
static ZEND_RESULT_CODE parse_elements(ArrayParserState *a)
{
char delims[] = {'}', (char) PHP_PQ_DELIM_OF_ARRAY(a->typ), 0};
while (SUCCESS == parse_element(a, delims[1])) {
switch (caa(a, delims, 0)) {
case 0:
return FAILURE;
case '}':
return SUCCESS;
default:
if (!*++a->ptr) {
php_error_docref(NULL, E_WARNING, "Failed to parse elements, reached end of input");
return FAILURE;
}
break;
}
}
return FAILURE;
}
static ZEND_RESULT_CODE parse_array(ArrayParserState *a)
{
HashTableList *list;
if (!caa(a, "{", 1)) {
return FAILURE;
}
list = ecalloc(1, sizeof(*list));
array_init(&list->arr);
if (a->list) {
add_next_index_zval(&a->list->arr, &list->arr);
list->parent = a->list;
}
a->list = list;
if (SUCCESS != parse_elements(a)) {
return FAILURE;
}
if (!caa(a, "}", 1)) {
return FAILURE;
}
/* step one level back up */
if (a->list->parent) {
HashTableList *l = a->list->parent;
efree(a->list);
a->list = l;
}
return SUCCESS;
}
HashTable *php_pq_parse_array(php_pqres_t *res, const char *val_str, size_t val_len, Oid typ)
{
HashTable *ht = NULL;
ArrayParserState a = {0};
a.typ = typ;
a.ptr = val_str;
a.end = val_str + val_len;
a.res = res;
if (SUCCESS != parse_array(&a)) {
while (a.list) {
HashTableList *l = a.list->parent;
zval_dtor(&a.list->arr);
efree(a.list);
a.list = l;
}
return ht;
}
if (*a.ptr) {
php_error_docref(NULL, E_NOTICE, "Trailing input: '%s'", a.ptr);
}
while (a.list) {
HashTableList *l = a.list->parent;
ht = Z_ARRVAL(a.list->arr);
efree(a.list);
a.list = l;
}
return ht;
}
/*
* 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
*/
pq-2.2.3/src/php_pq_misc.h 0000644 0000765 0000024 00000011763 14560227740 014227 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifndef PHP_PQ_ERROR_H
#define PHP_PQ_ERROR_H
#include
#include "php_pqres.h"
#define z_is_true zend_is_true
#define smart_str_s(ss) (ss)->s
#define smart_str_v(ss) (smart_str_s(ss)?(ss)->s->val:NULL)
#define smart_str_l(ss) (smart_str_s(ss)?(ss)->s->len:0)
/* clear result object associated with a result handle */
extern void php_pqres_clear(PGresult *r);
/* clear any asynchronous results */
extern void php_pqconn_clear(PGconn *conn);
/* safe wrappers to clear any asynchronous wrappers before querying synchronously */
extern PGresult *php_pq_exec(PGconn *conn, const char *query);
extern PGresult *php_pq_exec_params(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const * paramValues, const int *paramLengths, const int *paramFormats, int resultFormat);
extern PGresult *php_pq_prepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes);
extern PGresult *php_pq_exec_prepared(PGconn *conn, const char *stmtName, int nParams, const char *const * paramValues, const int *paramLengths, const int *paramFormats, int resultFormat);
/* convert version to string */
extern void php_pq_version_to_string(int version, char *buffer, int len);
/* trim LF from EOL */
extern char *php_pq_rtrim(char *e);
/* R, W, RW */
extern const char *php_pq_strmode(long mode);
/* free zval ptr values (as hash dtor) */
extern void php_pq_hash_ptr_dtor(zval *p);
#define PHP_PQerrorMessage(c) php_pq_rtrim(PQerrorMessage((c)))
#define PHP_PQresultErrorMessage(r) php_pq_rtrim(PQresultErrorMessage((r)))
extern zend_class_entry *php_pqdt_class_entry;
extern zval *php_pqdt_from_string(zval *zv, char *input_fmt, char *dt_str, size_t dt_len, const char *output_fmt, zval *ztimezone);
extern zend_string *php_pqdt_to_string(zval *zdt, const char *format);
extern zend_class_entry *php_pqconv_class_entry;
extern HashTable *php_pq_parse_array(php_pqres_t *res, const char *val_str, size_t val_len, Oid typ);
/* ZE compat */
#if PHP_VERSION_ID >= 80000
extern int php_pq_compare_index(Bucket *lptr, Bucket *rptr);
# define php_pq_call_method(objval_ptr, method_name, num_args, ...) \
zend_call_method_with_ ## num_args ## _params( \
Z_OBJ_P(objval_ptr), Z_OBJCE_P(objval_ptr), NULL, \
(method_name), __VA_ARGS__)
# define php_pq_read_property(objval_ptr, prop_name, tmpval_ptr) \
zend_read_property(Z_OBJCE_P(objval_ptr), Z_OBJ_P(objval_ptr), \
(prop_name), strlen(prop_name), 0, (tmpval_ptr))
# define php_pq_update_property(objval_ptr, prop_name, newval_ptr) \
zend_update_property(Z_OBJCE_P(objval_ptr), Z_OBJ_P(objval_ptr), \
(prop_name), strlen(prop_name), (newval_ptr))
#define php_pq_cast_object(objval_ptr, cast_type, retval_ptr) \
(Z_OBJ_HT_P(objval_ptr)->cast_object && \
SUCCESS == Z_OBJ_HT_P(objval_ptr)->cast_object(Z_OBJ_P(objval_ptr), (retval_ptr), (cast_type)))
#else
extern int php_pq_compare_index(const void *lptr, const void *rptr);
# define zend_ce_countable spl_ce_Countable
# define php_pq_call_method(objval_ptr, method_name, num_args, ...) \
zend_call_method_with_ ## num_args ## _params( \
(objval_ptr), NULL, NULL, \
(method_name), __VA_ARGS__)
# define php_pq_read_property(objval_ptr, prop_name, tmpval_ptr) \
zend_read_property(Z_OBJCE_P(objval_ptr), (objval_ptr), \
(prop_name), strlen(prop_name), 0, (tmpval_ptr))
# define php_pq_update_property(objval_ptr, prop_name, newval_ptr) \
zend_update_property(Z_OBJCE_P(objval_ptr), (objval_ptr), \
(prop_name), strlen(prop_name), (newval_ptr))
#define php_pq_cast_object(objval_ptr, cast_type, retval_ptr) \
(Z_OBJ_HT_P(objval_ptr)->cast_object && \
SUCCESS == Z_OBJ_HT_P(objval_ptr)->cast_object(objval_ptr, (retval_ptr), (cast_type)))
#endif
#if PHP_VERSION_ID < 80100
# define ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \
ZEND_BEGIN_ARG_INFO_EX(name, 0, return_reference, required_num_args)
# define ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, type, allow_null) \
ZEND_BEGIN_ARG_INFO_EX(name, 0, return_reference, required_num_args)
#endif
#ifndef ZEND_ACC_READONLY
#define ZEND_ACC_READONLY 0
#endif
extern PHP_MINIT_FUNCTION(pq_misc);
#endif
/*
* 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
*/
pq-2.2.3/src/php_pq_module.c 0000644 0000765 0000024 00000006575 14560227740 014561 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include
#include
#include
#include "php_pq.h"
#include "php_pq_misc.h"
#include "php_pqcancel.h"
#include "php_pqconn.h"
#include "php_pqcopy.h"
#include "php_pqcur.h"
#include "php_pqexc.h"
#include "php_pqlob.h"
#include "php_pqres.h"
#include "php_pqstm.h"
#include "php_pqtxn.h"
#include "php_pqtypes.h"
ZEND_DECLARE_MODULE_GLOBALS(php_pq);
static void php_pq_globals_init_once(zend_php_pq_globals *G)
{
memset(G, 0, sizeof(*G));
}
#define PHP_MINIT_CALL(i) do { \
if (SUCCESS != PHP_MINIT(i)(type, module_number)) { \
return FAILURE; \
} \
} while(0)
static PHP_MINIT_FUNCTION(pq)
{
ZEND_INIT_MODULE_GLOBALS(php_pq, php_pq_globals_init_once, NULL);
PHP_MINIT_CALL(pq_misc);
PHP_MINIT_CALL(pqexc);
PHP_MINIT_CALL(pqconn);
PHP_MINIT_CALL(pqcancel);
PHP_MINIT_CALL(pqtypes);
PHP_MINIT_CALL(pqres);
PHP_MINIT_CALL(pqstm);
PHP_MINIT_CALL(pqtxn);
PHP_MINIT_CALL(pqcur);
PHP_MINIT_CALL(pqcopy);
PHP_MINIT_CALL(pqlob);
return SUCCESS;
}
#define PHP_MSHUT_CALL(i) do { \
if (SUCCESS != PHP_MSHUTDOWN(i)(type, module_number)) { \
return FAILURE; \
} \
} while(0)
static PHP_MSHUTDOWN_FUNCTION(pq)
{
PHP_MSHUT_CALL(pqlob);
PHP_MSHUT_CALL(pqcopy);
PHP_MSHUT_CALL(pqcur);
PHP_MSHUT_CALL(pqtxn);
PHP_MSHUT_CALL(pqstm);
PHP_MSHUT_CALL(pqres);
PHP_MSHUT_CALL(pqtypes);
PHP_MSHUT_CALL(pqcancel);
PHP_MSHUT_CALL(pqconn);
return SUCCESS;
}
static PHP_MINFO_FUNCTION(pq)
{
#ifdef HAVE_PQLIBVERSION
int libpq_v;
#endif
char libpq_version[10] = "pre-9.1";
php_info_print_table_start();
php_info_print_table_header(2, "PQ Support", "enabled");
php_info_print_table_row(2, "Extension Version", PHP_PQ_VERSION);
php_info_print_table_end();
php_info_print_table_start();
php_info_print_table_header(3, "Used Library", "Compiled", "Linked");
#ifdef HAVE_PQLIBVERSION
libpq_v = PQlibVersion();
php_pq_version_to_string(libpq_v, libpq_version, sizeof(libpq_version));
#endif
php_info_print_table_row(3, "libpq", PHP_PQ_LIBVERSION, libpq_version);
php_info_print_table_end();
}
static const zend_function_entry pq_functions[] = {
{0}
};
static zend_module_dep pq_module_deps[] = {
ZEND_MOD_REQUIRED("raphf")
ZEND_MOD_REQUIRED("spl")
ZEND_MOD_OPTIONAL("json")
ZEND_MOD_END
};
zend_module_entry pq_module_entry = {
STANDARD_MODULE_HEADER_EX,
NULL,
pq_module_deps,
"pq",
pq_functions,
PHP_MINIT(pq),
PHP_MSHUTDOWN(pq),
NULL,/*PHP_RINIT(pq),*/
NULL,/*PHP_RSHUTDOWN(pq),*/
PHP_MINFO(pq),
PHP_PQ_VERSION,
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_PQ
ZEND_GET_MODULE(pq)
#endif
/*
* 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
*/
pq-2.2.3/src/php_pq_object.c 0000644 0000765 0000024 00000020721 14560227740 014527 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include
#include "php_pq_object.h"
#include "php_pq_misc.h"
void *php_pq_object_create(zend_class_entry *ce, void *intern, size_t obj_size, zend_object_handlers *oh, HashTable *ph)
{
php_pq_object_t *o = ecalloc(1, obj_size + zend_object_properties_size(ce));
zend_object_std_init(&o->zo, ce);
object_properties_init(&o->zo, ce);
o->zo.handlers = oh;
o->intern = intern;
o->prophandler = ph;
zend_hash_init(&o->gc, 0, NULL, NULL, 0);
return o;
}
void php_pq_object_dtor(zend_object *o)
{
php_pq_object_t *obj = PHP_PQ_OBJ(NULL, o);
zend_hash_destroy(&obj->gc);
zend_object_std_dtor(o);
}
void php_pq_object_to_zval(void *o, zval *zv)
{
php_pq_object_t *obj = o;
ZVAL_OBJ(zv, &obj->zo);
Z_ADDREF_P(zv);
}
void php_pq_object_to_zval_no_addref(void *o, zval *zv)
{
php_pq_object_t *obj = o;
ZVAL_OBJ(zv, &obj->zo);
}
void php_pq_object_addref(void *o)
{
php_pq_object_t *obj = o;
#ifdef GC_ADDREF
GC_ADDREF(&obj->zo);
#else
++GC_REFCOUNT(&obj->zo);
#endif
}
void php_pq_object_delref(void *o)
{
php_pq_object_t *obj = o;
zval tmp;
/* this should gc immediately */
ZVAL_OBJ(&tmp, &obj->zo);
zval_ptr_dtor(&tmp);
}
struct apply_pi_to_ht_arg {
HashTable *ht;
php_pq_object_t *pq_obj;
unsigned gc:1;
};
static int apply_pi_to_ht(zval *p, void *a)
{
zend_property_info *pi = Z_PTR_P(p);
struct apply_pi_to_ht_arg *arg = a;
if (arg->gc) {
php_pq_object_prophandler_t *handler;
if ((handler = zend_hash_find_ptr(arg->pq_obj->prophandler, pi->name)) && handler->gc) {
zval return_value;
ZVAL_ARR(&return_value, arg->ht);
handler->gc(arg->pq_obj, &return_value);
}
} else {
zval tmp_prop, *property;
#if PHP_VERSION_ID < 80000
zval zobj;
ZVAL_OBJ(&zobj, &arg->pq_obj->zo);
# if PHP_VERSION_ID < 70100
property = zend_read_property(arg->pq_obj->zo.ce, &zobj, pi->name->val, pi->name->len, 0, &tmp_prop);
# else
property = zend_read_property_ex(arg->pq_obj->zo.ce, &zobj, pi->name, 0, &tmp_prop);
# endif
#else
property = zend_read_property_ex(arg->pq_obj->zo.ce, &arg->pq_obj->zo, pi->name, 0, &tmp_prop);
#endif
zend_hash_update(arg->ht, pi->name, property);
}
return ZEND_HASH_APPLY_KEEP;
}
static inline HashTable *php_pq_object_debug_info_ex(zend_object *object, int *temp)
{
struct apply_pi_to_ht_arg arg = {NULL};
*temp = 1;
ALLOC_HASHTABLE(arg.ht);
ZEND_INIT_SYMTABLE(arg.ht);
arg.pq_obj = PHP_PQ_OBJ(NULL, object);
arg.gc = 0;
zend_hash_apply_with_argument(&arg.pq_obj->zo.ce->properties_info, apply_pi_to_ht, &arg);
return arg.ht;
}
#if PHP_VERSION_ID >= 80000
HashTable *php_pq_object_debug_info(zend_object *object, int *temp)
{
return php_pq_object_debug_info_ex(object, temp);
}
#else
HashTable *php_pq_object_debug_info(zval *object, int *temp)
{
return php_pq_object_debug_info_ex(Z_OBJ_P(object), temp);
}
#endif
static inline HashTable *php_pq_object_properties_ex(zend_object *object, HashTable *props)
{
struct apply_pi_to_ht_arg arg = {NULL};
arg.ht = props;
arg.pq_obj = PHP_PQ_OBJ(NULL, object);
arg.gc = 0;
zend_hash_apply_with_argument(&arg.pq_obj->zo.ce->properties_info, apply_pi_to_ht, &arg);
return arg.ht;
}
#if PHP_VERSION_ID >= 80000
HashTable *php_pq_object_properties(zend_object *object)
{
return php_pq_object_properties_ex(object, zend_std_get_properties(object));
}
#else
HashTable *php_pq_object_properties(zval *object)
{
return php_pq_object_properties_ex(Z_OBJ_P(object), zend_std_get_properties(object));
}
#endif
static inline HashTable *php_pq_object_get_gc_ex(zend_object *object, HashTable *props, zval **table, int *n)
{
struct apply_pi_to_ht_arg arg = {NULL};
arg.pq_obj = PHP_PQ_OBJ(NULL, object);
arg.ht = &arg.pq_obj->gc;
arg.gc = 1;
if (GC_REFCOUNT(arg.ht) == 1) {
zend_hash_clean(arg.ht);
zend_hash_copy(arg.ht, props, NULL);
zend_hash_apply_with_argument(&arg.pq_obj->zo.ce->properties_info, apply_pi_to_ht, &arg);
}
*table = NULL;
*n = 0;
return arg.ht;
}
#if PHP_VERSION_ID >= 80000
HashTable *php_pq_object_get_gc(zend_object *object, zval **table, int *n)
{
return php_pq_object_get_gc_ex(object, zend_std_get_properties(object), table, n);
}
#else
HashTable *php_pq_object_get_gc(zval *object, zval **table, int *n)
{
return php_pq_object_get_gc_ex(Z_OBJ_P(object), zend_std_get_properties(object), table, n);
}
#endif
zend_class_entry *ancestor(zend_class_entry *ce)
{
while (ce->parent) {
ce = ce->parent;
}
return ce;
}
static inline int php_pq_object_read_prop_ex(zend_object *object, zend_string *member, int type, zval *return_value)
{
php_pq_object_t *obj = PHP_PQ_OBJ(NULL, object);
php_pq_object_prophandler_t *handler;
if (!obj->intern) {
php_error(E_RECOVERABLE_ERROR, "%s not initialized", ancestor(obj->zo.ce)->name->val);
} else if (!(handler = zend_hash_find_ptr(obj->prophandler, member)) || !handler->read) {
/* default handler */
} else if (type != BP_VAR_R) {
php_error(E_WARNING, "Cannot access %s properties by reference or array key/index", ancestor(obj->zo.ce)->name->val);
} else {
handler->read(obj, return_value);
return SUCCESS;
}
return FAILURE;
}
#if PHP_VERSION_ID >= 80000
zval *php_pq_object_read_prop(zend_object *object, zend_string *member, int type, void **cache_slot, zval *tmp)
{
if (SUCCESS != php_pq_object_read_prop_ex(object, member, type, tmp)) {
return zend_std_read_property(object, member, type, cache_slot, tmp);
}
zend_std_write_property(object, member, tmp, cache_slot);
if (cache_slot) {
*cache_slot = NULL;
}
return tmp;
}
#else
zval *php_pq_object_read_prop(zval *object, zval *member, int type, void **cache_slot, zval *tmp)
{
zend_string *member_str = zval_get_string(member);
if (SUCCESS != php_pq_object_read_prop_ex(Z_OBJ_P(object), member_str, type, tmp)) {
zend_string_release(member_str);
return zend_get_std_object_handlers()->read_property(object, member, type, cache_slot, tmp);
}
zend_string_release(member_str);
zend_std_write_property(object, member, tmp, cache_slot);
if (cache_slot) {
*cache_slot = NULL;
}
return tmp;
}
#endif
static inline int php_pq_object_write_prop_ex(zend_object *object, zend_string *member, zval *value)
{
php_pq_object_t *obj = PHP_PQ_OBJ(NULL, object);
php_pq_object_prophandler_t *handler;
if (!obj->intern) {
php_error(E_RECOVERABLE_ERROR, "%s not initialized", ancestor(obj->zo.ce)->name->val);
} else if (!(handler = zend_hash_find_ptr(obj->prophandler, member))) {
/* default handler */
} else {
if (handler->write) {
handler->write(obj, value);
}
return SUCCESS;
}
return FAILURE;
}
#if PHP_VERSION_ID >= 80000
zval *php_pq_object_write_prop(zend_object *object, zend_string *member, zval *value, void **cache_slot)
{
if (SUCCESS != php_pq_object_write_prop_ex(object, member, value)) {
return zend_std_write_property(object, member, value, cache_slot);
}
return value;
}
#elif PHP_VERSION_ID >= 70400
zval *php_pq_object_write_prop(zval *object, zval *member, zval *value, void **cache_slot)
{
zend_string *member_str = zval_get_string(member);
if (SUCCESS != php_pq_object_write_prop_ex(Z_OBJ_P(object), member_str, value)) {
value = zend_std_write_property(object, member, value, cache_slot);
}
zend_string_release(member_str);
return value;
}
#else
void php_pq_object_write_prop(zval *object, zval *member, zval *value, void **cache_slot)
{
zend_string *member_str = zval_get_string(member);
if (SUCCESS != php_pq_object_write_prop_ex(Z_OBJ_P(object), member_str, value)) {
zend_std_write_property(object, member, value, cache_slot);
}
zend_string_release(member_str);
}
#endif
#if PHP_VERSION_ID >= 80000
zval *php_pq_object_get_prop_ptr_null(zend_object *object, zend_string *member, int type, void **cache_slot)
{
return NULL;
}
#else
zval *php_pq_object_get_prop_ptr_null(zval *object, zval *member, int type, void **cache_slot)
{
return NULL;
}
#endif
void php_pq_object_prophandler_dtor(zval *zv) {
pefree(Z_PTR_P(zv), 1);
}
pq-2.2.3/src/php_pq_object.h 0000644 0000765 0000024 00000006307 14560227740 014540 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifndef PHP_PQ_OBJECT_H
#define PHP_PQ_OBJECT_H
#define PHP_PQ_OBJ_DECL(_intern_type) \
_intern_type intern; \
HashTable *prophandler; \
HashTable gc; \
zend_object zo;
typedef struct php_pq_object {
PHP_PQ_OBJ_DECL(void *)
} php_pq_object_t;
static inline void *PHP_PQ_OBJ(zval *zv, zend_object *zo) {
if (zv) {
zo = Z_OBJ_P(zv);
}
return (void *) (((char *) zo) - zo->handlers->offset);
}
extern zend_class_entry *ancestor(zend_class_entry *ce);
typedef void (*php_pq_object_prophandler_func_t)(void *o, zval *return_value);
typedef struct php_pq_object_prophandler {
php_pq_object_prophandler_func_t read;
php_pq_object_prophandler_func_t write;
php_pq_object_prophandler_func_t gc;
} php_pq_object_prophandler_t;
extern void php_pq_object_prophandler_dtor(zval *zv);
extern void *php_pq_object_create(zend_class_entry *ce, void *intern, size_t obj_size, zend_object_handlers *oh, HashTable *ph);
extern void php_pq_object_dtor(zend_object *obj);
extern void php_pq_object_to_zval(void *o, zval *zv);
extern void php_pq_object_to_zval_no_addref(void *o, zval *zv);
extern void php_pq_object_addref(void *o);
extern void php_pq_object_delref(void *o);
#if PHP_VERSION_ID >= 80000
extern HashTable *php_pq_object_debug_info(zend_object *object, int *temp);
extern HashTable *php_pq_object_properties(zend_object *object);
extern HashTable *php_pq_object_get_gc(zend_object *object, zval **table, int *n);
extern zval *php_pq_object_read_prop(zend_object *object, zend_string *member, int type, void **cache_slot, zval *tmp);
extern zval *php_pq_object_write_prop(zend_object *object, zend_string *member, zval *value, void **cache_slot);
extern zval *php_pq_object_get_prop_ptr_null(zend_object *object, zend_string *member, int type, void **cache_slot);
#else
extern HashTable *php_pq_object_debug_info(zval *object, int *temp);
extern HashTable *php_pq_object_properties(zval *object);
extern HashTable *php_pq_object_get_gc(zval *object, zval **table, int *n);
extern zval *php_pq_object_read_prop(zval *object, zval *member, int type, void **cache_slot, zval *tmp);
# if PHP_VERSION_ID >= 70400
extern zval *php_pq_object_write_prop(zval *object, zval *member, zval *value, void **cache_slot);
# else
extern void php_pq_object_write_prop(zval *object, zval *member, zval *value, void **cache_slot);
# endif
extern zval *php_pq_object_get_prop_ptr_null(zval *object, zval *member, int type, void **cache_slot);
#endif
#endif
/*
* 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
*/
pq-2.2.3/src/php_pq_params.c 0000644 0000765 0000024 00000021377 14560227740 014554 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include
#include
#include
#include
#include
#include
#include "php_pq.h"
#include "php_pq_params.h"
#include "php_pq_misc.h"
#undef PHP_PQ_TYPE
#include "php_pq_type.h"
void php_pq_params_set_type_conv(php_pq_params_t *p, HashTable *conv)
{
zend_hash_clean(&p->type.conv);
zend_hash_copy(&p->type.conv, conv, (copy_ctor_func_t) zval_add_ref);
}
static int apply_to_oid(zval *ztype, void *arg)
{
Oid **types = arg;
**types = zval_get_long(ztype);
++*types;
return ZEND_HASH_APPLY_KEEP;
}
unsigned php_pq_params_set_type_oids(php_pq_params_t *p, HashTable *oids)
{
p->type.count = oids ? zend_hash_num_elements(oids) : 0;
if (p->type.oids) {
efree(p->type.oids);
p->type.oids = NULL;
}
if (p->type.count) {
Oid *ptr = ecalloc(p->type.count + 1, sizeof(*p->type.oids));
/* +1 for when less types than params are specified */
p->type.oids = ptr;
zend_hash_apply_with_argument(oids, apply_to_oid, &ptr);
}
return p->type.count;
}
unsigned php_pq_params_add_type_oid(php_pq_params_t *p, Oid type)
{
p->type.oids = safe_erealloc(p->type.oids, ++p->type.count, sizeof(*p->type.oids), sizeof(*p->type.oids));
p->type.oids[p->type.count] = 0;
p->type.oids[p->type.count-1] = type;
return p->type.count;
}
static zend_string *object_param_to_string(php_pq_params_t *p, zval *zobj, Oid type)
{
#ifdef PHP_PQ_OID_JSON
smart_str str = {0};
#endif
switch (type) {
#ifdef PHP_PQ_OID_JSON
# ifdef PHP_PQ_OID_JSONB
case PHP_PQ_OID_JSONB:
# endif
case PHP_PQ_OID_JSON:
# if PHP_VERSION_ID >= 70100
JSON_G(encode_max_depth) = PHP_JSON_PARSER_DEFAULT_DEPTH;
# endif
php_json_encode(&str, zobj, PHP_JSON_UNESCAPED_UNICODE);
smart_str_0(&str);
return str.s;
#endif
case PHP_PQ_OID_DATE:
return php_pqdt_to_string(zobj, "Y-m-d");
#ifdef PHP_PQ_OID_ABSTIME
case PHP_PQ_OID_ABSTIME:
return php_pqdt_to_string(zobj, "Y-m-d H:i:s");
#endif
case PHP_PQ_OID_TIMESTAMP:
return php_pqdt_to_string(zobj, "Y-m-d H:i:s.u");
case PHP_PQ_OID_TIMESTAMPTZ:
return php_pqdt_to_string(zobj, "Y-m-d H:i:s.uO");
}
return zval_get_string(zobj);
}
struct apply_to_param_from_array_arg {
php_pq_params_t *params;
unsigned index;
smart_str *buffer;
Oid type;
char delim;
zval *zconv;
};
static int apply_to_param_from_array(zval *zparam, void *arg_ptr)
{
struct apply_to_param_from_array_arg subarg, *arg = arg_ptr;
char *tmp;
size_t len;
zend_string *str, *tmpstr;
if (arg->index++) {
smart_str_appendc(arg->buffer, arg->delim);
}
if (arg->zconv) {
zval ztype, rv;
ZVAL_LONG(&ztype, arg->type);
php_pq_call_method(arg->zconv, "converttostring", 2, &rv, zparam, &ztype);
tmpstr = zval_get_string(&rv);
zval_ptr_dtor(&rv);
goto append_string;
} else {
again:
switch (Z_TYPE_P(zparam)) {
case IS_REFERENCE:
ZVAL_DEREF(zparam);
goto again;
case IS_NULL:
smart_str_appends(arg->buffer, "NULL");
break;
case IS_TRUE:
smart_str_appends(arg->buffer, "t");
break;
case IS_FALSE:
smart_str_appends(arg->buffer, "f");
break;
case IS_LONG:
smart_str_append_long(arg->buffer, Z_LVAL_P(zparam));
break;
case IS_DOUBLE:
len = spprintf(&tmp, 0, "%F", Z_DVAL_P(zparam));
smart_str_appendl(arg->buffer, tmp, len);
efree(tmp);
break;
case IS_ARRAY:
subarg = *arg;
subarg.index = 0;
smart_str_appendc(arg->buffer, '{');
zend_hash_apply_with_argument(Z_ARRVAL_P(zparam), apply_to_param_from_array, &subarg);
smart_str_appendc(arg->buffer, '}');
break;
case IS_OBJECT:
if ((tmpstr = object_param_to_string(arg->params, zparam, arg->type))) {
goto append_string;
}
/* no break */
default:
tmpstr = zval_get_string(zparam);
append_string:
#if PHP_VERSION_ID < 70300
str = php_addslashes(tmpstr, 1);
#else
str = php_addslashes(tmpstr);
zend_string_release(tmpstr);
#endif
smart_str_appendc(arg->buffer, '"');
smart_str_appendl(arg->buffer, str->val, str->len);
smart_str_appendc(arg->buffer, '"');
zend_string_release(str);
break;
}
}
++arg->index;
return ZEND_HASH_APPLY_KEEP;
}
static zend_string *array_param_to_string(php_pq_params_t *p, zval *zarr, Oid type)
{
smart_str s = {0};
struct apply_to_param_from_array_arg arg = {NULL};
switch (type) {
#ifdef PHP_PQ_OID_JSON
# ifdef PHP_PQ_OID_JSONB
case PHP_PQ_OID_JSONB:
# endif
case PHP_PQ_OID_JSON:
php_json_encode(&s, zarr, PHP_JSON_UNESCAPED_UNICODE);
break;
#endif
default:
arg.params = p;
arg.buffer = &s;
arg.type = PHP_PQ_TYPE_OF_ARRAY(type);
arg.delim = PHP_PQ_DELIM_OF_ARRAY(type);
arg.zconv = zend_hash_index_find(&p->type.conv, PHP_PQ_TYPE_OF_ARRAY(type));
smart_str_appendc(arg.buffer, '{');
SEPARATE_ZVAL(zarr);
zend_hash_apply_with_argument(Z_ARRVAL_P(zarr), apply_to_param_from_array, &arg);
smart_str_appendc(arg.buffer, '}');
break;
}
smart_str_0(&s);
return s.s;
}
static void php_pq_params_set_param(php_pq_params_t *p, unsigned index, zval *zpp)
{
zval *zconv = NULL;
Oid type = p->type.count > index ? p->type.oids[index] : 0;
if (type && (zconv = zend_hash_index_find(&p->type.conv, type))) {
zval ztype, rv;
ZVAL_NULL(&rv);
ZVAL_LONG(&ztype, type);
php_pq_call_method(zconv, "converttostring", 2, &rv, zpp, &ztype);
convert_to_string(&rv);
p->param.strings[index] = Z_STRVAL_P(&rv);
zend_hash_next_index_insert(&p->param.dtor, &rv);
} else {
zval tmp;
zend_string *str = NULL;
char tmp_str[64];
size_t tmp_len = 0;
again:
switch (Z_TYPE_P(zpp)) {
case IS_REFERENCE:
ZVAL_DEREF(zpp);
goto again;
case IS_NULL:
p->param.strings[index] = NULL;
return;
case IS_TRUE:
p->param.strings[index] = "t";
break;
case IS_FALSE:
p->param.strings[index] = "f";
return;
case IS_DOUBLE:
tmp_len = slprintf(tmp_str, sizeof(tmp_str), "%F", Z_DVAL_P(zpp));
str = zend_string_init(tmp_str, tmp_len, 0);
break;
case IS_ARRAY:
str = array_param_to_string(p, zpp, type);
break;
case IS_OBJECT:
if ((str = object_param_to_string(p, zpp, type))) {
break;
}
/* no break */
default:
str = zval_get_string(zpp);
break;
}
if (str) {
ZVAL_STR(&tmp, str);
p->param.strings[index] = Z_STRVAL(tmp);
zend_hash_next_index_insert(&p->param.dtor, &tmp);
}
}
}
struct apply_to_params_arg {
php_pq_params_t *params;
unsigned index;
};
static int apply_to_params(zval *zp, void *arg_ptr)
{
struct apply_to_params_arg *arg = arg_ptr;
ZVAL_DEREF(zp);
SEPARATE_ZVAL(zp);
php_pq_params_set_param(arg->params, arg->index++, zp);
return ZEND_HASH_APPLY_KEEP;
}
unsigned php_pq_params_add_param(php_pq_params_t *p, zval *param)
{
p->param.strings = safe_erealloc(p->param.strings, ++p->param.count, sizeof(*p->param.strings), 0);
php_pq_params_set_param(p, p->param.count-1, param);
return p->type.count;
}
unsigned php_pq_params_set_params(php_pq_params_t *p, HashTable *params)
{
p->param.count = params ? zend_hash_num_elements(params) : 0;
if (p->param.strings) {
efree(p->param.strings);
p->param.strings = NULL;
}
zend_hash_clean(&p->param.dtor);
if (p->param.count) {
struct apply_to_params_arg arg = {p, 0};
p->param.strings = ecalloc(p->param.count, sizeof(*p->param.strings));
zend_hash_apply_with_argument(params, apply_to_params, &arg);
}
return p->param.count;
}
void php_pq_params_free(php_pq_params_t **p)
{
if (*p) {
php_pq_params_set_type_oids(*p, NULL);
php_pq_params_set_params(*p, NULL);
zend_hash_destroy(&(*p)->param.dtor);
zend_hash_destroy(&(*p)->type.conv);
efree(*p);
*p = NULL;
}
}
php_pq_params_t *php_pq_params_init(HashTable *conv, HashTable *oids, HashTable *params)
{
php_pq_params_t *p = ecalloc(1, sizeof(*p));
zend_hash_init(&p->type.conv, 0, NULL, ZVAL_PTR_DTOR, 0);
zend_hash_init(&p->param.dtor, 0, NULL, ZVAL_PTR_DTOR, 0);
if (conv) {
php_pq_params_set_type_conv(p, conv);
}
if (oids) {
php_pq_params_set_type_oids(p, oids);
}
if (params) {
php_pq_params_set_params(p, params);
}
return p;
}
/*
* 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
*/
pq-2.2.3/src/php_pq_params.h 0000644 0000765 0000024 00000003110 14560227740 014542 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifndef PHP_PQ_PARAMS_H
#define PHP_PQ_PARAMS_H
typedef struct php_pq_params {
struct {
HashTable conv;
unsigned count;
Oid *oids;
} type;
struct {
HashTable dtor;
unsigned count;
char **strings;
} param;
} php_pq_params_t;
extern php_pq_params_t *php_pq_params_init(HashTable *conv, HashTable *oids, HashTable *params);
extern void php_pq_params_free(php_pq_params_t **p);
extern unsigned php_pq_params_set_params(php_pq_params_t *p, HashTable *params);
extern unsigned php_pq_params_set_type_oids(php_pq_params_t *p, HashTable *oids);
extern unsigned php_pq_params_add_type_oid(php_pq_params_t *p, Oid type);
extern unsigned php_pq_params_add_param(php_pq_params_t *p, zval *param);
extern void php_pq_params_set_type_conv(php_pq_params_t *p, HashTable *conv);
#endif
/*
* 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
*/
pq-2.2.3/src/php_pqres.c 0000644 0000765 0000024 00000114056 14560227740 013720 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include
#include
#include
#include
#include "php_pq.h"
#include "php_pq_misc.h"
#include "php_pq_object.h"
#include "php_pqexc.h"
#include "php_pqres.h"
#undef PHP_PQ_TYPE
#include "php_pq_type.h"
zend_class_entry *php_pqres_class_entry;
static zend_object_handlers php_pqres_object_handlers;
static HashTable php_pqres_object_prophandlers;
static zend_object_iterator_funcs php_pqres_iterator_funcs;
static inline zend_object_iterator *php_pqres_iterator_init_ex(zend_class_entry *ce, zval *object, int by_ref)
{
php_pqres_iterator_t *iter;
zval tmp, *zfetch_type;
iter = ecalloc(1, sizeof(*iter));
iter->zi.funcs = &php_pqres_iterator_funcs;
ZVAL_COPY_VALUE(&iter->zi.data, object);
zfetch_type = php_pq_read_property(object, "fetchType", &tmp);
iter->fetch_type = zval_get_long(zfetch_type);
#if DBG_GC
fprintf(stderr, "INIT iter(#%d) %p res(#%d) %p\n", iter->zi.std.handle, iter, Z_OBJ_HANDLE_P(object), PHP_PQ_OBJ(object, NULL));
#endif
return (zend_object_iterator *) iter;
}
static zend_object_iterator *php_pqres_iterator_init(zend_class_entry *ce, zval *object, int by_ref)
{
zend_object_iterator *iter = php_pqres_iterator_init_ex(ce, object, by_ref);
zend_iterator_init(iter);
Z_ADDREF_P(object);
return iter;
}
static void php_pqres_internal_iterator_init(zval *zobj)
{
php_pqres_object_t *obj = PHP_PQ_OBJ(zobj, NULL);
obj->intern->iter = (php_pqres_iterator_t *) php_pqres_iterator_init_ex(Z_OBJCE_P(zobj), zobj, 0);
obj->intern->iter->zi.funcs->rewind((zend_object_iterator *) obj->intern->iter);
}
static inline void php_pqres_iterator_dtor_ex(zend_object_iterator *i)
{
php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
#if DBG_GC
fprintf(stderr, "FREE iter(#%d) rc=%d %p\n", iter->zi.std.handle, GC_REFCOUNT(&iter->zi.std), iter);
#endif
if (!Z_ISUNDEF(iter->current_val)) {
zval_ptr_dtor(&iter->current_val);
ZVAL_UNDEF(&iter->current_val);
}
}
static void php_pqres_iterator_dtor(zend_object_iterator *i)
{
php_pqres_iterator_dtor_ex(i);
zval_ptr_dtor(&i->data);
}
static void php_pqres_internal_iterator_dtor(php_pqres_object_t *obj)
{
if (obj->intern && obj->intern->iter) {
php_pqres_iterator_dtor_ex((zend_object_iterator *) obj->intern->iter);
efree(obj->intern->iter);
obj->intern->iter = NULL;
}
}
static ZEND_RESULT_CODE php_pqres_iterator_valid(zend_object_iterator *i)
{
php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
php_pqres_object_t *obj = PHP_PQ_OBJ(&i->data, NULL);
switch (PQresultStatus(obj->intern->res)) {
case PGRES_TUPLES_OK:
#ifdef HAVE_PGRES_SINGLE_TUPLE
case PGRES_SINGLE_TUPLE:
#endif
if (PQntuples(obj->intern->res) <= iter->index) {
return FAILURE;
}
break;
default:
return FAILURE;
}
return SUCCESS;
}
#define PHP_PQRES_JSON_OPTIONS(res) \
(php_pqres_fetch_type(res) != PHP_PQRES_FETCH_OBJECT ? PHP_JSON_OBJECT_AS_ARRAY:0)
zval *php_pqres_typed_zval(php_pqres_t *res, Oid typ, zval *zv)
{
zval *zconv;
HashTable *ht;
zend_string *str;
if ((zconv = zend_hash_index_find(&res->converters, typ))) {
zval ztype, rv;
ZVAL_NULL(&rv);
ZVAL_LONG(&ztype, typ);
php_pq_call_method(zconv, "convertfromstring", 2, &rv, zv, &ztype);
zval_ptr_dtor(zv);
ZVAL_ZVAL(zv, &rv, 0, 0);
return zv;
}
str = zval_get_string(zv);
zval_ptr_dtor(zv);
switch (typ) {
case PHP_PQ_OID_BOOL:
if (!(res->auto_convert & PHP_PQRES_CONV_BOOL)) {
goto noconversion;
}
ZVAL_BOOL(zv, *str->val == 't');
break;
case PHP_PQ_OID_INT8:
case PHP_PQ_OID_TID:
case PHP_PQ_OID_INT4:
case PHP_PQ_OID_INT2:
case PHP_PQ_OID_XID:
case PHP_PQ_OID_OID:
if (!(res->auto_convert & PHP_PQRES_CONV_INT)) {
goto noconversion;
}
{
zend_long lval;
double dval;
switch (is_numeric_str_function(str, &lval, &dval)) {
case IS_LONG:
ZVAL_LONG(zv, lval);
break;
case IS_DOUBLE:
ZVAL_DOUBLE(zv, dval);
break;
default:
goto noconversion;
}
}
break;
case PHP_PQ_OID_FLOAT4:
case PHP_PQ_OID_FLOAT8:
if (!(res->auto_convert & PHP_PQRES_CONV_FLOAT)) {
goto noconversion;
}
ZVAL_DOUBLE(zv, zend_strtod(str->val, NULL));
break;
case PHP_PQ_OID_DATE:
if (!(res->auto_convert & PHP_PQRES_CONV_DATETIME)) {
goto noconversion;
}
php_pqdt_from_string(zv, NULL, str->val, str->len, "Y-m-d", NULL);
break;
#ifdef PHP_PQ_OID_ABSTIME
case PHP_PQ_OID_ABSTIME:
if (!(res->auto_convert & PHP_PQRES_CONV_DATETIME)) {
goto noconversion;
}
php_pqdt_from_string(zv, NULL, str->val, str->len, "Y-m-d H:i:s", NULL);
break;
#endif
case PHP_PQ_OID_TIMESTAMP:
if (!(res->auto_convert & PHP_PQRES_CONV_DATETIME)) {
goto noconversion;
}
php_pqdt_from_string(zv, NULL, str->val, str->len, "Y-m-d H:i:s.u", NULL);
break;
case PHP_PQ_OID_TIMESTAMPTZ:
if (!(res->auto_convert & PHP_PQRES_CONV_DATETIME)) {
goto noconversion;
}
php_pqdt_from_string(zv, NULL, str->val, str->len, "Y-m-d H:i:s.uO", NULL);
break;
#ifdef PHP_PQ_OID_JSON
# ifdef PHP_PQ_OID_JSONB
case PHP_PQ_OID_JSONB:
# endif
case PHP_PQ_OID_JSON:
if (!(res->auto_convert & PHP_PQRES_CONV_JSON)) {
goto noconversion;
}
php_json_decode_ex(zv, str->val, str->len, PHP_PQRES_JSON_OPTIONS(res), 512 /* PHP_JSON_DEFAULT_DEPTH */);
break;
#endif
case PHP_PQ_OID_BYTEA:
if (!(res->auto_convert & PHP_PQRES_CONV_BYTEA)) {
goto noconversion;
} else {
size_t to_len;
char *to_str = (char *) PQunescapeBytea((unsigned char *) str->val, &to_len);
if (!to_str) {
ZVAL_NULL(zv);
php_error_docref(NULL, E_WARNING, "Failed to unsescape BYTEA: '%s'", str->val);
} else {
ZVAL_STRINGL(zv, to_str, to_len);
PQfreemem(to_str);
}
}
break;
default:
if (!(res->auto_convert & PHP_PQRES_CONV_ARRAY)) {
goto noconversion;
}
if (PHP_PQ_TYPE_IS_ARRAY(typ) && (ht = php_pq_parse_array(res, str->val, str->len, PHP_PQ_TYPE_OF_ARRAY(typ)))) {
ZVAL_ARR(zv, ht);
} else {
goto noconversion;
}
break;
}
zend_string_release(str);
return zv;
noconversion:
ZVAL_STR(zv, str);
return zv;
}
static inline zval *php_pqres_get_col(php_pqres_t *r, unsigned row, unsigned col, zval *zv)
{
if (PQgetisnull(r->res, row, col)) {
ZVAL_NULL(zv);
} else {
ZVAL_STRINGL(zv, PQgetvalue(r->res, row, col), PQgetlength(r->res, row, col));
zv = php_pqres_typed_zval(r, PQftype(r->res, col), zv);
}
return zv;
}
static inline void php_pqres_add_col_to_zval(php_pqres_t *r, unsigned row, unsigned col, php_pqres_fetch_t fetch_type, zval *data)
{
if (PQgetisnull(r->res, row, col)) {
switch (fetch_type) {
case PHP_PQRES_FETCH_OBJECT:
add_property_null(data, PQfname(r->res, col));
break;
case PHP_PQRES_FETCH_ASSOC:
add_assoc_null(data, PQfname(r->res, col));
break;
case PHP_PQRES_FETCH_ARRAY:
add_index_null(data, col);
break;
}
} else {
zval zv;
ZVAL_STRINGL(&zv, PQgetvalue(r->res, row, col), PQgetlength(r->res, row, col));
php_pqres_typed_zval(r, PQftype(r->res, col), &zv);
switch (fetch_type) {
case PHP_PQRES_FETCH_OBJECT:
add_property_zval(data, PQfname(r->res, col), &zv);
zval_ptr_dtor(&zv);
break;
case PHP_PQRES_FETCH_ASSOC:
add_assoc_zval(data, PQfname(r->res, col), &zv);
break;
case PHP_PQRES_FETCH_ARRAY:
add_index_zval(data, col, &zv);
break;
}
}
}
zval *php_pqres_row_to_zval(PGresult *res, unsigned row, php_pqres_fetch_t fetch_type, zval *data)
{
int c, cols = PQnfields(res);
php_pqres_object_t *res_obj = PQresultInstanceData(res, php_pqconn_event);
if (Z_TYPE_P(data) != IS_OBJECT && Z_TYPE_P(data) != IS_ARRAY) {
if (PHP_PQRES_FETCH_OBJECT == fetch_type) {
object_init(data);
} else {
array_init_size(data, cols);
}
}
if (PQntuples(res) > row) {
for (c = 0; c < cols; ++c) {
php_pqres_add_col_to_zval(res_obj->intern, row, c, fetch_type, data);
}
}
return data;
}
static zval *php_pqres_iterator_current(zend_object_iterator *i)
{
php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
php_pqres_object_t *obj = PHP_PQ_OBJ(&i->data, NULL);
if (Z_ISUNDEF(iter->current_val)) {
php_pqres_row_to_zval(obj->intern->res, iter->index, iter->fetch_type, &iter->current_val);
}
return &iter->current_val;
}
static void php_pqres_iterator_key(zend_object_iterator *i, zval *key)
{
php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
ZVAL_LONG(key, iter->index);
}
static void php_pqres_iterator_invalidate(zend_object_iterator *i)
{
php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
if (!Z_ISUNDEF(iter->current_val)) {
zval_ptr_dtor(&iter->current_val);
ZVAL_UNDEF(&iter->current_val);
}
}
static void php_pqres_iterator_next(zend_object_iterator *i)
{
php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
php_pqres_iterator_invalidate(i);
++iter->index;
}
static void php_pqres_iterator_rewind(zend_object_iterator *i)
{
php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
php_pqres_iterator_invalidate(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) */
php_pqres_iterator_invalidate
#if PHP_VERSION_ID >= 80000
, NULL
#endif
};
static inline ZEND_RESULT_CODE php_pqres_count_elements_ex(zend_object *object, zend_long *count)
{
php_pqres_object_t *obj = PHP_PQ_OBJ(NULL, object);
if (!obj->intern) {
return FAILURE;
} else {
*count = (zend_long) PQntuples(obj->intern->res);
return SUCCESS;
}
}
#if PHP_VERSION_ID >= 80000
static ZEND_RESULT_CODE php_pqres_count_elements(zend_object *object, zend_long *count)
{
return php_pqres_count_elements_ex(object, count);
}
#else
static ZEND_RESULT_CODE php_pqres_count_elements(zval *object, zend_long *count)
{
return php_pqres_count_elements_ex(Z_OBJ_P(object), count);
}
#endif
ZEND_RESULT_CODE php_pqres_success(PGresult *res)
{
zval zexc, zsqlstate;
switch (PQresultStatus(res)) {
case PGRES_BAD_RESPONSE:
case PGRES_NONFATAL_ERROR:
case PGRES_FATAL_ERROR:
ZVAL_OBJ(&zexc, throw_exce(EX_SQL, "%s", PHP_PQresultErrorMessage(res)));
ZVAL_STRING(&zsqlstate, PQresultErrorField(res, PG_DIAG_SQLSTATE));
php_pq_update_property(&zexc, "sqlstate", &zsqlstate);
zval_ptr_dtor(&zsqlstate);
return FAILURE;
default:
return SUCCESS;
}
}
php_pqres_object_t *php_pqres_init_instance_data(PGresult *res, php_pqconn_object_t *conn_obj)
{
php_pqres_object_t *obj;
php_pqres_t *r = ecalloc(1, sizeof(*r));
r->res = res;
zend_hash_init(&r->bound, 0, 0, ZVAL_PTR_DTOR, 0);
zend_hash_init(&r->converters, zend_hash_num_elements(&conn_obj->intern->converters), 0, ZVAL_PTR_DTOR, 0);
zend_hash_copy(&r->converters, &conn_obj->intern->converters, (copy_ctor_func_t) zval_add_ref);
r->auto_convert = conn_obj->intern->default_auto_convert;
r->default_fetch_type = conn_obj->intern->default_fetch_type;
obj = php_pqres_create_object_ex(php_pqres_class_entry, r);
PQresultSetInstanceData(res, php_pqconn_event, obj);
return obj;
}
php_pqres_fetch_t php_pqres_fetch_type(php_pqres_t *res)
{
return res->iter ? res->iter->fetch_type : res->default_fetch_type;
}
static void php_pqres_object_free(zend_object *o)
{
php_pqres_object_t *obj = PHP_PQ_OBJ(NULL, o);
if (obj->intern) {
if (obj->intern->res) {
PQresultSetInstanceData(obj->intern->res, php_pqconn_event, NULL);
PQclear(obj->intern->res);
obj->intern->res = NULL;
}
php_pqres_internal_iterator_dtor(obj);
zend_hash_destroy(&obj->intern->bound);
zend_hash_destroy(&obj->intern->converters);
efree(obj->intern);
obj->intern = NULL;
}
php_pq_object_dtor(o);
}
php_pqres_object_t *php_pqres_create_object_ex(zend_class_entry *ce, php_pqres_t *intern)
{
return php_pq_object_create(ce, intern, sizeof(php_pqres_object_t),
&php_pqres_object_handlers, &php_pqres_object_prophandlers);
}
static zend_object *php_pqres_create_object(zend_class_entry *class_type)
{
return &php_pqres_create_object_ex(class_type, NULL)->zo;
}
static void php_pqres_object_read_status(void *o, zval *return_value)
{
php_pqres_object_t *obj = o;
RETVAL_LONG(PQresultStatus(obj->intern->res));
}
static void php_pqres_object_read_status_message(void *o, zval *return_value)
{
php_pqres_object_t *obj = o;
RETVAL_STRING(PQresStatus(PQresultStatus(obj->intern->res))+sizeof("PGRES"));
}
static void php_pqres_object_read_error_message(void *o, zval *return_value)
{
php_pqres_object_t *obj = o;
char *error = PHP_PQresultErrorMessage(obj->intern->res);
if (error) {
RETVAL_STRING(error);
} else {
RETVAL_NULL();
}
}
#ifndef PG_DIAG_SEVERITY
# define PG_DIAG_SEVERITY 'S'
#endif
#ifndef PG_DIAG_SQLSTATE
# define PG_DIAG_SQLSTATE 'C'
#endif
#ifndef PG_DIAG_MESSAGE_PRIMARY
# define PG_DIAG_MESSAGE_PRIMARY 'M'
#endif
#ifndef PG_DIAG_MESSAGE_DETAIL
# define PG_DIAG_MESSAGE_DETAIL 'D'
#endif
#ifndef PG_DIAG_MESSAGE_HINT
# define PG_DIAG_MESSAGE_HINT 'H'
#endif
#ifndef PG_DIAG_STATEMENT_POSITION
# define PG_DIAG_STATEMENT_POSITION 'P'
#endif
#ifndef PG_DIAG_INTERNAL_POSITION
# define PG_DIAG_INTERNAL_POSITION 'p'
#endif
#ifndef PG_DIAG_INTERNAL_QUERY
# define PG_DIAG_INTERNAL_QUERY 'q'
#endif
#ifndef PG_DIAG_CONTEXT
# define PG_DIAG_CONTEXT 'W'
#endif
#ifndef PG_DIAG_SCHEMA_NAME
# define PG_DIAG_SCHEMA_NAME 's'
#endif
#ifndef PG_DIAG_TABLE_NAME
# define PG_DIAG_TABLE_NAME 't'
#endif
#ifndef PG_DIAG_COLUMN_NAME
# define PG_DIAG_COLUMN_NAME 'c'
#endif
#ifndef PG_DIAG_DATATYPE_NAME
# define PG_DIAG_DATATYPE_NAME 'd'
#endif
#ifndef PG_DIAG_CONSTRAINT_NAME
# define PG_DIAG_CONSTRAINT_NAME 'n'
#endif
#ifndef PG_DIAG_SOURCE_FILE
# define PG_DIAG_SOURCE_FILE 'F'
#endif
#ifndef PG_DIAG_SOURCE_LINE
# define PG_DIAG_SOURCE_LINE 'L'
#endif
#ifndef PG_DIAG_SOURCE_FUNCTION
# define PG_DIAG_SOURCE_FUNCTION 'R'
#endif
static void php_pqres_object_read_diag(void *o, zval *return_value)
{
php_pqres_object_t *obj = o;
int i;
struct {
char code;
const char *const name;
} diag[] = {
{PG_DIAG_SEVERITY, "severity"},
{PG_DIAG_SQLSTATE, "sqlstate"},
{PG_DIAG_MESSAGE_PRIMARY, "message_primary"},
{PG_DIAG_MESSAGE_DETAIL, "message_detail"},
{PG_DIAG_MESSAGE_HINT, "message_hint"},
{PG_DIAG_STATEMENT_POSITION,"statement_position"},
{PG_DIAG_INTERNAL_POSITION, "internal_position"},
{PG_DIAG_INTERNAL_QUERY, "internal_query"},
{PG_DIAG_CONTEXT, "context"},
{PG_DIAG_SCHEMA_NAME, "schema_name"},
{PG_DIAG_TABLE_NAME, "table_name"},
{PG_DIAG_COLUMN_NAME, "column_name"},
{PG_DIAG_DATATYPE_NAME, "datatype_name"},
{PG_DIAG_CONSTRAINT_NAME, "constraint_name"},
{PG_DIAG_SOURCE_FILE, "source_file"},
{PG_DIAG_SOURCE_LINE, "source_line"},
{PG_DIAG_SOURCE_FUNCTION, "source_function"},
};
array_init_size(return_value, 32);
for (i = 0; i < sizeof(diag)/sizeof(diag[0]); ++i) {
char *value = PQresultErrorField(obj->intern->res, diag[i].code);
if (value) {
add_assoc_string(return_value, diag[i].name, value);
} else {
add_assoc_null(return_value, diag[i].name);
}
}
}
static void php_pqres_object_read_num_rows(void *o, zval *return_value)
{
php_pqres_object_t *obj = o;
RETVAL_LONG(PQntuples(obj->intern->res));
}
static void php_pqres_object_read_num_cols(void *o, zval *return_value)
{
php_pqres_object_t *obj = o;
RETVAL_LONG(PQnfields(obj->intern->res));
}
static void php_pqres_object_read_affected_rows(void *o, zval *return_value)
{
php_pqres_object_t *obj = o;
RETVAL_LONG(atoi(PQcmdTuples(obj->intern->res)));
}
static void php_pqres_object_read_fetch_type(void *o, zval *return_value)
{
php_pqres_object_t *obj = o;
RETVAL_LONG(php_pqres_fetch_type(obj->intern));
}
static void php_pqres_object_write_fetch_type(void *o, zval *value)
{
php_pqres_object_t *obj = o;
if (!obj->intern->iter) {
zval object;
ZVAL_OBJ(&object, &obj->zo);
php_pqres_internal_iterator_init(&object);
}
obj->intern->iter->fetch_type = zval_get_long(value);
}
static void php_pqres_object_read_auto_conv(void *o, zval *return_value)
{
php_pqres_object_t *obj = o;
RETVAL_LONG(obj->intern->auto_convert);
}
static void php_pqres_object_write_auto_conv(void *o, zval *value)
{
php_pqres_object_t *obj = o;
obj->intern->auto_convert = zval_get_long(value);
}
static ZEND_RESULT_CODE php_pqres_iteration(zval *zobj, php_pqres_object_t *obj, php_pqres_fetch_t fetch_type, zval *row)
{
ZEND_RESULT_CODE rv;
php_pqres_fetch_t orig_fetch;
if (!obj) {
obj = PHP_PQ_OBJ(zobj, NULL);
}
if (obj->intern->iter) {
obj->intern->iter->zi.funcs->move_forward((zend_object_iterator *) obj->intern->iter);
} else {
php_pqres_internal_iterator_init(zobj);
}
orig_fetch = obj->intern->iter->fetch_type;
obj->intern->iter->fetch_type = fetch_type;
if (SUCCESS == (rv = obj->intern->iter->zi.funcs->valid((zend_object_iterator *) obj->intern->iter))) {
zval *tmp = obj->intern->iter->zi.funcs->get_current_data((zend_object_iterator *) obj->intern->iter);
ZVAL_COPY_VALUE(row, tmp);
}
obj->intern->iter->fetch_type = orig_fetch;
return rv;
}
typedef struct php_pqres_col {
char *name;
int num;
} php_pqres_col_t;
static ZEND_RESULT_CODE column_nn(php_pqres_object_t *obj, zval *zcol, php_pqres_col_t *col)
{
zend_long index = -1;
char *name = NULL;
if (!zcol) {
index = 0;
} else {
switch (Z_TYPE_P(zcol)) {
case IS_NULL:
index = 0;
break;
case IS_LONG:
index = Z_LVAL_P(zcol);
break;
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;
}
}
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, E_WARNING, "Failed to find column at index " ZEND_LONG_FMT, index);
return FAILURE;
}
if (col->num == -1) {
php_error_docref(NULL, E_WARNING, "Failed to find column with name '%s'", name);
return FAILURE;
}
return SUCCESS;
}
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;
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "z/z", &zcol, &zref);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
} else {
php_pqres_col_t col;
if (SUCCESS != column_nn(obj, zcol, &col)) {
RETVAL_FALSE;
} else {
Z_TRY_ADDREF_P(zref);
if (!zend_hash_index_update(&obj->intern->bound, col.num, zref)) {
php_error_docref(NULL, E_WARNING, "Failed to bind column %s@%d", col.name, col.num);
RETVAL_FALSE;
} else {
zend_hash_sort(&obj->intern->bound, php_pq_compare_index, 0);
RETVAL_TRUE;
}
}
}
}
}
static int apply_bound(zval *zbound, int argc, va_list argv, zend_hash_key *key)
{
zval *zvalue;
zval *zrow = va_arg(argv, zval *);
ZEND_RESULT_CODE *rv = va_arg(argv, ZEND_RESULT_CODE *);
if (!(zvalue = zend_hash_index_find(Z_ARRVAL_P(zrow), key->h))) {
php_error_docref(NULL, E_WARNING, "Failed to find column ad index " ZEND_ULONG_FMT, key->h);
*rv = FAILURE;
return ZEND_HASH_APPLY_STOP;
} else {
ZVAL_DEREF(zbound);
zval_dtor(zbound);
ZVAL_COPY(zbound, zvalue);
*rv = SUCCESS;
return ZEND_HASH_APPLY_KEEP;
}
}
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_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
} else {
zval row;
zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh);
if (SUCCESS == php_pqres_iteration(getThis(), obj, PHP_PQRES_FETCH_ARRAY, &row)) {
zend_hash_apply_with_arguments(&obj->intern->bound, apply_bound, 2, &row, &rv);
if (SUCCESS == rv) {
RETVAL_ZVAL(&row, 1, 0);
}
}
zend_restore_error_handling(&zeh);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_row, 0, 0, 0)
ZEND_ARG_INFO(0, fetch_type)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqres, fetchRow) {
zend_error_handling zeh;
php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
zend_long fetch_type = -1;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &fetch_type);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
} else {
zval row;
if (fetch_type == -1) {
fetch_type = php_pqres_fetch_type(obj->intern);
}
zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh);
if (SUCCESS == php_pqres_iteration(getThis(), obj, fetch_type, &row)) {
RETVAL_ZVAL(&row, 1, 0);
}
zend_restore_error_handling(&zeh);
}
}
}
static zval *column_at(zval *row, int col)
{
zval *data = NULL;
HashTable *ht = HASH_OF(row);
int count = zend_hash_num_elements(ht);
if (col >= count) {
php_error_docref(NULL, E_WARNING, "Column index %d exceeds column count %d", col, count);
} else {
zend_hash_internal_pointer_reset(ht);
while (col-- > 0) {
zend_hash_move_forward(ht);
}
data = zend_hash_get_current_data(ht);
}
return data;
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_col, 0, 0, 1)
ZEND_ARG_INFO(1, ref)
ZEND_ARG_INFO(0, col)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqres, fetchCol) {
zend_error_handling zeh;
zval *zcol = NULL, *zref;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "z|z/!", &zref, &zcol);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
} else {
zval row;
zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh);
if (SUCCESS == php_pqres_iteration(getThis(), obj, php_pqres_fetch_type(obj->intern), &row)) {
php_pqres_col_t col;
if (SUCCESS != column_nn(obj, zcol, &col)) {
RETVAL_FALSE;
} else {
zval *zres = column_at(&row, col.num);
if (!zres) {
RETVAL_FALSE;
} else {
ZVAL_DEREF(zref);
zval_dtor(zref);
ZVAL_ZVAL(zref, zres, 1, 0);
RETVAL_TRUE;
}
}
}
zend_restore_error_handling(&zeh);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_all_cols, 0, 0, 0)
ZEND_ARG_INFO(0, col)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqres, fetchAllCols) {
zend_error_handling zeh;
zval *zcol = NULL;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|z!", &zcol);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
} else {
php_pqres_col_t col;
zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh);
if (SUCCESS == column_nn(obj, zcol, &col)) {
int r, rows = PQntuples(obj->intern->res);
zval tmp;
array_init(return_value);
for (r = 0; r < rows; ++r) {
add_next_index_zval(return_value, php_pqres_get_col(obj->intern, r, col.num, &tmp));
}
}
zend_restore_error_handling(&zeh);
}
}
}
struct apply_to_col_arg {
php_pqres_object_t *obj;
php_pqres_col_t *cols;
ZEND_RESULT_CODE status;
};
static int apply_to_col(zval *c, void *a)
{
struct apply_to_col_arg *arg = a;
if (SUCCESS != column_nn(arg->obj, c, arg->cols)) {
arg->status = FAILURE;
return ZEND_HASH_APPLY_STOP;
} else {
arg->status = SUCCESS;
++arg->cols;
return ZEND_HASH_APPLY_KEEP;
}
}
static php_pqres_col_t *php_pqres_convert_to_cols(php_pqres_object_t *obj, HashTable *ht)
{
struct apply_to_col_arg arg = {NULL};
php_pqres_col_t *tmp;
arg.obj = obj;
arg.cols = ecalloc(zend_hash_num_elements(ht), sizeof(*tmp));
tmp = arg.cols;
zend_hash_apply_with_argument(ht, apply_to_col, &arg);
if (SUCCESS == arg.status) {
return tmp;
} else {
efree(tmp);
return NULL;
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqres_map, 0, 0, 0)
ZEND_ARG_INFO(0, keys)
ZEND_ARG_INFO(0, vals)
ZEND_ARG_INFO(0, fetch_type)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqres, map) {
zend_error_handling zeh;
zval *zkeys = 0, *zvals = 0;
zend_long fetch_type = -1;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|z/!z/!l", &zkeys, &zvals, &fetch_type);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
} else {
int ks = 0, vs = 0;
php_pqres_col_t def = {PQfname(obj->intern->res, 0), 0}, *keys = NULL, *vals = NULL;
if (zkeys) {
convert_to_array(zkeys);
if ((ks = zend_hash_num_elements(Z_ARRVAL_P(zkeys)))) {
keys = php_pqres_convert_to_cols(obj, Z_ARRVAL_P(zkeys));
} else {
ks = 1;
keys = &def;
}
} else {
ks = 1;
keys = &def;
}
if (zvals) {
convert_to_array(zvals);
if ((vs = zend_hash_num_elements(Z_ARRVAL_P(zvals)))) {
vals = php_pqres_convert_to_cols(obj, Z_ARRVAL_P(zvals));
}
}
if (fetch_type == -1) {
fetch_type = php_pqres_fetch_type(obj->intern);
}
if (keys) {
int rows, r;
zval *cur;
switch (fetch_type) {
case PHP_PQRES_FETCH_ARRAY:
case PHP_PQRES_FETCH_ASSOC:
array_init(return_value);
break;
case PHP_PQRES_FETCH_OBJECT:
object_init(return_value);
break;
}
for (r = 0, rows = PQntuples(obj->intern->res); r < rows; ++r) {
int k, v;
zval *ptr;
cur = return_value;
for (k = 0; k < ks; ++k) {
char *key = PQgetvalue(obj->intern->res, r, keys[k].num);
int len = PQgetlength(obj->intern->res, r, keys[k].num);
if (!(ptr = zend_symtable_str_find(HASH_OF(cur), key, len))) {
zval tmp;
switch (fetch_type) {
case PHP_PQRES_FETCH_ARRAY:
case PHP_PQRES_FETCH_ASSOC:
array_init(&tmp);
break;
case PHP_PQRES_FETCH_OBJECT:
object_init(&tmp);
break;
}
if (!(ptr = zend_symtable_str_update(HASH_OF(cur), key, len, &tmp))) {
throw_exce(EX_RUNTIME, "Failed to create map");
goto err;
}
cur = ptr;
}
cur = ptr;
}
if (vals && vs) {
for (v = 0; v < vs; ++v) {
char *val = PQgetvalue(obj->intern->res, r, vals[v].num);
int len = PQgetlength(obj->intern->res, r, vals[v].num);
switch (fetch_type) {
case PHP_PQRES_FETCH_ARRAY:
add_index_stringl(cur, vals[v].num, val, len);
break;
case PHP_PQRES_FETCH_ASSOC:
add_assoc_stringl(cur, vals[v].name, val, len);
break;
case PHP_PQRES_FETCH_OBJECT:
add_property_stringl(cur, vals[v].name, val, len);
break;
}
}
} else {
php_pqres_row_to_zval(obj->intern->res, r, fetch_type, cur);
}
}
}
err:
if (keys && keys != &def) {
efree(keys);
}
if (vals) {
efree(vals);
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_all, 0, 0, 0)
ZEND_ARG_INFO(0, fetch_type)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqres, fetchAll) {
zend_error_handling zeh;
zend_long fetch_type = -1;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &fetch_type);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
} else {
int r, rows = PQntuples(obj->intern->res);
zval tmp;
if (fetch_type == -1) {
fetch_type = php_pqres_fetch_type(obj->intern);
}
array_init(return_value);
for (r = 0; r < rows; ++r) {
ZVAL_NULL(&tmp);
add_next_index_zval(return_value, php_pqres_row_to_zval(obj->intern->res, r, fetch_type, &tmp));
}
}
}
}
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_pqres_count, 0, 0, IS_LONG, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqres, count) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
zend_long count;
if (SUCCESS != php_pqres_count_elements_ex(Z_OBJ_P(getThis()), &count)) {
throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
} else {
RETVAL_LONG(count);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqres_desc, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqres, desc) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
} else {
int p, params;
array_init(return_value);
for (p = 0, params = PQnparams(obj->intern->res); p < params; ++p) {
add_next_index_long(return_value, PQparamtype(obj->intern->res, p));
}
}
}
}
#if PHP_VERSION_ID >= 80000
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(ai_pqres_getIterator, 0, 0, Traversable, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqres, getIterator)
{
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
} else {
zend_create_internal_iterator_zval(return_value, getThis());
}
}
}
#endif
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, fetchAll, ai_pqres_fetch_all, ZEND_ACC_PUBLIC)
PHP_ME(pqres, fetchAllCols, ai_pqres_fetch_all_cols, ZEND_ACC_PUBLIC)
PHP_ME(pqres, count, ai_pqres_count, ZEND_ACC_PUBLIC)
PHP_ME(pqres, map, ai_pqres_map, ZEND_ACC_PUBLIC)
PHP_ME(pqres, desc, ai_pqres_desc, ZEND_ACC_PUBLIC)
#if PHP_VERSION_ID >= 80000
PHP_ME(pqres, getIterator, ai_pqres_getIterator, ZEND_ACC_PUBLIC)
#endif
{0}
};
PHP_MSHUTDOWN_FUNCTION(pqres)
{
zend_hash_destroy(&php_pqres_object_prophandlers);
return SUCCESS;
}
PHP_MINIT_FUNCTION(pqres)
{
zend_class_entry ce = {0};
php_pq_object_prophandler_t ph = {0};
INIT_NS_CLASS_ENTRY(ce, "pq", "Result", php_pqres_methods);
php_pqres_class_entry = zend_register_internal_class_ex(&ce, NULL);
php_pqres_class_entry->create_object = php_pqres_create_object;
php_pqres_class_entry->get_iterator = php_pqres_iterator_init;
#if PHP_VERSION_ID >= 80000
zend_class_implements(php_pqres_class_entry, 2, zend_ce_aggregate, zend_ce_countable);
#else
zend_class_implements(php_pqres_class_entry, 2, zend_ce_traversable, zend_ce_countable);
#endif
memcpy(&php_pqres_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
php_pqres_object_handlers.offset = XtOffsetOf(php_pqres_object_t, zo);
php_pqres_object_handlers.free_obj = php_pqres_object_free;
php_pqres_object_handlers.read_property = php_pq_object_read_prop;
php_pqres_object_handlers.write_property = php_pq_object_write_prop;
php_pqres_object_handlers.clone_obj = NULL;
php_pqres_object_handlers.get_property_ptr_ptr = php_pq_object_get_prop_ptr_null;
php_pqres_object_handlers.get_gc = php_pq_object_get_gc;
php_pqres_object_handlers.get_debug_info = php_pq_object_debug_info;
php_pqres_object_handlers.get_properties = php_pq_object_properties;
php_pqres_object_handlers.count_elements = php_pqres_count_elements;
zend_hash_init(&php_pqres_object_prophandlers, 9, NULL, php_pq_object_prophandler_dtor, 1);
zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("status"), ZEND_ACC_PUBLIC);
ph.read = php_pqres_object_read_status;
zend_hash_str_add_mem(&php_pqres_object_prophandlers, "status", sizeof("status")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("statusMessage"), ZEND_ACC_PUBLIC);
ph.read = php_pqres_object_read_status_message;
zend_hash_str_add_mem(&php_pqres_object_prophandlers, "statusMessage", sizeof("statusMessage")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC);
ph.read = php_pqres_object_read_error_message;
zend_hash_str_add_mem(&php_pqres_object_prophandlers, "errorMessage", sizeof("errorMessage")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("diag"), ZEND_ACC_PUBLIC);
ph.read = php_pqres_object_read_diag;
zend_hash_str_add_mem(&php_pqres_object_prophandlers, "diag", sizeof("diag")-1, (void *) &ph, sizeof(ph));
zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC);
ph.read = php_pqres_object_read_num_rows;
zend_hash_str_add_mem(&php_pqres_object_prophandlers, "numRows", sizeof("numRows")-1, (void *) &ph, sizeof(ph));
zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC);
ph.read = php_pqres_object_read_num_cols;
zend_hash_str_add_mem(&php_pqres_object_prophandlers, "numCols", sizeof("numCols")-1, (void *) &ph, sizeof(ph));
zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC);
ph.read = php_pqres_object_read_affected_rows;
zend_hash_str_add_mem(&php_pqres_object_prophandlers, "affectedRows", sizeof("affectedRows")-1, (void *) &ph, sizeof(ph));
zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY, ZEND_ACC_PUBLIC);
ph.read = php_pqres_object_read_fetch_type;
ph.write = php_pqres_object_write_fetch_type;
zend_hash_str_add_mem(&php_pqres_object_prophandlers, "fetchType", sizeof("fetchType")-1, (void *) &ph, sizeof(ph));
ph.write = NULL;
zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("autoConvert"), PHP_PQRES_CONV_ALL, ZEND_ACC_PUBLIC);
ph.read = php_pqres_object_read_auto_conv;
ph.write = php_pqres_object_write_auto_conv;
zend_hash_str_add_mem(&php_pqres_object_prophandlers, "autoConvert", sizeof("autoConvert")-1, (void *) &ph, sizeof(ph));
ph.write = NULL;
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_IN"), PGRES_COPY_IN);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR);
#ifdef HAVE_PGRES_COPY_BOTH
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH);
#endif
#ifdef HAVE_PGRES_SINGLE_TUPLE
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE);
#endif
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_BOOL"), PHP_PQRES_CONV_BOOL);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_INT"), PHP_PQRES_CONV_INT);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_FLOAT"), PHP_PQRES_CONV_FLOAT);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_SCALAR"), PHP_PQRES_CONV_SCALAR);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ARRAY"), PHP_PQRES_CONV_ARRAY);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_DATETIME"), PHP_PQRES_CONV_DATETIME);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_JSON"), PHP_PQRES_CONV_JSON);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_BYTEA"), PHP_PQRES_CONV_BYTEA);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ALL"), PHP_PQRES_CONV_ALL);
return SUCCESS;
}
/*
* 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
*/
pq-2.2.3/src/php_pqres.h 0000644 0000765 0000024 00000004632 14560227740 013723 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifndef PHP_PQRES_H
#define PHP_PQRES_H
#include "php_pqconn.h"
typedef enum php_pqres_fetch {
PHP_PQRES_FETCH_ARRAY,
PHP_PQRES_FETCH_ASSOC,
PHP_PQRES_FETCH_OBJECT
} php_pqres_fetch_t;
#define PHP_PQRES_CONV_BOOL 0x0001
#define PHP_PQRES_CONV_INT 0x0002
#define PHP_PQRES_CONV_FLOAT 0x0004
#define PHP_PQRES_CONV_BYTEA 0x0008
#define PHP_PQRES_CONV_SCALAR 0x000f
#define PHP_PQRES_CONV_ARRAY 0x0010
#define PHP_PQRES_CONV_DATETIME 0x0020
#define PHP_PQRES_CONV_JSON 0x0100
#define PHP_PQRES_CONV_ALL 0xffff
typedef struct php_pqres_iterator {
zend_object_iterator zi;
zval current_val;
unsigned index;
php_pqres_fetch_t fetch_type;
} php_pqres_iterator_t;
typedef struct php_pqres {
PGresult *res;
php_pqres_iterator_t *iter;
HashTable bound;
HashTable converters;
unsigned auto_convert;
php_pqres_fetch_t default_fetch_type;
} php_pqres_t;
typedef struct php_pqres_object {
PHP_PQ_OBJ_DECL(php_pqres_t *)
} php_pqres_object_t;
extern ZEND_RESULT_CODE php_pqres_success(PGresult *res);
extern php_pqres_object_t *php_pqres_init_instance_data(PGresult *res, php_pqconn_object_t *obj);
extern zval *php_pqres_row_to_zval(PGresult *res, unsigned row, php_pqres_fetch_t fetch_type, zval *data);
extern zval *php_pqres_typed_zval(php_pqres_t *res, Oid typ, zval *zv);
extern php_pqres_fetch_t php_pqres_fetch_type(php_pqres_t *res);
#include "php_pq_object.h"
#include "php_pqconn_event.h"
extern zend_class_entry *php_pqres_class_entry;
extern php_pqres_object_t *php_pqres_create_object_ex(zend_class_entry *ce, php_pqres_t *intern);
extern PHP_MINIT_FUNCTION(pqres);
extern PHP_MSHUTDOWN_FUNCTION(pqres);
#endif
/*
* 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
*/
pq-2.2.3/src/php_pqstm.c 0000644 0000765 0000024 00000042765 14560227740 013741 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include
#include
#include "php_pq.h"
#include "php_pq_misc.h"
#include "php_pq_object.h"
#include "php_pqexc.h"
#include "php_pqconn.h"
#include "php_pqres.h"
#include "php_pqstm.h"
zend_class_entry *php_pqstm_class_entry;
static zend_object_handlers php_pqstm_object_handlers;
static HashTable php_pqstm_object_prophandlers;
static void php_pqstm_deallocate(php_pqstm_object_t *obj, zend_bool async, zend_bool silent)
{
if (obj->intern->allocated) {
char *quoted_name = PQescapeIdentifier(obj->intern->conn->intern->conn, obj->intern->name, strlen(obj->intern->name));
if (quoted_name) {
smart_str cmd = {0};
smart_str_appends(&cmd, "DEALLOCATE ");
smart_str_appends(&cmd, quoted_name);
smart_str_0(&cmd);
if (async) {
if (PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd))) {
obj->intern->conn->intern->poller = PQconsumeInput;
php_pqconn_notify_listeners(obj->intern->conn);
} else if (!silent) {
throw_exce(EX_IO, "Failed to deallocate statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
}
} else {
PGresult *res;
if ((res = php_pq_exec(obj->intern->conn->intern->conn, smart_str_v(&cmd)))) {
php_pqres_clear(res);
} else if (!silent) {
throw_exce(EX_RUNTIME, "Failed to deallocate statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
}
}
PQfreemem(quoted_name);
smart_str_free(&cmd);
}
obj->intern->allocated = 0;
zend_hash_str_del(&obj->intern->conn->intern->statements, obj->intern->name, strlen(obj->intern->name));
}
}
static void php_pqstm_object_free(zend_object *o)
{
php_pqstm_object_t *obj = PHP_PQ_OBJ(NULL, o);
#if DBG_GC
fprintf(stderr, "FREE stm(#%d) %p (conn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->conn->zo.handle, obj->intern->conn);
#endif
if (obj->intern) {
if (obj->intern->conn->intern) {
php_pq_callback_dtor(&obj->intern->conn->intern->onevent);
php_pqstm_deallocate(obj, 0, 1);
php_pq_object_delref(obj->intern->conn);
}
efree(obj->intern->name);
efree(obj->intern->query);
zend_hash_destroy(&obj->intern->bound);
if (obj->intern->params) {
php_pq_params_free(&obj->intern->params);
}
efree(obj->intern);
obj->intern = NULL;
}
php_pq_object_dtor(o);
}
php_pqstm_object_t *php_pqstm_create_object_ex(zend_class_entry *ce, php_pqstm_t *intern)
{
return php_pq_object_create(ce, intern, sizeof(php_pqstm_object_t),
&php_pqstm_object_handlers, &php_pqstm_object_prophandlers);
}
static zend_object *php_pqstm_create_object(zend_class_entry *class_type)
{
return &php_pqstm_create_object_ex(class_type, NULL)->zo;
}
static void php_pqstm_object_read_name(void *o, zval *return_value)
{
php_pqstm_object_t *obj = o;
RETVAL_STRING(obj->intern->name);
}
static void php_pqstm_object_read_connection(void *o, zval *return_value)
{
php_pqstm_object_t *obj = o;
php_pq_object_to_zval(obj->intern->conn, return_value);
}
static void php_pqstm_object_gc_connection(void *o, zval *return_value)
{
php_pqstm_object_t *obj = o;
zval zconn;
php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn);
add_next_index_zval(return_value, &zconn);
}
static void php_pqstm_object_read_query(void *o, zval *return_value)
{
php_pqstm_object_t *obj = o;
RETVAL_STRING(obj->intern->query);
}
static void php_pqstm_object_read_types(void *o, zval *return_value)
{
int i;
php_pqstm_object_t *obj = o;
array_init_size(return_value, obj->intern->params->type.count);
for (i = 0; i < obj->intern->params->type.count; i++) {
add_next_index_long(return_value, (long)obj->intern->params->type.oids[i]);
}
}
php_pqstm_t *php_pqstm_init(php_pqconn_object_t *conn, const char *name, const char *query, php_pq_params_t *params)
{
php_pqstm_t *stm = ecalloc(1, sizeof(*stm));
php_pq_object_addref(conn);
stm->conn = conn;
stm->name = estrdup(name);
stm->params = params;
stm->query = estrdup(query);
stm->allocated = 1;
ZEND_INIT_SYMTABLE(&stm->bound);
zend_hash_str_add_ptr(&conn->intern->statements, name, strlen(name), stm);
return stm;
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_construct, 0, 0, 3)
ZEND_ARG_OBJ_INFO(0, connection, pq\\Connection, 0)
ZEND_ARG_INFO(0, name)
ZEND_ARG_INFO(0, query)
ZEND_ARG_ARRAY_INFO(0, types, 1)
ZEND_ARG_INFO(0, async)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqstm, __construct) {
zend_error_handling zeh;
zval *zconn, *ztypes = NULL;
char *name_str, *query_str;
size_t name_len, *query_len;
zend_bool async = 0;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "Oss|a/!b", &zconn, php_pqconn_class_entry, &name_str, &name_len, &query_str, &query_len, &ztypes, &async);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
php_pqconn_object_t *conn_obj = PHP_PQ_OBJ(zconn, NULL);
if (obj->intern) {
throw_exce(EX_BAD_METHODCALL, "pq\\Statement already initialized");
} else if (!conn_obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
php_pq_params_t *params = php_pq_params_init(&conn_obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, NULL);
if (async) {
rv = php_pqconn_prepare_async(zconn, conn_obj, name_str, query_str, params);
} else {
rv = php_pqconn_prepare(zconn, conn_obj, name_str, query_str, params);
}
if (SUCCESS == rv) {
obj->intern = php_pqstm_init(conn_obj, name_str, query_str, params);
}
}
}
}
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) {
zend_long param_no;
zval *param_ref;
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "lz", ¶m_no, ¶m_ref);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized");
} else if (!obj->intern->allocated) {
throw_exce(EX_UNINITIALIZED, "pq\\Statement has been deallocated");
} else {
Z_ADDREF_P(param_ref);
zend_hash_index_update(&obj->intern->bound, param_no, param_ref);
zend_hash_sort(&obj->intern->bound, php_pq_compare_index, 0);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec, 0, 0, 0)
ZEND_ARG_ARRAY_INFO(0, params, 1)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqstm, exec) {
zend_error_handling zeh;
zval *zparams = NULL;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|a/!", &zparams);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized");
} else if (!obj->intern->allocated) {
throw_exce(EX_UNINITIALIZED, "pq\\Statement has been deallocated");
} else {
PGresult *res;
php_pq_params_set_params(obj->intern->params, zparams ? Z_ARRVAL_P(zparams) : &obj->intern->bound);
res = php_pq_exec_prepared(obj->intern->conn->intern->conn, obj->intern->name, obj->intern->params->param.count, (const char *const*) obj->intern->params->param.strings, NULL, NULL, 0);
php_pq_params_set_params(obj->intern->params, NULL);
if (!res) {
throw_exce(EX_RUNTIME, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else if (SUCCESS == php_pqres_success(res)) {
php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), return_value);
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec_async, 0, 0, 0)
ZEND_ARG_ARRAY_INFO(0, params, 1)
ZEND_ARG_INFO(0, callable)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqstm, execAsync) {
zend_error_handling zeh;
zval *zparams = NULL;
php_pq_callback_t resolver = PHP_PQ_CALLBACK_INIT;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|a/!f", &zparams, &resolver.fci, &resolver.fcc);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized");
} else if (!obj->intern->allocated) {
throw_exce(EX_UNINITIALIZED, "pq\\Statement has been deallocated");
} else {
int rc;
php_pq_params_set_params(obj->intern->params, zparams ? Z_ARRVAL_P(zparams) : &obj->intern->bound);
rc = PQsendQueryPrepared(obj->intern->conn->intern->conn, obj->intern->name, obj->intern->params->param.count, (const char *const*) obj->intern->params->param.strings, NULL, NULL, 0);
php_pq_params_set_params(obj->intern->params, NULL);
if (!rc) {
throw_exce(EX_IO, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
#if HAVE_PQSETSINGLEROWMODE
} else if (obj->intern->conn->intern->unbuffered && !PQsetSingleRowMode(obj->intern->conn->intern->conn)) {
throw_exce(EX_RUNTIME, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
#endif
} else {
php_pq_callback_recurse(&obj->intern->conn->intern->onevent, &resolver);
obj->intern->conn->intern->poller = PQconsumeInput;
}
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqstm, desc) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized");
} else if (!obj->intern->allocated) {
throw_exce(EX_UNINITIALIZED, "pq\\Statement has been deallocated");
} else {
PGresult *res = PQdescribePrepared(obj->intern->conn->intern->conn, obj->intern->name);
if (!res) {
throw_exce(EX_RUNTIME, "Failed to describe statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
if (SUCCESS == php_pqres_success(res)) {
int p, params;
array_init(return_value);
for (p = 0, params = PQnparams(res); p < params; ++p) {
add_next_index_long(return_value, PQparamtype(res, p));
}
}
php_pqres_clear(res);
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc_async, 0, 0, 1)
ZEND_ARG_INFO(0, callable)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqstm, descAsync) {
zend_error_handling zeh;
php_pq_callback_t resolver = PHP_PQ_CALLBACK_INIT;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "f", &resolver.fci, &resolver.fcc);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized");
} else if (!obj->intern->allocated) {
throw_exce(EX_UNINITIALIZED, "pq\\Statement has been deallocated");
} else if (!PQsendDescribePrepared(obj->intern->conn->intern->conn, obj->intern->name)) {
throw_exce(EX_IO, "Failed to describe statement: %s", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
php_pq_callback_recurse(&obj->intern->conn->intern->onevent, &resolver);
obj->intern->conn->intern->poller = PQconsumeInput;
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
static zend_always_inline void php_pqstm_deallocate_handler(INTERNAL_FUNCTION_PARAMETERS, zend_bool async)
{
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (rv == SUCCESS) {
php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized");
} else {
php_pqstm_deallocate(obj, async, 0);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_deallocate, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqstm, deallocate)
{
php_pqstm_deallocate_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_deallocate_async, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqstm, deallocateAsync)
{
php_pqstm_deallocate_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
}
static inline void php_pqstm_prepare_handler(INTERNAL_FUNCTION_PARAMETERS, zend_bool async)
{
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (rv == SUCCESS) {
php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized");
} else if (!obj->intern->allocated) {
if (async) {
rv = php_pqconn_prepare_async(NULL, obj->intern->conn, obj->intern->name, obj->intern->query, obj->intern->params);
} else {
rv = php_pqconn_prepare(NULL, obj->intern->conn, obj->intern->name, obj->intern->query, obj->intern->params);
}
if (SUCCESS == rv) {
obj->intern->allocated = 1;
zend_hash_str_add_ptr(&obj->intern->conn->intern->statements,
obj->intern->name, strlen(obj->intern->name), obj->intern);
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_prepare, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqstm, prepare)
{
php_pqstm_prepare_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_prepare_async, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqstm, prepareAsync)
{
php_pqstm_prepare_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
}
static zend_function_entry php_pqstm_methods[] = {
PHP_ME(pqstm, __construct, ai_pqstm_construct, ZEND_ACC_PUBLIC)
PHP_ME(pqstm, bind, ai_pqstm_bind, ZEND_ACC_PUBLIC)
PHP_ME(pqstm, deallocate, ai_pqstm_deallocate, ZEND_ACC_PUBLIC)
PHP_ME(pqstm, deallocateAsync, ai_pqstm_deallocate_async, ZEND_ACC_PUBLIC)
PHP_ME(pqstm, desc, ai_pqstm_desc, ZEND_ACC_PUBLIC)
PHP_ME(pqstm, descAsync, ai_pqstm_desc_async, ZEND_ACC_PUBLIC)
PHP_ME(pqstm, exec, ai_pqstm_exec, ZEND_ACC_PUBLIC)
PHP_ME(pqstm, execAsync, ai_pqstm_exec_async, ZEND_ACC_PUBLIC)
PHP_ME(pqstm, prepare, ai_pqstm_prepare, ZEND_ACC_PUBLIC)
PHP_ME(pqstm, prepareAsync, ai_pqstm_prepare_async, ZEND_ACC_PUBLIC)
{0}
};
PHP_MSHUTDOWN_FUNCTION(pqstm)
{
zend_hash_destroy(&php_pqstm_object_prophandlers);
return SUCCESS;
}
PHP_MINIT_FUNCTION(pqstm)
{
zend_class_entry ce = {0};
php_pq_object_prophandler_t ph = {0};
INIT_NS_CLASS_ENTRY(ce, "pq", "Statement", php_pqstm_methods);
php_pqstm_class_entry = zend_register_internal_class_ex(&ce, NULL);
php_pqstm_class_entry->create_object = php_pqstm_create_object;
memcpy(&php_pqstm_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
php_pqstm_object_handlers.offset = XtOffsetOf(php_pqstm_object_t, zo);
php_pqstm_object_handlers.free_obj = php_pqstm_object_free;
php_pqstm_object_handlers.read_property = php_pq_object_read_prop;
php_pqstm_object_handlers.write_property = php_pq_object_write_prop;
php_pqstm_object_handlers.clone_obj = NULL;
php_pqstm_object_handlers.get_property_ptr_ptr = php_pq_object_get_prop_ptr_null;
php_pqstm_object_handlers.get_gc = php_pq_object_get_gc;
php_pqstm_object_handlers.get_properties = php_pq_object_properties;
php_pqstm_object_handlers.get_debug_info = php_pq_object_debug_info;
zend_hash_init(&php_pqstm_object_prophandlers, 4, NULL, php_pq_object_prophandler_dtor, 1);
zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("name"), ZEND_ACC_PUBLIC);
ph.read = php_pqstm_object_read_name;
zend_hash_str_add_mem(&php_pqstm_object_prophandlers, "name", sizeof("name")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC);
ph.read = php_pqstm_object_read_connection;
ph.gc = php_pqstm_object_gc_connection;
zend_hash_str_add_mem(&php_pqstm_object_prophandlers, "connection", sizeof("connection")-1, (void *) &ph, sizeof(ph));
ph.gc = NULL;
zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("query"), ZEND_ACC_PUBLIC);
ph.read = php_pqstm_object_read_query;
zend_hash_str_add_mem(&php_pqstm_object_prophandlers, "query", sizeof("query")-1, (void *) &ph, sizeof(ph));
zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("types"), ZEND_ACC_PUBLIC);
ph.read = php_pqstm_object_read_types;
zend_hash_str_add_mem(&php_pqstm_object_prophandlers, "types", sizeof("types")-1, (void *) &ph, sizeof(ph));
return SUCCESS;
}
/*
* 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
*/
pq-2.2.3/src/php_pqstm.h 0000644 0000765 0000024 00000002724 14560227740 013735 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifndef PHP_PQSTM_H
#define PHP_PQSTM_H
#include "php_pqconn.h"
typedef struct php_pqstm {
php_pqconn_object_t *conn;
char *name;
HashTable bound;
php_pq_params_t *params;
char *query;
unsigned allocated:1;
} php_pqstm_t;
typedef struct php_pqstm_object {
PHP_PQ_OBJ_DECL(php_pqstm_t *)
} php_pqstm_object_t;
extern zend_class_entry *php_pqstm_class_entry;
extern php_pqstm_object_t *php_pqstm_create_object_ex(zend_class_entry *ce, php_pqstm_t *intern);
extern php_pqstm_t *php_pqstm_init(php_pqconn_object_t *conn, const char *name, const char *query, php_pq_params_t *params);
extern PHP_MINIT_FUNCTION(pqstm);
extern PHP_MSHUTDOWN_FUNCTION(pqstm);
#endif
/*
* 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
*/
pq-2.2.3/src/php_pqtxn.c 0000644 0000765 0000024 00000070625 14560227740 013743 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include
#include
#include
#include
#include "php_pq.h"
#include "php_pq_misc.h"
#include "php_pq_object.h"
#include "php_pqexc.h"
#include "php_pqres.h"
#include "php_pqlob.h"
#include "php_pqtxn.h"
zend_class_entry *php_pqtxn_class_entry;
static zend_object_handlers php_pqtxn_object_handlers;
static HashTable php_pqtxn_object_prophandlers;
const char *php_pq_isolation_level(long *isolation)
{
switch (*isolation) {
case PHP_PQTXN_SERIALIZABLE:
return "SERIALIZABLE";
case PHP_PQTXN_REPEATABLE_READ:
return "REPEATABLE READ";
default:
*isolation = PHP_PQTXN_READ_COMMITTED;
/* no break */
case PHP_PQTXN_READ_COMMITTED:
return "READ COMMITTED";
}
}
static void php_pqtxn_object_free(zend_object *o)
{
php_pqtxn_object_t *obj = PHP_PQ_OBJ(NULL, o);
#if DBG_GC
fprintf(stderr, "FREE txn(#%d) %p (conn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->conn->zo.handle, obj->intern->conn);
#endif
if (obj->intern) {
if (obj->intern->open && obj->intern->conn->intern) {
PGresult *res = php_pq_exec(obj->intern->conn->intern->conn, "ROLLBACK");
if (res) {
php_pqres_clear(res);
}
}
php_pq_object_delref(obj->intern->conn);
efree(obj->intern);
obj->intern = NULL;
}
php_pq_object_dtor(o);
}
php_pqtxn_object_t *php_pqtxn_create_object_ex(zend_class_entry *ce, php_pqtxn_t *intern)
{
return php_pq_object_create(ce, intern, sizeof(php_pqtxn_object_t),
&php_pqtxn_object_handlers, &php_pqtxn_object_prophandlers);
}
static zend_object *php_pqtxn_create_object(zend_class_entry *class_type)
{
return &php_pqtxn_create_object_ex(class_type, NULL)->zo;
}
static void php_pqtxn_object_read_connection(void *o, zval *return_value)
{
php_pqtxn_object_t *obj = o;
php_pq_object_to_zval(obj->intern->conn, return_value);
}
static void php_pqtxn_object_gc_connection(void *o, zval *return_value)
{
php_pqtxn_object_t *obj = o;
zval zconn;
php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn);
add_next_index_zval(return_value, &zconn);
}
static void php_pqtxn_object_read_isolation(void *o, zval *return_value)
{
php_pqtxn_object_t *obj = o;
RETVAL_LONG(obj->intern->isolation);
}
static void php_pqtxn_object_read_readonly(void *o, zval *return_value)
{
php_pqtxn_object_t *obj = o;
RETVAL_BOOL(obj->intern->readonly);
}
static void php_pqtxn_object_read_deferrable(void *o, zval *return_value)
{
php_pqtxn_object_t *obj = o;
RETVAL_BOOL(obj->intern->deferrable);
}
static void php_pqtxn_object_write_isolation(void *o, zval *value)
{
php_pqtxn_object_t *obj = o;
php_pqtxn_isolation_t orig = obj->intern->isolation;
PGresult *res;
switch ((obj->intern->isolation = zval_get_long(value))) {
case PHP_PQTXN_READ_COMMITTED:
res = php_pq_exec(obj->intern->conn->intern->conn, "SET TRANSACTION ISOLATION LEVEL READ COMMITED");
break;
case PHP_PQTXN_REPEATABLE_READ:
res = php_pq_exec(obj->intern->conn->intern->conn, "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ");
break;
case PHP_PQTXN_SERIALIZABLE:
res = php_pq_exec(obj->intern->conn->intern->conn, "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
break;
default:
obj->intern->isolation = orig;
res = NULL;
break;
}
if (res) {
php_pqres_success(res);
php_pqres_clear(res);
}
}
static void php_pqtxn_object_write_readonly(void *o, zval *value)
{
php_pqtxn_object_t *obj = o;
PGresult *res;
if ((obj->intern->readonly = z_is_true(value))) {
res = php_pq_exec(obj->intern->conn->intern->conn, "SET TRANSACTION READ ONLY");
} else {
res = php_pq_exec(obj->intern->conn->intern->conn, "SET TRANSACTION READ WRITE");
}
if (res) {
php_pqres_success(res);
php_pqres_clear(res);
}
}
static void php_pqtxn_object_write_deferrable(void *o, zval *value)
{
php_pqtxn_object_t *obj = o;
PGresult *res;
if ((obj->intern->deferrable = z_is_true(value))) {
res = php_pq_exec(obj->intern->conn->intern->conn, "SET TRANSACTION DEFERRABLE");
} else {
res = php_pq_exec(obj->intern->conn->intern->conn, "SET TRANSACTION NOT DEFERRABLE");
}
if (res) {
php_pqres_success(res);
php_pqres_clear(res);
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_construct, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, connection, pq\\Connection, 0)
ZEND_ARG_INFO(0, async)
ZEND_ARG_INFO(0, isolation)
ZEND_ARG_INFO(0, readonly)
ZEND_ARG_INFO(0, deferrable)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtxn, __construct) {
zend_error_handling zeh;
zval *zconn;
zend_long isolation = PHP_PQTXN_READ_COMMITTED;
zend_bool async = 0, readonly = 0, deferrable = 0;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "O|blbb", &zconn, php_pqconn_class_entry, &async, &isolation, &readonly, &deferrable);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *conn_obj = PHP_PQ_OBJ(zconn, NULL);
if (!conn_obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
switch (ZEND_NUM_ARGS()) {
case 1:
case 2:
isolation = conn_obj->intern->default_txn_isolation;
/* no break */
case 3:
readonly = conn_obj->intern->default_txn_readonly;
/* no break */
case 4:
deferrable = conn_obj->intern->default_txn_deferrable;
break;
}
if (async) {
rv = php_pqconn_start_transaction_async(zconn, conn_obj, isolation, readonly, deferrable);
} else {
rv = php_pqconn_start_transaction(zconn, conn_obj, isolation, readonly, deferrable);
}
if (SUCCESS == rv) {
php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
obj->intern = ecalloc(1, sizeof(*obj->intern));
php_pq_object_addref(conn_obj);
obj->intern->conn = conn_obj;
obj->intern->open = 1;
obj->intern->isolation = isolation;
obj->intern->readonly = readonly;
obj->intern->deferrable = deferrable;
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_savepoint, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtxn, savepoint) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized");
} else if (!obj->intern->open) {
throw_exce(EX_RUNTIME, "pq\\Transaction already closed");
} else {
PGresult *res;
smart_str cmd = {0};
smart_str_appends(&cmd, "SAVEPOINT \"");
smart_str_append_unsigned(&cmd, ++obj->intern->savepoint);
smart_str_appends(&cmd, "\"");
smart_str_0(&cmd);
res = php_pq_exec(obj->intern->conn->intern->conn, smart_str_v(&cmd));
if (!res) {
throw_exce(EX_RUNTIME, "Failed to create %s (%s)", smart_str_v(&cmd), PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
php_pqres_success(res);
php_pqres_clear(res);
}
smart_str_free(&cmd);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_savepoint_async, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtxn, savepointAsync) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized");
} else if (!obj->intern->open) {
throw_exce(EX_RUNTIME, "pq\\Transaction already closed");
} else {
smart_str cmd = {0};
smart_str_appends(&cmd, "SAVEPOINT \"");
smart_str_append_unsigned(&cmd, ++obj->intern->savepoint);
smart_str_appends(&cmd, "\"");
smart_str_0(&cmd);
if (!PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd))) {
throw_exce(EX_IO, "Failed to create %s (%s)", smart_str_v(&cmd), PHP_PQerrorMessage(obj->intern->conn->intern->conn));
}
smart_str_free(&cmd);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtxn, commit) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Transacation not initialized");
} else if (!obj->intern->open) {
throw_exce(EX_RUNTIME, "pq\\Transaction already closed");
} else {
PGresult *res;
smart_str cmd = {0};
zend_bool just_release_sp = !!obj->intern->savepoint;
if (!just_release_sp) {
res = php_pq_exec(obj->intern->conn->intern->conn, "COMMIT");
} else {
smart_str_appends(&cmd, "RELEASE SAVEPOINT \"");
smart_str_append_unsigned(&cmd, obj->intern->savepoint--);
smart_str_appends(&cmd, "\"");
smart_str_0(&cmd);
res = php_pq_exec(obj->intern->conn->intern->conn, smart_str_v(&cmd));
}
if (!res) {
throw_exce(EX_RUNTIME, "Failed to %s (%s)", smart_str_l(&cmd) ? smart_str_v(&cmd) : "commit transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
if (SUCCESS == php_pqres_success(res)) {
if (!just_release_sp) {
obj->intern->open = 0;
}
}
php_pqres_clear(res);
}
smart_str_free(&cmd);
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit_async, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtxn, commitAsync) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized");
} else if (!obj->intern->open) {
throw_exce(EX_RUNTIME, "pq\\Transaction already closed");
} else {
int rc;
smart_str cmd = {0};
zend_bool just_release_sp = !!obj->intern->savepoint;
if (!just_release_sp) {
rc = PQsendQuery(obj->intern->conn->intern->conn, "COMMIT");
} else {
smart_str_appends(&cmd, "RELEASE SAVEPOINT \"");
smart_str_append_unsigned(&cmd, obj->intern->savepoint--);
smart_str_appends(&cmd, "\"");
smart_str_0(&cmd);
rc = PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd));
}
if (!rc) {
throw_exce(EX_IO, "Failed to %s (%s)", smart_str_l(&cmd) ? smart_str_v(&cmd) : "commmit transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
if (!just_release_sp) {
obj->intern->open = 0;
}
obj->intern->conn->intern->poller = PQconsumeInput;
php_pqconn_notify_listeners(obj->intern->conn);
}
smart_str_free(&cmd);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtxn, rollback) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized");
} else if (!obj->intern->open) {
throw_exce(EX_RUNTIME, "pq\\Transaction already closed");
} else {
PGresult *res;
smart_str cmd = {0};
zend_bool just_release_sp = !!obj->intern->savepoint;
if (!just_release_sp) {
res = php_pq_exec(obj->intern->conn->intern->conn, "ROLLBACK");
} else {
smart_str_appends(&cmd, "ROLLBACK TO SAVEPOINT \"");
smart_str_append_unsigned(&cmd, obj->intern->savepoint--);
smart_str_appends(&cmd, "\"");
smart_str_0(&cmd);
res = php_pq_exec(obj->intern->conn->intern->conn, smart_str_v(&cmd));
}
if (!res) {
throw_exce(EX_RUNTIME, "Failed to %s (%s)", smart_str_l(&cmd) ? smart_str_v(&cmd) : "rollback transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
if (SUCCESS == php_pqres_success(res)) {
if (!just_release_sp) {
obj->intern->open = 0;
}
}
php_pqres_clear(res);
}
smart_str_free(&cmd);
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback_async, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtxn, rollbackAsync) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized");
} else if (!obj->intern->open) {
throw_exce(EX_RUNTIME, "pq\\Transaction already closed");
} else {
int rc;
smart_str cmd = {0};
zend_bool just_release_sp = !!obj->intern->savepoint;
if (!just_release_sp) {
rc = PQsendQuery(obj->intern->conn->intern->conn, "ROLLBACK");
} else {
smart_str_appends(&cmd, "ROLLBACK TO SAVEPOINT \"");
smart_str_append_unsigned(&cmd, obj->intern->savepoint--);
smart_str_appends(&cmd, "\"");
smart_str_0(&cmd);
rc = PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd));
}
if (!rc) {
throw_exce(EX_IO, "Failed to %s (%s)", smart_str_l(&cmd) ? smart_str_v(&cmd) : "rollback transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
if (!just_release_sp) {
obj->intern->open = 0;
}
obj->intern->conn->intern->poller = PQconsumeInput;
}
smart_str_free(&cmd);
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_export_snapshot, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtxn, exportSnapshot) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized");
} else {
PGresult *res = php_pq_exec(obj->intern->conn->intern->conn, "SELECT pg_export_snapshot()");
if (!res) {
throw_exce(EX_RUNTIME, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
if (SUCCESS == php_pqres_success(res)) {
RETVAL_STRING(PQgetvalue(res, 0, 0));
}
php_pqres_clear(res);
}
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_export_snapshot_async, 0, 0, 0)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtxn, exportSnapshotAsync) {
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized");
} else if (!PQsendQuery(obj->intern->conn->intern->conn, "SELECT pg_export_snapshot()")) {
throw_exce(EX_IO, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
obj->intern->conn->intern->poller = PQconsumeInput;
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_import_snapshot, 0, 0, 1)
ZEND_ARG_INFO(0, snapshot_id)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtxn, importSnapshot) {
zend_error_handling zeh;
char *snapshot_str;
size_t snapshot_len;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &snapshot_str, &snapshot_len);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized");
} else if (obj->intern->isolation < PHP_PQTXN_REPEATABLE_READ) {
throw_exce(EX_RUNTIME, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot");
} else {
char *sid = PQescapeLiteral(obj->intern->conn->intern->conn, snapshot_str, snapshot_len);
if (!sid) {
throw_exce(EX_ESCAPE, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
PGresult *res;
smart_str cmd = {0};
smart_str_appends(&cmd, "SET TRANSACTION SNAPSHOT ");
smart_str_appends(&cmd, sid);
smart_str_0(&cmd);
res = php_pq_exec(obj->intern->conn->intern->conn, smart_str_v(&cmd));
if (!res) {
throw_exce(EX_RUNTIME, "Failed to import transaction snapshot (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
php_pqres_success(res);
php_pqres_clear(res);
}
smart_str_free(&cmd);
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_import_snapshot_async, 0, 0, 1)
ZEND_ARG_INFO(0, snapshot_id)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtxn, importSnapshotAsync) {
zend_error_handling zeh;
char *snapshot_str;
size_t snapshot_len;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &snapshot_str, &snapshot_len);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized");
} else if (obj->intern->isolation < PHP_PQTXN_REPEATABLE_READ) {
throw_exce(EX_RUNTIME, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot");
} else {
char *sid = PQescapeLiteral(obj->intern->conn->intern->conn, snapshot_str, snapshot_len);
if (!sid) {
throw_exce(EX_ESCAPE, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
smart_str cmd = {0};
smart_str_appends(&cmd, "SET TRANSACTION SNAPSHOT ");
smart_str_appends(&cmd, sid);
smart_str_0(&cmd);
if (!PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd))) {
throw_exce(EX_IO, "Failed to %s (%s)", smart_str_v(&cmd), PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
obj->intern->conn->intern->poller = PQconsumeInput;
}
smart_str_free(&cmd);
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_open_lob, 0, 0, 1)
ZEND_ARG_INFO(0, oid)
ZEND_ARG_INFO(0, mode)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtxn, openLOB) {
zend_error_handling zeh;
zend_long mode = INV_WRITE|INV_READ, loid;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &loid, &mode);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized");
} else {
int lofd = lo_open(obj->intern->conn->intern->conn, loid, mode);
if (lofd < 0) {
throw_exce(EX_RUNTIME, "Failed to open large object with oid=%lu with mode '%s' (%s)", loid, php_pq_strmode(mode), PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
php_pqlob_t *lob = ecalloc(1, sizeof(*lob));
lob->lofd = lofd;
lob->loid = loid;
php_pq_object_addref(obj);
lob->txn = obj;
RETVAL_OBJ(&php_pqlob_create_object_ex(php_pqlob_class_entry, lob)->zo);
}
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_create_lob, 0, 0, 0)
ZEND_ARG_INFO(0, mode)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtxn, createLOB) {
zend_error_handling zeh;
zend_long mode = INV_WRITE|INV_READ;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &mode);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized");
} else {
Oid loid = lo_creat(obj->intern->conn->intern->conn, mode);
if (loid == InvalidOid) {
throw_exce(EX_RUNTIME, "Failed to create large object with mode '%s' (%s)", php_pq_strmode(mode), PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
int lofd = lo_open(obj->intern->conn->intern->conn, loid, mode);
if (lofd < 0) {
throw_exce(EX_RUNTIME, "Failed to open large object with oid=%lu with mode '%s': %s", loid, php_pq_strmode(mode), PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
php_pqlob_t *lob = ecalloc(1, sizeof(*lob));
lob->lofd = lofd;
lob->loid = loid;
php_pq_object_addref(obj);
lob->txn = obj;
RETVAL_OBJ(&php_pqlob_create_object_ex(php_pqlob_class_entry, lob)->zo);
}
}
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_unlink_lob, 0, 0, 1)
ZEND_ARG_INFO(0, oid)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtxn, unlinkLOB) {
zend_error_handling zeh;
zend_long loid;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "l", &loid);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized");
} else {
int rc = lo_unlink(obj->intern->conn->intern->conn, loid);
if (rc != 1) {
throw_exce(EX_RUNTIME, "Failed to unlink LOB (oid=%lu): %s", loid, PHP_PQerrorMessage(obj->intern->conn->intern->conn));
}
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_import_lob, 0, 0, 1)
ZEND_ARG_INFO(0, local_path)
ZEND_ARG_INFO(0, oid)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtxn, importLOB) {
zend_error_handling zeh;
char *path_str;
size_t path_len;
zend_long oid = InvalidOid;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "p|l", &path_str, &path_len, &oid);
zend_restore_error_handling(&zeh);
if (rv == SUCCESS) {
php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized");
} else {
if (oid == InvalidOid) {
oid = lo_import(obj->intern->conn->intern->conn, path_str);
} else {
oid = lo_import_with_oid(obj->intern->conn->intern->conn, path_str, oid);
}
if (oid == InvalidOid) {
throw_exce(EX_RUNTIME, "Failed to import LOB from '%s' (%s)", path_str, PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
RETVAL_LONG(oid);
}
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_export_lob, 0, 0, 2)
ZEND_ARG_INFO(0, oid)
ZEND_ARG_INFO(0, local_path)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtxn, exportLOB) {
zend_error_handling zeh;
char *path_str;
size_t path_len;
zend_long oid;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "lp", &oid, &path_str, &path_len);
zend_restore_error_handling(&zeh);
if (rv == SUCCESS) {
php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized");
} else {
int rc = lo_export(obj->intern->conn->intern->conn, oid, path_str);
if (rc == -1) {
throw_exce(EX_RUNTIME, "Failed to export LOB (oid=%lu) to '%s' (%s)", oid, path_str, PHP_PQerrorMessage(obj->intern->conn->intern->conn));
}
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
static zend_function_entry php_pqtxn_methods[] = {
PHP_ME(pqtxn, __construct, ai_pqtxn_construct, ZEND_ACC_PUBLIC)
PHP_ME(pqtxn, commit, ai_pqtxn_commit, ZEND_ACC_PUBLIC)
PHP_ME(pqtxn, rollback, ai_pqtxn_rollback, ZEND_ACC_PUBLIC)
PHP_ME(pqtxn, commitAsync, ai_pqtxn_commit_async, ZEND_ACC_PUBLIC)
PHP_ME(pqtxn, rollbackAsync, ai_pqtxn_rollback_async, ZEND_ACC_PUBLIC)
PHP_ME(pqtxn, savepoint, ai_pqtxn_savepoint, ZEND_ACC_PUBLIC)
PHP_ME(pqtxn, savepointAsync, ai_pqtxn_savepoint_async, ZEND_ACC_PUBLIC)
PHP_ME(pqtxn, exportSnapshot, ai_pqtxn_export_snapshot, ZEND_ACC_PUBLIC)
PHP_ME(pqtxn, exportSnapshotAsync, ai_pqtxn_export_snapshot_async, ZEND_ACC_PUBLIC)
PHP_ME(pqtxn, importSnapshot, ai_pqtxn_import_snapshot, ZEND_ACC_PUBLIC)
PHP_ME(pqtxn, importSnapshotAsync, ai_pqtxn_import_snapshot_async, ZEND_ACC_PUBLIC)
PHP_ME(pqtxn, openLOB, ai_pqtxn_open_lob, ZEND_ACC_PUBLIC)
PHP_ME(pqtxn, createLOB, ai_pqtxn_create_lob, ZEND_ACC_PUBLIC)
PHP_ME(pqtxn, unlinkLOB, ai_pqtxn_unlink_lob, ZEND_ACC_PUBLIC)
PHP_ME(pqtxn, importLOB, ai_pqtxn_import_lob, ZEND_ACC_PUBLIC)
PHP_ME(pqtxn, exportLOB, ai_pqtxn_export_lob, ZEND_ACC_PUBLIC)
{0}
};
PHP_MSHUTDOWN_FUNCTION(pqtxn)
{
zend_hash_destroy(&php_pqtxn_object_prophandlers);
return SUCCESS;
}
PHP_MINIT_FUNCTION(pqtxn)
{
zend_class_entry ce = {0};
php_pq_object_prophandler_t ph = {0};
INIT_NS_CLASS_ENTRY(ce, "pq", "Transaction", php_pqtxn_methods);
php_pqtxn_class_entry = zend_register_internal_class_ex(&ce, NULL);
php_pqtxn_class_entry->create_object = php_pqtxn_create_object;
memcpy(&php_pqtxn_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
php_pqtxn_object_handlers.offset = XtOffsetOf(php_pqtxn_object_t, zo);
php_pqtxn_object_handlers.free_obj = php_pqtxn_object_free;
php_pqtxn_object_handlers.read_property = php_pq_object_read_prop;
php_pqtxn_object_handlers.write_property = php_pq_object_write_prop;
php_pqtxn_object_handlers.clone_obj = NULL;
php_pqtxn_object_handlers.get_property_ptr_ptr = php_pq_object_get_prop_ptr_null;
php_pqtxn_object_handlers.get_gc = php_pq_object_get_gc;
php_pqtxn_object_handlers.get_properties = php_pq_object_properties;
php_pqtxn_object_handlers.get_debug_info = php_pq_object_debug_info;
zend_hash_init(&php_pqtxn_object_prophandlers, 4, NULL, php_pq_object_prophandler_dtor, 1);
zend_declare_property_null(php_pqtxn_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC);
ph.read = php_pqtxn_object_read_connection;
ph.gc = php_pqtxn_object_gc_connection;
zend_hash_str_add_mem(&php_pqtxn_object_prophandlers, "connection", sizeof("connection")-1, (void *) &ph, sizeof(ph));
ph.gc = NULL;
zend_declare_property_null(php_pqtxn_class_entry, ZEND_STRL("isolation"), ZEND_ACC_PUBLIC);
ph.read = php_pqtxn_object_read_isolation;
ph.write = php_pqtxn_object_write_isolation;
zend_hash_str_add_mem(&php_pqtxn_object_prophandlers, "isolation", sizeof("isolation")-1, (void *) &ph, sizeof(ph));
zend_declare_property_bool(php_pqtxn_class_entry, ZEND_STRL("readonly"), 0, ZEND_ACC_PUBLIC);
ph.read = php_pqtxn_object_read_readonly;
ph.write = php_pqtxn_object_write_readonly;
zend_hash_str_add_mem(&php_pqtxn_object_prophandlers, "readonly", sizeof("readonly")-1, (void *) &ph, sizeof(ph));
zend_declare_property_bool(php_pqtxn_class_entry, ZEND_STRL("deferrable"), 0, ZEND_ACC_PUBLIC);
ph.read = php_pqtxn_object_read_deferrable;
ph.write = php_pqtxn_object_write_deferrable;
zend_hash_str_add_mem(&php_pqtxn_object_prophandlers, "deferrable", sizeof("deferrable")-1, (void *) &ph, sizeof(ph));
ph.write = NULL;
zend_declare_class_constant_long(php_pqtxn_class_entry, ZEND_STRL("READ_COMMITTED"), PHP_PQTXN_READ_COMMITTED);
zend_declare_class_constant_long(php_pqtxn_class_entry, ZEND_STRL("REPEATABLE_READ"), PHP_PQTXN_REPEATABLE_READ);
zend_declare_class_constant_long(php_pqtxn_class_entry, ZEND_STRL("SERIALIZABLE"), PHP_PQTXN_SERIALIZABLE);
return SUCCESS;
}
/*
* 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
*/
pq-2.2.3/src/php_pqtxn.h 0000644 0000765 0000024 00000003071 14560227740 013737 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifndef PHP_PQTXN_H
#define PHP_PQTXN_H
#include "php_pqconn.h"
typedef enum php_pqtxn_isolation {
PHP_PQTXN_READ_COMMITTED,
PHP_PQTXN_REPEATABLE_READ,
PHP_PQTXN_SERIALIZABLE,
} php_pqtxn_isolation_t;
typedef struct php_pqtxn {
php_pqconn_object_t *conn;
php_pqtxn_isolation_t isolation;
unsigned savepoint;
unsigned open:1;
unsigned readonly:1;
unsigned deferrable:1;
} php_pqtxn_t;
typedef struct php_pqtxn_object {
PHP_PQ_OBJ_DECL(php_pqtxn_t *)
} php_pqtxn_object_t;
extern const char *php_pq_isolation_level(long *isolation);
extern zend_class_entry *php_pqtxn_class_entry;
extern php_pqtxn_object_t *php_pqtxn_create_object_ex(zend_class_entry *ce, php_pqtxn_t *intern);
extern PHP_MINIT_FUNCTION(pqtxn);
extern PHP_MSHUTDOWN_FUNCTION(pqtxn);
#endif
/*
* 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
*/
pq-2.2.3/src/php_pqtypes.c 0000644 0000765 0000024 00000027156 14560227740 014277 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include
#include
#include "php_pq.h"
#include "php_pq_misc.h"
#include "php_pq_object.h"
#include "php_pqexc.h"
#include "php_pqres.h"
#include "php_pqtypes.h"
zend_class_entry *php_pqtypes_class_entry;
static zend_object_handlers php_pqtypes_object_handlers;
static HashTable php_pqtypes_object_prophandlers;
static void php_pqtypes_object_free(zend_object *o)
{
php_pqtypes_object_t *obj = PHP_PQ_OBJ(NULL, o);
#if DBG_GC
fprintf(stderr, "FREE types(#%d) %p (conn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->conn->zo.handle, obj->intern->conn);
#endif
if (obj->intern) {
zend_hash_destroy(&obj->intern->types);
php_pq_object_delref(obj->intern->conn);
efree(obj->intern);
obj->intern = NULL;
}
php_pq_object_dtor(o);
}
php_pqtypes_object_t *php_pqtypes_create_object_ex(zend_class_entry *ce, php_pqtypes_t *intern)
{
return php_pq_object_create(ce, intern, sizeof(php_pqtypes_object_t),
&php_pqtypes_object_handlers, &php_pqtypes_object_prophandlers);
}
static zend_object *php_pqtypes_create_object(zend_class_entry *class_type)
{
return &php_pqtypes_create_object_ex(class_type, NULL)->zo;
}
static void php_pqtypes_object_read_connection(void *o, zval *return_value)
{
php_pqtypes_object_t *obj = o;
php_pq_object_to_zval(obj->intern->conn, return_value);
}
static void php_pqtypes_object_gc_connection(void *o, zval *return_value)
{
php_pqtypes_object_t *obj = o;
zval zconn;
php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn);
add_next_index_zval(return_value, &zconn);
}
static inline int has_dimension(HashTable *ht, zval *member, zend_string **key, zend_long *index)
{
if (Z_TYPE_P(member) == IS_LONG) {
*index = Z_LVAL_P(member);
check_index:
return zend_hash_index_exists(ht, *index);
} else {
zend_string *str = zval_get_string(member);
if (is_numeric_str_function(str, index, NULL)) {
zend_string_release(str);
goto check_index;
}
if (zend_hash_exists(ht, str)) {
*key = str;
return 1;
}
zend_string_release(str);
return 0;
}
}
static inline int php_pqtypes_object_has_dimension_ex(zend_object *object, zval *member, int check_empty)
{
php_pqtypes_object_t *obj = PHP_PQ_OBJ(NULL, object);
zend_string *key = NULL;
zend_long index = 0;
if (has_dimension(&obj->intern->types, member, &key, &index)) {
if (check_empty) {
zval *data;
if (key) {
if ((data = zend_hash_find(&obj->intern->types, key))) {
zend_string_release(key);
return Z_TYPE_P(data) != IS_NULL;
}
zend_string_release(key);
} else if ((data = zend_hash_index_find(&obj->intern->types, index))) {
return Z_TYPE_P(data) != IS_NULL;
}
} else {
if (key) {
zend_string_release(key);
}
return 1;
}
}
return 0;
}
#if PHP_VERSION_ID >= 80000
static int php_pqtypes_object_has_dimension(zend_object *object, zval *member, int check_empty)
{
return php_pqtypes_object_has_dimension_ex(object, member, check_empty);
}
#else
static int php_pqtypes_object_has_dimension(zval *object, zval *member, int check_empty)
{
return php_pqtypes_object_has_dimension_ex(Z_OBJ_P(object), member, check_empty);
}
#endif
static inline zval *php_pqtypes_object_read_dimension_ex(zend_object *object, zval *member, int type, zval *rv)
{
php_pqtypes_object_t *obj = PHP_PQ_OBJ(NULL, object);
zend_string *key = NULL;
zend_long index = 0;
zval *data = NULL;
if (has_dimension(&obj->intern->types, member, &key, &index)) {
if (key) {
data = zend_hash_find(&obj->intern->types, key);
zend_string_release(key);
} else {
data = zend_hash_index_find(&obj->intern->types, index);
}
}
return data;
}
#if PHP_VERSION_ID >= 80000
static zval *php_pqtypes_object_read_dimension(zend_object *object, zval *member, int type, zval *rv)
{
return php_pqtypes_object_read_dimension_ex(object, member, type, rv);
}
#else
static zval *php_pqtypes_object_read_dimension(zval *object, zval *member, int type, zval *rv)
{
return php_pqtypes_object_read_dimension_ex(Z_OBJ_P(object), member, type, rv);
}
#endif
#if PHP_VERSION_ID >= 80000
static void php_pqtypes_object_write_dimension(zend_object *object, zval *offset, zval *value)
{
throw_exce(EX_RUNTIME, "pq\\Types object must not be modified");
}
#else
static void php_pqtypes_object_write_dimension(zval *object, zval *offset, zval *value)
{
throw_exce(EX_RUNTIME, "pq\\Types object must not be modified");
}
#endif
#if PHP_VERSION_ID >= 80000
static void php_pqtypes_object_unset_dimension(zend_object *object, zval *offset)
{
throw_exce(EX_RUNTIME, "pq\\Types object must not be modified");
}
#else
static void php_pqtypes_object_unset_dimension(zval *object, zval *offset)
{
throw_exce(EX_RUNTIME, "pq\\Types object must not be modified");
}
#endif
ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_construct, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, connection, pq\\Connection, 0)
ZEND_ARG_ARRAY_INFO(0, namespaces, 1)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtypes, __construct) {
zend_error_handling zeh;
zval *zconn, *znsp = NULL;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "O|a!", &zconn, php_pqconn_class_entry, &znsp);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqconn_object_t *conn_obj = PHP_PQ_OBJ(zconn, NULL);
if (!conn_obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
} else {
php_pqtypes_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
obj->intern = ecalloc(1, sizeof(*obj->intern));
obj->intern->conn = conn_obj;
php_pq_object_addref(conn_obj);
zend_hash_init(&obj->intern->types, 512, NULL, ZVAL_PTR_DTOR, 0);
if (znsp) {
php_pq_call_method(getThis(), "refresh", 1, NULL, znsp);
} else {
php_pq_call_method(getThis(), "refresh", 0, NULL);
}
}
}
}
#define PHP_PQ_TYPES_QUERY \
"select t.oid, t.typname, t.* " \
"from pg_type t join pg_namespace n on t.typnamespace=n.oid " \
"where typisdefined"
#ifndef PHP_PQ_OID_TEXT
# define PHP_PQ_OID_TEXT 25
#endif
static int apply_nsp(zval *zp, int argc, va_list argv, zend_hash_key *key)
{
unsigned pcount, tcount;
php_pq_params_t *params = va_arg(argv, php_pq_params_t *);
smart_str *str = va_arg(argv, smart_str *);
tcount = php_pq_params_add_type_oid(params, PHP_PQ_OID_TEXT);
pcount = php_pq_params_add_param(params, zp);
if (tcount != pcount) {
php_error_docref(NULL, E_WARNING, "Param/Type count mismatch");
return ZEND_HASH_APPLY_STOP;
}
if (pcount > 1) {
smart_str_appendc(str, ',');
}
smart_str_appendc(str, '$');
smart_str_append_unsigned(str, pcount);
return ZEND_HASH_APPLY_KEEP;
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_refresh, 0, 0, 0)
ZEND_ARG_ARRAY_INFO(0, namespaces, 1)
ZEND_END_ARG_INFO();
static PHP_METHOD(pqtypes, refresh) {
HashTable *nsp = NULL;
zend_error_handling zeh;
ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|H/!", &nsp);
zend_restore_error_handling(&zeh);
if (SUCCESS == rv) {
php_pqtypes_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
if (!obj->intern) {
throw_exce(EX_UNINITIALIZED, "pq\\Types not initialized");
} else {
PGresult *res;
if (!nsp || !zend_hash_num_elements(nsp)) {
res = php_pq_exec(obj->intern->conn->intern->conn, PHP_PQ_TYPES_QUERY " and nspname in ('public', 'pg_catalog')");
} else {
smart_str str = {0};
php_pq_params_t *params = php_pq_params_init(&obj->intern->conn->intern->converters, NULL, NULL);
smart_str_appends(&str, PHP_PQ_TYPES_QUERY " and nspname in(");
zend_hash_apply_with_arguments(nsp, apply_nsp, 2, params, &str);
smart_str_appendc(&str, ')');
smart_str_0(&str);
res = php_pq_exec_params(obj->intern->conn->intern->conn, smart_str_v(&str), params->param.count, params->type.oids, (const char *const*) params->param.strings, NULL, NULL, 0);
smart_str_free(&str);
php_pq_params_free(¶ms);
}
if (!res) {
throw_exce(EX_RUNTIME, "Failed to fetch types (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
} else {
if (SUCCESS == php_pqres_success(res)) {
int r, rows;
for (r = 0, rows = PQntuples(res); r < rows; ++r) {
zval tmp, *row;
ZVAL_NULL(&tmp);
row = php_pqres_row_to_zval(res, r, PHP_PQRES_FETCH_OBJECT, &tmp);
Z_ADDREF_P(row);
zend_hash_index_update(&obj->intern->types, atol(PQgetvalue(res, r, 0 )), row);
zend_hash_str_update(&obj->intern->types, PQgetvalue(res, r, 1), PQgetlength(res, r, 1), row);
}
}
php_pqres_clear(res);
php_pqconn_notify_listeners(obj->intern->conn);
}
}
}
}
static zend_function_entry php_pqtypes_methods[] = {
PHP_ME(pqtypes, __construct, ai_pqtypes_construct, ZEND_ACC_PUBLIC)
PHP_ME(pqtypes, refresh, ai_pqtypes_refresh, ZEND_ACC_PUBLIC)
{0}
};
PHP_MSHUTDOWN_FUNCTION(pqtypes)
{
zend_hash_destroy(&php_pqtypes_object_prophandlers);
return SUCCESS;
}
PHP_MINIT_FUNCTION(pqtypes)
{
zend_class_entry ce = {0};
php_pq_object_prophandler_t ph = {0};
INIT_NS_CLASS_ENTRY(ce, "pq", "Types", php_pqtypes_methods);
php_pqtypes_class_entry = zend_register_internal_class_ex(&ce, NULL);
php_pqtypes_class_entry->create_object = php_pqtypes_create_object;
/*
zend_class_implements(php_pqtypes_class_entry, 1, zend_ce_arrayaccess);
*/
memcpy(&php_pqtypes_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
php_pqtypes_object_handlers.offset = XtOffsetOf(php_pqtypes_object_t, zo);
php_pqtypes_object_handlers.free_obj = php_pqtypes_object_free;
php_pqtypes_object_handlers.read_property = php_pq_object_read_prop;
php_pqtypes_object_handlers.write_property = php_pq_object_write_prop;
php_pqtypes_object_handlers.clone_obj = NULL;
php_pqtypes_object_handlers.get_property_ptr_ptr = php_pq_object_get_prop_ptr_null;
php_pqtypes_object_handlers.get_gc = php_pq_object_get_gc;
php_pqtypes_object_handlers.get_properties = php_pq_object_properties;
php_pqtypes_object_handlers.get_debug_info = php_pq_object_debug_info;
php_pqtypes_object_handlers.has_dimension = php_pqtypes_object_has_dimension;
php_pqtypes_object_handlers.read_dimension = php_pqtypes_object_read_dimension;
php_pqtypes_object_handlers.unset_dimension = php_pqtypes_object_unset_dimension;
php_pqtypes_object_handlers.write_dimension = php_pqtypes_object_write_dimension;
zend_hash_init(&php_pqtypes_object_prophandlers, 1, NULL, php_pq_object_prophandler_dtor, 1);
zend_declare_property_null(php_pqtypes_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC);
ph.read = php_pqtypes_object_read_connection;
ph.gc = php_pqtypes_object_gc_connection;
zend_hash_str_add_mem(&php_pqtypes_object_prophandlers, "connection", sizeof("connection")-1, (void *) &ph, sizeof(ph));
ph.gc = NULL;
# undef PHP_PQ_TYPE
# define PHP_PQ_TYPE(name, oid) zend_declare_class_constant_long(php_pqtypes_class_entry, ZEND_STRL(name), oid);
# include "php_pq_type.h"
return SUCCESS;
}
/*
* 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
*/
pq-2.2.3/src/php_pqtypes.h 0000644 0000765 0000024 00000002444 14560227740 014275 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifndef PHP_PQTYPES_H
#define PHP_PQTYPES_H
#include "php_pqconn.h"
typedef struct php_pqtypes {
HashTable types;
php_pqconn_object_t *conn;
} php_pqtypes_t;
typedef struct php_pqtypes_object {
PHP_PQ_OBJ_DECL(php_pqtypes_t *)
} php_pqtypes_object_t;
extern zend_class_entry *php_pqtypes_class_entry;
extern php_pqtypes_object_t *php_pqtypes_create_object_ex(zend_class_entry *ce, php_pqtypes_t *intern);
extern PHP_MINIT_FUNCTION(pqtypes);
extern PHP_MSHUTDOWN_FUNCTION(pqtypes);
#endif
/*
* 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
*/
pq-2.2.3/tests/async001.phpt 0000644 0000765 0000024 00000001540 14560227740 014352 0 ustar mike staff --TEST--
async connect
--SKIPIF--
--FILE--
status);
echo "W";
$w = array($c->socket);
$r = $e = null;
stream_select($r, $w, $e, null);
while (true) {
$s[] = $c->status;
echo "P";
switch ($c->poll()) {
case pq\Connection::POLLING_READING:
echo "R";
$w = $e = null;
$r = array($c->socket);
stream_select($r, $w, $e, NULL);
break;
case pq\Connection::POLLING_WRITING:
echo "W";
$w = array($c->socket);
$r = $e = null;
stream_select($r, $w, $e, null);
break;
case pq\Connection::POLLING_FAILED:
echo "F";
break 2;
case pq\Connection::POLLING_OK:
echo "S";
break 2;
}
}
$s[] = $c->status;
printf("\n%s\n", implode(",", $s));
?>
DONE
--EXPECTREGEX--
Test
(WP(RP)*)+S
[23](,\d*)*,0
DONE
pq-2.2.3/tests/async002.phpt 0000644 0000765 0000024 00000002015 14560227740 014351 0 ustar mike staff --TEST--
async reset
--SKIPIF--
--FILE--
status);
echo "W";
$w = array($c->socket);
$r = $e = null;
stream_select($r, $w, $e, null);
while (true) {
$s[] = $c->status;
echo "P";
switch ($c->poll()) {
case pq\Connection::POLLING_READING:
echo "R";
$w = $e = null;
$r = array($c->socket);
stream_select($r, $w, $e, NULL);
break;
case pq\Connection::POLLING_WRITING:
echo "W";
$w = array($c->socket);
$r = $e = null;
stream_select($r, $w, $e, null);
break;
case pq\Connection::POLLING_FAILED:
echo "F";
break 2;
case pq\Connection::POLLING_OK:
echo "S";
break 2;
}
}
$s[] = $c->status;
printf("\n%s\n", implode(",", $s));
}
complete($c);
if ($c->status == pq\Connection::OK) {
$c->resetAsync();
complete($c);
}
?>
DONE
--EXPECTREGEX--
Test
(WP(RP)*)+S
[23](,\d*)*,0
(WP(RP)*)+S
[23](,\d*)*,0
DONE
pq-2.2.3/tests/async003.phpt 0000644 0000765 0000024 00000004133 14560227740 014355 0 ustar mike staff --TEST--
async exec
--SKIPIF--
--FILE--
execAsync("SELECT 1+2+3; SELECT 2,3,4", function ($res) {
var_dump($res);
});
do {
while ($c->busy) {
$r = array($c->socket);
$w = $e = null;
if (stream_select($r, $w, $e, 1, 1000)) {
$c->poll();
}
}
} while ($c->getResult());
?>
DONE
--EXPECTF--
Test
object(pq\Result)#%d (9) {
["status"]=>
int(2)
["statusMessage"]=>
string(9) "TUPLES_OK"
["errorMessage"]=>
string(0) ""
["diag"]=>
array(17) {
["severity"]=>
NULL
["sqlstate"]=>
NULL
["message_primary"]=>
NULL
["message_detail"]=>
NULL
["message_hint"]=>
NULL
["statement_position"]=>
NULL
["internal_position"]=>
NULL
["internal_query"]=>
NULL
["context"]=>
NULL
["schema_name"]=>
NULL
["table_name"]=>
NULL
["column_name"]=>
NULL
["datatype_name"]=>
NULL
["constraint_name"]=>
NULL
["source_file"]=>
NULL
["source_line"]=>
NULL
["source_function"]=>
NULL
}
["numRows"]=>
int(1)
["numCols"]=>
int(1)
["affectedRows"]=>
int(%d)
["fetchType"]=>
int(0)
["autoConvert"]=>
int(65535)
}
object(pq\Result)#%d (9) {
["status"]=>
int(2)
["statusMessage"]=>
string(9) "TUPLES_OK"
["errorMessage"]=>
string(0) ""
["diag"]=>
array(17) {
["severity"]=>
NULL
["sqlstate"]=>
NULL
["message_primary"]=>
NULL
["message_detail"]=>
NULL
["message_hint"]=>
NULL
["statement_position"]=>
NULL
["internal_position"]=>
NULL
["internal_query"]=>
NULL
["context"]=>
NULL
["schema_name"]=>
NULL
["table_name"]=>
NULL
["column_name"]=>
NULL
["datatype_name"]=>
NULL
["constraint_name"]=>
NULL
["source_file"]=>
NULL
["source_line"]=>
NULL
["source_function"]=>
NULL
}
["numRows"]=>
int(1)
["numCols"]=>
int(3)
["affectedRows"]=>
int(%d)
["fetchType"]=>
int(0)
["autoConvert"]=>
int(65535)
}
DONE
pq-2.2.3/tests/async004.phpt 0000644 0000765 0000024 00000002501 14560227740 014353 0 ustar mike staff --TEST--
async exec params
--SKIPIF--
--FILE--
execParamsAsync("SELECT \$1,\$2::int4", array(1,2), array($t["int4"]->oid), function ($res) {
var_dump($res);
});
do {
while ($c->busy) {
$r = array($c->socket);
$w = $e = null;
if (stream_select($r, $w, $e, null)) {
$c->poll();
}
}
} while ($c->getResult());
?>
DONE
--EXPECTF--
Test
object(pq\Result)#%d (9) {
["status"]=>
int(2)
["statusMessage"]=>
string(9) "TUPLES_OK"
["errorMessage"]=>
string(0) ""
["diag"]=>
array(17) {
["severity"]=>
NULL
["sqlstate"]=>
NULL
["message_primary"]=>
NULL
["message_detail"]=>
NULL
["message_hint"]=>
NULL
["statement_position"]=>
NULL
["internal_position"]=>
NULL
["internal_query"]=>
NULL
["context"]=>
NULL
["schema_name"]=>
NULL
["table_name"]=>
NULL
["column_name"]=>
NULL
["datatype_name"]=>
NULL
["constraint_name"]=>
NULL
["source_file"]=>
NULL
["source_line"]=>
NULL
["source_function"]=>
NULL
}
["numRows"]=>
int(1)
["numCols"]=>
int(2)
["affectedRows"]=>
int(%d)
["fetchType"]=>
int(0)
["autoConvert"]=>
int(65535)
}
DONE
pq-2.2.3/tests/async005.phpt 0000644 0000765 0000024 00000002724 14560227740 014363 0 ustar mike staff --TEST--
async prepared statement
--SKIPIF--
--FILE--
connection->busy) {
$r = array($s->connection->socket);
$w = $e = null;
if (stream_select($r, $w, $e, null)) {
$s->connection->poll();
}
}
} while ($s->connection->getResult());
}
$c = new pq\Connection(PQ_DSN);
$t = new pq\Types($c);
$s = $c->prepareAsync("test", "SELECT \$1,\$2::int4", array($t["int4"]->oid));
complete($s);
$s->execAsync(array(1,2), function ($res) {
var_dump($res);
});
complete($s);
?>
DONE
--EXPECTF--
Test
object(pq\Result)#%d (9) {
["status"]=>
int(2)
["statusMessage"]=>
string(9) "TUPLES_OK"
["errorMessage"]=>
string(0) ""
["diag"]=>
array(17) {
["severity"]=>
NULL
["sqlstate"]=>
NULL
["message_primary"]=>
NULL
["message_detail"]=>
NULL
["message_hint"]=>
NULL
["statement_position"]=>
NULL
["internal_position"]=>
NULL
["internal_query"]=>
NULL
["context"]=>
NULL
["schema_name"]=>
NULL
["table_name"]=>
NULL
["column_name"]=>
NULL
["datatype_name"]=>
NULL
["constraint_name"]=>
NULL
["source_file"]=>
NULL
["source_line"]=>
NULL
["source_function"]=>
NULL
}
["numRows"]=>
int(1)
["numCols"]=>
int(2)
["affectedRows"]=>
int(%d)
["fetchType"]=>
int(0)
["autoConvert"]=>
int(65535)
}
DONE
pq-2.2.3/tests/async006.phpt 0000644 0000765 0000024 00000007620 14560227740 014364 0 ustar mike staff --TEST--
async unbuffered exec
--SKIPIF--
--FILE--
unbuffered = true;
$c->execAsync("SELECT a FROM generate_series(1,3) a", function ($res) {
var_dump($res);
});
do {
while ($c->busy) {
$r = array($c->socket);
$w = $e = null;
if (stream_select($r, $w, $e, null)) {
$c->poll();
}
}
} while ($c->getResult());
?>
DONE
--EXPECTF--
Test
object(pq\Result)#%d (9) {
["status"]=>
int(9)
["statusMessage"]=>
string(12) "SINGLE_TUPLE"
["errorMessage"]=>
string(0) ""
["diag"]=>
array(17) {
["severity"]=>
NULL
["sqlstate"]=>
NULL
["message_primary"]=>
NULL
["message_detail"]=>
NULL
["message_hint"]=>
NULL
["statement_position"]=>
NULL
["internal_position"]=>
NULL
["internal_query"]=>
NULL
["context"]=>
NULL
["schema_name"]=>
NULL
["table_name"]=>
NULL
["column_name"]=>
NULL
["datatype_name"]=>
NULL
["constraint_name"]=>
NULL
["source_file"]=>
NULL
["source_line"]=>
NULL
["source_function"]=>
NULL
}
["numRows"]=>
int(1)
["numCols"]=>
int(1)
["affectedRows"]=>
int(0)
["fetchType"]=>
int(0)
["autoConvert"]=>
int(65535)
}
object(pq\Result)#%d (9) {
["status"]=>
int(9)
["statusMessage"]=>
string(12) "SINGLE_TUPLE"
["errorMessage"]=>
string(0) ""
["diag"]=>
array(17) {
["severity"]=>
NULL
["sqlstate"]=>
NULL
["message_primary"]=>
NULL
["message_detail"]=>
NULL
["message_hint"]=>
NULL
["statement_position"]=>
NULL
["internal_position"]=>
NULL
["internal_query"]=>
NULL
["context"]=>
NULL
["schema_name"]=>
NULL
["table_name"]=>
NULL
["column_name"]=>
NULL
["datatype_name"]=>
NULL
["constraint_name"]=>
NULL
["source_file"]=>
NULL
["source_line"]=>
NULL
["source_function"]=>
NULL
}
["numRows"]=>
int(1)
["numCols"]=>
int(1)
["affectedRows"]=>
int(0)
["fetchType"]=>
int(0)
["autoConvert"]=>
int(65535)
}
object(pq\Result)#%d (9) {
["status"]=>
int(9)
["statusMessage"]=>
string(12) "SINGLE_TUPLE"
["errorMessage"]=>
string(0) ""
["diag"]=>
array(17) {
["severity"]=>
NULL
["sqlstate"]=>
NULL
["message_primary"]=>
NULL
["message_detail"]=>
NULL
["message_hint"]=>
NULL
["statement_position"]=>
NULL
["internal_position"]=>
NULL
["internal_query"]=>
NULL
["context"]=>
NULL
["schema_name"]=>
NULL
["table_name"]=>
NULL
["column_name"]=>
NULL
["datatype_name"]=>
NULL
["constraint_name"]=>
NULL
["source_file"]=>
NULL
["source_line"]=>
NULL
["source_function"]=>
NULL
}
["numRows"]=>
int(1)
["numCols"]=>
int(1)
["affectedRows"]=>
int(0)
["fetchType"]=>
int(0)
["autoConvert"]=>
int(65535)
}
object(pq\Result)#%d (9) {
["status"]=>
int(2)
["statusMessage"]=>
string(9) "TUPLES_OK"
["errorMessage"]=>
string(0) ""
["diag"]=>
array(17) {
["severity"]=>
NULL
["sqlstate"]=>
NULL
["message_primary"]=>
NULL
["message_detail"]=>
NULL
["message_hint"]=>
NULL
["statement_position"]=>
NULL
["internal_position"]=>
NULL
["internal_query"]=>
NULL
["context"]=>
NULL
["schema_name"]=>
NULL
["table_name"]=>
NULL
["column_name"]=>
NULL
["datatype_name"]=>
NULL
["constraint_name"]=>
NULL
["source_file"]=>
NULL
["source_line"]=>
NULL
["source_function"]=>
NULL
}
["numRows"]=>
int(0)
["numCols"]=>
int(1)
["affectedRows"]=>
int(3)
["fetchType"]=>
int(0)
["autoConvert"]=>
int(65535)
}
DONE
pq-2.2.3/tests/async007.phpt 0000644 0000765 0000024 00000001320 14560227740 014354 0 ustar mike staff --TEST--
async statement
--SKIPIF--
--FILE--
busy) {
$r = array($c->socket);
$w = $e = null;
if (stream_select($r, $w, $e, null)) {
$c->poll();
}
}
} while ($c->getResult());
}
$c = new pq\Connection(PQ_DSN);
$t = new pq\Types($c);
$s = new pq\Statement($c, "test1", "SELECT NOW() - \$1", null, true);
complete($s->connection);
$s->execAsync(array("2012-12-12 12:12:12"));
complete($s->connection);
$s->descAsync(function($r) use ($t) {
list($typeOid) = $r->desc();
printf("%s\n", $t[$typeOid]->typname);
});
complete($s->connection);
?>
DONE
--EXPECT--
Test
timestamptz
DONE
pq-2.2.3/tests/async008.phpt 0000644 0000765 0000024 00000001532 14560227740 014362 0 ustar mike staff --TEST--
async cursor
--SKIPIF--
--FILE--
busy) {
$r = array($c->socket);
$w = $e = null;
if (stream_select($r, $w, $e, null)) {
$c->poll();
}
}
} while ($c->getResult());
}
$c = new pq\Connection(PQ_DSN);
$p = $c->declareAsync("mycursor", pq\Cursor::WITH_HOLD,
"SELECT * FROM generate_series(0,29) s WHERE (s%2)=0");
complete($c);
do {
$p->fetchAsync(2, function ($r) {
foreach ($r as $row) {
foreach ($row as $col) {
echo " $col";
}
echo "\n";
}
});
complete($p->connection);
$p->moveAsync(1, function ($r) use(&$keep_going) {
$keep_going = $r->affectedRows;
});
complete($p->connection);
} while ($keep_going);
?>
===DONE===
--EXPECT--
Test
0
2
6
8
12
14
18
20
24
26
===DONE===
pq-2.2.3/tests/async009.phpt 0000644 0000765 0000024 00000001510 14560227740 014357 0 ustar mike staff --TEST--
Deallocate and prepare statement async
--SKIPIF--
--FILE--
busy) {
$r = array($c->socket);
$w = $e = null;
if (stream_select($r, $w, $e, null)) {
$c->poll();
}
}
} while ($c->getResult());
}
$c = new pq\Connection(PQ_DSN);
$s = $c->prepareAsync("test1", "SELECT 'test' || \$1");
complete($c);
$r = $s->exec(array("ing"));
$r->fetchCol($d);
var_dump($d);
$s->deallocateAsync();
complete($c);
try {
$s->exec(array("ing"));
} catch (pq\Exception\BadMethodCallException $e) {
echo "Caught exception\n";
}
$s->prepareAsync();
complete($c);
$r = $s->exec(array("ing"));
$r->fetchCol($d);
var_dump($d);
?>
DONE
--EXPECT--
Test
string(7) "testing"
Caught exception
string(7) "testing"
DONE
pq-2.2.3/tests/async010.phpt 0000644 0000765 0000024 00000002071 14560227740 014352 0 ustar mike staff --TEST--
asnyc query not cleaned before sync exec
--SKIPIF--
--FILE--
$c->execAsync("select clock_timestamp(), pg_sleep(0.1), clock_timestamp()", function($r) {
var_dump([
"cb" => $r->fetchRow()
]);
})
]);
var_dump([
"execParams" => $c->execParams("select \$1::int4", [123])->fetchRow()
]);
?>
DONE
--EXPECTF--
Test
array(1) {
["async"]=>
NULL
}
array(1) {
["cb"]=>
array(3) {
[0]=>
object(pq\DateTime)#%d (4) {
["format"]=>
string(14) "Y-m-d H:i:s.uO"
["date"]=>
string(26) "%s"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "%s"
}
[1]=>
string(0) ""
[2]=>
object(pq\DateTime)#%d (4) {
["format"]=>
string(14) "Y-m-d H:i:s.uO"
["date"]=>
string(26) "%s"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "%s"
}
}
}
array(1) {
["execParams"]=>
array(1) {
[0]=>
int(123)
}
}
DONE
pq-2.2.3/tests/basic001.phpt 0000644 0000765 0000024 00000002105 14560227740 014314 0 ustar mike staff --TEST--
basic functionality
--SKIPIF--
--FILE--
exec("SELECT 1 as one, 2 as two from generate_series(1,2)");
var_dump($res->status == pq\Result::TUPLES_OK);
var_dump($res->numRows);
var_dump($res->numCols);
var_dump(count($res) == $res->count(), $res->numRows == count($res));
foreach ($res as $rowNum => $rowData) {
printf("%d.0 => %d\n", $rowNum, $rowData[0]);
printf("%d.1 => %d\n", $rowNum, $rowData[1]);
}
$res->fetchType = pq\Result::FETCH_ASSOC;
foreach ($res as $rowNum => $rowData) {
printf("%d.0 => %d\n", $rowNum, $rowData["one"]);
printf("%d.1 => %d\n", $rowNum, $rowData["two"]);
}
$res->fetchType = pq\Result::FETCH_OBJECT;
foreach ($res as $rowNum => $rowData) {
printf("%d.0 => %d\n", $rowNum, $rowData->one);
printf("%d.1 => %d\n", $rowNum, $rowData->two);
}
?>
DONE
--EXPECT--
Test
bool(true)
int(2)
int(2)
bool(true)
bool(true)
0.0 => 1
0.1 => 2
1.0 => 1
1.1 => 2
0.0 => 1
0.1 => 2
1.0 => 1
1.1 => 2
0.0 => 1
0.1 => 2
1.0 => 1
1.1 => 2
DONE
pq-2.2.3/tests/basic002.phpt 0000644 0000765 0000024 00000000635 14560227740 014323 0 ustar mike staff --TEST--
basic functionality
--SKIPIF--
--FILE--
prepare("test1", "SELECT \$1",array($t["text"]->oid));
$r = $s->exec(array("fooo"));
printf("%s\n", $r->errorMessage);
var_dump($r->fetchCol($val));
var_dump($val);
?>
DONE
--EXPECT--
Test
bool(true)
string(4) "fooo"
DONE
pq-2.2.3/tests/basic003.phpt 0000644 0000765 0000024 00000000476 14560227740 014327 0 ustar mike staff --TEST--
basic functionality
--SKIPIF--
--FILE--
libraryVersion);
var_dump($c->protocolVersion);
var_dump($c->serverVersion);
?>
DONE
--EXPECTF--
Test
string(%d) "%s"
int(%d)
string(%d) "%s"
DONE
pq-2.2.3/tests/bound002.phpt 0000644 0000765 0000024 00000001014 14560227740 014341 0 ustar mike staff --TEST--
fetch bound
--SKIPIF--
--FILE--
exec("select 1*a,2*a,3*a from generate_series(2,3) a");
$r->bind(0, $a);
$r->bind(1, $b);
$r->bind(2, $c);
while ($s = $r->fetchBound()) {
var_dump($s,$a,$b,$c);
}
?>
DONE
--EXPECT--
Test
array(3) {
[0]=>
int(2)
[1]=>
int(4)
[2]=>
int(6)
}
int(2)
int(4)
int(6)
array(3) {
[0]=>
int(3)
[1]=>
int(6)
[2]=>
int(9)
}
int(3)
int(6)
int(9)
DONE
pq-2.2.3/tests/callback001.phpt 0000644 0000765 0000024 00000000666 14560227740 015001 0 ustar mike staff --TEST--
callback sanity
--SKIPIF--
--FILE--
execAsync("select 1; select 2", function($r) {
print_r($r->fetchAll());
});
$c->exec("select 3");
?>
===DONE===
--EXPECT--
Test
Array
(
[0] => Array
(
[0] => 1
)
)
Array
(
[0] => Array
(
[0] => 2
)
)
===DONE===
pq-2.2.3/tests/callback002.phpt 0000644 0000765 0000024 00000001156 14560227740 014775 0 ustar mike staff --TEST--
callback sanity
--SKIPIF--
--FILE--
execAsync("select 1; select 2", function($r) {
print_r($r->fetchAll());
});
try {
$c->execAsync("select 3; select 4", function($r) {
});
} catch (Exception $e) {
printf("%s\n", $e->getMessage());
}
$c->exec("");
?>
===DONE===
--EXPECT--
Test
Failed to execute query (another command is already in progress)
Array
(
[0] => Array
(
[0] => 1
)
)
Array
(
[0] => Array
(
[0] => 2
)
)
===DONE===
pq-2.2.3/tests/callback003.phpt 0000644 0000765 0000024 00000001776 14560227740 015006 0 ustar mike staff --TEST--
callback sanity
--SKIPIF--
--FILE--
execAsync("select 1; select 2", function($r) use($c) {
echo "CALLBACK 1\n";
print_r($r->fetchAll());
$c->exec("select 'bug'");
try {
$c->execAsync("select 3; select 4", function($r) {
echo "CALLBACK 2\n";
print_r($r->fetchAll());
});
} catch (Exception $e) {
printf("%s\n", $e->getMessage());
}
});
$c->exec("select 'end'");
?>
===DONE===
--EXPECT--
Test
CALLBACK 1
Array
(
[0] => Array
(
[0] => 1
)
)
CALLBACK 1
Array
(
[0] => Array
(
[0] => 2
)
)
CALLBACK 2
Array
(
[0] => Array
(
[0] => 3
)
)
CALLBACK 2
Array
(
[0] => Array
(
[0] => 4
)
)
CALLBACK 2
Array
(
[0] => Array
(
[0] => 3
)
)
CALLBACK 2
Array
(
[0] => Array
(
[0] => 4
)
)
===DONE=== pq-2.2.3/tests/cancel001.phpt 0000644 0000765 0000024 00000003025 14560227740 014462 0 ustar mike staff --TEST--
cancel
--SKIPIF--
--FILE--
exec("SET lc_messages TO 'C'");
} catch (pq\Exception $e) {
// no not fail if we are not superuser
}
$x = new pq\Cancel($c);
$c->execAsync("SELECT pg_sleep(10)");
$x->cancel();
var_dump($c === $x->connection);
var_dump($c->getResult());
printf("%s\n", $c->errorMessage);
?>
DONE
--EXPECTF--
Test
bool(true)
object(pq\Result)#%d (9) {
["status"]=>
int(7)
["statusMessage"]=>
string(11) "FATAL_ERROR"
["errorMessage"]=>
string(47) "ERROR: canceling statement due to user request"
["diag"]=>
array(17) {
["severity"]=>
string(5) "ERROR"
["sqlstate"]=>
string(5) "57014"
["message_primary"]=>
string(39) "canceling statement due to user request"
["message_detail"]=>
NULL
["message_hint"]=>
NULL
["statement_position"]=>
NULL
["internal_position"]=>
NULL
["internal_query"]=>
NULL
["context"]=>
NULL
["schema_name"]=>
NULL
["table_name"]=>
NULL
["column_name"]=>
NULL
["datatype_name"]=>
NULL
["constraint_name"]=>
NULL
["source_file"]=>
string(10) "postgres.c"
["source_line"]=>
string(4) "%d"
["source_function"]=>
string(17) "ProcessInterrupts"
}
["numRows"]=>
int(0)
["numCols"]=>
int(0)
["affectedRows"]=>
int(0)
["fetchType"]=>
int(0)
["autoConvert"]=>
int(65535)
}
ERROR: canceling statement due to user request
DONE
pq-2.2.3/tests/conv001.phpt 0000644 0000765 0000024 00000016715 14560227740 014214 0 ustar mike staff --TEST--
converter
--SKIPIF--
--INI--
date.timezone=UTC
--FILE--
types = $types;
}
}
class HStoreConverter extends Converter
{
function convertTypes() {
return [ $this->types["hstore"]->oid ];
}
function convertFromString($string, $type) {
return eval("return [$string];");
}
function convertToString($data, $type) {
$string = "";
foreach ($data as $k => $v) {
if (isset($v)) {
$string .= sprintf("\"%s\"=>\"%s\",", addslashes($k), addslashes($v));
} else {
$string .= sprintf("\"%s\"=>NULL,", addslashes($k));
}
}
return $string;
}
}
class IntVectorConverter extends Converter
{
function convertTypes() {
return [
$this->types["int2vector"]->oid,
$this->types["oidvector"]->oid
];
}
function convertFromString($string, $type) {
return array_map("intval", explode(" ", $string));
}
function convertToString($data, $type) {
return implode(" ", $data);
}
}
class JSONConverter extends Converter
{
function convertTypes() {
return [ $this->types["json"]->oid ];
}
function convertFromString($string, $type) {
return json_decode($string, true);
}
function convertToString($data, $type) {
return json_encode($data);
}
}
class Point {
public $x;
public $y;
function __construct($x, $y) {
$this->x = $x;
$this->y = $y;
}
}
class Box {
public $p1;
public $p2;
function __construct(Point $p1, Point $p2) {
$this->p1 = $p1;
$this->p2 = $p2;
}
}
class BoxConverter extends Converter
{
function convertTypes() {
return [ $this->types["box"]->oid ];
}
function convertToString($box, $type) {
return sprintf("(%F,%F),(%F,%F)",
$box->p1->x, $box->p1->y,
$box->p2->x, $box->p2->y
);
}
function convertFromString($data, $type) {
list($p1x, $p1y, $p2x, $p2y) = sscanf($data, "(%f,%f),(%f,%f)");
return new Box(new Point($p1x, $p1y), new Point($p2x, $p2y));
}
}
class Text {
private $data;
function __construct($data) {
$this->data = $data;
}
function __toString() {
return (string) $this->data;
}
}
$c = new pq\Connection(PQ_DSN);
$c->exec("CREATE EXTENSION IF NOT EXISTS hstore");
$t = new pq\Types($c);
$c->setConverter(new HStoreConverter($t));
$c->setConverter(new IntVectorConverter($t));
if (!(defined("pq\\Types::JSON") && defined("pq\\Result::CONV_JSON"))) {
$c->setConverter(new JSONConverter($t));
}
$c->setConverter(new BoxConverter($t));
$r = $c->execParams("SELECT \$1 as hs, \$2 as iv, \$3 as oids, \$4 as js, \$5 as ia, \$6 as ta, \$7 as ba, \$8 as da, \$9 as dbl, \$10 as bln, ".
"\$11 as dt1, \$12 as dt3, \$13 as dt4, \$14 as dt5, \$15 as dt7, \$16 as dt8, \$17 as txta, \$18 as boxa",
array(
// hstore
array(
"k1" => "v1",
"k2" => "v2",
"k3" => null
),
// vectors
array(
1, 3, 5, 7, 9, 11
),
array(
2345124, 1431341, 1343423
),
// JSON
(object) array(
"int" => 123,
"obj" => (object) array(
"a" => 1,
"b" => 2,
"c" => 3,
),
"str" => "äüö"
),
// arrays
array(array(array(1,2,3))),
array(array("a\"","b}",null)),
array(true,false),
array(1.1,2.2),
// double
123.456,
// bool
true,
// datetimes
new pq\Datetime,
new pq\Datetime,
new pq\Datetime,
new pq\Datetime,
new pq\Datetime,
new pq\Datetime,
// text array
[new Text(0), new Text(" or "), new Text(true)],
// box array
[new Box(new Point(1,2), new Point(2,3)), new Box(new Point(3,4), new Point(4,5))],
),
array(
$t["hstore"]->oid,
$t["int2vector"]->oid,
$t["oidvector"]->oid,
$t["json"]->oid,
$t["_int4"]->oid,
$t["_text"]->oid,
$t["_bool"]->oid,
$t["_float8"]->oid,
$t["float4"]->oid,
$t["bool"]->oid,
$t["date"]->oid,
$t["timestamp"]->oid,
$t["timestamptz"]->oid,
$t["date"]->oid,
$t["timestamp"]->oid,
$t["timestamptz"]->oid,
$t["_text"]->oid,
$t["_box"]->oid
)
);
var_dump($r->fetchAll());
?>
Done
--EXPECTF--
Test
array(1) {
[0]=>
array(%d) {
[0]=>
array(3) {
["k1"]=>
string(2) "v1"
["k2"]=>
string(2) "v2"
["k3"]=>
NULL
}
[1]=>
array(6) {
[0]=>
int(1)
[1]=>
int(3)
[2]=>
int(5)
[3]=>
int(7)
[4]=>
int(9)
[5]=>
int(11)
}
[2]=>
array(3) {
[0]=>
int(2345124)
[1]=>
int(1431341)
[2]=>
int(1343423)
}
[3]=>
array(3) {
["int"]=>
int(123)
["obj"]=>
array(3) {
["a"]=>
int(1)
["b"]=>
int(2)
["c"]=>
int(3)
}
["str"]=>
string(6) "äüö"
}
[4]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
}
}
[5]=>
array(1) {
[0]=>
array(3) {
[0]=>
string(2) "a""
[1]=>
string(2) "b}"
[2]=>
NULL
}
}
[6]=>
array(2) {
[0]=>
bool(true)
[1]=>
bool(false)
}
[7]=>
array(2) {
[0]=>
float(1.1)
[1]=>
float(2.2)
}
[8]=>
float(123.456)
[9]=>
bool(true)
[10]=>
object(pq\DateTime)#%d (4) {
["format"]=>
string(5) "Y-m-d"
["date"]=>
string(26) "%d-%d-%d 00:00:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
[11]=>
object(pq\DateTime)#%d (4) {
["format"]=>
string(13) "Y-m-d H:i:s.u"
["date"]=>
string(26) "%d-%d-%d %d:%d:%d.%d"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
[12]=>
object(pq\DateTime)#%d (4) {
["format"]=>
string(14) "Y-m-d H:i:s.uO"
["date"]=>
string(26) "%d-%d-%d %d:%d:%d.%d"
["timezone_type"]=>
int(1)
["timezone"]=>
string(%d) "%s"
}
[13]=>
object(pq\DateTime)#%d (4) {
["format"]=>
string(5) "Y-m-d"
["date"]=>
string(26) "%d-%d-%d 00:00:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
[14]=>
object(pq\DateTime)#%d (4) {
["format"]=>
string(13) "Y-m-d H:i:s.u"
["date"]=>
string(26) "%d-%d-%d %d:%d:%d.%d"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
[15]=>
object(pq\DateTime)#%d (4) {
["format"]=>
string(14) "Y-m-d H:i:s.uO"
["date"]=>
string(26) "%d-%d-%d %d:%d:%d.%d"
["timezone_type"]=>
int(1)
["timezone"]=>
string(%d) "%s"
}
[16]=>
array(3) {
[0]=>
string(1) "0"
[1]=>
string(4) " or "
[2]=>
string(1) "1"
}
[17]=>
array(2) {
[0]=>
object(Box)#%d (2) {
["p1"]=>
object(Point)#%d (2) {
["x"]=>
float(2)
["y"]=>
float(3)
}
["p2"]=>
object(Point)#%d (2) {
["x"]=>
float(1)
["y"]=>
float(2)
}
}
[1]=>
object(Box)#%d (2) {
["p1"]=>
object(Point)#%d (2) {
["x"]=>
float(4)
["y"]=>
float(5)
}
["p2"]=>
object(Point)#%d (2) {
["x"]=>
float(3)
["y"]=>
float(4)
}
}
}
}
}
Done
pq-2.2.3/tests/copy001.phpt 0000644 0000765 0000024 00000002324 14560227740 014210 0 ustar mike staff --TEST--
copy
--SKIPIF--
--FILE--
exec("DROP TABLE IF EXISTS copy_test; CREATE TABLE copy_test (id serial, line text);");
$file = file(__FILE__);
$in = new pq\COPY($c, "copy_test (line)", pq\COPY::FROM_STDIN, "DELIMITER '\t'");
var_dump(
$c === $in->connection,
"copy_test (line)" === $in->expression,
pq\COPY::FROM_STDIN === $in->direction,
"DELIMITER '\t'" === $in->options
);
foreach ($file as $i => $line) {
$in->put(addcslashes($line, "\\\t"));
}
$in->end();
$out = new pq\COPY($c, "copy_test (line)", pq\COPY::TO_STDOUT, "DELIMITER '\t'");
var_dump(
$c === $out->connection,
"copy_test (line)" === $out->expression,
pq\COPY::TO_STDOUT === $out->direction,
"DELIMITER '\t'" === $out->options
);
while ($out->get($line)) {
$lines[] = stripcslashes($line);
}
var_dump($file == $lines);
if ($file != $lines) {
foreach (array_keys(array_diff($file, $lines)) as $idx) {
var_dump($idx, $file[$idx], $lines[$idx], "##############");
}
}
$c->exec("DROP TABLE copy_test");
?>
DONE
--EXPECT--
Test
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
DONE
pq-2.2.3/tests/crash_cur_reverse_dep.phpt 0000644 0000765 0000024 00000000561 14560227740 017352 0 ustar mike staff --TEST--
crash txn reverse dependency from connection
--SKIPIF--
="))
echo "skip PHP_VERSION>=8.2 (dynamic properties deprecated)\n";
?>
--FILE--
t = $c->startTransaction();
?>
===DONE===
--EXPECT--
Test
===DONE===
pq-2.2.3/tests/crash_result_iterator.phpt 0000644 0000765 0000024 00000000660 14560227740 017425 0 ustar mike staff --TEST--
crash result iterator
--SKIPIF--
--FILE--
exec($sql) as $row) {
var_dump($row);
}
?>
===DONE===
--EXPECT--
Test
array(1) {
[0]=>
int(1)
}
array(1) {
[0]=>
int(2)
}
array(1) {
[0]=>
int(3)
}
===DONE===
pq-2.2.3/tests/crash_stm_reverse_dep.phpt 0000644 0000765 0000024 00000000572 14560227740 017366 0 ustar mike staff --TEST--
crash stm reverse dependency from connection
--SKIPIF--
="))
echo "skip PHP_VERSION>=8.2 (dynamic properties deprecated)\n";
?>
--FILE--
s = $c->prepare("test", "SELECT 1");
?>
===DONE===
--EXPECT--
Test
===DONE===
pq-2.2.3/tests/crash_txn_reverse_dep.phpt 0000644 0000765 0000024 00000000620 14560227740 017366 0 ustar mike staff --TEST--
crash txn reverse dependency from connection
--SKIPIF--
="))
echo "skip PHP_VERSION>=8.2 (dynamic properties deprecated)\n";
?>
--FILE--
c = $c->declare("test", pq\Cursor::WITH_HOLD, "SELECT 1");
?>
===DONE===
--EXPECT--
Test
===DONE===
pq-2.2.3/tests/crash_unbuffered_async_prepare.phpt 0000644 0000765 0000024 00000001145 14560227740 021235 0 ustar mike staff --TEST--
crash unbuffered async prepare
--SKIPIF--
--FILE--
busy) {
$r = array($c->socket);
$w = $e = null;
if (stream_select($r, $w, $e, null)) {
$c->poll();
}
}
} while ($c->getResult());
}
try {
$c = new pq\Connection(PQ_DSN);
$c->unbuffered = true;
$s = $c->prepareAsync("test", "SELECT * from generate_series(1,2)");
complete($c);
$r = $s->execAsync();
complete($c);
} catch (Exception $e) {
echo $e;
}
unset($c);
?>
===DONE===
--EXPECT--
Test
===DONE=== pq-2.2.3/tests/cursor001.phpt 0000644 0000765 0000024 00000001706 14560227740 014556 0 ustar mike staff --TEST--
cursor
--SKIPIF--
--FILE--
declare("mycursor", pq\Cursor::WITH_HOLD,
"SELECT * FROM generate_series(0,29) s WHERE (s%2)=0");
for ($r = $p->fetch(2); $r->numRows; $p->move(1), $r = $p->fetch(2)) {
foreach ($r as $row) {
foreach ($row as $col) {
echo " $col";
}
echo "\n";
}
}
try {
$p = new pq\Cursor($c, "mycursor", pq\Cursor::WITH_HOLD,
"SELECT * FROM generate_series(0,29) s WHERE (s%2)=0");
} catch (Exception $ex) {
$p->close();
}
$p = new pq\Cursor($c, "mycursor", pq\Cursor::WITH_HOLD,
"SELECT * FROM generate_series(0,29) s WHERE (s%2)=0");
for ($r = $p->fetch(2); $r->numRows; $p->move(1), $r = $p->fetch(2)) {
foreach ($r as $row) {
foreach ($row as $col) {
echo " $col";
}
echo "\n";
}
}
?>
===DONE===
--EXPECT--
Test
0
2
6
8
12
14
18
20
24
26
0
2
6
8
12
14
18
20
24
26
===DONE===
pq-2.2.3/tests/encoding001.phpt 0000644 0000765 0000024 00000000765 14560227740 015033 0 ustar mike staff --TEST--
encoding
--SKIPIF--
--FILE--
encoding);
$c->encoding = "utf8";
var_dump($c->encoding);
$c->exec("SELECT 'ßüpä…'")->fetchCol($val);
var_dump($val);
$tmp = 12345;
$c->encoding = $tmp;
var_dump($c->encoding);
?>
DONE
--EXPECTF--
Test
string(%d) "%s"
string(4) "UTF8"
string(10) "ßüpä…"
Notice: Unrecognized encoding '12345' in %s on line %d
string(4) "UTF8"
DONE
pq-2.2.3/tests/exceptions001.phpt 0000644 0000765 0000024 00000001633 14560227740 015421 0 ustar mike staff --TEST--
exceptions
--SKIPIF--
--FILE--
getCode() == pq\Exception::INVALID_ARGUMENT, $e->getCode()."!=".pq\Exception::INVALID_ARGUMENT);
}
class c extends pq\Connection {
function __construct() {
}
function open($dsn) {
parent::__construct($dsn);
}
}
$c = new c;
try {
$c->reset();
foo();
} catch (pq\Exception\BadMethodCallException $e) {
assert($e->getCode() == pq\Exception::UNINITIALIZED, $e->getCode()."!=".pq\Exception::UNINITIALIZED);
}
$c->open(PQ_DSN);
try {
$c->open(PQ_DSN);
foo();
} catch (pq\Exception\BadMethodCallException $e) {
assert($e->getCode() == pq\Exception::BAD_METHODCALL, $e->getCode()."!=".pq\Exception::BAD_METHODCALL);
}
?>
DONE
--EXPECT--
Test
DONE
pq-2.2.3/tests/exceptions002.phpt 0000644 0000765 0000024 00000000675 14560227740 015427 0 ustar mike staff --TEST--
sql exception
--SKIPIF--
--FILE--
exec("SELECT 1 FROM probably_non_existent_table");
} catch (pq\Exception $e) {
var_dump($e instanceof pq\Exception\DomainException);
var_dump($e->getCode() == pq\Exception::SQL);
var_dump($e->sqlstate);
}
?>
DONE
--EXPECT--
Test
bool(true)
bool(true)
string(5) "42P01"
DONE
pq-2.2.3/tests/fetch001.phpt 0000644 0000765 0000024 00000001671 14560227740 014333 0 ustar mike staff --TEST--
fetch type
--SKIPIF--
--FILE--
exec("SELECT a,b, NULL as c from generate_series(1,2) a, generate_series(2,4) b");
$r->fetchType = pq\Result::FETCH_ARRAY;
foreach ($r as $k => $v) {
printf("%s => %s,%s,%s\n", $k, $v[0], $v[1], $v[2]);
$r->fetchType = (string) $r->fetchType;
}
$r->fetchType = pq\Result::FETCH_ASSOC;
foreach ($r as $k => $v) {
printf("%s => %s,%s,%s\n", $k, $v["a"], $v["b"], $v["c"]);
$r->fetchType = (string) $r->fetchType;
}
$r->fetchType = pq\Result::FETCH_OBJECT;
foreach ($r as $k => $v) {
printf("%s => %s,%s,%s\n", $k, $v->a, $v->b, $v->c);
$r->fetchType = (string) $r->fetchType;
}
?>
DONE
--EXPECT--
Test
0 => 1,2,
1 => 1,3,
2 => 1,4,
3 => 2,2,
4 => 2,3,
5 => 2,4,
0 => 1,2,
1 => 1,3,
2 => 1,4,
3 => 2,2,
4 => 2,3,
5 => 2,4,
0 => 1,2,
1 => 1,3,
2 => 1,4,
3 => 2,2,
4 => 2,3,
5 => 2,4,
DONE
pq-2.2.3/tests/flush001.phpt 0000644 0000765 0000024 00000001363 14560227740 014361 0 ustar mike staff --TEST--
flush
--SKIPIF--
--FILE--
nonblocking = true;
var_dump($c->nonblocking);
$c->execAsync("SELECT '".str_repeat("a", 6e7)."'", function($r) {
$r->fetchCol($s);
var_dump(strlen($s));
});
var_dump($flushed = $c->flush());
do {
while (!$flushed || $c->busy) {
$r = $c->busy ? [$c->socket] : null;
$w = !$flushed ?[$c->socket] : null;
if (stream_select($r, $w, $e, null)) {
if ($r) {
printf("P%d", $c->poll());
}
if ($w) {
printf("F%d", $flushed = $c->flush());
}
}
}
echo "\n";
} while ($c->getResult());
?>
===DONE===
--EXPECTF--
Test
bool(true)
bool(%s)
%r(F0)*(F1)*(P3)+%r
int(60000000)
===DONE===
pq-2.2.3/tests/gh-issue015_listeners.phpt 0000644 0000765 0000024 00000002554 14560227740 017064 0 ustar mike staff --TEST--
restore listeners on reset
--SKIPIF--
--INI--
date.timezone=UTC
--FILE--
listen("notify", function($channel, $message) {
printf("%s: %s\n", $channel, $message);
});
$c->on(pq\Connection::EVENT_RESET, function($conn) {
printf("Connection was reset\n");
});
$c->notify("notify", "Gotcha!");
$c->resetAsync();
// wait until the stream becomes writable
$w = array($c->socket);
$r = $e = null;
if (stream_select($r, $w, $e, null)) {
// loop until the connection is established
while (true) {
switch ($c->poll()) {
case pq\Connection::POLLING_READING:
// we should wait for the stream to be read-ready
$r = array($c->socket);
stream_select($r, $w, $e, NULL);
break;
case pq\Connection::POLLING_WRITING:
// we should wait for the stream to be write-ready
$w = array($c->socket);
$r = $e = null;
stream_select($r, $w, $e, null);
break;
case pq\Connection::POLLING_FAILED:
printf("Connection failed: %s\n", $c->errorMessage);
break 2;
case pq\Connection::POLLING_OK:
printf("Connection completed\n");
break 2;
}
}
}
$c->notify("notify", "Do you miss me?");
$c->exec("");
?>
===DONE===
--EXPECT--
Test
notify: Gotcha!
Connection was reset
Connection completed
notify: Do you miss me?
===DONE=== pq-2.2.3/tests/gh-issue015_statements.phpt 0000644 0000765 0000024 00000001223 14560227740 017233 0 ustar mike staff --TEST--
restore statements on reset
--SKIPIF--
--INI--
date.timezone=UTC
--FILE--
prepare("test", "SELECT 1");
$c->on(pq\Connection::EVENT_RESET, function($conn) {
printf("Connection was reset\n");
});
var_dump($s->exec()->fetchRow());
$c->reset();
// Fatal error: Uncaught exception 'pq\Exception\DomainException' with message 'ERROR: prepared statement "test" does not exist'
var_dump($s->exec()->fetchRow());
?>
===DONE===
--EXPECT--
Test
array(1) {
[0]=>
int(1)
}
Connection was reset
array(1) {
[0]=>
int(1)
}
===DONE=== pq-2.2.3/tests/gh-issue047_jsonb.phpt 0000644 0000765 0000024 00000001052 14560227740 016164 0 ustar mike staff --TEST--
json conv broken since 2.2.1
--SKIPIF--
--INI--
date.timezone=UTC
--FILE--
defaultFetchType = \pq\Result::FETCH_ASSOC;
$q = <<exec($q);
var_dump($r->fetchAll());
?>
===DONE===
--EXPECT--
Test
array(2) {
[0]=>
array(1) {
["jsonb"]=>
string(4) "text"
}
[1]=>
array(1) {
["jsonb"]=>
int(0)
}
}
===DONE===
pq-2.2.3/tests/info001.phpt 0000644 0000765 0000024 00000000430 14560227740 014165 0 ustar mike staff --TEST--
connection info
--SKIPIF--
--FILE--
db,
$c->user,
$c->pass,
$c->host,
$c->port,
$c->options
);
?>
DONE
--EXPECTF--
Test
%s
DONE
pq-2.2.3/tests/info002.phpt 0000644 0000765 0000024 00000000422 14560227740 014167 0 ustar mike staff --TEST--
ext info
--SKIPIF--
--FILE--
info();
?>
Done
--EXPECTF--
Test
pq
PQ Support => enabled
Extension Version => %s
Used Library => Compiled => Linked
libpq => %s => %s
Done
pq-2.2.3/tests/lob001.phpt 0000644 0000765 0000024 00000001156 14560227740 014014 0 ustar mike staff --TEST--
large objects
--SKIPIF--
--FILE--
startTransaction();
$lob = $t->createLOB();
var_dump($lob->transaction === $t);
$lob->write(file_get_contents(__FILE__));
var_dump($lob->tell());
$lob->seek(0, SEEK_SET);
$dat = $lob->read(filesize(__FILE__));
var_dump(md5($dat)===md5_file(__FILE__));
$lob->truncate(5);
$lob = new pq\Lob($t, $lob->oid);
var_dump($lob->read(123));
$t->commit();
$t->unlinkLOB($lob->oid);
?>
DONE
--EXPECTF--
Test
bool(true)
int(474)
bool(true)
string(5) "%c?php"
DONE
pq-2.2.3/tests/lob002.phpt 0000644 0000765 0000024 00000001463 14560227740 014016 0 ustar mike staff --TEST--
large object stream
--SKIPIF--
--FILE--
startTransaction();
$lob = $t->createLOB();
fwrite($lob->stream, file_get_contents(__FILE__));
var_dump(ftell($lob->stream));
fseek($lob->stream, 0, SEEK_SET);
$dat = fread($lob->stream, filesize(__FILE__));
var_dump(md5($dat)===md5_file(__FILE__));
ftruncate($lob->stream, 5);
$lob = new pq\Lob($t, $lob->oid);
var_dump(fread($lob->stream, 123));
$t->commit();
$t->unlinkLOB($lob->oid);
?>
DONE
--EXPECTF--
Test
int(488)
bool(true)
Warning: ftruncate(): Can't truncate this stream! in %s on line %d
string(123) "%c?php
echo "Test\n";
include "_setup.inc";
$c = new pq\Connection(PQ_DSN);
$t = $c->startTransaction();
$lob = $t->creat"
DONE
pq-2.2.3/tests/lob003.phpt 0000644 0000765 0000024 00000001103 14560227740 014006 0 ustar mike staff --TEST--
large object closing stream
--SKIPIF--
--FILE--
startTransaction();
$lob = $t->createLOB();
var_dump($lob->stream);
var_dump($lob->stream);
fclose($lob->stream); // bad boy!
var_dump($lob->stream);
var_dump(fread($lob->stream, 5));
$lob = null;
?>
DONE
--EXPECTF--
Test
resource(%d) of type (stream)
resource(%d) of type (stream)
Warning: fclose(): %d is not a valid stream resource in %s on line %d
resource(%d) of type (stream)
string(0) ""
DONE
pq-2.2.3/tests/lob004.phpt 0000644 0000765 0000024 00000000653 14560227740 014020 0 ustar mike staff --TEST--
large object import/export
--SKIPIF--
--CLEAN--
--FILE--
importLOB(__FILE__);
var_dump($oid);
$t->exportLOB($oid, "lob004.tmp");
var_dump(md5_file(__FILE__)===md5_file("lob004.tmp"));
?>
DONE
--EXPECTF--
Test
int(%d)
bool(true)
DONE
pq-2.2.3/tests/map001.phpt 0000644 0000765 0000024 00000006061 14560227740 014015 0 ustar mike staff --TEST--
map result
--SKIPIF--
--FILE--
exec("select (ARRAY['one','two','three','four','five','six','seven','eight','nine','ten'])[a] num, ".
"round(log(a)::numeric,3) log, round(exp(a)::numeric,3) exp from generate_series(1,10) a");
$r->fetchType = pq\Result::FETCH_OBJECT;
var_dump($r->map());
var_dump($r->map() == $r->map(0));
var_dump($r->map() == $r->map(0, array(0,1,2)));
$r = $c->exec("select * from generate_series(0,1) a, generate_series(0,1) b, generate_series(0,1) c, generate_series(0,1) d ".
"order by a,b,c,d");
$r->fetchType = pq\Result::FETCH_ARRAY;
var_dump($r->map(array(0,"b",2), "d"));
?>
DONE
--EXPECTF--
Test
object(stdClass)#%d (10) {
["one"]=>
object(stdClass)#%d (3) {
["num"]=>
string(3) "one"
["log"]=>
string(5) "0.000"
["exp"]=>
string(5) "2.718"
}
["two"]=>
object(stdClass)#%d (3) {
["num"]=>
string(3) "two"
["log"]=>
string(5) "0.301"
["exp"]=>
string(5) "7.389"
}
["three"]=>
object(stdClass)#%d (3) {
["num"]=>
string(5) "three"
["log"]=>
string(5) "0.477"
["exp"]=>
string(6) "20.086"
}
["four"]=>
object(stdClass)#%d (3) {
["num"]=>
string(4) "four"
["log"]=>
string(5) "0.602"
["exp"]=>
string(6) "54.598"
}
["five"]=>
object(stdClass)#%d (3) {
["num"]=>
string(4) "five"
["log"]=>
string(5) "0.699"
["exp"]=>
string(7) "148.413"
}
["six"]=>
object(stdClass)#%d (3) {
["num"]=>
string(3) "six"
["log"]=>
string(5) "0.778"
["exp"]=>
string(7) "403.429"
}
["seven"]=>
object(stdClass)#%d (3) {
["num"]=>
string(5) "seven"
["log"]=>
string(5) "0.845"
["exp"]=>
string(8) "1096.633"
}
["eight"]=>
object(stdClass)#%d (3) {
["num"]=>
string(5) "eight"
["log"]=>
string(5) "0.903"
["exp"]=>
string(8) "2980.958"
}
["nine"]=>
object(stdClass)#%d (3) {
["num"]=>
string(4) "nine"
["log"]=>
string(5) "0.954"
["exp"]=>
string(8) "8103.084"
}
["ten"]=>
object(stdClass)#%d (3) {
["num"]=>
string(3) "ten"
["log"]=>
string(5) "1.000"
["exp"]=>
string(9) "22026.466"
}
}
bool(true)
bool(true)
array(2) {
[0]=>
array(2) {
[0]=>
array(2) {
[0]=>
array(1) {
[3]=>
string(1) "1"
}
[1]=>
array(1) {
[3]=>
string(1) "1"
}
}
[1]=>
array(2) {
[0]=>
array(1) {
[3]=>
string(1) "1"
}
[1]=>
array(1) {
[3]=>
string(1) "1"
}
}
}
[1]=>
array(2) {
[0]=>
array(2) {
[0]=>
array(1) {
[3]=>
string(1) "1"
}
[1]=>
array(1) {
[3]=>
string(1) "1"
}
}
[1]=>
array(2) {
[0]=>
array(1) {
[3]=>
string(1) "1"
}
[1]=>
array(1) {
[3]=>
string(1) "1"
}
}
}
}
DONE
pq-2.2.3/tests/notify001.phpt 0000644 0000765 0000024 00000002143 14560227740 014545 0 ustar mike staff --TEST--
notify
--SKIPIF--
--FILE--
listen("test", function($channel, $message, $pid) {
printf("%s(%d): %s\n", $channel, $pid, $message);
});
$producer = new pq\Connection(PQ_DSN);
$producer->notify("test", "this is a test");
$consumer->exec("select 1");
$producer->notify("test", "this is an async test");
$r = array($consumer->socket);
$w = null; $e = null;
stream_select($r, $w, $e, NULL);
$consumer->poll();
$producer->notify("other", "this should not show up");
stream_select($r, $w, $e, 0,1000);
$consumer->poll();
$producer->notify("test", "just to be sure");
$r = array($consumer->socket);
$w = null; $e = null;
stream_select($r, $w, $e, 0,1000);
$consumer->poll();
$consumer->unlisten("test");
$producer->notify("test", "this shouldn't show up either");
$r = array($consumer->socket);
$w = null; $e = null;
stream_select($r, $w, $e, 0,1000);
$consumer->poll();
?>
DONE
--EXPECTF--
Test
test(%d): this is a test
test(%d): this is an async test
test(%d): just to be sure
DONE
pq-2.2.3/tests/persistent001.phpt 0000644 0000765 0000024 00000001170 14560227740 015434 0 ustar mike staff --TEST--
persistent handles
--SKIPIF--
--FILE--
listen("chan", function($chan, $msg) {
// dummy
});
$c->on(pq\Connection::EVENT_RESULT, function($c, $res) {
});
}
if (!($i%10)) gc_collect_cycles();
$c->exec("");
}
var_dump(raphf\stat_persistent_handles()->{"pq\\Connection"});
?>
DONE
--EXPECTF--
Test
array(1) {
["%S"]=>
array(2) {
["used"]=>
int(1)
["free"]=>
int(2)
}
}
DONE
pq-2.2.3/tests/res001.phpt 0000644 0000765 0000024 00000003741 14560227740 014033 0 ustar mike staff --TEST--
empty result
--SKIPIF--
--FILE--
Done
--EXPECTF--
Test
Warning: pq\Result not initialized in %s on line %d
Warning: pq\Result not initialized in %s on line %d
Warning: pq\Result not initialized in %s on line %d
Warning: pq\Result not initialized in %s on line %d
Warning: pq\Result not initialized in %s on line %d
Warning: pq\Result not initialized in %s on line %d
Warning: pq\Result not initialized in %s on line %d
Warning: pq\Result not initialized in %s on line %d
Warning: pq\Result not initialized in %s on line %d
object(pq\Result)#%d (9) {
["status"]=>
NULL
["statusMessage"]=>
NULL
["errorMessage"]=>
NULL
["diag"]=>
NULL
["numRows"]=>
int(0)
["numCols"]=>
int(0)
["affectedRows"]=>
int(0)
["fetchType"]=>
int(0)
["autoConvert"]=>
int(65535)
}
Test
Warning: pq\Result not initialized in %s on line %d
Warning: pq\Result not initialized in %s on line %d
Warning: pq\Result not initialized in %s on line %d
Warning: pq\Result not initialized in %s on line %d
Warning: pq\Result not initialized in %s on line %d
Warning: pq\Result not initialized in %s on line %d
Warning: pq\Result not initialized in %s on line %d
Warning: pq\Result not initialized in %s on line %d
Warning: pq\Result not initialized in %s on line %d
Warning: pq\Result not initialized in %s on line %d
array(10) {
["affectedRows"]=>
int(0)
["autoConvert"]=>
int(65535)
["diag"]=>
NULL
["dummy"]=>
int(2)
["errorMessage"]=>
NULL
["fetchType"]=>
int(0)
["numCols"]=>
int(0)
["numRows"]=>
int(0)
["status"]=>
NULL
["statusMessage"]=>
NULL
}
Done
pq-2.2.3/tests/reset001.phpt 0000644 0000765 0000024 00000000535 14560227740 014362 0 ustar mike staff --TEST--
connection reset
--SKIPIF--
--FILE--
reset();
var_dump($c->status);
$c->on(pq\Connection::EVENT_RESET, function ($c) { print "RESET!\n"; });
$c->reset();
var_dump($c->status);
?>
DONE
--EXPECT--
Test
int(0)
RESET!
int(0)
DONE
pq-2.2.3/tests/savepoint001.phpt 0000644 0000765 0000024 00000000447 14560227740 015252 0 ustar mike staff --TEST--
savepoints
--SKIPIF--
--FILE--
startTransaction();
$t->savepoint();
$t->savepoint();
$t->rollback();
$t->commit();
$t->rollback();
?>
DONE
--EXPECT--
Test
DONE
pq-2.2.3/tests/stm_bound001.phpt 0000644 0000765 0000024 00000001234 14560227740 015227 0 ustar mike staff --TEST--
statement w/ bound vars
--SKIPIF--
--FILE--
bind(0, $_1);
$s->bind(1, $_2);
$s->bind(2, $_3);
$r = $s->exec();
var_dump($r->fetchAll());
$_1 = "\$1";
$_2 = "\$2";
$_3 = "\$3";
$r = $s->exec();
var_dump($r->fetchAll());
?>
Done
--EXPECT--
Test
array(1) {
[0]=>
array(3) {
[0]=>
NULL
[1]=>
NULL
[2]=>
NULL
}
}
array(1) {
[0]=>
array(3) {
[0]=>
string(2) "$1"
[1]=>
string(2) "$2"
[2]=>
string(2) "$3"
}
}
Done
pq-2.2.3/tests/stm_deallocate_prepare001.phpt 0000644 0000765 0000024 00000001107 14560227740 017732 0 ustar mike staff --TEST--
Deallocated and prepare statement
--SKIPIF--
--FILE--
prepare("test1", "SELECT 'test' || \$1");
$r = $s->exec(array("ing"));
$r->fetchCol($d);
var_dump($d);
$s->deallocate();
try {
$s->exec(array("ing"));
} catch (pq\Exception\BadMethodCallException $e) {
echo "Caught exception\n";
}
$s->prepare();
$r = $s->exec(array("ing"));
$r->fetchCol($d);
var_dump($d);
?>
DONE
--EXPECT--
Test
string(7) "testing"
Caught exception
string(7) "testing"
DONE
pq-2.2.3/tests/stm_desc001.phpt 0000644 0000765 0000024 00000000546 14560227740 015043 0 ustar mike staff --TEST--
desc statement
--SKIPIF--
--FILE--
prepare("test1", "SELECT NOW() - \$1");
$r = $s->exec(array("2012-12-12 12:12:12"));
$d = $s->desc();
printf("%s\n", (new pq\Types($c))[$d[0]]->typname);
?>
DONE
--EXPECT--
Test
timestamptz
DONE
pq-2.2.3/tests/stm_desc002.phpt 0000644 0000765 0000024 00000000557 14560227740 015046 0 ustar mike staff --TEST--
desc statement
--SKIPIF--
--FILE--
exec(array("2012-12-12 12:12:12"));
$d = $s->desc();
printf("%s\n", (new pq\Types($c))[$d[0]]->typname);
?>
DONE
--EXPECT--
Test
timestamptz
DONE
pq-2.2.3/tests/stm_props001.phpt 0000644 0000765 0000024 00000001272 14560227740 015265 0 ustar mike staff --TEST--
Statement properties
--SKIPIF--
--FILE--
connection);
var_dump($n === $s->name);
var_dump($q === $s->query);
var_dump($t === $s->types);
$n = 'props2';
$s = $c->prepare($n, $q, $t);
var_dump($c === $s->connection);
var_dump($n === $s->name);
var_dump($q === $s->query);
var_dump($t === $s->types);
?>
Done
--EXPECT--
Test
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
Done
pq-2.2.3/tests/trans001.phpt 0000644 0000765 0000024 00000002410 14560227740 014361 0 ustar mike staff --TEST--
transaction
--SKIPIF--
--FILE--
exec("DROP TABLE IF EXISTS test CASCADE");
$c->exec("SET client_min_messages TO NOTICE");
try {
$c->exec("SET lc_messages TO 'C'");
} catch (pq\Exception $e) {
// do not die if we are not superuser
}
$c->on(pq\Connection::EVENT_NOTICE, function($c, $notice) {
echo "Got notice: $notice\n";
});
var_dump($c->transactionStatus == pq\Connection::TRANS_IDLE);
$t = new pq\Transaction($c);
var_dump($t->connection->transactionStatus == pq\Connection::TRANS_INTRANS);
$c->exec("DROP TABLE IF EXISTS test");
$c->off(pq\Connection::EVENT_NOTICE);
$c->exec("CREATE TABLE test (id serial, data text)");
$s = $c->prepare("test_insert", "INSERT INTO test (data) VALUES (\$1)", array((new pq\Types($c))["text"]->oid));
$s->exec(array("a"));
$s->exec(array("b"));
$s->exec(array("c"));
$r = $c->exec("SELECT * FROM test");
while ($row = $r->fetchRow(pq\Result::FETCH_OBJECT)) {
printf("%d => %s\n", $row->id, $row->data);
}
$t->rollback();
var_dump($c->transactionStatus == pq\Connection::TRANS_IDLE);
?>
DONE
--EXPECT--
Test
bool(true)
bool(true)
Got notice: NOTICE: table "test" does not exist, skipping
1 => a
2 => b
3 => c
bool(true)
DONE
pq-2.2.3/tests/trans002.phpt 0000644 0000765 0000024 00000000732 14560227740 014367 0 ustar mike staff --TEST--
txn properties
--SKIPIF--
--FILE--
isolation,
$t->readonly,
$t->deferrable
);
$t->isolation = pq\Transaction::SERIALIZABLE;
$t->readonly = true;
$t->deferrable = true;
var_dump(
$t->isolation,
$t->readonly,
$t->deferrable
);
?>
DONE
--EXPECTF--
Test
int(0)
bool(false)
bool(false)
int(2)
bool(true)
bool(true)
DONE
pq-2.2.3/tests/types001.phpt 0000644 0000765 0000024 00000001065 14560227740 014403 0 ustar mike staff --TEST--
types functionality
--SKIPIF--
--FILE--
connection === $c);
var_dump(isset($t["int4"]), empty($t["int4"]));
var_dump(isset($t["whatthahell"]), empty($t["whatthahell"]));
var_dump(isset($t[25]), empty($t[25]));
var_dump(isset($t[0]), empty($t[0]));
?>
DONE
--EXPECT--
Test
bool(true)
bool(true)
bool(false)
bool(false)
bool(true)
bool(true)
bool(false)
bool(false)
bool(true)
DONE
pq-2.2.3/tests/types002.phpt 0000644 0000765 0000024 00000004356 14560227740 014412 0 ustar mike staff --TEST--
extended type support
--SKIPIF--
--INI--
date.timezone=UTC
--FILE--
exec("SET timezone TO UTC; SELECT
NULL as null,
true as bool,
1::int2 as int2,
2::int4 as int4,
3::int8 as int8,
1.1::float4 as float4,
2.2::float8 as float8,
'2013-01-01'::date as date,
'2013-01-01 01:01:01'::timestamp as timestamp,
'2013-01-01 01:01:01 UTC'::timestamptz as timestamptz,
array[array[1,2,3],array[4,5,6],array[NULL::int,NULL::int,NULL::int]] as intarray,
array[box(point(1,2),point(2,3)),box(point(4,5),point(5,6))] as boxarray,
array[]::text[] as emptyarray,
'foo\n'::bytea as bytea,
'foo\n'::bytea::text as bytea_text
");
var_dump($r->fetchRow(pq\Result::FETCH_ASSOC));
?>
DONE
--EXPECTF--
Test
array(15) {
["null"]=>
NULL
["bool"]=>
bool(true)
["int2"]=>
int(1)
["int4"]=>
int(2)
["int8"]=>
int(3)
["float4"]=>
float(1.1)
["float8"]=>
float(2.2)
["date"]=>
object(pq\DateTime)#%d (4) {
["format"]=>
string(5) "Y-m-d"
["date"]=>
string(%d) "2013-01-01 00:00:00%r(\.000000)?%r"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
["timestamp"]=>
object(pq\DateTime)#%d (4) {
["format"]=>
string(13) "Y-m-d H:i:s.u"
["date"]=>
string(%d) "2013-01-01 01:01:01%r(\.000000)?%r"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
["timestamptz"]=>
object(pq\DateTime)#%d (4) {
["format"]=>
string(14) "Y-m-d H:i:s.uO"
["date"]=>
string(%d) "2013-01-01 01:01:01%r(\.000000)?%r"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
["intarray"]=>
array(3) {
[0]=>
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
[1]=>
array(3) {
[0]=>
int(4)
[1]=>
int(5)
[2]=>
int(6)
}
[2]=>
array(3) {
[0]=>
NULL
[1]=>
NULL
[2]=>
NULL
}
}
["boxarray"]=>
array(2) {
[0]=>
string(11) "(2,3),(1,2)"
[1]=>
string(11) "(5,6),(4,5)"
}
["emptyarray"]=>
array(0) {
}
["bytea"]=>
string(4) "foo
"
["bytea_text"]=>
string(10) "\x666f6f0a"
}
DONE
pq-2.2.3/tests/unbuffered001.phpt 0000644 0000765 0000024 00000001612 14560227740 015362 0 ustar mike staff --TEST--
unbuffered result
--SKIPIF--
--FILE--
unbuffered ? true : false);
$c->unbuffered = 1;
var_dump($c->unbuffered);
$c->execAsync("SELECT a from generate_series(1,10) a", function($res) {
switch ($res->status) {
case pq\Result::SINGLE_TUPLE:
$res->fetchCol($val, "a");
printf("%s\n", $val);
break;
case pq\Result::TUPLES_OK:
printf("-> fetching done\n");
break;
default:
printf("!! %s\n", $res->errorMessage);
break;
}
});
do {
while ($c->busy) {
$r = array($c->socket);
$w = $e = null;
if (stream_select($r, $w, $e, null)) {
$c->poll();
}
}
} while ($c->getResult());
?>
DONE
--EXPECTF--
Test
bool(false)
bool(true)
1
2
3
4
5
6
7
8
9
10
-> fetching done
DONE
pq-2.2.3/tests/_setup.inc 0000644 0000765 0000024 00000000076 14560227740 014114 0 ustar mike staff serverVersion) > 0) {
die("skip server {$c->serverVersion} is too old, needed " . SERVER_MIN);
}
} catch (pq\Exception $e) {
die("skip could not connect to PQ_DSN ".$e->getMessage());
}
pq-2.2.3/AUTHORS 0000644 0000765 0000024 00000000037 14560227740 012025 0 ustar mike staff Michael Wallner
pq-2.2.3/BUGS 0000644 0000765 0000024 00000000051 14560227740 011434 0 ustar mike staff Yay, no known and unresolved issues yet!
pq-2.2.3/CONTRIBUTING.md 0000644 0000765 0000024 00000003616 14560227740 013214 0 ustar mike staff # Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of
fostering an open and welcoming community, we pledge to respect all people who
contribute through reporting issues, posting feature requests, updating
documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free
experience for everyone, regardless of level of experience, gender, gender
identity and expression, sexual orientation, disability, personal appearance,
body size, race, ethnicity, age, religion, or nationality.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic
addresses, without explicit permission
* Other unethical or unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct. By adopting this Code of Conduct, project
maintainers commit themselves to fairly and consistently applying these
principles to every aspect of managing this project. Project maintainers who do
not follow or enforce the Code of Conduct may be permanently removed from the
project team.
This code of conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by opening an issue or contacting one or more of the project maintainers.
This Code of Conduct is adapted from the
[Contributor Covenant](http://contributor-covenant.org), version 1.2.0,
available at http://contributor-covenant.org/version/1/2/0/.
pq-2.2.3/CREDITS 0000644 0000765 0000024 00000000023 14560227740 011770 0 ustar mike staff pq
Michael Wallner
pq-2.2.3/LICENSE 0000644 0000765 0000024 00000002501 14560227740 011760 0 ustar mike staff Copyright (c) 2013, Michael Wallner .
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
pq-2.2.3/THANKS 0000644 0000765 0000024 00000000143 14560227740 011666 0 ustar mike staff Thanks go to the following people, who have contributed to this project:
Remi Collet
Chris Wright
pq-2.2.3/TODO 0000644 0000765 0000024 00000000206 14560227740 011443 0 ustar mike staff * COPY: getAsync & putAsync
* fetchInto/fetchCtor?
* binary protocol?
* parse explicit array dimension information in front of arrays
pq-2.2.3/README.md 0000644 0000765 0000024 00000004160 14560227740 012235 0 ustar mike staff # pecl/pq
[](https://github.com/m6w6/ext-pq/actions?query=branch%3Amaster+workflow%3Aci)
[](https://codecov.io/gh/m6w6/ext-pq)
## About:
This is a modern binding to the mature [libpq](http://www.postgresql.org/docs/current/static/libpq.html), the official PostgreSQL C-client library.
### Highlights:
* Nearly 100% support for [asynchronous usage](https://mdref.m6w6.name/pq/Connection/:%20Asynchronous%20Usage).
* Extended [type support by pg_type](https://mdref.m6w6.name/pq/Types/:%20Overview).
* Fetching simple [multi-dimensional array maps](https://mdref.m6w6.name/pq/Result/map).
* Working [Gateway implementation](https://github.com/m6w6/pq-gateway).
## Documentation
See the [online markdown reference](https://mdref.m6w6.name/pq).
Known issues are listed in [BUGS](./BUGS) and future ideas can be found in [TODO](./TODO).
## Install
### PECL
pecl install pq
### PHARext
Watch out for [PECL replicates](https://replicator.pharext.org?pq)
and pharext packages attached to [releases](https://github.com/m6w6/ext-pq/releases).
### Checkout
git clone github.com:m6w6/ext-pq
cd ext-pq
/path/to/phpize
./configure --with-php-config=/path/to/php-config
make
sudo make install
## Dependencies:
This extension unconditionally depends on the pre-loaded presence of the following PHP extensions:
- [raphf](http://pecl.php.net/package/raphf)
- [spl](http://php.net/spl)
It optionally depends on the following extensions:
* [json](http://php.net/json)
## ChangeLog
A comprehensive list of changes can be obtained from the
[PECL website](https://pecl.php.net/package-changelog.php?package=pq).
## License
ext-pq is licensed under the 2-Clause-BSD license, which can be found in
the accompanying [LICENSE](./LICENSE) file.
## Contributing
All forms of contribution are welcome! Please see the bundled
[CONTRIBUTING](./CONTRIBUTING.md) note for the general principles followed.
The list of past and current contributors is maintained in [THANKS](./THANKS).
pq-2.2.3/config.m4 0000644 0000765 0000024 00000000077 14560227740 012470 0 ustar mike staff dnl phpize stub of config9.m4 for pecl/pq
sinclude(config9.m4)
pq-2.2.3/config9.m4 0000644 0000765 0000024 00000010551 14560227740 012557 0 ustar mike staff PHP_ARG_WITH(pq, [whether to enable libpq (PostgreSQL) support],
[ --with-pq[=DIR] Include libpq 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
AC_MSG_CHECKING(for pg_config)
for i in $SEARCH_PATH; do
if test -x "$i/bin/pg_config"; then
PG_CONFIG="$i/bin/pg_config"
break
fi
done
if test -z "$PG_CONFIG"; then
AC_PATH_PROG(PG_CONFIG, pg_config, no)
fi
AC_MSG_RESULT($PG_CONFIG)
if test "$PG_CONFIG" = "no"; then
AC_MSG_ERROR(could not find a usable pg_config in $SEARCH_PATH)
else
if test "$PHP_PQ" != "yes" -a "$PHP_PQ/bin/pg_config" != "$PG_CONFIG"; then
AC_MSG_WARN(Found pg_config is not in $PHP_PQ)
fi
AC_MSG_CHECKING(for PostgreSQL version)
PQ_VERSION=$($PG_CONFIG --version | $SED 's/PostgreSQL //')
if test -z "$PQ_VERSION"; then
AC_MSG_RESULT(not found)
AC_MSG_ERROR(\`$PG_CONFIG --version\` did not provide any meaningful output, please reinstall postgresql/libpq)
else
AC_MSG_RESULT($PQ_VERSION)
AC_DEFINE_UNQUOTED(PHP_PQ_LIBVERSION, "$PQ_VERSION", [ ])
fi
PQ_INCDIR=$($PG_CONFIG --includedir)
PQ_LIBDIR=$($PG_CONFIG --libdir)
fi
PHP_ADD_INCLUDE($PQ_INCDIR)
ifdef([AC_PROG_EGREP], [
AC_PROG_EGREP
], [
AC_CHECK_PROG(EGREP, egrep, egrep)
])
dnl
dnl PQ_CHECK_CONST(name)
dnl
AC_DEFUN([PQ_CHECK_CONST], [
AC_MSG_CHECKING(for $1)
if $EGREP -q $1 $PQ_INCDIR/libpq-fe.h; then
AC_DEFINE(HAVE_$1, 1, [Have $1])
AC_MSG_RESULT(yep)
else
AC_MSG_RESULT(nope)
fi
])
PQ_CHECK_CONST(PGRES_SINGLE_TUPLE)
PQ_CHECK_CONST(PGRES_COPY_BOTH)
PQ_CHECK_CONST(CONNECTION_CHECK_WRITABLE)
PQ_CHECK_CONST(CONNECTION_CONSUME)
PQ_CHECK_CONST(CONNECTION_GSS_STARTUP)
dnl
dnl PQ_CHECK_FUNC(sym, fail-hard)
dnl
AC_DEFUN([PQ_CHECK_FUNC], [
PQ_SYM=$1
FAIL_HARD=$2
save_LIBS="$LIBS"
LIBS=
PHP_CHECK_LIBRARY(pq, $1, [
AC_DEFINE([HAVE_]translit($1,a-z,A-Z), 1, Have $1)
], [
if test -n "$FAIL_HARD"; then
if $FAIL_HARD; then
AC_MSG_ERROR(could not find $PQ_SYM in -lpq -L$PQ_LIBDIR)
fi
fi
], [
-L$PQ_LIBDIR
])
LIBS="$save_LIBS"
])
PQ_CHECK_FUNC(PQregisterEventProc, true)
PHP_ADD_LIBRARY_WITH_PATH(pq, $PQ_LIBDIR, PQ_SHARED_LIBADD)
PHP_SUBST(PQ_SHARED_LIBADD)
PQ_CHECK_FUNC(PQlibVersion)
PQ_CHECK_FUNC(PQprotocolVersion)
PQ_CHECK_FUNC(PQserverVersion)
PQ_CHECK_FUNC(PQconninfo)
PQ_CHECK_FUNC(PQsetSingleRowMode)
dnl
dnl PQ_HAVE_PHP_EXT(name[, code-if-yes[, code-if-not]])
dnl
AC_DEFUN([PQ_HAVE_PHP_EXT], [
extname=$1
haveext=$[PHP_]translit($1,a-z_-,A-Z__)
AC_MSG_CHECKING([for ext/$extname support])
if test "$haveext" != "no" && test "x$haveext" != "x"; then
[PHP_PQ_HAVE_EXT_]translit($1,a-z_-,A-Z__)=1
AC_MSG_RESULT([yes])
$2
elif test -x "$PHP_EXECUTABLE"; then
grepext=`$PHP_EXECUTABLE -m | $EGREP ^$extname\$`
if test "$grepext" = "$extname"; then
[PHP_PQ_HAVE_EXT_]translit($1,a-z_-,A-Z__)=1
AC_MSG_RESULT([yes])
$2
else
[PHP_PQ_HAVE_EXT_]translit($1,a-z_-,A-Z__)=
AC_MSG_RESULT([no])
$3
fi
else
[PHP_PQ_HAVE_EXT_]translit($1,a-z_-,A-Z__)=
AC_MSG_RESULT([no])
$3
fi
])
PQ_SRC="\
src/php_pq_module.c\
src/php_pq_misc.c\
src/php_pq_callback.c\
src/php_pq_object.c\
src/php_pq_params.c\
src/php_pqcancel.c\
src/php_pqconn.c\
src/php_pqconn_event.c\
src/php_pqcopy.c\
src/php_pqexc.c\
src/php_pqlob.c\
src/php_pqres.c\
src/php_pqstm.c\
src/php_pqtxn.c\
src/php_pqtypes.c\
src/php_pqcur.c\
"
PHP_NEW_EXTENSION(pq, $PQ_SRC, $ext_shared)
PHP_ADD_BUILD_DIR($ext_builddir/src)
PHP_ADD_INCLUDE($ext_srcdir/src)
PQ_HAVE_PHP_EXT([raphf], [
AC_MSG_CHECKING([for php_raphf.h])
PQ_EXT_RAPHF_INCDIR=
for i in `echo $INCLUDES | $SED -e's/-I//g'` $abs_srcdir ../raphf; do
if test -d $i; then
if test -f $i/php_raphf.h; then
PQ_EXT_RAPHF_INCDIR=$i
break
elif test -f $i/ext/raphf/php_raphf.h; then
PQ_EXT_RAPHF_INCDIR=$i/ext/raphf
break
fi
fi
done
if test "x$PQ_EXT_RAPHF_INCDIR" = "x"; then
AC_MSG_ERROR([not found])
else
AC_MSG_RESULT([$PQ_EXT_RAPHF_INCDIR])
AC_DEFINE([PHP_PQ_HAVE_PHP_RAPHF_H], [1], [Have ext/raphf support])
PHP_ADD_INCLUDE([$PQ_EXT_RAPHF_INCDIR])
fi
], [
AC_MSG_ERROR([Please install pecl/raphf and activate extension=raphf.$SHLIB_DL_SUFFIX_NAME in your php.ini])
])
PHP_ADD_EXTENSION_DEP(pq, raphf, true)
fi
pq-2.2.3/php_pq.h 0000644 0000765 0000024 00000003110 14560227740 012410 0 ustar mike staff /*
+--------------------------------------------------------------------+
| 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) 2013, Michael Wallner |
+--------------------------------------------------------------------+
*/
#ifndef PHP_PQ_H
#define PHP_PQ_H
#define PHP_PQ_VERSION "2.2.3"
#ifdef PHP_WIN32
# define PHP_PQ_API __declspec(dllexport)
#elif defined(__GNUC__) && __GNUC__ >= 4
# define PHP_PQ_API extern __attribute__ ((visibility("default")))
#else
# define PHP_PQ_API extern
#endif
extern int pq_module_number;
extern zend_module_entry pq_module_entry;
#define phpext_pq_ptr &pq_module_entry
ZEND_BEGIN_MODULE_GLOBALS(php_pq)
struct {
/* for ext-raphf */
zend_string *name;
} connection;
ZEND_END_MODULE_GLOBALS(php_pq)
ZEND_EXTERN_MODULE_GLOBALS(php_pq);
#ifdef ZTS
# include "TSRM/TSRM.h"
# define PHP_PQ_G ((zend_php_pq_globals *) (*((void ***) tsrm_get_ls_cache()))[TSRM_UNSHUFFLE_RSRC_ID(php_pq_globals_id)])
#else
# define PHP_PQ_G (&php_pq_globals)
#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
*/
pq-2.2.3/php_pq_type.h 0000644 0000765 0000024 00000046646 14560227740 013476 0 ustar mike staff
/* Generated file. See scripts/gen_pq_type-pq11.php */
#ifndef PHP_PQ_TYPE
# define PHP_PQ_TYPE(t,o)
#endif
#ifndef PHP_PQ_OID_BOOL
# define PHP_PQ_OID_BOOL 16
#endif
PHP_PQ_TYPE("BOOL", 16)
#ifndef PHP_PQ_OID_BYTEA
# define PHP_PQ_OID_BYTEA 17
#endif
PHP_PQ_TYPE("BYTEA", 17)
#ifndef PHP_PQ_OID_CHAR
# define PHP_PQ_OID_CHAR 18
#endif
PHP_PQ_TYPE("CHAR", 18)
#ifndef PHP_PQ_OID_NAME
# define PHP_PQ_OID_NAME 19
#endif
PHP_PQ_TYPE("NAME", 19)
#ifndef PHP_PQ_OID_INT8
# define PHP_PQ_OID_INT8 20
#endif
PHP_PQ_TYPE("INT8", 20)
#ifndef PHP_PQ_OID_INT2
# define PHP_PQ_OID_INT2 21
#endif
PHP_PQ_TYPE("INT2", 21)
#ifndef PHP_PQ_OID_INT2VECTOR
# define PHP_PQ_OID_INT2VECTOR 22
#endif
PHP_PQ_TYPE("INT2VECTOR", 22)
#ifndef PHP_PQ_OID_INT4
# define PHP_PQ_OID_INT4 23
#endif
PHP_PQ_TYPE("INT4", 23)
#ifndef PHP_PQ_OID_REGPROC
# define PHP_PQ_OID_REGPROC 24
#endif
PHP_PQ_TYPE("REGPROC", 24)
#ifndef PHP_PQ_OID_TEXT
# define PHP_PQ_OID_TEXT 25
#endif
PHP_PQ_TYPE("TEXT", 25)
#ifndef PHP_PQ_OID_OID
# define PHP_PQ_OID_OID 26
#endif
PHP_PQ_TYPE("OID", 26)
#ifndef PHP_PQ_OID_TID
# define PHP_PQ_OID_TID 27
#endif
PHP_PQ_TYPE("TID", 27)
#ifndef PHP_PQ_OID_XID
# define PHP_PQ_OID_XID 28
#endif
PHP_PQ_TYPE("XID", 28)
#ifndef PHP_PQ_OID_CID
# define PHP_PQ_OID_CID 29
#endif
PHP_PQ_TYPE("CID", 29)
#ifndef PHP_PQ_OID_OIDVECTOR
# define PHP_PQ_OID_OIDVECTOR 30
#endif
PHP_PQ_TYPE("OIDVECTOR", 30)
#ifndef PHP_PQ_OID_PG_DDL_COMMAND
# define PHP_PQ_OID_PG_DDL_COMMAND 32
#endif
PHP_PQ_TYPE("PG_DDL_COMMAND", 32)
#ifndef PHP_PQ_OID_PG_TYPE
# define PHP_PQ_OID_PG_TYPE 71
#endif
PHP_PQ_TYPE("PG_TYPE", 71)
#ifndef PHP_PQ_OID_PG_ATTRIBUTE
# define PHP_PQ_OID_PG_ATTRIBUTE 75
#endif
PHP_PQ_TYPE("PG_ATTRIBUTE", 75)
#ifndef PHP_PQ_OID_PG_PROC
# define PHP_PQ_OID_PG_PROC 81
#endif
PHP_PQ_TYPE("PG_PROC", 81)
#ifndef PHP_PQ_OID_PG_CLASS
# define PHP_PQ_OID_PG_CLASS 83
#endif
PHP_PQ_TYPE("PG_CLASS", 83)
#ifndef PHP_PQ_OID_JSON
# define PHP_PQ_OID_JSON 114
#endif
PHP_PQ_TYPE("JSON", 114)
#ifndef PHP_PQ_OID_XML
# define PHP_PQ_OID_XML 142
#endif
PHP_PQ_TYPE("XML", 142)
#ifndef PHP_PQ_OID_XMLARRAY
# define PHP_PQ_OID_XMLARRAY 143
#endif
PHP_PQ_TYPE("XMLARRAY", 143)
#ifndef PHP_PQ_OID_PG_NODE_TREE
# define PHP_PQ_OID_PG_NODE_TREE 194
#endif
PHP_PQ_TYPE("PG_NODE_TREE", 194)
#ifndef PHP_PQ_OID_JSONARRAY
# define PHP_PQ_OID_JSONARRAY 199
#endif
PHP_PQ_TYPE("JSONARRAY", 199)
#ifndef PHP_PQ_OID_SMGR
# define PHP_PQ_OID_SMGR 210
#endif
PHP_PQ_TYPE("SMGR", 210)
#ifndef PHP_PQ_OID_INDEX_AM_HANDLER
# define PHP_PQ_OID_INDEX_AM_HANDLER 325
#endif
PHP_PQ_TYPE("INDEX_AM_HANDLER", 325)
#ifndef PHP_PQ_OID_POINT
# define PHP_PQ_OID_POINT 600
#endif
PHP_PQ_TYPE("POINT", 600)
#ifndef PHP_PQ_OID_LSEG
# define PHP_PQ_OID_LSEG 601
#endif
PHP_PQ_TYPE("LSEG", 601)
#ifndef PHP_PQ_OID_PATH
# define PHP_PQ_OID_PATH 602
#endif
PHP_PQ_TYPE("PATH", 602)
#ifndef PHP_PQ_OID_BOX
# define PHP_PQ_OID_BOX 603
#endif
PHP_PQ_TYPE("BOX", 603)
#ifndef PHP_PQ_OID_POLYGON
# define PHP_PQ_OID_POLYGON 604
#endif
PHP_PQ_TYPE("POLYGON", 604)
#ifndef PHP_PQ_OID_LINE
# define PHP_PQ_OID_LINE 628
#endif
PHP_PQ_TYPE("LINE", 628)
#ifndef PHP_PQ_OID_LINEARRAY
# define PHP_PQ_OID_LINEARRAY 629
#endif
PHP_PQ_TYPE("LINEARRAY", 629)
#ifndef PHP_PQ_OID_CIDR
# define PHP_PQ_OID_CIDR 650
#endif
PHP_PQ_TYPE("CIDR", 650)
#ifndef PHP_PQ_OID_CIDRARRAY
# define PHP_PQ_OID_CIDRARRAY 651
#endif
PHP_PQ_TYPE("CIDRARRAY", 651)
#ifndef PHP_PQ_OID_FLOAT4
# define PHP_PQ_OID_FLOAT4 700
#endif
PHP_PQ_TYPE("FLOAT4", 700)
#ifndef PHP_PQ_OID_FLOAT8
# define PHP_PQ_OID_FLOAT8 701
#endif
PHP_PQ_TYPE("FLOAT8", 701)
#ifndef PHP_PQ_OID_UNKNOWN
# define PHP_PQ_OID_UNKNOWN 705
#endif
PHP_PQ_TYPE("UNKNOWN", 705)
#ifndef PHP_PQ_OID_CIRCLE
# define PHP_PQ_OID_CIRCLE 718
#endif
PHP_PQ_TYPE("CIRCLE", 718)
#ifndef PHP_PQ_OID_CIRCLEARRAY
# define PHP_PQ_OID_CIRCLEARRAY 719
#endif
PHP_PQ_TYPE("CIRCLEARRAY", 719)
#ifndef PHP_PQ_OID_MACADDR8
# define PHP_PQ_OID_MACADDR8 774
#endif
PHP_PQ_TYPE("MACADDR8", 774)
#ifndef PHP_PQ_OID_MACADDR8ARRAY
# define PHP_PQ_OID_MACADDR8ARRAY 775
#endif
PHP_PQ_TYPE("MACADDR8ARRAY", 775)
#ifndef PHP_PQ_OID_MONEY
# define PHP_PQ_OID_MONEY 790
#endif
PHP_PQ_TYPE("MONEY", 790)
#ifndef PHP_PQ_OID_MONEYARRAY
# define PHP_PQ_OID_MONEYARRAY 791
#endif
PHP_PQ_TYPE("MONEYARRAY", 791)
#ifndef PHP_PQ_OID_MACADDR
# define PHP_PQ_OID_MACADDR 829
#endif
PHP_PQ_TYPE("MACADDR", 829)
#ifndef PHP_PQ_OID_INET
# define PHP_PQ_OID_INET 869
#endif
PHP_PQ_TYPE("INET", 869)
#ifndef PHP_PQ_OID_BOOLARRAY
# define PHP_PQ_OID_BOOLARRAY 1000
#endif
PHP_PQ_TYPE("BOOLARRAY", 1000)
#ifndef PHP_PQ_OID_BYTEAARRAY
# define PHP_PQ_OID_BYTEAARRAY 1001
#endif
PHP_PQ_TYPE("BYTEAARRAY", 1001)
#ifndef PHP_PQ_OID_CHARARRAY
# define PHP_PQ_OID_CHARARRAY 1002
#endif
PHP_PQ_TYPE("CHARARRAY", 1002)
#ifndef PHP_PQ_OID_NAMEARRAY
# define PHP_PQ_OID_NAMEARRAY 1003
#endif
PHP_PQ_TYPE("NAMEARRAY", 1003)
#ifndef PHP_PQ_OID_INT2ARRAY
# define PHP_PQ_OID_INT2ARRAY 1005
#endif
PHP_PQ_TYPE("INT2ARRAY", 1005)
#ifndef PHP_PQ_OID_INT2VECTORARRAY
# define PHP_PQ_OID_INT2VECTORARRAY 1006
#endif
PHP_PQ_TYPE("INT2VECTORARRAY", 1006)
#ifndef PHP_PQ_OID_INT4ARRAY
# define PHP_PQ_OID_INT4ARRAY 1007
#endif
PHP_PQ_TYPE("INT4ARRAY", 1007)
#ifndef PHP_PQ_OID_REGPROCARRAY
# define PHP_PQ_OID_REGPROCARRAY 1008
#endif
PHP_PQ_TYPE("REGPROCARRAY", 1008)
#ifndef PHP_PQ_OID_TEXTARRAY
# define PHP_PQ_OID_TEXTARRAY 1009
#endif
PHP_PQ_TYPE("TEXTARRAY", 1009)
#ifndef PHP_PQ_OID_TIDARRAY
# define PHP_PQ_OID_TIDARRAY 1010
#endif
PHP_PQ_TYPE("TIDARRAY", 1010)
#ifndef PHP_PQ_OID_XIDARRAY
# define PHP_PQ_OID_XIDARRAY 1011
#endif
PHP_PQ_TYPE("XIDARRAY", 1011)
#ifndef PHP_PQ_OID_CIDARRAY
# define PHP_PQ_OID_CIDARRAY 1012
#endif
PHP_PQ_TYPE("CIDARRAY", 1012)
#ifndef PHP_PQ_OID_OIDVECTORARRAY
# define PHP_PQ_OID_OIDVECTORARRAY 1013
#endif
PHP_PQ_TYPE("OIDVECTORARRAY", 1013)
#ifndef PHP_PQ_OID_BPCHARARRAY
# define PHP_PQ_OID_BPCHARARRAY 1014
#endif
PHP_PQ_TYPE("BPCHARARRAY", 1014)
#ifndef PHP_PQ_OID_VARCHARARRAY
# define PHP_PQ_OID_VARCHARARRAY 1015
#endif
PHP_PQ_TYPE("VARCHARARRAY", 1015)
#ifndef PHP_PQ_OID_INT8ARRAY
# define PHP_PQ_OID_INT8ARRAY 1016
#endif
PHP_PQ_TYPE("INT8ARRAY", 1016)
#ifndef PHP_PQ_OID_POINTARRAY
# define PHP_PQ_OID_POINTARRAY 1017
#endif
PHP_PQ_TYPE("POINTARRAY", 1017)
#ifndef PHP_PQ_OID_LSEGARRAY
# define PHP_PQ_OID_LSEGARRAY 1018
#endif
PHP_PQ_TYPE("LSEGARRAY", 1018)
#ifndef PHP_PQ_OID_PATHARRAY
# define PHP_PQ_OID_PATHARRAY 1019
#endif
PHP_PQ_TYPE("PATHARRAY", 1019)
#ifndef PHP_PQ_OID_BOXARRAY
# define PHP_PQ_OID_BOXARRAY 1020
#endif
PHP_PQ_TYPE("BOXARRAY", 1020)
#ifndef PHP_PQ_OID_FLOAT4ARRAY
# define PHP_PQ_OID_FLOAT4ARRAY 1021
#endif
PHP_PQ_TYPE("FLOAT4ARRAY", 1021)
#ifndef PHP_PQ_OID_FLOAT8ARRAY
# define PHP_PQ_OID_FLOAT8ARRAY 1022
#endif
PHP_PQ_TYPE("FLOAT8ARRAY", 1022)
#ifndef PHP_PQ_OID_POLYGONARRAY
# define PHP_PQ_OID_POLYGONARRAY 1027
#endif
PHP_PQ_TYPE("POLYGONARRAY", 1027)
#ifndef PHP_PQ_OID_OIDARRAY
# define PHP_PQ_OID_OIDARRAY 1028
#endif
PHP_PQ_TYPE("OIDARRAY", 1028)
#ifndef PHP_PQ_OID_ACLITEM
# define PHP_PQ_OID_ACLITEM 1033
#endif
PHP_PQ_TYPE("ACLITEM", 1033)
#ifndef PHP_PQ_OID_ACLITEMARRAY
# define PHP_PQ_OID_ACLITEMARRAY 1034
#endif
PHP_PQ_TYPE("ACLITEMARRAY", 1034)
#ifndef PHP_PQ_OID_MACADDRARRAY
# define PHP_PQ_OID_MACADDRARRAY 1040
#endif
PHP_PQ_TYPE("MACADDRARRAY", 1040)
#ifndef PHP_PQ_OID_INETARRAY
# define PHP_PQ_OID_INETARRAY 1041
#endif
PHP_PQ_TYPE("INETARRAY", 1041)
#ifndef PHP_PQ_OID_BPCHAR
# define PHP_PQ_OID_BPCHAR 1042
#endif
PHP_PQ_TYPE("BPCHAR", 1042)
#ifndef PHP_PQ_OID_VARCHAR
# define PHP_PQ_OID_VARCHAR 1043
#endif
PHP_PQ_TYPE("VARCHAR", 1043)
#ifndef PHP_PQ_OID_DATE
# define PHP_PQ_OID_DATE 1082
#endif
PHP_PQ_TYPE("DATE", 1082)
#ifndef PHP_PQ_OID_TIME
# define PHP_PQ_OID_TIME 1083
#endif
PHP_PQ_TYPE("TIME", 1083)
#ifndef PHP_PQ_OID_TIMESTAMP
# define PHP_PQ_OID_TIMESTAMP 1114
#endif
PHP_PQ_TYPE("TIMESTAMP", 1114)
#ifndef PHP_PQ_OID_TIMESTAMPARRAY
# define PHP_PQ_OID_TIMESTAMPARRAY 1115
#endif
PHP_PQ_TYPE("TIMESTAMPARRAY", 1115)
#ifndef PHP_PQ_OID_DATEARRAY
# define PHP_PQ_OID_DATEARRAY 1182
#endif
PHP_PQ_TYPE("DATEARRAY", 1182)
#ifndef PHP_PQ_OID_TIMEARRAY
# define PHP_PQ_OID_TIMEARRAY 1183
#endif
PHP_PQ_TYPE("TIMEARRAY", 1183)
#ifndef PHP_PQ_OID_TIMESTAMPTZ
# define PHP_PQ_OID_TIMESTAMPTZ 1184
#endif
PHP_PQ_TYPE("TIMESTAMPTZ", 1184)
#ifndef PHP_PQ_OID_TIMESTAMPTZARRAY
# define PHP_PQ_OID_TIMESTAMPTZARRAY 1185
#endif
PHP_PQ_TYPE("TIMESTAMPTZARRAY", 1185)
#ifndef PHP_PQ_OID_INTERVAL
# define PHP_PQ_OID_INTERVAL 1186
#endif
PHP_PQ_TYPE("INTERVAL", 1186)
#ifndef PHP_PQ_OID_INTERVALARRAY
# define PHP_PQ_OID_INTERVALARRAY 1187
#endif
PHP_PQ_TYPE("INTERVALARRAY", 1187)
#ifndef PHP_PQ_OID_NUMERICARRAY
# define PHP_PQ_OID_NUMERICARRAY 1231
#endif
PHP_PQ_TYPE("NUMERICARRAY", 1231)
#ifndef PHP_PQ_OID_CSTRINGARRAY
# define PHP_PQ_OID_CSTRINGARRAY 1263
#endif
PHP_PQ_TYPE("CSTRINGARRAY", 1263)
#ifndef PHP_PQ_OID_TIMETZ
# define PHP_PQ_OID_TIMETZ 1266
#endif
PHP_PQ_TYPE("TIMETZ", 1266)
#ifndef PHP_PQ_OID_TIMETZARRAY
# define PHP_PQ_OID_TIMETZARRAY 1270
#endif
PHP_PQ_TYPE("TIMETZARRAY", 1270)
#ifndef PHP_PQ_OID_BIT
# define PHP_PQ_OID_BIT 1560
#endif
PHP_PQ_TYPE("BIT", 1560)
#ifndef PHP_PQ_OID_BITARRAY
# define PHP_PQ_OID_BITARRAY 1561
#endif
PHP_PQ_TYPE("BITARRAY", 1561)
#ifndef PHP_PQ_OID_VARBIT
# define PHP_PQ_OID_VARBIT 1562
#endif
PHP_PQ_TYPE("VARBIT", 1562)
#ifndef PHP_PQ_OID_VARBITARRAY
# define PHP_PQ_OID_VARBITARRAY 1563
#endif
PHP_PQ_TYPE("VARBITARRAY", 1563)
#ifndef PHP_PQ_OID_NUMERIC
# define PHP_PQ_OID_NUMERIC 1700
#endif
PHP_PQ_TYPE("NUMERIC", 1700)
#ifndef PHP_PQ_OID_REFCURSOR
# define PHP_PQ_OID_REFCURSOR 1790
#endif
PHP_PQ_TYPE("REFCURSOR", 1790)
#ifndef PHP_PQ_OID_REFCURSORARRAY
# define PHP_PQ_OID_REFCURSORARRAY 2201
#endif
PHP_PQ_TYPE("REFCURSORARRAY", 2201)
#ifndef PHP_PQ_OID_REGPROCEDURE
# define PHP_PQ_OID_REGPROCEDURE 2202
#endif
PHP_PQ_TYPE("REGPROCEDURE", 2202)
#ifndef PHP_PQ_OID_REGOPER
# define PHP_PQ_OID_REGOPER 2203
#endif
PHP_PQ_TYPE("REGOPER", 2203)
#ifndef PHP_PQ_OID_REGOPERATOR
# define PHP_PQ_OID_REGOPERATOR 2204
#endif
PHP_PQ_TYPE("REGOPERATOR", 2204)
#ifndef PHP_PQ_OID_REGCLASS
# define PHP_PQ_OID_REGCLASS 2205
#endif
PHP_PQ_TYPE("REGCLASS", 2205)
#ifndef PHP_PQ_OID_REGTYPE
# define PHP_PQ_OID_REGTYPE 2206
#endif
PHP_PQ_TYPE("REGTYPE", 2206)
#ifndef PHP_PQ_OID_REGPROCEDUREARRAY
# define PHP_PQ_OID_REGPROCEDUREARRAY 2207
#endif
PHP_PQ_TYPE("REGPROCEDUREARRAY", 2207)
#ifndef PHP_PQ_OID_REGOPERARRAY
# define PHP_PQ_OID_REGOPERARRAY 2208
#endif
PHP_PQ_TYPE("REGOPERARRAY", 2208)
#ifndef PHP_PQ_OID_REGOPERATORARRAY
# define PHP_PQ_OID_REGOPERATORARRAY 2209
#endif
PHP_PQ_TYPE("REGOPERATORARRAY", 2209)
#ifndef PHP_PQ_OID_REGCLASSARRAY
# define PHP_PQ_OID_REGCLASSARRAY 2210
#endif
PHP_PQ_TYPE("REGCLASSARRAY", 2210)
#ifndef PHP_PQ_OID_REGTYPEARRAY
# define PHP_PQ_OID_REGTYPEARRAY 2211
#endif
PHP_PQ_TYPE("REGTYPEARRAY", 2211)
#ifndef PHP_PQ_OID_RECORD
# define PHP_PQ_OID_RECORD 2249
#endif
PHP_PQ_TYPE("RECORD", 2249)
#ifndef PHP_PQ_OID_CSTRING
# define PHP_PQ_OID_CSTRING 2275
#endif
PHP_PQ_TYPE("CSTRING", 2275)
#ifndef PHP_PQ_OID_ANY
# define PHP_PQ_OID_ANY 2276
#endif
PHP_PQ_TYPE("ANY", 2276)
#ifndef PHP_PQ_OID_ANYARRAY
# define PHP_PQ_OID_ANYARRAY 2277
#endif
PHP_PQ_TYPE("ANYARRAY", 2277)
#ifndef PHP_PQ_OID_VOID
# define PHP_PQ_OID_VOID 2278
#endif
PHP_PQ_TYPE("VOID", 2278)
#ifndef PHP_PQ_OID_TRIGGER
# define PHP_PQ_OID_TRIGGER 2279
#endif
PHP_PQ_TYPE("TRIGGER", 2279)
#ifndef PHP_PQ_OID_LANGUAGE_HANDLER
# define PHP_PQ_OID_LANGUAGE_HANDLER 2280
#endif
PHP_PQ_TYPE("LANGUAGE_HANDLER", 2280)
#ifndef PHP_PQ_OID_INTERNAL
# define PHP_PQ_OID_INTERNAL 2281
#endif
PHP_PQ_TYPE("INTERNAL", 2281)
#ifndef PHP_PQ_OID_OPAQUE
# define PHP_PQ_OID_OPAQUE 2282
#endif
PHP_PQ_TYPE("OPAQUE", 2282)
#ifndef PHP_PQ_OID_ANYELEMENT
# define PHP_PQ_OID_ANYELEMENT 2283
#endif
PHP_PQ_TYPE("ANYELEMENT", 2283)
#ifndef PHP_PQ_OID__RECORD
# define PHP_PQ_OID__RECORD 2287
#endif
PHP_PQ_TYPE("_RECORD", 2287)
#ifndef PHP_PQ_OID_ANYNONARRAY
# define PHP_PQ_OID_ANYNONARRAY 2776
#endif
PHP_PQ_TYPE("ANYNONARRAY", 2776)
#ifndef PHP_PQ_OID_TXID_SNAPSHOTARRAY
# define PHP_PQ_OID_TXID_SNAPSHOTARRAY 2949
#endif
PHP_PQ_TYPE("TXID_SNAPSHOTARRAY", 2949)
#ifndef PHP_PQ_OID_UUID
# define PHP_PQ_OID_UUID 2950
#endif
PHP_PQ_TYPE("UUID", 2950)
#ifndef PHP_PQ_OID_UUIDARRAY
# define PHP_PQ_OID_UUIDARRAY 2951
#endif
PHP_PQ_TYPE("UUIDARRAY", 2951)
#ifndef PHP_PQ_OID_TXID_SNAPSHOT
# define PHP_PQ_OID_TXID_SNAPSHOT 2970
#endif
PHP_PQ_TYPE("TXID_SNAPSHOT", 2970)
#ifndef PHP_PQ_OID_FDW_HANDLER
# define PHP_PQ_OID_FDW_HANDLER 3115
#endif
PHP_PQ_TYPE("FDW_HANDLER", 3115)
#ifndef PHP_PQ_OID_PG_LSN
# define PHP_PQ_OID_PG_LSN 3220
#endif
PHP_PQ_TYPE("PG_LSN", 3220)
#ifndef PHP_PQ_OID_PG_LSNARRAY
# define PHP_PQ_OID_PG_LSNARRAY 3221
#endif
PHP_PQ_TYPE("PG_LSNARRAY", 3221)
#ifndef PHP_PQ_OID_TSM_HANDLER
# define PHP_PQ_OID_TSM_HANDLER 3310
#endif
PHP_PQ_TYPE("TSM_HANDLER", 3310)
#ifndef PHP_PQ_OID_PG_NDISTINCT
# define PHP_PQ_OID_PG_NDISTINCT 3361
#endif
PHP_PQ_TYPE("PG_NDISTINCT", 3361)
#ifndef PHP_PQ_OID_PG_DEPENDENCIES
# define PHP_PQ_OID_PG_DEPENDENCIES 3402
#endif
PHP_PQ_TYPE("PG_DEPENDENCIES", 3402)
#ifndef PHP_PQ_OID_ANYENUM
# define PHP_PQ_OID_ANYENUM 3500
#endif
PHP_PQ_TYPE("ANYENUM", 3500)
#ifndef PHP_PQ_OID_TSVECTOR
# define PHP_PQ_OID_TSVECTOR 3614
#endif
PHP_PQ_TYPE("TSVECTOR", 3614)
#ifndef PHP_PQ_OID_TSQUERY
# define PHP_PQ_OID_TSQUERY 3615
#endif
PHP_PQ_TYPE("TSQUERY", 3615)
#ifndef PHP_PQ_OID_GTSVECTOR
# define PHP_PQ_OID_GTSVECTOR 3642
#endif
PHP_PQ_TYPE("GTSVECTOR", 3642)
#ifndef PHP_PQ_OID_TSVECTORARRAY
# define PHP_PQ_OID_TSVECTORARRAY 3643
#endif
PHP_PQ_TYPE("TSVECTORARRAY", 3643)
#ifndef PHP_PQ_OID_GTSVECTORARRAY
# define PHP_PQ_OID_GTSVECTORARRAY 3644
#endif
PHP_PQ_TYPE("GTSVECTORARRAY", 3644)
#ifndef PHP_PQ_OID_TSQUERYARRAY
# define PHP_PQ_OID_TSQUERYARRAY 3645
#endif
PHP_PQ_TYPE("TSQUERYARRAY", 3645)
#ifndef PHP_PQ_OID_REGCONFIG
# define PHP_PQ_OID_REGCONFIG 3734
#endif
PHP_PQ_TYPE("REGCONFIG", 3734)
#ifndef PHP_PQ_OID_REGCONFIGARRAY
# define PHP_PQ_OID_REGCONFIGARRAY 3735
#endif
PHP_PQ_TYPE("REGCONFIGARRAY", 3735)
#ifndef PHP_PQ_OID_REGDICTIONARY
# define PHP_PQ_OID_REGDICTIONARY 3769
#endif
PHP_PQ_TYPE("REGDICTIONARY", 3769)
#ifndef PHP_PQ_OID_REGDICTIONARYARRAY
# define PHP_PQ_OID_REGDICTIONARYARRAY 3770
#endif
PHP_PQ_TYPE("REGDICTIONARYARRAY", 3770)
#ifndef PHP_PQ_OID_JSONB
# define PHP_PQ_OID_JSONB 3802
#endif
PHP_PQ_TYPE("JSONB", 3802)
#ifndef PHP_PQ_OID_JSONBARRAY
# define PHP_PQ_OID_JSONBARRAY 3807
#endif
PHP_PQ_TYPE("JSONBARRAY", 3807)
#ifndef PHP_PQ_OID_ANYRANGE
# define PHP_PQ_OID_ANYRANGE 3831
#endif
PHP_PQ_TYPE("ANYRANGE", 3831)
#ifndef PHP_PQ_OID_EVENT_TRIGGER
# define PHP_PQ_OID_EVENT_TRIGGER 3838
#endif
PHP_PQ_TYPE("EVENT_TRIGGER", 3838)
#ifndef PHP_PQ_OID_INT4RANGE
# define PHP_PQ_OID_INT4RANGE 3904
#endif
PHP_PQ_TYPE("INT4RANGE", 3904)
#ifndef PHP_PQ_OID_INT4RANGEARRAY
# define PHP_PQ_OID_INT4RANGEARRAY 3905
#endif
PHP_PQ_TYPE("INT4RANGEARRAY", 3905)
#ifndef PHP_PQ_OID_NUMRANGE
# define PHP_PQ_OID_NUMRANGE 3906
#endif
PHP_PQ_TYPE("NUMRANGE", 3906)
#ifndef PHP_PQ_OID_NUMRANGEARRAY
# define PHP_PQ_OID_NUMRANGEARRAY 3907
#endif
PHP_PQ_TYPE("NUMRANGEARRAY", 3907)
#ifndef PHP_PQ_OID_TSRANGE
# define PHP_PQ_OID_TSRANGE 3908
#endif
PHP_PQ_TYPE("TSRANGE", 3908)
#ifndef PHP_PQ_OID_TSRANGEARRAY
# define PHP_PQ_OID_TSRANGEARRAY 3909
#endif
PHP_PQ_TYPE("TSRANGEARRAY", 3909)
#ifndef PHP_PQ_OID_TSTZRANGE
# define PHP_PQ_OID_TSTZRANGE 3910
#endif
PHP_PQ_TYPE("TSTZRANGE", 3910)
#ifndef PHP_PQ_OID_TSTZRANGEARRAY
# define PHP_PQ_OID_TSTZRANGEARRAY 3911
#endif
PHP_PQ_TYPE("TSTZRANGEARRAY", 3911)
#ifndef PHP_PQ_OID_DATERANGE
# define PHP_PQ_OID_DATERANGE 3912
#endif
PHP_PQ_TYPE("DATERANGE", 3912)
#ifndef PHP_PQ_OID_DATERANGEARRAY
# define PHP_PQ_OID_DATERANGEARRAY 3913
#endif
PHP_PQ_TYPE("DATERANGEARRAY", 3913)
#ifndef PHP_PQ_OID_INT8RANGE
# define PHP_PQ_OID_INT8RANGE 3926
#endif
PHP_PQ_TYPE("INT8RANGE", 3926)
#ifndef PHP_PQ_OID_INT8RANGEARRAY
# define PHP_PQ_OID_INT8RANGEARRAY 3927
#endif
PHP_PQ_TYPE("INT8RANGEARRAY", 3927)
#ifndef PHP_PQ_OID_REGNAMESPACE
# define PHP_PQ_OID_REGNAMESPACE 4089
#endif
PHP_PQ_TYPE("REGNAMESPACE", 4089)
#ifndef PHP_PQ_OID_REGNAMESPACEARRAY
# define PHP_PQ_OID_REGNAMESPACEARRAY 4090
#endif
PHP_PQ_TYPE("REGNAMESPACEARRAY", 4090)
#ifndef PHP_PQ_OID_REGROLE
# define PHP_PQ_OID_REGROLE 4096
#endif
PHP_PQ_TYPE("REGROLE", 4096)
#ifndef PHP_PQ_OID_REGROLEARRAY
# define PHP_PQ_OID_REGROLEARRAY 4097
#endif
PHP_PQ_TYPE("REGROLEARRAY", 4097)
#ifndef PHP_PQ_TYPE_IS_ARRAY
# define PHP_PQ_TYPE_IS_ARRAY(oid) ( \
0 \
|| ((oid) == 143) \
|| ((oid) == 199) \
|| ((oid) == 629) \
|| ((oid) == 651) \
|| ((oid) == 719) \
|| ((oid) == 775) \
|| ((oid) == 791) \
|| ((oid) == 1000) \
|| ((oid) == 1001) \
|| ((oid) == 1002) \
|| ((oid) == 1003) \
|| ((oid) == 1005) \
|| ((oid) == 1006) \
|| ((oid) == 1007) \
|| ((oid) == 1008) \
|| ((oid) == 1009) \
|| ((oid) == 1010) \
|| ((oid) == 1011) \
|| ((oid) == 1012) \
|| ((oid) == 1013) \
|| ((oid) == 1014) \
|| ((oid) == 1015) \
|| ((oid) == 1016) \
|| ((oid) == 1017) \
|| ((oid) == 1018) \
|| ((oid) == 1019) \
|| ((oid) == 1020) \
|| ((oid) == 1021) \
|| ((oid) == 1022) \
|| ((oid) == 1027) \
|| ((oid) == 1028) \
|| ((oid) == 1034) \
|| ((oid) == 1040) \
|| ((oid) == 1041) \
|| ((oid) == 1115) \
|| ((oid) == 1182) \
|| ((oid) == 1183) \
|| ((oid) == 1185) \
|| ((oid) == 1187) \
|| ((oid) == 1231) \
|| ((oid) == 1263) \
|| ((oid) == 1270) \
|| ((oid) == 1561) \
|| ((oid) == 1563) \
|| ((oid) == 2201) \
|| ((oid) == 2207) \
|| ((oid) == 2208) \
|| ((oid) == 2209) \
|| ((oid) == 2210) \
|| ((oid) == 2211) \
|| ((oid) == 2949) \
|| ((oid) == 2951) \
|| ((oid) == 3221) \
|| ((oid) == 3643) \
|| ((oid) == 3644) \
|| ((oid) == 3645) \
|| ((oid) == 3735) \
|| ((oid) == 3770) \
|| ((oid) == 3807) \
|| ((oid) == 3905) \
|| ((oid) == 3907) \
|| ((oid) == 3909) \
|| ((oid) == 3911) \
|| ((oid) == 3913) \
|| ((oid) == 3927) \
|| ((oid) == 4090) \
|| ((oid) == 4097) \
)
#endif
#ifndef PHP_PQ_TYPE_OF_ARRAY
# define PHP_PQ_TYPE_OF_ARRAY(oid) ( \
(oid) == 143 ? 142 : \
(oid) == 199 ? 114 : \
(oid) == 629 ? 628 : \
(oid) == 651 ? 650 : \
(oid) == 719 ? 718 : \
(oid) == 775 ? 774 : \
(oid) == 791 ? 790 : \
(oid) == 1000 ? 16 : \
(oid) == 1001 ? 17 : \
(oid) == 1002 ? 18 : \
(oid) == 1003 ? 19 : \
(oid) == 1005 ? 21 : \
(oid) == 1006 ? 22 : \
(oid) == 1007 ? 23 : \
(oid) == 1008 ? 24 : \
(oid) == 1009 ? 25 : \
(oid) == 1010 ? 27 : \
(oid) == 1011 ? 28 : \
(oid) == 1012 ? 29 : \
(oid) == 1013 ? 30 : \
(oid) == 1014 ? 1042 : \
(oid) == 1015 ? 1043 : \
(oid) == 1016 ? 20 : \
(oid) == 1017 ? 600 : \
(oid) == 1018 ? 601 : \
(oid) == 1019 ? 602 : \
(oid) == 1020 ? 603 : \
(oid) == 1021 ? 700 : \
(oid) == 1022 ? 701 : \
(oid) == 1027 ? 604 : \
(oid) == 1028 ? 26 : \
(oid) == 1034 ? 1033 : \
(oid) == 1040 ? 829 : \
(oid) == 1041 ? 869 : \
(oid) == 1115 ? 1114 : \
(oid) == 1182 ? 1082 : \
(oid) == 1183 ? 1083 : \
(oid) == 1185 ? 1184 : \
(oid) == 1187 ? 1186 : \
(oid) == 1231 ? 1700 : \
(oid) == 1263 ? 2275 : \
(oid) == 1270 ? 1266 : \
(oid) == 1561 ? 1560 : \
(oid) == 1563 ? 1562 : \
(oid) == 2201 ? 1790 : \
(oid) == 2207 ? 2202 : \
(oid) == 2208 ? 2203 : \
(oid) == 2209 ? 2204 : \
(oid) == 2210 ? 2205 : \
(oid) == 2211 ? 2206 : \
(oid) == 2949 ? 2970 : \
(oid) == 2951 ? 2950 : \
(oid) == 3221 ? 3220 : \
(oid) == 3643 ? 3614 : \
(oid) == 3644 ? 3642 : \
(oid) == 3645 ? 3615 : \
(oid) == 3735 ? 3734 : \
(oid) == 3770 ? 3769 : \
(oid) == 3807 ? 3802 : \
(oid) == 3905 ? 3904 : \
(oid) == 3907 ? 3906 : \
(oid) == 3909 ? 3908 : \
(oid) == 3911 ? 3910 : \
(oid) == 3913 ? 3912 : \
(oid) == 3927 ? 3926 : \
(oid) == 4090 ? 4089 : \
(oid) == 4097 ? 4096 : \
0 \
)
#endif
#ifndef PHP_PQ_DELIM_OF_ARRAY
# define PHP_PQ_DELIM_OF_ARRAY(oid) ((char) ( \
(oid) == 1020 ? ';' : \
(oid) == 603 ? ';' : \
',' \
))
#endif