summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xext/pdo/pdo.c4
-rwxr-xr-xext/pdo/pdo_dbh.c73
-rwxr-xr-xext/pdo/pdo_stmt.c342
-rwxr-xr-xext/pdo/php_pdo_driver.h20
-rwxr-xr-xext/pdo/php_pdo_int.h3
5 files changed, 420 insertions, 22 deletions
diff --git a/ext/pdo/pdo.c b/ext/pdo/pdo.c
index cc620d810e..ea03f61cf3 100755
--- a/ext/pdo/pdo.c
+++ b/ext/pdo/pdo.c
@@ -225,6 +225,9 @@ PHP_MINIT_FUNCTION(pdo)
REGISTER_LONG_CONSTANT("PDO_FETCH_BOTH", (long)PDO_FETCH_BOTH, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PDO_FETCH_OBJ", (long)PDO_FETCH_OBJ, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PDO_FETCH_BOUND",(long)PDO_FETCH_BOUND, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("PDO_FETCH_COLUMN",(long)PDO_FETCH_COLUMN, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("PDO_FETCH_CLASS",(long)PDO_FETCH_CLASS, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("PDO_FETCH_INTO", (long)PDO_FETCH_INTO, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PDO_ATTR_AUTOCOMMIT", (long)PDO_ATTR_AUTOCOMMIT, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PDO_ATTR_SCROLL", (long)PDO_ATTR_SCROLL, CONST_CS|CONST_PERSISTENT);
@@ -272,6 +275,7 @@ PHP_MINIT_FUNCTION(pdo)
INIT_CLASS_ENTRY(ce, "PDOStatement", pdo_dbstmt_functions);
ce.create_object = pdo_dbstmt_new;
pdo_dbstmt_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ pdo_dbstmt_ce->get_iterator = pdo_stmt_iter_get;
INIT_CLASS_ENTRY(ce, "PDORow", pdo_row_functions);
ce.create_object = pdo_row_new;
diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c
index b1cda08f37..2e814ed99c 100755
--- a/ext/pdo/pdo_dbh.c
+++ b/ext/pdo/pdo_dbh.c
@@ -348,6 +348,8 @@ static PHP_METHOD(PDO, prepare)
/* unconditionally keep this for later reference */
stmt->query_string = estrndup(statement, statement_len);
stmt->query_stringlen = statement_len;
+ stmt->default_fetch_type = PDO_FETCH_BOTH;
+
if (dbh->methods->preparer(dbh, statement, statement_len, stmt, options, driver_options TSRMLS_CC)) {
/* prepared; create a statement object for PHP land to access it */
Z_TYPE_P(return_value) = IS_OBJECT;
@@ -630,6 +632,76 @@ static PHP_METHOD(PDO, errorInfo)
}
/* }}} */
+/* {{{ proto object PDO::queryAndIterate(string sql [, PDOStatement::setFetchMode() args])
+ Prepare and execute $sql; returns the statement object for iteration */
+static PHP_METHOD(PDO, queryAndIterate)
+{
+ pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+ pdo_stmt_t *stmt;
+ char *statement;
+ int statement_len;
+ zval *driver_options = NULL;
+ long options = 0;
+
+ if (FAILURE == zend_parse_parameters(1 TSRMLS_CC, "s", &statement,
+ &statement_len)) {
+ RETURN_FALSE;
+ }
+
+ PDO_DBH_CLEAR_ERR();
+ stmt = ecalloc(1, sizeof(*stmt));
+ /* unconditionally keep this for later reference */
+ stmt->query_string = estrndup(statement, statement_len);
+ stmt->query_stringlen = statement_len;
+ stmt->default_fetch_type = PDO_FETCH_BOTH;
+
+ if (dbh->methods->preparer(dbh, statement, statement_len, stmt, options, driver_options TSRMLS_CC)) {
+ /* prepared; create a statement object for PHP land to access it */
+ Z_TYPE_P(return_value) = IS_OBJECT;
+ Z_OBJ_HANDLE_P(return_value) = zend_objects_store_put(stmt, NULL, pdo_dbstmt_free_storage, NULL TSRMLS_CC);
+ Z_OBJ_HT_P(return_value) = &pdo_dbstmt_object_handlers;
+
+ /* give it a reference to me */
+ stmt->database_object_handle = *getThis();
+ zend_objects_store_add_ref(getThis() TSRMLS_CC);
+ stmt->dbh = dbh;
+
+ /* we haven't created a lazy object yet */
+ ZVAL_NULL(&stmt->lazy_object_ref);
+
+ stmt->refcount = 1;
+
+ if (ZEND_NUM_ARGS() == 1 ||
+ SUCCESS == pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAM_PASSTHRU,
+ stmt, 1)) {
+ PDO_STMT_CLEAR_ERR();
+
+ /* now execute the statement */
+ PDO_STMT_CLEAR_ERR();
+ if (stmt->methods->executer(stmt TSRMLS_CC)) {
+ int ret = 1;
+ if (!stmt->executed) {
+ if (stmt->dbh->alloc_own_columns) {
+ ret = pdo_stmt_describe_columns(stmt TSRMLS_CC);
+ }
+ stmt->executed = 1;
+ }
+ if (ret) {
+ return;
+ }
+ }
+ }
+ /* something broke */
+ PDO_HANDLE_STMT_ERR();
+
+ /* TODO: kill the object handle for the stmt here */
+ } else {
+ efree(stmt);
+ PDO_HANDLE_DBH_ERR();
+ }
+ RETURN_FALSE;
+}
+/* }}} */
function_entry pdo_dbh_functions[] = {
PHP_ME_MAPPING(__construct, dbh_constructor, NULL)
@@ -644,6 +716,7 @@ function_entry pdo_dbh_functions[] = {
PHP_ME(PDO, errorCode, NULL, ZEND_ACC_PUBLIC)
PHP_ME(PDO, errorInfo, NULL, ZEND_ACC_PUBLIC)
PHP_ME(PDO, getAttribute, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(PDO, queryAndIterate,NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index 3d2d183190..e4f89b16a4 100755
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -108,7 +108,7 @@ iterate:
return ret;
}
-static int describe_columns(pdo_stmt_t *stmt TSRMLS_DC)
+int pdo_stmt_describe_columns(pdo_stmt_t *stmt TSRMLS_DC)
{
int col;
@@ -338,7 +338,7 @@ static PHP_METHOD(PDOStatement, execute)
if (stmt->dbh->alloc_own_columns) {
/* for "big boy" drivers, we need to allocate memory to fetch
* the results into, so lets do that now */
- ret = describe_columns(stmt TSRMLS_CC);
+ ret = pdo_stmt_describe_columns(stmt TSRMLS_CC);
}
stmt->executed = 1;
@@ -394,7 +394,7 @@ static int do_fetch_common(pdo_stmt_t *stmt, int do_bind TSRMLS_DC)
}
/* some drivers might need to describe the columns now */
- if (!stmt->columns && !describe_columns(stmt TSRMLS_CC)) {
+ if (!stmt->columns && !pdo_stmt_describe_columns(stmt TSRMLS_CC)) {
return 0;
}
@@ -436,6 +436,10 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, enum pdo_
{
enum pdo_fetch_type really_how = how;
+ if (really_how == PDO_FETCH_USE_DEFAULT) {
+ really_how = how = stmt->default_fetch_type;
+ }
+
if (!do_fetch_common(stmt, do_bind TSRMLS_CC)) {
return 0;
}
@@ -453,10 +457,44 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, enum pdo_
return 1;
}
- array_init(return_value);
+ switch (how) {
+ case PDO_FETCH_ASSOC:
+ case PDO_FETCH_BOTH:
+ case PDO_FETCH_NUM:
+ array_init(return_value);
+ break;
+
+ 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;
+ }
+ return 0;
- if (how == PDO_FETCH_OBJ) {
- how = PDO_FETCH_ASSOC;
+ case PDO_FETCH_OBJ:
+ object_init_ex(return_value, ZEND_STANDARD_CLASS_DEF_PTR);
+ break;
+
+ case PDO_FETCH_CLASS:
+ object_init_ex(return_value, stmt->fetch.cls.ce);
+
+ /* TODO: call ctor */
+ break;
+
+ case PDO_FETCH_INTO:
+ Z_TYPE_P(return_value) = IS_OBJECT;
+ Z_OBJ_HANDLE_P(return_value) = Z_OBJ_HANDLE_P(stmt->fetch.into);
+ Z_OBJ_HT_P(return_value) = Z_OBJ_HT_P(stmt->fetch.into);
+ zend_objects_store_add_ref(stmt->fetch.into);
+
+ if (zend_get_class_entry(return_value) == ZEND_STANDARD_CLASS_DEF_PTR) {
+ how = PDO_FETCH_OBJ;
+ }
+ break;
+
+ default:
+ /* shouldn't happen */
+ return 0;
}
for (i = 0; i < stmt->column_count; i++) {
@@ -464,20 +502,29 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, enum pdo_
MAKE_STD_ZVAL(val);
fetch_value(stmt, val, i TSRMLS_CC);
- if (how == PDO_FETCH_ASSOC || how == PDO_FETCH_BOTH) {
- add_assoc_zval(return_value, stmt->columns[i].name, val);
- }
- if (how == PDO_FETCH_NUM || how == PDO_FETCH_BOTH) {
- add_next_index_zval(return_value, val);
- }
+ switch (how) {
+ case PDO_FETCH_ASSOC:
+ add_assoc_zval(return_value, stmt->columns[i].name, val);
+ break;
- if (how == PDO_FETCH_BOTH) {
- ZVAL_ADDREF(val);
- }
- }
+ case PDO_FETCH_BOTH:
+ add_assoc_zval(return_value, stmt->columns[i].name, val);
+ ZVAL_ADDREF(val);
+ add_next_index_zval(return_value, val);
+ break;
+
+ case PDO_FETCH_NUM:
+ add_next_index_zval(return_value, val);
+ break;
- if (really_how == PDO_FETCH_OBJ) {
- object_and_properties_init(return_value, ZEND_STANDARD_CLASS_DEF_PTR, Z_ARRVAL_P(return_value));
+ case PDO_FETCH_OBJ:
+ case PDO_FETCH_INTO:
+ case PDO_FETCH_CLASS:
+ zend_update_property(NULL, return_value,
+ stmt->columns[i].name, stmt->columns[i].namelen,
+ val TSRMLS_CC);
+ break;
+ }
}
}
@@ -488,7 +535,7 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, enum pdo_
Fetches the next row and returns it, or false if there are no more rows */
static PHP_METHOD(PDOStatement, fetch)
{
- long how = PDO_FETCH_BOTH;
+ long how = PDO_FETCH_USE_DEFAULT;
pdo_stmt_t *stmt = (pdo_stmt_t*)zend_object_store_get_object(getThis() TSRMLS_CC);
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &how)) {
@@ -528,7 +575,7 @@ static PHP_METHOD(PDOStatement, fetchSingle)
static PHP_METHOD(PDOStatement, fetchAll)
{
pdo_stmt_t *stmt = (pdo_stmt_t*)zend_object_store_get_object(getThis() TSRMLS_CC);
- long how = PDO_FETCH_BOTH;
+ long how = PDO_FETCH_USE_DEFAULT;
zval *data;
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &how)) {
@@ -750,6 +797,140 @@ static PHP_METHOD(PDOStatement, getColumnMeta)
}
/* }}} */
+/* {{{ proto bool PDOStatement::setFetchMode(int mode [)
+ Returns meta data for a numbered column */
+
+int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, int skip)
+{
+ long mode = PDO_FETCH_BOTH;
+ int argc = ZEND_NUM_ARGS() - skip;
+ zval ***args;
+ zend_class_entry **cep;
+
+ /* TODO: clear up class stuff here */
+ switch (stmt->default_fetch_type) {
+ case PDO_FETCH_CLASS:
+ if (stmt->fetch.cls.ctor_args) {
+ FREE_ZVAL(stmt->fetch.cls.ctor_args);
+ stmt->fetch.cls.ctor_args = NULL;
+ }
+ break;
+
+ case PDO_FETCH_INTO:
+ if (stmt->fetch.into) {
+ ZVAL_DELREF(stmt->fetch.into);
+ stmt->fetch.into = NULL;
+ }
+ break;
+ default:
+ ;
+ }
+
+ stmt->default_fetch_type = PDO_FETCH_BOTH;
+
+ if (argc == 0) {
+ return SUCCESS;
+ }
+
+ args = safe_emalloc(ZEND_NUM_ARGS(), sizeof(zval*), 0);
+
+ if (FAILURE == zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args)) {
+fail_out:
+ efree(args);
+ return FAILURE;
+ }
+
+ convert_to_long_ex(args[skip]);
+ mode = Z_LVAL_PP(args[skip]);
+
+ switch (mode) {
+ case PDO_FETCH_LAZY:
+ case PDO_FETCH_ASSOC:
+ case PDO_FETCH_NUM:
+ case PDO_FETCH_BOTH:
+ case PDO_FETCH_OBJ:
+ case PDO_FETCH_BOUND:
+ break;
+
+ case PDO_FETCH_COLUMN:
+ if (argc != 2) {
+ goto fail_out;
+ }
+ convert_to_long_ex(args[skip+1]);
+ stmt->fetch.column = Z_LVAL_PP(args[skip+1]);
+ break;
+
+ case PDO_FETCH_CLASS:
+ if (argc < 2 || argc > 3) {
+ goto fail_out;
+ }
+ convert_to_string_ex(args[skip+1]);
+
+ if (FAILURE == zend_lookup_class(Z_STRVAL_PP(args[skip+1]),
+ Z_STRLEN_PP(args[skip+1]), &cep)) {
+ goto fail_out;
+ }
+
+ if (!cep || !*cep) {
+ goto fail_out;
+ }
+
+ stmt->fetch.cls.ce = *cep;
+
+ if (stmt->dbh->is_persistent) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP might crash if you don't call $stmt->setFetchMode() to reset to defaults on this persistent statement. This will be fixed in a later release");
+ }
+
+ if (argc == 3) {
+ convert_to_array_ex(args[skip+2]);
+ stmt->fetch.cls.ctor_args = *args[skip+2];
+ zval_copy_ctor(stmt->fetch.cls.ctor_args);
+ }
+ break;
+
+ case PDO_FETCH_INTO:
+ if (argc != 2) {
+ goto fail_out;
+ }
+ if (Z_TYPE_PP(args[skip+1]) != IS_OBJECT) {
+ goto fail_out;
+ }
+
+ if (stmt->dbh->is_persistent) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP might crash if you don't call $stmt->setFetchMode() to reset to defaults on this persistent statement. This will be fixed in a later release");
+ }
+
+ MAKE_STD_ZVAL(stmt->fetch.into);
+
+ Z_TYPE_P(stmt->fetch.into) = IS_OBJECT;
+ Z_OBJ_HANDLE_P(stmt->fetch.into) = Z_OBJ_HANDLE_PP(args[skip+1]);
+ Z_OBJ_HT_P(stmt->fetch.into) = Z_OBJ_HT_PP(args[skip+1]);
+ zend_objects_store_add_ref(stmt->fetch.into);
+ break;
+
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "mode is out of range");
+ return FAILURE;
+ }
+
+ stmt->default_fetch_type = mode;
+ efree(args);
+
+ return SUCCESS;
+}
+
+static PHP_METHOD(PDOStatement, setFetchMode)
+{
+ pdo_stmt_t *stmt = (pdo_stmt_t*)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ RETVAL_BOOL(
+ pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAM_PASSTHRU,
+ stmt, 0) == SUCCESS ? 1 : 0
+ );
+}
+/* }}} */
+
+
function_entry pdo_dbstmt_functions[] = {
PHP_ME(PDOStatement, execute, NULL, ZEND_ACC_PUBLIC)
PHP_ME(PDOStatement, fetch, NULL, ZEND_ACC_PUBLIC)
@@ -764,6 +945,7 @@ function_entry pdo_dbstmt_functions[] = {
PHP_ME(PDOStatement, getAttribute, NULL, ZEND_ACC_PUBLIC)
PHP_ME(PDOStatement, columnCount, NULL, ZEND_ACC_PUBLIC)
PHP_ME(PDOStatement, getColumnMeta, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(PDOStatement, setFetchMode, NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
@@ -959,6 +1141,126 @@ zend_object_value pdo_dbstmt_new(zend_class_entry *ce TSRMLS_DC)
}
/* }}} */
+/* {{{ statement iterator */
+
+struct php_pdo_iterator {
+ zend_object_iterator iter;
+ pdo_stmt_t *stmt;
+ ulong key;
+ zval *fetch_ahead;
+};
+
+static void pdo_stmt_iter_dtor(zend_object_iterator *iter TSRMLS_DC)
+{
+ struct php_pdo_iterator *I = (struct php_pdo_iterator*)iter->data;
+
+ if (--I->stmt->refcount == 0) {
+ free_statement(I->stmt TSRMLS_CC);
+ }
+
+ if (I->fetch_ahead) {
+ ZVAL_DELREF(I->fetch_ahead);
+ }
+
+ efree(I);
+}
+
+static int pdo_stmt_iter_valid(zend_object_iterator *iter TSRMLS_DC)
+{
+ struct php_pdo_iterator *I = (struct php_pdo_iterator*)iter->data;
+
+ return I->fetch_ahead ? SUCCESS : FAILURE;
+}
+
+static void pdo_stmt_iter_get_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
+{
+ struct php_pdo_iterator *I = (struct php_pdo_iterator*)iter->data;
+ zval **ptr_ptr;
+ zval *ptr;
+
+ /* sanity */
+ if (!I->fetch_ahead) {
+ *data = NULL;
+ return;
+ }
+
+ ptr_ptr = emalloc(sizeof(*ptr_ptr));
+ *ptr_ptr = I->fetch_ahead;
+ ZVAL_ADDREF(I->fetch_ahead);
+
+ *data = ptr_ptr;
+}
+
+static int pdo_stmt_iter_get_key(zend_object_iterator *iter, char **str_key, uint *str_key_len,
+ ulong *int_key TSRMLS_DC)
+{
+ struct php_pdo_iterator *I = (struct php_pdo_iterator*)iter->data;
+
+ if (I->key == (ulong)-1) {
+ return HASH_KEY_NON_EXISTANT;
+ }
+ *int_key = I->key;
+ return HASH_KEY_IS_LONG;
+}
+
+static void pdo_stmt_iter_move_forwards(zend_object_iterator *iter TSRMLS_DC)
+{
+ struct php_pdo_iterator *I = (struct php_pdo_iterator*)iter->data;
+
+ if (I->fetch_ahead) {
+ ZVAL_DELREF(I->fetch_ahead);
+ I->fetch_ahead = NULL;
+ }
+
+ MAKE_STD_ZVAL(I->fetch_ahead);
+
+ if (!do_fetch(I->stmt, TRUE, I->fetch_ahead, PDO_FETCH_USE_DEFAULT TSRMLS_CC)) {
+ pdo_stmt_t *stmt = I->stmt; /* for PDO_HANDLE_STMT_ERR() */
+
+ PDO_HANDLE_STMT_ERR();
+ I->key = (ulong)-1;
+ FREE_ZVAL(I->fetch_ahead);
+ I->fetch_ahead = NULL;
+
+ return;
+ }
+
+ I->key++;
+}
+
+static zend_object_iterator_funcs pdo_stmt_iter_funcs = {
+ pdo_stmt_iter_dtor,
+ pdo_stmt_iter_valid,
+ pdo_stmt_iter_get_data,
+ pdo_stmt_iter_get_key,
+ pdo_stmt_iter_move_forwards,
+ NULL
+};
+
+zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object TSRMLS_DC)
+{
+ pdo_stmt_t *stmt = (pdo_stmt_t*)zend_object_store_get_object(object TSRMLS_CC);
+ struct php_pdo_iterator *I;
+
+ I = ecalloc(1, sizeof(*I));
+ I->iter.funcs = &pdo_stmt_iter_funcs;
+ I->iter.data = I;
+ I->stmt = stmt;
+ stmt->refcount++;
+
+ MAKE_STD_ZVAL(I->fetch_ahead);
+ if (!do_fetch(I->stmt, TRUE, I->fetch_ahead, PDO_FETCH_USE_DEFAULT TSRMLS_CC)) {
+ PDO_HANDLE_STMT_ERR();
+ I->key = (ulong)-1;
+ FREE_ZVAL(I->fetch_ahead);
+ I->fetch_ahead = NULL;
+ }
+
+ return &I->iter;
+}
+
+/* }}} */
+
/* {{{ overloaded handlers for PDORow class (used by PDO_FETCH_LAZY) */
function_entry pdo_row_functions[] = {
diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h
index 082154a533..4bc96d51b3 100755
--- a/ext/pdo/php_pdo_driver.h
+++ b/ext/pdo/php_pdo_driver.h
@@ -35,7 +35,7 @@ struct pdo_bound_param_data;
# define FALSE 0
#endif
-#define PDO_DRIVER_API 20040925
+#define PDO_DRIVER_API 20041027
enum pdo_param_type {
PDO_PARAM_NULL,
@@ -43,16 +43,20 @@ enum pdo_param_type {
PDO_PARAM_STR,
PDO_PARAM_LOB,
PDO_PARAM_STMT, /* hierarchical result set */
-
};
enum pdo_fetch_type {
+ PDO_FETCH_USE_DEFAULT,
PDO_FETCH_LAZY,
PDO_FETCH_ASSOC,
PDO_FETCH_NUM,
PDO_FETCH_BOTH,
PDO_FETCH_OBJ,
PDO_FETCH_BOUND, /* return true/false only; rely on bound columns */
+ PDO_FETCH_COLUMN, /* fetch a numbered column only */
+ PDO_FETCH_CLASS, /* create an instance of named class, call ctor and set properties */
+ PDO_FETCH_INTO, /* fetch row into an existing object */
+ PDO_FETCH__MAX /* must be last */
};
enum pdo_attribute_type {
@@ -358,6 +362,7 @@ struct _pdo_dbh_t {
const char *persistent_id;
int persistent_id_len;
unsigned int refcount;
+
};
/* describes a column */
@@ -434,6 +439,17 @@ struct _pdo_stmt_t {
* Let's keep it here. */
zval lazy_object_ref;
unsigned long refcount;
+
+ /* defaults for fetches */
+ enum pdo_fetch_type default_fetch_type;
+ union {
+ int column;
+ struct {
+ zend_class_entry *ce;
+ zval *ctor_args;
+ } cls;
+ zval *into;
+ } fetch;
};
/* call this in MINIT to register your PDO driver */
diff --git a/ext/pdo/php_pdo_int.h b/ext/pdo/php_pdo_int.h
index 8d2be68450..8e00989567 100755
--- a/ext/pdo/php_pdo_int.h
+++ b/ext/pdo/php_pdo_int.h
@@ -34,7 +34,10 @@ extern zend_object_value pdo_dbstmt_new(zend_class_entry *ce TSRMLS_DC);
extern function_entry pdo_dbstmt_functions[];
extern zend_class_entry *pdo_dbstmt_ce;
void pdo_dbstmt_free_storage(zend_object *object TSRMLS_DC);
+zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object TSRMLS_DC);
extern zend_object_handlers pdo_dbstmt_object_handlers;
+int pdo_stmt_describe_columns(pdo_stmt_t *stmt TSRMLS_DC);
+int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, int skip_first_arg);
extern zend_object_value pdo_row_new(zend_class_entry *ce TSRMLS_DC);
extern function_entry pdo_row_functions[];