summaryrefslogtreecommitdiff
path: root/ext/pdo
diff options
context:
space:
mode:
authorMarcus Boerger <helly@php.net>2005-02-27 22:32:11 +0000
committerMarcus Boerger <helly@php.net>2005-02-27 22:32:11 +0000
commit03a4a8c11d019532ea2781c3d213d6f616e251ff (patch)
tree6d82df11df522f040fcbec6d8f33432075916644 /ext/pdo
parent893e9c04989fd31bbc6f7e5c7939d260a2c6e5d3 (diff)
downloadphp-git-03a4a8c11d019532ea2781c3d213d6f616e251ff.tar.gz
- Add some fetch column related capailities
- Add direct (classtype based) unserializing capabilities
Diffstat (limited to 'ext/pdo')
-rwxr-xr-xext/pdo/pdo.c1
-rwxr-xr-xext/pdo/pdo_stmt.c89
-rwxr-xr-xext/pdo/php_pdo_driver.h3
-rwxr-xr-xext/pdo/tests/pdo_015.inc25
4 files changed, 100 insertions, 18 deletions
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 @@
+<?php # vim:ft=php
+
+require_once('pdo.inc');
+
+set_sql('create1', 'CREATE TABLE test(id int PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(20))');
+set_sql('insert1', 'INSERT INTO test VALUES(1, \'A\', \'A2\')');
+set_sql('insert2', 'INSERT INTO test VALUES(2, \'A\', \'B2\')');
+set_sql('select1', 'SELECT id, val, val2 FROM test');
+set_sql('select2', 'SELECT val, val2 FROM test');
+
+
+$DB->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));
+
+?>