/* {{{ proto bool PDOStatement::nextRowset()
Advances to the next rowset in a multi-rowset statement handle. Returns true if it succeded, false otherwise */
-static PHP_METHOD(PDOStatement, nextRowset)
-{
- pdo_stmt_t *stmt = (pdo_stmt_t*)zend_object_store_get_object(getThis() TSRMLS_CC);
- if (!stmt->methods->next_rowset) {
- pdo_raise_impl_error(stmt->dbh, stmt, "IM001", "driver does not support multiple rowsets" TSRMLS_CC);
- RETURN_FALSE;
+static int pdo_stmt_do_next_rowset(pdo_stmt_t *stmt TSRMLS_DC)
+{
+ if (!stmt->methods->next_rowset(stmt TSRMLS_CC)) {
+ return 0;
}
- PDO_STMT_CLEAR_ERR();
-
/* un-describe */
if (stmt->columns) {
int i;
efree(cols[i].name);
}
efree(stmt->columns);
+ stmt->columns = NULL;
+ stmt->column_count = 0;
}
- stmt->columns = NULL;
- if (!stmt->methods->next_rowset(stmt TSRMLS_CC)) {
- stmt->column_count = 0;
+ pdo_stmt_describe_columns(stmt TSRMLS_CC);
+
+ return 1;
+}
+
+static PHP_METHOD(PDOStatement, nextRowset)
+{
+ pdo_stmt_t *stmt = (pdo_stmt_t*)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ if (!stmt->methods->next_rowset) {
+ pdo_raise_impl_error(stmt->dbh, stmt, "IM001", "driver does not support multiple rowsets" TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ PDO_STMT_CLEAR_ERR();
+
+ if (!pdo_stmt_do_next_rowset(stmt TSRMLS_CC)) {
PDO_HANDLE_STMT_ERR();
RETURN_FALSE;
}
}
/* }}} */
+/* {{{ proto bool PDOStatement::closeCursor()
+ Closes the cursor, leaving the statement ready for re-execution. */
+static PHP_METHOD(PDOStatement, closeCursor)
+{
+ pdo_stmt_t *stmt = (pdo_stmt_t*)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ if (!stmt->methods->cursor_closer) {
+ /* emulate it by fetching and discarding rows */
+ do {
+ while (stmt->methods->fetcher(stmt, PDO_FETCH_ORI_NEXT, 0 TSRMLS_CC))
+ ;
+ if (!stmt->methods->next_rowset) {
+ break;
+ }
+
+ if (!pdo_stmt_do_next_rowset(stmt TSRMLS_CC)) {
+ break;
+ }
+
+ } while (1);
+ RETURN_TRUE;
+ }
+
+ PDO_STMT_CLEAR_ERR();
+
+ if (!stmt->methods->cursor_closer(stmt TSRMLS_CC)) {
+ PDO_HANDLE_STMT_ERR();
+ RETURN_FALSE;
+ }
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+
function_entry pdo_dbstmt_functions[] = {
PHP_ME(PDOStatement, execute, NULL, ZEND_ACC_PUBLIC)
PHP_ME(PDOStatement, fetch, NULL, ZEND_ACC_PUBLIC)
PHP_ME(PDOStatement, getColumnMeta, NULL, ZEND_ACC_PUBLIC)
PHP_ME(PDOStatement, setFetchMode, NULL, ZEND_ACC_PUBLIC)
PHP_ME(PDOStatement, nextRowset, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(PDOStatement, closeCursor, NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
# define FALSE 0
#endif
-#define PDO_DRIVER_API 20050708
+#define PDO_DRIVER_API 20050709
enum pdo_param_type {
PDO_PARAM_NULL,
* to the caller. */
typedef int (*pdo_stmt_next_rowset_func)(pdo_stmt_t *stmt TSRMLS_DC);
+/* closes the active cursor on a statement, leaving the prepared
+ * statement ready for re-execution. Useful to explicitly state
+ * that you are done with a given rowset, without having to explicitly
+ * fetch all the rows. */
+typedef int (*pdo_stmt_cursor_closer_func)(pdo_stmt_t *stmt TSRMLS_DC);
+
struct pdo_stmt_methods {
pdo_stmt_dtor_func dtor;
pdo_stmt_execute_func executer;
pdo_stmt_get_attr_func get_attribute;
pdo_stmt_get_column_meta_func get_column_meta;
pdo_stmt_next_rowset_func next_rowset;
+ pdo_stmt_cursor_closer_func cursor_closer;
};
/* }}} */
$db->exec('INSERT INTO test VALUES(1, \'String1\')');
$db->exec('INSERT INTO test VALUES(2, \'String2\')');
-if ($db->getAttribute(PDO_ATTR_DRIVER_NAME) == 'mysql') {
- $db->setAttribute(PDO_MYSQL_ATTR_USE_BUFFERED_QUERY, 1);
-}
-
$stmt1 = $db->prepare('SELECT COUNT(idx) FROM test');
$stmt2 = $db->prepare('SELECT idx, txt FROM test ORDER by idx');
$stmt1->execute();
var_dump($stmt1->fetchColumn());
+$stmt1 = null;
$stmt2->execute();
$cont = $stmt2->fetchAll(PDO_FETCH_COLUMN|PDO_FETCH_UNIQUE);
$stmt3->bindColumn('txt', $col1);
}
var_dump($stmt3->fetch(PDO_FETCH_BOUND));
+ $stmt3->closeCursor();
var_dump($stmt4->execute());
if ($idx == 0) {
$stmt4->bindColumn('idx', $col2);
}
var_dump($stmt4->fetch(PDO_FETCH_BOUND));
+ $stmt4->closeCursor();
var_dump(array($col2=>$col1));
}
var_dump(array($idx=>$txt));
var_dump($stmt3->execute());
var_dump($stmt3->fetch(PDO_FETCH_BOUND));
+ $stmt3->closeCursor();
var_dump($col1);
var_dump($stmt4->execute());
var_dump($stmt4->fetch(PDO_FETCH_BOUND));
+ $stmt4->closeCursor();
var_dump($col1);
}