diff options
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/pdo/pdo_dbh.c | 8 | ||||
| -rw-r--r-- | ext/pdo/php_pdo_driver.h | 5 | ||||
| -rw-r--r-- | ext/pdo_dblib/dblib_driver.c | 3 | ||||
| -rw-r--r-- | ext/pdo_firebird/firebird_driver.c | 6 | ||||
| -rw-r--r-- | ext/pdo_mysql/mysql_driver.c | 3 | ||||
| -rw-r--r-- | ext/pdo_oci/oci_driver.c | 7 | ||||
| -rw-r--r-- | ext/pdo_odbc/odbc_driver.c | 6 | ||||
| -rw-r--r-- | ext/pdo_pgsql/pgsql_driver.c | 1 | ||||
| -rw-r--r-- | ext/pdo_sqlite/sqlite_driver.c | 22 | ||||
| -rw-r--r-- | ext/pdo_sqlite/tests/gc.phpt | 24 | 
10 files changed, 75 insertions, 10 deletions
| diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 2e81db2bbf..25ee7afb2e 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -1291,8 +1291,12 @@ static int dbh_compare(zval *object1, zval *object2)  static HashTable *dbh_get_gc(zend_object *object, zval **gc_data, int *gc_count)  {  	pdo_dbh_t *dbh = php_pdo_dbh_fetch_inner(object); -	*gc_data = &dbh->def_stmt_ctor_args; -	*gc_count = 1; +	zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); +	zend_get_gc_buffer_add_zval(gc_buffer, &dbh->def_stmt_ctor_args); +	if (dbh->methods->get_gc) { +		dbh->methods->get_gc(dbh, gc_buffer); +	} +	zend_get_gc_buffer_use(gc_buffer, gc_data, gc_count);  	return zend_std_get_properties(object);  } diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h index 960ddec4ef..974eb0bad0 100644 --- a/ext/pdo/php_pdo_driver.h +++ b/ext/pdo/php_pdo_driver.h @@ -286,6 +286,10 @@ typedef int (*pdo_dbh_check_liveness_func)(pdo_dbh_t *dbh);   * scope */  typedef void (*pdo_dbh_request_shutdown)(pdo_dbh_t *dbh); +/* Called when the PDO handle is scanned for GC. Should populate the get_gc buffer + * with any zvals in the driver_data that would be freed if the handle is destroyed. */ +typedef void (*pdo_dbh_get_gc_func)(pdo_dbh_t *dbh, zend_get_gc_buffer *buffer); +  /* for adding methods to the dbh or stmt objects  pointer to a list of driver specific functions. The convention is  to prefix the function names using the PDO driver name; this will @@ -316,6 +320,7 @@ struct pdo_dbh_methods {  	pdo_dbh_get_driver_methods_func get_driver_methods;  	pdo_dbh_request_shutdown	persistent_shutdown;  	pdo_dbh_txn_func		in_transaction; +	pdo_dbh_get_gc_func		get_gc;  };  /* }}} */ diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c index 7f160a402f..e581642037 100644 --- a/ext/pdo_dblib/dblib_driver.c +++ b/ext/pdo_dblib/dblib_driver.c @@ -417,7 +417,8 @@ static const struct pdo_dbh_methods dblib_methods = {  	NULL, /* check liveness */  	NULL, /* get driver methods */  	NULL, /* request shutdown */ -	NULL  /* in transaction */ +	NULL, /* in transaction */ +	NULL /* get gc */  };  static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options) diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index c27a9e2ed5..c299907f0f 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -1005,7 +1005,11 @@ static const struct pdo_dbh_methods firebird_methods = { /* {{{ */  	NULL, /* last_id not supported */  	pdo_firebird_fetch_error_func,  	firebird_handle_get_attribute, -	NULL /* check_liveness */ +	NULL, /* check_liveness */ +	NULL, /* get driver methods */ +	NULL, /* request shutdown */ +	NULL, /* in transaction */ +	NULL /* get gc */  };  /* }}} */ diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c index a666489a50..19923464e4 100644 --- a/ext/pdo_mysql/mysql_driver.c +++ b/ext/pdo_mysql/mysql_driver.c @@ -563,7 +563,8 @@ static const struct pdo_dbh_methods mysql_methods = {  	pdo_mysql_check_liveness,  	NULL,  	pdo_mysql_request_shutdown, -	pdo_mysql_in_transaction +	pdo_mysql_in_transaction, +	NULL /* get_gc */  };  /* }}} */ diff --git a/ext/pdo_oci/oci_driver.c b/ext/pdo_oci/oci_driver.c index 096a26575e..2c65fc973b 100644 --- a/ext/pdo_oci/oci_driver.c +++ b/ext/pdo_oci/oci_driver.c @@ -705,9 +705,10 @@ static const struct pdo_dbh_methods oci_methods = {  	pdo_oci_fetch_error_func,  	oci_handle_get_attribute,  	pdo_oci_check_liveness,	/* check_liveness */ -	NULL,	/* get_driver_methods */ -	NULL, -	NULL +	NULL, /* get_driver_methods */ +	NULL, /* request_shutdown */ +	NULL, /* in_transaction */ +	NULL /* get_gc */  };  static int pdo_oci_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ */ diff --git a/ext/pdo_odbc/odbc_driver.c b/ext/pdo_odbc/odbc_driver.c index 9a254553d5..81e4915da5 100644 --- a/ext/pdo_odbc/odbc_driver.c +++ b/ext/pdo_odbc/odbc_driver.c @@ -384,7 +384,11 @@ static const struct pdo_dbh_methods odbc_methods = {  	NULL,	/* last id */  	pdo_odbc_fetch_error_func,  	odbc_handle_get_attr,	/* get attr */ -	NULL,	/* check_liveness */ +	NULL, /* check_liveness */ +	NULL, /* get_driver_methods */ +	NULL, /* request_shutdown */ +	NULL, /* in_transaction */ +	NULL /* get_gc */  };  static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ */ diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index d800d65a2d..37680b8efa 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -1179,6 +1179,7 @@ static const struct pdo_dbh_methods pgsql_methods = {  	pdo_pgsql_get_driver_methods,  /* get_driver_methods */  	NULL,  	pgsql_handle_in_transaction, +	NULL /* get_gc */  };  static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ */ diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c index 26fa1c00eb..a8a96c7a13 100644 --- a/ext/pdo_sqlite/sqlite_driver.c +++ b/ext/pdo_sqlite/sqlite_driver.c @@ -695,6 +695,25 @@ static void pdo_sqlite_request_shutdown(pdo_dbh_t *dbh)  	}  } +static void pdo_sqlite_get_gc(pdo_dbh_t *dbh, zend_get_gc_buffer *gc_buffer) +{ +	pdo_sqlite_db_handle *H = dbh->driver_data; + +	struct pdo_sqlite_func *func = H->funcs; +	while (func) { +		zend_get_gc_buffer_add_zval(gc_buffer, &func->func); +		zend_get_gc_buffer_add_zval(gc_buffer, &func->step); +		zend_get_gc_buffer_add_zval(gc_buffer, &func->fini); +		func = func->next; +	} + +	struct pdo_sqlite_collation *collation = H->collations; +	while (collation) { +		zend_get_gc_buffer_add_zval(gc_buffer, &collation->callback); +		collation = collation->next; +	} +} +  static const struct pdo_dbh_methods sqlite_methods = {  	sqlite_handle_closer,  	sqlite_handle_preparer, @@ -710,7 +729,8 @@ static const struct pdo_dbh_methods sqlite_methods = {  	NULL,	/* check_liveness: not needed */  	get_driver_methods,  	pdo_sqlite_request_shutdown, -	NULL +	NULL, /* in_transaction */ +	pdo_sqlite_get_gc  };  static char *make_filename_safe(const char *filename) diff --git a/ext/pdo_sqlite/tests/gc.phpt b/ext/pdo_sqlite/tests/gc.phpt new file mode 100644 index 0000000000..25407697e6 --- /dev/null +++ b/ext/pdo_sqlite/tests/gc.phpt @@ -0,0 +1,24 @@ +--TEST-- +GC support for PDO Sqlite driver data +--SKIPIF-- +<?php +if (!extension_loaded('pdo_sqlite')) print 'skip not loaded'; +?> +--FILE-- +<?php + +class Obj { +	public $a; +	public function callback() { } +} + +$obj = new Obj; +$obj->a = new PDO('sqlite::memory:'); +$obj->a->sqliteCreateFunction('func1', function() use ($obj) {}, 1); +$obj->a->sqliteCreateAggregate('func2', function() use ($obj) {}, function() use($obj) {}); +$obj->a->sqliteCreateCollation('col', function() use ($obj) {}); + +?> +===DONE=== +--EXPECT-- +===DONE=== | 
