From 03a4a8c11d019532ea2781c3d213d6f616e251ff Mon Sep 17 00:00:00 2001 From: Marcus Boerger Date: Sun, 27 Feb 2005 22:32:11 +0000 Subject: [PATCH] - Add some fetch column related capailities - Add direct (classtype based) unserializing capabilities --- ext/pdo/pdo.c | 1 + ext/pdo/pdo_stmt.c | 89 +++++++++++++++++++++++++++++++-------- ext/pdo/php_pdo_driver.h | 3 +- ext/pdo/tests/pdo_015.inc | 25 +++++++++++ 4 files changed, 100 insertions(+), 18 deletions(-) create mode 100755 ext/pdo/tests/pdo_015.inc diff --git a/ext/pdo/pdo.c b/ext/pdo/pdo.c index 795f8f1e59..05e1886ef2 100755 --- a/ext/pdo/pdo.c +++ b/ext/pdo/pdo.c @@ -282,6 +282,7 @@ PHP_MINIT_FUNCTION(pdo) REGISTER_LONG_CONSTANT("PDO_FETCH_GROUP",(long)PDO_FETCH_GROUP, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PDO_FETCH_UNIQUE",(long)PDO_FETCH_UNIQUE, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PDO_FETCH_CLASSTYPE",(long)PDO_FETCH_CLASSTYPE, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PDO_FETCH_SERIALIZE",(long)PDO_FETCH_SERIALIZE, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PDO_ATTR_AUTOCOMMIT", (long)PDO_ATTR_AUTOCOMMIT, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PDO_ATTR_PREFETCH", (long)PDO_ATTR_PREFETCH, CONST_CS|CONST_PERSISTENT); diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 895d58d840..59e7a0b5c3 100755 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -29,6 +29,7 @@ #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" +#include "ext/standard/php_var.h" #include "php_pdo.h" #include "php_pdo_driver.h" #include "php_pdo_int.h" @@ -202,7 +203,7 @@ static void get_lazy_object(pdo_stmt_t *stmt, zval *return_value TSRMLS_DC) /* { { if (Z_TYPE(stmt->lazy_object_ref) == IS_NULL) { Z_TYPE(stmt->lazy_object_ref) = IS_OBJECT; - Z_OBJ_HANDLE(stmt->lazy_object_ref) = zend_objects_store_put(stmt, zend_objects_destroy_object, pdo_row_free_storage, NULL TSRMLS_CC); + Z_OBJ_HANDLE(stmt->lazy_object_ref) = zend_objects_store_put(stmt, (zend_objects_store_dtor_t)zend_objects_destroy_object, pdo_row_free_storage, NULL TSRMLS_CC); Z_OBJ_HT(stmt->lazy_object_ref) = &pdo_row_object_handlers; stmt->refcount++; } @@ -735,8 +736,13 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, case PDO_FETCH_COLUMN: if (stmt->fetch.column >= 0 && stmt->fetch.column < stmt->column_count) { fetch_value(stmt, return_value, stmt->fetch.column TSRMLS_CC); - return 1; + if (!return_all) { + return 1; + } else { + break; + } } + fprintf(stderr, "FAIL\n"); return 0; case PDO_FETCH_OBJ: @@ -768,11 +774,13 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, zval_dtor(&val); } ce = stmt->fetch.cls.ce; - object_init_ex(return_value, ce); - if (!stmt->fetch.cls.fci.size) { - if (!do_fetch_class_prepare(stmt TSRMLS_CC)) - { - return 0; + if ((flags & PDO_FETCH_SERIALIZE) == 0) { + object_init_ex(return_value, ce); + if (!stmt->fetch.cls.fci.size) { + if (!do_fetch_class_prepare(stmt TSRMLS_CC)) + { + return 0; + } } } break; @@ -807,7 +815,11 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, INIT_PZVAL(&grp_val); fetch_value(stmt, &grp_val, i TSRMLS_CC); convert_to_string(&grp_val); - i++; + if (how == PDO_FETCH_COLUMN) { + i = stmt->column_count; /* no more data to fetch */ + } else { + i++; + } } for (idx = 0; i < stmt->column_count; i++, idx++) { @@ -838,9 +850,32 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, break; case PDO_FETCH_CLASS: - zend_update_property(ce, return_value, - stmt->columns[i].name, stmt->columns[i].namelen, - val TSRMLS_CC); + if ((flags & PDO_FETCH_SERIALIZE) == 0 || idx) { + zend_update_property(ce, return_value, + stmt->columns[i].name, stmt->columns[i].namelen, + val TSRMLS_CC); + } else { +#ifdef MBO_0 + php_unserialize_data_t var_hash; + + PHP_VAR_UNSERIALIZE_INIT(var_hash); + if (php_var_unserialize(&return_value, (const unsigned char**)&Z_STRVAL_P(val), Z_STRVAL_P(val)+Z_STRLEN_P(val), NULL TSRMLS_CC) == FAILURE) { + zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Cannot unserialize data"); + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + return 0; + } + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); +#else + if (!ce->unserialize) { + zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Class %s cannot be unserialized", ce->name); + return 0; + } else if (ce->unserialize(&return_value, ce, Z_TYPE_P(val) == IS_STRING ? Z_STRVAL_P(val) : "", Z_TYPE_P(val) == IS_STRING ? Z_STRLEN_P(val) : 0, NULL TSRMLS_CC) == FAILURE) { + zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Class %s cannot be unserialized", ce->name); + zval_dtor(return_value); + ZVAL_NULL(return_value); + } +#endif + } break; case PDO_FETCH_FUNC: @@ -944,17 +979,21 @@ static int pdo_stmt_verify_mode(pdo_stmt_t *stmt, int mode, int fetch_all TSRMLS return 1; default: + if ((flags & PDO_FETCH_SERIALIZE) == PDO_FETCH_SERIALIZE) { + zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Fetch mode flag PDO_FETCH_SERIALIZE requires mode PDO_FETCH_CLASS", mode); + return 0; + } if ((flags & PDO_FETCH_CLASSTYPE) == PDO_FETCH_CLASSTYPE) { zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Fetch mode flag PDO_FETCH_CLASSTYPE requires mode PDO_FETCH_CLASS", mode); return 0; } - /* no break; */ - - case PDO_FETCH_CLASS: if (mode >= PDO_FETCH__MAX) { zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Fetch mode %d is invalid", mode); return 0; } + /* no break; */ + + case PDO_FETCH_CLASS: return 1; } } @@ -1156,10 +1195,26 @@ static PHP_METHOD(PDOStatement, fetchAll) } do_fetch_func_prepare(stmt TSRMLS_CC); break; + + case PDO_FETCH_COLUMN: + switch(ZEND_NUM_ARGS()) { + case 0: + case 1: + stmt->fetch.column = how & PDO_FETCH_GROUP ? 1 : 0; + break; + case 2: + convert_to_long(arg2); + stmt->fetch.column = Z_LVAL_P(arg2); + break; + case 3: + zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Third parameter not allowed for specified fetch mode"); + error = 1; + } + break; default: if (ZEND_NUM_ARGS() > 1) { - zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Additional parameter not allowed for specified fetch mode"); + zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Additional parameters not allowed for specified fetch mode"); error = 1; } } @@ -1818,7 +1873,7 @@ zend_object_value pdo_dbstmt_new(zend_class_entry *ce TSRMLS_DC) ALLOC_HASHTABLE(stmt->properties); zend_hash_init(stmt->properties, 0, NULL, ZVAL_PTR_DTOR, 0); - retval.handle = zend_objects_store_put(stmt, zend_objects_destroy_object, pdo_dbstmt_free_storage, NULL TSRMLS_CC); + retval.handle = zend_objects_store_put(stmt, (zend_objects_store_dtor_t)zend_objects_destroy_object, pdo_dbstmt_free_storage, NULL TSRMLS_CC); retval.handlers = &pdo_dbstmt_object_handlers; return retval; @@ -2133,7 +2188,7 @@ zend_object_value pdo_row_new(zend_class_entry *ce TSRMLS_DC) { zend_object_value retval; - retval.handle = zend_objects_store_put(NULL, zend_objects_destroy_object, pdo_row_free_storage, NULL TSRMLS_CC); + retval.handle = zend_objects_store_put(NULL, (zend_objects_store_dtor_t)zend_objects_destroy_object, pdo_row_free_storage, NULL TSRMLS_CC); retval.handlers = &pdo_row_object_handlers; return retval; diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h index 6348349dca..428be16928 100755 --- a/ext/pdo/php_pdo_driver.h +++ b/ext/pdo/php_pdo_driver.h @@ -44,7 +44,7 @@ PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC); # define FALSE 0 #endif -#define PDO_DRIVER_API 20050226 +#define PDO_DRIVER_API 20050227 enum pdo_param_type { PDO_PARAM_NULL, @@ -95,6 +95,7 @@ enum pdo_fetch_type { #define PDO_FETCH_GROUP 0x00010000 /* fetch into groups */ #define PDO_FETCH_UNIQUE 0x00030000 /* fetch into groups assuming first col is unique */ #define PDO_FETCH_CLASSTYPE 0x00040000 /* fetch class gets its class name from 1st column */ +#define PDO_FETCH_SERIALIZE 0x00080000 /* fetch class instances by calling serialize */ /* fetch orientation for scrollable cursors */ enum pdo_fetch_orientation { diff --git a/ext/pdo/tests/pdo_015.inc b/ext/pdo/tests/pdo_015.inc new file mode 100755 index 0000000000..c35a5bd021 --- /dev/null +++ b/ext/pdo/tests/pdo_015.inc @@ -0,0 +1,25 @@ +exec($SQL['create1']); +$DB->exec($SQL['insert1']); +$DB->exec($SQL['insert2']); + +var_dump($DB->query($SQL['select1'])->fetchAll(PDO_FETCH_COLUMN)); +var_dump($DB->query($SQL['select1'])->fetchAll(PDO_FETCH_COLUMN, 2)); +var_dump($DB->query($SQL['select1'])->fetchAll(PDO_FETCH_COLUMN|PDO_FETCH_GROUP)); +var_dump($DB->query($SQL['select1'])->fetchAll(PDO_FETCH_COLUMN|PDO_FETCH_UNIQUE)); +var_dump($DB->query($SQL['select1'])->fetchAll(PDO_FETCH_COLUMN|PDO_FETCH_UNIQUE, 0)); +var_dump($DB->query($SQL['select1'])->fetchAll(PDO_FETCH_COLUMN|PDO_FETCH_UNIQUE, 1)); +var_dump($DB->query($SQL['select1'])->fetchAll(PDO_FETCH_COLUMN|PDO_FETCH_UNIQUE, 2)); +var_dump($DB->query($SQL['select2'])->fetchAll(PDO_FETCH_COLUMN|PDO_FETCH_GROUP)); + +?> -- 2.40.0