#include <php.h>
#include <ext/spl/spl_iterators.h>
-#if HAVE_JSON
-#include <ext/json/php_json.h>
+#if PHP_PQ_HAVE_PHP_JSON_H
+#include <php_json.h> /* we've added the include directory to INCLUDES */
#endif
+
#include <libpq-events.h>
#include "php_pq.h"
static HashTable php_pqres_object_prophandlers;
static zend_object_iterator_funcs php_pqres_iterator_funcs;
-static zend_object_iterator *php_pqres_iterator_init(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
+static zend_object_iterator *php_pqres_iterator_init(zend_class_entry *ce, zval *object, int by_ref)
{
php_pqres_iterator_t *iter;
- zval *prop, *zfetch_type;
+ zval tmp, *zfetch_type;
iter = ecalloc(1, sizeof(*iter));
iter->zi.funcs = &php_pqres_iterator_funcs;
- iter->zi.data = object;
- /* do not addref, because the iterator lives inside this object anyway */
+ iter->zi.data = PHP_PQ_OBJ(object, NULL);
+ php_pq_object_addref(iter->zi.data);
- zfetch_type = prop = zend_read_property(ce, object, ZEND_STRL("fetchType"), 0 TSRMLS_CC);
- if (Z_TYPE_P(zfetch_type) != IS_LONG) {
- convert_to_long_ex(&zfetch_type);
- }
- iter->fetch_type = Z_LVAL_P(zfetch_type);
- if (zfetch_type != prop) {
- zval_ptr_dtor(&zfetch_type);
- }
- if (Z_REFCOUNT_P(prop)) {
- zval_ptr_dtor(&prop);
- } else {
- zval_dtor(prop);
- FREE_ZVAL(prop);
- }
+ zfetch_type = zend_read_property(ce, object, ZEND_STRL("fetchType"), 0, &tmp);
+ iter->fetch_type = zval_get_long(zfetch_type);
return (zend_object_iterator *) iter;
}
-static void php_pqres_iterator_dtor(zend_object_iterator *i TSRMLS_DC)
+static void php_pqres_iterator_dtor(zend_object_iterator *i)
{
php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
+ php_pqres_object_t *obj = i->data;
- if (iter->current_val) {
+ if (!Z_IS_UNDEF(&iter->current_val)) {
zval_ptr_dtor(&iter->current_val);
- iter->current_val = NULL;
}
+ php_pq_object_delref(obj);
efree(iter);
}
-static STATUS php_pqres_iterator_valid(zend_object_iterator *i TSRMLS_DC)
+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 = zend_object_store_get_object(iter->zi.data TSRMLS_CC);
+ php_pqres_object_t *obj = i->data;
switch (PQresultStatus(obj->intern->res)) {
case PGRES_TUPLES_OK:
-#if HAVE_PGRES_SINGLE_TUPLE
+#ifdef HAVE_PGRES_SINGLE_TUPLE
case PGRES_SINGLE_TUPLE:
#endif
if (PQntuples(obj->intern->res) <= iter->index) {
return SUCCESS;
}
-zval *php_pqres_typed_zval(php_pqres_t *res, char *val, size_t len, Oid typ TSRMLS_DC)
-{
- zval *zv, **zconv;
+#define PHP_PQRES_JSON_OPTIONS(res) \
+ (php_pqres_fetch_type(res) != PHP_PQRES_FETCH_OBJECT ? PHP_JSON_OBJECT_AS_ARRAY:0)
- MAKE_STD_ZVAL(zv);
+zval *php_pqres_typed_zval(php_pqres_t *res, Oid typ, zval *zv)
+{
+ zval *zconv;
+ HashTable *ht;
+ zend_string *str;
- if (SUCCESS == zend_hash_index_find(&res->converters, typ, (void *) &zconv)) {
- zval *ztype, *tmp = NULL;
+ if ((zconv = zend_hash_index_find(&res->converters, typ))) {
+ zval ztype, rv;
- MAKE_STD_ZVAL(ztype);
- ZVAL_LONG(ztype, typ);
- ZVAL_STRINGL(zv, val, len, 1);
- zend_call_method_with_2_params(zconv, NULL, NULL, "convertfromstring", &tmp, zv, ztype);
- zval_ptr_dtor(&ztype);
+ ZVAL_NULL(&rv);
+ ZVAL_LONG(&ztype, typ);
+ zend_call_method_with_2_params(zconv, NULL, NULL, "convertfromstring", &rv, zv, &ztype);
- if (tmp) {
- zval_ptr_dtor(&zv);
- zv = tmp;
- }
+ ZVAL_ZVAL(&rv, zv, 1, 1);
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, *val == 't');
+ ZVAL_BOOL(zv, *str->val == 't');
break;
-#if SIZEOF_LONG >= 8
+
case PHP_PQ_OID_INT8:
case PHP_PQ_OID_TID:
-#endif
case PHP_PQ_OID_INT4:
case PHP_PQ_OID_INT2:
case PHP_PQ_OID_XID:
if (!(res->auto_convert & PHP_PQRES_CONV_INT)) {
goto noconversion;
}
- ZVAL_LONG(zv, zend_atol(val, len));
+ {
+ 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:
if (!(res->auto_convert & PHP_PQRES_CONV_FLOAT)) {
goto noconversion;
}
- ZVAL_DOUBLE(zv, zend_strtod(val, NULL));
+ 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(val, len, "Y-m-d", zv TSRMLS_CC);
+ php_pqdt_from_string(zv, NULL, str->val, str->len, "Y-m-d", NULL);
break;
case PHP_PQ_OID_ABSTIME:
if (!(res->auto_convert & PHP_PQRES_CONV_DATETIME)) {
goto noconversion;
}
- php_pqdt_from_string(val, len, "Y-m-d H:i:s", zv TSRMLS_CC);
+ php_pqdt_from_string(zv, NULL, str->val, str->len, "Y-m-d H:i:s", NULL);
break;
case PHP_PQ_OID_TIMESTAMP:
if (!(res->auto_convert & PHP_PQRES_CONV_DATETIME)) {
goto noconversion;
}
- php_pqdt_from_string(val, len, "Y-m-d H:i:s.u", zv TSRMLS_CC);
+ 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(val, len, "Y-m-d H:i:s.uO", zv TSRMLS_CC);
+ php_pqdt_from_string(zv, NULL, str->val, str->len, "Y-m-d H:i:s.uO", NULL);
break;
-#if HAVE_JSON && defined(PHP_PQ_OID_JSON)
+#if PHP_PQ_HAVE_PHP_JSON_H && defined(PHP_PQ_OID_JSON)
# ifdef PHP_PQ_OID_JSONB
case PHP_PQ_OID_JSONB:
# endif
if (!(res->auto_convert & PHP_PQRES_CONV_JSON)) {
goto noconversion;
}
- php_json_decode_ex(zv, val, len, 0, 512 /* PHP_JSON_DEFAULT_DEPTH */ TSRMLS_CC);
+ php_json_decode_ex(zv, str->val, str->len, PHP_PQRES_JSON_OPTIONS(res), 512 /* PHP_JSON_DEFAULT_DEPTH */);
break;
#endif
if (!(res->auto_convert & PHP_PQRES_CONV_ARRAY)) {
goto noconversion;
}
- if (PHP_PQ_TYPE_IS_ARRAY(typ) && (Z_ARRVAL_P(zv) = php_pq_parse_array(res, val, len, PHP_PQ_TYPE_OF_ARRAY(typ) TSRMLS_CC))) {
- Z_TYPE_P(zv) = IS_ARRAY;
+ 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 {
- noconversion:
- ZVAL_STRINGL(zv, val, len, 1);
+ goto noconversion;
}
break;
}
+ zend_sring_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 TSRMLS_DC)
+static inline zval *php_pqres_get_col(php_pqres_t *r, unsigned row, unsigned col, zval *zv)
{
- zval *zv;
-
if (PQgetisnull(r->res, row, col)) {
- MAKE_STD_ZVAL(zv);
ZVAL_NULL(zv);
} else {
- zv = php_pqres_typed_zval(r, PQgetvalue(r->res, row, col), PQgetlength(r->res, row, col), PQftype(r->res, col) TSRMLS_CC);
+ 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 TSRMLS_DC)
+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) {
break;
}
} else {
- zval *zv;
+ zval zv;
- zv = php_pqres_typed_zval(r, PQgetvalue(r->res, row, col), PQgetlength(r->res, row, col), PQftype(r->res, col) TSRMLS_CC);
+ 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);
+ 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);
+ add_assoc_zval(data, PQfname(r->res, col), &zv);
break;
case PHP_PQRES_FETCH_ARRAY:
- add_index_zval(data, col, zv);
+ 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_ptr TSRMLS_DC)
+zval *php_pqres_row_to_zval(PGresult *res, unsigned row, php_pqres_fetch_t fetch_type, zval *data)
{
- zval *data = NULL;
int c, cols;
php_pqres_object_t *res_obj = PQresultInstanceData(res, php_pqconn_event);
- if (data_ptr) {
- data = *data_ptr;
- }
- if (!data) {
- MAKE_STD_ZVAL(data);
+ 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(data);
}
- if (data_ptr) {
- *data_ptr = data;
- }
}
if (PQntuples(res) > row) {
for (c = 0, cols = PQnfields(res); c < cols; ++c) {
- php_pqres_add_col_to_zval(res_obj->intern, row, c, fetch_type, data TSRMLS_CC);
+ php_pqres_add_col_to_zval(res_obj->intern, row, c, fetch_type, data);
}
}
static void php_pqres_iterator_current(zend_object_iterator *i, zval ***data_ptr TSRMLS_DC)
{
php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
- php_pqres_object_t *obj = zend_object_store_get_object(iter->zi.data TSRMLS_CC);
+ php_pqres_object_t *obj = i->data;
if (!iter->current_val) {
iter->current_val = php_pqres_row_to_zval(obj->intern->res, iter->index, iter->fetch_type, NULL TSRMLS_CC);
}
}
-STATUS php_pqres_success(PGresult *res TSRMLS_DC)
+ZEND_RESULT_CODE php_pqres_success(PGresult *res TSRMLS_DC)
{
zval *zexc;
}
}
+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(void *o TSRMLS_DC)
{
php_pqres_object_t *obj = o;
{
php_pqres_object_t *obj = o;
- if (obj->intern->iter) {
- RETVAL_LONG(obj->intern->iter->fetch_type);
- } else {
- RETVAL_LONG(obj->intern->default_fetch_type);
- }
+ RETVAL_LONG(php_pqres_fetch_type(obj->intern));
}
static void php_pqres_object_write_fetch_type(zval *object, void *o, zval *value TSRMLS_DC)
}
}
-static STATUS php_pqres_iteration(zval *this_ptr, php_pqres_object_t *obj, php_pqres_fetch_t fetch_type, zval ***row TSRMLS_DC)
+static ZEND_RESULT_CODE php_pqres_iteration(zval *this_ptr, php_pqres_object_t *obj, php_pqres_fetch_t fetch_type, zval ***row TSRMLS_DC)
{
- STATUS rv;
+ ZEND_RESULT_CODE rv;
php_pqres_fetch_t orig_fetch;
if (!obj) {
int num;
} php_pqres_col_t;
-static STATUS column_nn(php_pqres_object_t *obj, zval *zcol, php_pqres_col_t *col TSRMLS_DC)
+static ZEND_RESULT_CODE column_nn(php_pqres_object_t *obj, zval *zcol, php_pqres_col_t *col TSRMLS_DC)
{
long index = -1;
char *name = NULL;
static PHP_METHOD(pqres, bind) {
zval *zcol, *zref;
zend_error_handling zeh;
- STATUS rv;
+ ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/z", &zcol, &zref);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to bind column %s@%d", col.name, col.num);
RETVAL_FALSE;
} else {
- zend_hash_sort(&obj->intern->bound, zend_qsort, compare_index, 0 TSRMLS_CC);
+ zend_hash_sort(&obj->intern->bound, zend_qsort, php_pq_compare_index, 0 TSRMLS_CC);
RETVAL_TRUE;
}
}
{
zval **zvalue, **zbound = p;
zval **zrow = va_arg(argv, zval **);
- STATUS *rv = va_arg(argv, STATUS *);
+ ZEND_RESULT_CODE *rv = va_arg(argv, ZEND_RESULT_CODE *);
if (SUCCESS != zend_hash_index_find(Z_ARRVAL_PP(zrow), key->h, (void *) &zvalue)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to find column ad index %lu", key->h);
ZEND_END_ARG_INFO();
static PHP_METHOD(pqres, fetchBound) {
zend_error_handling zeh;
- STATUS rv;
+ ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
rv = zend_parse_parameters_none();
zend_error_handling zeh;
php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
long fetch_type = -1;
- STATUS rv;
+ ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &fetch_type);
zval **row = NULL;
if (fetch_type == -1) {
- fetch_type = obj->intern->iter ? obj->intern->iter->fetch_type : obj->intern->default_fetch_type;
+ fetch_type = php_pqres_fetch_type(obj->intern);
}
zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh TSRMLS_CC);
static PHP_METHOD(pqres, fetchCol) {
zend_error_handling zeh;
zval *zcol = NULL, *zref;
- STATUS rv;
+ ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z/!", &zref, &zcol);
zval **row = NULL;
zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh TSRMLS_CC);
- php_pqres_iteration(getThis(), obj, obj->intern->iter ? obj->intern->iter->fetch_type : 0, &row TSRMLS_CC);
+ php_pqres_iteration(getThis(), obj, php_pqres_fetch_type(obj->intern), &row TSRMLS_CC);
if (row) {
php_pqres_col_t col;
static PHP_METHOD(pqres, fetchAllCols) {
zend_error_handling zeh;
zval *zcol = NULL;
- STATUS rv;
+ ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!", &zcol);
struct apply_to_col_arg {
php_pqres_object_t *obj;
php_pqres_col_t *cols;
- STATUS status;
+ ZEND_RESULT_CODE status;
};
static int apply_to_col(void *p, void *a TSRMLS_DC)
zend_error_handling zeh;
zval *zkeys = 0, *zvals = 0;
long fetch_type = -1;
- STATUS rv;
+ ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z/!z/!l", &zkeys, &zvals, &fetch_type);
}
if (fetch_type == -1) {
- fetch_type = obj->intern->iter ? obj->intern->iter->fetch_type : obj->intern->default_fetch_type;
+ fetch_type = php_pqres_fetch_type(obj->intern);
}
if (keys) {
static PHP_METHOD(pqres, fetchAll) {
zend_error_handling zeh;
long fetch_type = -1;
- STATUS rv;
+ ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &fetch_type);
int r, rows = PQntuples(obj->intern->res);
if (fetch_type == -1) {
- fetch_type = obj->intern->iter ? obj->intern->iter->fetch_type : obj->intern->default_fetch_type;
+ fetch_type = php_pqres_fetch_type(obj->intern);
}
array_init(return_value);
ZEND_END_ARG_INFO();
static PHP_METHOD(pqres, count) {
zend_error_handling zeh;
- STATUS rv;
+ ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
rv = zend_parse_parameters_none();
ZEND_END_ARG_INFO();
static PHP_METHOD(pqres, desc) {
zend_error_handling zeh;
- STATUS rv;
+ ZEND_RESULT_CODE rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
rv = zend_parse_parameters_none();
#ifdef HAVE_PGRES_COPY_BOTH
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH TSRMLS_CC);
#endif
-#if HAVE_PGRES_SINGLE_TUPLE
+#ifdef HAVE_PGRES_SINGLE_TUPLE
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE TSRMLS_CC);
#endif
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_SCALAR"), PHP_PQRES_CONV_SCALAR TSRMLS_CC);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ARRAY"), PHP_PQRES_CONV_ARRAY TSRMLS_CC);
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_DATETIME"), PHP_PQRES_CONV_DATETIME TSRMLS_CC);
-#if HAVE_JSON
+#if PHP_PQ_HAVE_PHP_JSON_H
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_JSON"), PHP_PQRES_CONV_JSON TSRMLS_CC);
#endif
zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ALL"), PHP_PQRES_CONV_ALL TSRMLS_CC);