mirror of
https://github.com/php/pecl-database-pdo_user.git
synced 2026-03-23 22:42:10 +01:00
Initial Release
This commit is contained in:
0
EXPERIMENTAL
Normal file
0
EXPERIMENTAL
Normal file
264
README.OBJECTS
Normal file
264
README.OBJECTS
Normal file
@@ -0,0 +1,264 @@
|
||||
PDO Userspace Driver
|
||||
--------------------
|
||||
|
||||
This extension exports three class definitions (two interfaces plus one static class):
|
||||
|
||||
interface PDO_User_Driver {
|
||||
function __construct($dsn, $user, $pass, $options) {
|
||||
/* new PDO('user:driver=classname;...') */
|
||||
}
|
||||
|
||||
function pdo_prepare($sql, $options) {
|
||||
/* PDO::prepare() or PDO::query() */
|
||||
|
||||
if (SUCCESS) {
|
||||
return new Object_Implementing_PDO_User_Statement($optional, $parameters);
|
||||
} else {
|
||||
/* If your class will be unable to perform the query, return false here to indicate failure */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function pdo_do($sql) {
|
||||
/* PDO::exec() */
|
||||
if (SUCCESS) {
|
||||
return $rowsAffected;
|
||||
} else {
|
||||
return FALSE; /* NULL or a negative number may also be used to indicate failure */
|
||||
}
|
||||
}
|
||||
|
||||
function pdo_quote($string) {
|
||||
/* PDO::quote() */
|
||||
|
||||
/* There is no "failure" mode for this method, you must return something */
|
||||
return $modifiedString;
|
||||
}
|
||||
|
||||
function pdo_begin() {
|
||||
/* PDO::beginTransaction() */
|
||||
if (SUCCESS) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function pdo_commit() {
|
||||
/* PDO::commit() */
|
||||
if (SUCCESS) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function pdo_rollback() {
|
||||
/* PDO::rollBack() */
|
||||
if (SUCCESS) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function pdo_lastInsertID($seq) {
|
||||
/* PDO::lastInsertID() */
|
||||
|
||||
/* There is no "failure" mode for this method, you must return something */
|
||||
return $lastIDString;
|
||||
}
|
||||
|
||||
function pdo_checkLiveness() {
|
||||
/* Called by PDO internally */
|
||||
return $driverIsAliveBool;
|
||||
}
|
||||
|
||||
function pdo_setAttribute($attr, $val) {
|
||||
/* PDO::setAttribute($attr, $val) */
|
||||
|
||||
/* $attr == PDO::ATTR_* */
|
||||
if (SUCCESS) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function pdo_getAttribute($attr) {
|
||||
/* PDO::getAttribute($attr) */
|
||||
|
||||
/* $attr == PDO::ATTR_* */
|
||||
if (SUCCESS) {
|
||||
return $attributeValue;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function pdo_close() {
|
||||
/* Called when shutting down a database handle - e.g. unset($pdoHandle); */
|
||||
|
||||
/* Return value ignored */
|
||||
}
|
||||
|
||||
function pdo_fetchError() {
|
||||
/* PDO::errorInfo */
|
||||
|
||||
return array(0 => 12345, 1 => 'Error 12345 has occured...blah...blah...blah');
|
||||
}
|
||||
}
|
||||
|
||||
interface PDO_User_Statement {
|
||||
function pdo_execute() {
|
||||
/* PDO_Statement::execute() */
|
||||
|
||||
/* The result of emulated bound parameters may be retreived via: */
|
||||
$resultQuery = PDO_User::statementParam($this, PDO_User::STATEMENT_PARAM_ACTIVE_QUERY);
|
||||
|
||||
if (SUCCESS) {
|
||||
return array('rows' => $numberOfRowsInSet, 'cols' => $numberOfColsInSet);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function pdo_fetch($orientation, $offset) {
|
||||
/* PDO_Statement::fetch() and family */
|
||||
|
||||
/* This method should only adjust the current cursor's position,
|
||||
* getcol() will be used to actually retreive the data */
|
||||
|
||||
/* $orientation is one of PDO::FETCH_ORI_*
|
||||
* $offset is a relative position to the location tagged by $orientation */
|
||||
if (SUCCESS) {
|
||||
return true;
|
||||
} else {
|
||||
/* e.g. - No more rows */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function pdo_nextRowset() {
|
||||
/* PDO_Statement::nextRowset() */
|
||||
|
||||
if (SUCCESS) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function pdo_describe($columnNumber) {
|
||||
/* Called after PDO_Statement::execute() to determine column names,
|
||||
* also used by PDO_Statement::getColumnMeta() */
|
||||
return array('name' => $nameOfColumn, 'maxlen' => $maximumLengthOfDataInColumn);
|
||||
}
|
||||
|
||||
function pdo_colmeta($columnNumber) {
|
||||
/* PDO_Statement::getColumnMeta() */
|
||||
/* Return as many of the supported fields as possible,
|
||||
* custom fields may also be returned by prefixing with user: */
|
||||
return array('scale' => $floatingPointScale,
|
||||
'table' => $sourceTable,
|
||||
'type' => $phpTypeName, /* e.g. 'string', 'integer', 'bool' */
|
||||
'native_type' => $dbTypeName, /* e.g. 'char', 'blog', 'double' */
|
||||
'flags' => array( 'primary_key',
|
||||
'not_null',
|
||||
'unique_key',
|
||||
'multiple_key',
|
||||
'unsigned',
|
||||
'auto_increment',
|
||||
'blob',
|
||||
'user:foo', /* custom flag(s) */
|
||||
),
|
||||
'user:bar' => 'baz' /* custom metadata(s) */
|
||||
);
|
||||
}
|
||||
|
||||
function pdo_getcol($columnNumber) {
|
||||
/* Called by PDO_Statement::fetch() family of functions */
|
||||
|
||||
return $contentsOfColumnForCurrentRow;
|
||||
}
|
||||
|
||||
function pdo_paramhook($event, $columnNumber, $columnName, $isParam, &$parameter) {
|
||||
/* Called before and after EXEC and FETCH events */
|
||||
/* $event is one of PDO::PARAM_EVT_EXEC_* or PDO_PARAM_EVT_FETCH_*
|
||||
* $columnNumber / $columnName are the identifiers of the column, either or both may be available
|
||||
* $isParam is TRUE for placeholder parameters (e.g. WHERE foo = ?), it is FALSE for result parameters (e.g. SELECT col1)
|
||||
* $parameter is the actual bound variable and is always passed by reference */
|
||||
|
||||
/* Return value is ignored */
|
||||
}
|
||||
|
||||
function pdo_setAttribute($attr, $val) {
|
||||
/* PDO_Statement::setAttribute($attr, $val) */
|
||||
|
||||
/* $attr == PDO::ATTR_* */
|
||||
if (SUCCESS) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function pdo_getAttribute($attr) {
|
||||
/* PDO_Statement::getAttribute($attr) */
|
||||
|
||||
/* $attr == PDO::ATTR_* */
|
||||
if (SUCCESS) {
|
||||
return $attributeValue;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function pdo_closeCursor() {
|
||||
/* PDO_Statement::closeCursor() */
|
||||
|
||||
if (SUCCESS) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function pdo_close() {
|
||||
/* Called with shutting down a statement */
|
||||
|
||||
/* Return value ignored */
|
||||
}
|
||||
}
|
||||
|
||||
class PDO_User {
|
||||
function parseDSN($dsn, $params) {
|
||||
/* Parses a DSN string in the format: var1=val1;var2=val2;var3=val3;...
|
||||
* For the variables named in $params, For example:
|
||||
|
||||
$result = PDO_User::parseDSN('host=localhost;port=3306', array('host','port'));
|
||||
print_r($result);
|
||||
|
||||
* Results in:
|
||||
|
||||
Array(2) {
|
||||
[host] => localhost
|
||||
[port] => 3306
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
function driverParam($attribute[, $value]) {
|
||||
/* $attribute is one of:
|
||||
PDO_User::DRIVER_PARAM_MAX_ESCAPSED_CHAR_LENGTH (used by emulated prepared statement routines internally)
|
||||
PDO_User::DRIVER_PARAM_DATA_SOURCE (refers to the $dsn passed to the driver class' constructor)
|
||||
PDO_User::DRIVER_PARAM_SQLSTATE (Driver's current SQLSTATE value)
|
||||
|
||||
PDO_User::STATEMENT_PARAM_ACTIVE_QUERY (Post-transformation emulated prepared statement result)
|
||||
PDO_User::STATEMENT_PARAM_SQLSTATE (Statement's current SQLSTATE value)
|
||||
|
||||
* When $value is passed, the parameter will be set to this new value
|
||||
* Whether or not $value is passed, the current value will be returned */
|
||||
}
|
||||
}
|
||||
40
config.m4
Normal file
40
config.m4
Normal file
@@ -0,0 +1,40 @@
|
||||
dnl
|
||||
dnl $Id$
|
||||
dnl
|
||||
|
||||
if test "$PHP_PDO" != "no"; then
|
||||
|
||||
PHP_ARG_ENABLE(pdo-user, for Userdriver support for PDO,
|
||||
[ --enable-pdo-user PDO: Userdriver support.])
|
||||
|
||||
if test "$PHP_PDO_USER" != "no"; then
|
||||
AC_DEFINE(HAVE_USER, 1, [Whether you have Userdriver Support])
|
||||
|
||||
ifdef([PHP_CHECK_PDO_INCLUDES],
|
||||
[
|
||||
PHP_CHECK_PDO_INCLUDES
|
||||
],[
|
||||
AC_MSG_CHECKING([for PDO includes])
|
||||
if test -f $abs_srcdir/include/php/ext/pdo/php_pdo_driver.h; then
|
||||
pdo_inc_path=$abs_srcdir/ext
|
||||
elif test -f $abs_srcdir/ext/pdo/php_pdo_driver.h; then
|
||||
pdo_inc_path=$abs_srcdir/ext
|
||||
elif test -f $prefix/include/php/ext/pdo/php_pdo_driver.h; then
|
||||
pdo_inc_path=$prefix/include/php/ext
|
||||
else
|
||||
AC_MSG_ERROR([Cannot find php_pdo_driver.h.])
|
||||
fi
|
||||
AC_MSG_RESULT($pdo_inc_path)
|
||||
])
|
||||
|
||||
PHP_NEW_EXTENSION(pdo_user, pdo_user.c pdo_user_driver.c pdo_user_statement.c pdo_user_object.c, $ext_shared,,-I$pdo_inc_path)
|
||||
ifdef([PHP_ADD_EXTENSION_DEP],
|
||||
[
|
||||
PHP_ADD_EXTENSION_DEP(pdo_user, pdo)
|
||||
])
|
||||
|
||||
PHP_SUBST(PDO_USER_SHARED_LIBADD)
|
||||
fi
|
||||
|
||||
fi
|
||||
dnl vim: se ts=2 sw=2 et:
|
||||
11
config.w32
Normal file
11
config.w32
Normal file
@@ -0,0 +1,11 @@
|
||||
// $Id$
|
||||
// vim:ft=javascript
|
||||
|
||||
ARG_ENABLE("pdo-sqlite", "for pdo_user support", "no");
|
||||
|
||||
if (PHP_PDO_USER != "no") {
|
||||
|
||||
EXTENSION("pdo_user", "pdo_user.c pdo_user_driver.c pdo_user_statement.c pdo_user_object.c");
|
||||
ADD_EXTENSION_DEP('pdo_user', 'pdo');
|
||||
}
|
||||
|
||||
66
package2.xml
Normal file
66
package2.xml
Normal file
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<package packagerversion="1.4.2" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
|
||||
http://pear.php.net/dtd/tasks-1.0.xsd
|
||||
http://pear.php.net/dtd/package-2.0
|
||||
http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<name>PDO_USER</name>
|
||||
<channel>pecl.php.net</channel>
|
||||
<summary>Userspace driver for PDO</summary>
|
||||
<description>This extension provides a Userspace interface for PDO drivers</description>
|
||||
<lead>
|
||||
<name>Sara Golemon</name>
|
||||
<user>pollita</user>
|
||||
<email>pollita@php.net</email>
|
||||
<active>yes</active>
|
||||
</lead>
|
||||
<date>2006-05-03</date>
|
||||
<version>
|
||||
<release>0.1.0</release>
|
||||
<api>0.1.0</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>beta</release>
|
||||
<api>beta</api>
|
||||
</stability>
|
||||
<license uri="http://www.php.net/license">PHP</license>
|
||||
<notes>Initial Release</notes>
|
||||
<contents>
|
||||
<dir name="/">
|
||||
<file name="config.m4" role="src" />
|
||||
<file name="config.w32" role="src" />
|
||||
<file name="CREDITS" role="doc" />
|
||||
<file name="EXPERIMENTAL" role="doc" />
|
||||
<file name="README.OBJECTS" role="doc" />
|
||||
<file name="pdo_user.c" role="src" />
|
||||
<file name="pdo_user_driver.c" role="src" />
|
||||
<file name="pdo_user_statement.c" role="src" />
|
||||
<file name="pdo_user_object.c" role="src" />
|
||||
<file name="php_pdo_user.h" role="src" />
|
||||
<file name="php_pdo_user_int.h" role="src" />
|
||||
<dir name="tests/">
|
||||
<file name="globals.phpt" role="test" />
|
||||
</dir> <!-- tests/ -->
|
||||
</dir> <!-- / -->
|
||||
</contents>
|
||||
<dependencies>
|
||||
<required>
|
||||
<php>
|
||||
<min>5.0.3</min>
|
||||
</php>
|
||||
<pearinstaller>
|
||||
<min>1.4.0</min>
|
||||
</pearinstaller>
|
||||
<package>
|
||||
<name>pdo</name>
|
||||
<channel>pecl.php.net</channel>
|
||||
<min>1.0.3</min>
|
||||
<providesextension>PDO</providesextension>
|
||||
</package>
|
||||
</required>
|
||||
</dependencies>
|
||||
<providesextension>PDO_USER</providesextension>
|
||||
<extsrcrelease />
|
||||
</package>
|
||||
|
||||
|
||||
216
pdo_user.c
Normal file
216
pdo_user.c
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2006 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Sara Golemon <pollita@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include "php_pdo_user_int.h"
|
||||
#include "ext/standard/info.h"
|
||||
|
||||
ZEND_DECLARE_MODULE_GLOBALS(pdo_user)
|
||||
|
||||
extern pdo_driver_t pdo_user_driver;
|
||||
|
||||
/* *********************************
|
||||
* PtrMap linked list management *
|
||||
********************************* */
|
||||
|
||||
struct _php_pdo_user_llist {
|
||||
php_pdo_user_llist *next, *prev;
|
||||
php_pdo_user_data *data;
|
||||
};
|
||||
|
||||
int php_pdo_user_ptrmap_map(php_pdo_user_data *data TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_llist *el = emalloc(sizeof(php_pdo_user_llist));
|
||||
|
||||
el->next = PDO_USER_G(ptr_map);
|
||||
el->prev = NULL;
|
||||
el->data = data;
|
||||
|
||||
if (PDO_USER_G(ptr_map)) {
|
||||
PDO_USER_G(ptr_map)->prev = el;
|
||||
}
|
||||
|
||||
PDO_USER_G(ptr_map) = el;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int php_pdo_user_ptrmap_unmap(php_pdo_user_data *data TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_llist *el = PDO_USER_G(ptr_map);
|
||||
|
||||
if (!el) {
|
||||
/* Nothing to unmap, not normal codepath... */
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
while (el) {
|
||||
if (el->data == data) {
|
||||
if (el->prev) {
|
||||
el->prev->next = el->next;
|
||||
} else {
|
||||
PDO_USER_G(ptr_map) = el->next;
|
||||
}
|
||||
if (el->next) {
|
||||
el->next->prev = el->prev;
|
||||
}
|
||||
efree(el);
|
||||
return SUCCESS;
|
||||
}
|
||||
el = el->next;
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
void *php_pdo_user_ptrmap_locate(zval *object TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_llist *el = PDO_USER_G(ptr_map);
|
||||
|
||||
if (!el) {
|
||||
/* Nothing to find */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (el) {
|
||||
if (el->data->object == object) {
|
||||
return el->data;
|
||||
}
|
||||
el = el->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void php_pdo_user_ptrmap_destroy(TSRMLS_D)
|
||||
{
|
||||
php_pdo_user_llist *el = PDO_USER_G(ptr_map);
|
||||
|
||||
while (el) {
|
||||
php_pdo_user_llist *next = el->next;
|
||||
|
||||
efree(el);
|
||||
el = next;
|
||||
}
|
||||
|
||||
PDO_USER_G(ptr_map) = NULL;
|
||||
}
|
||||
|
||||
/* ***********************
|
||||
* Module Housekeeping *
|
||||
*********************** */
|
||||
|
||||
/* {{{ pdo_user_functions[] */
|
||||
#if ZEND_MODULE_API_NO >= 20050922
|
||||
static zend_module_dep pdo_user_deps[] = {
|
||||
ZEND_MOD_REQUIRED("pdo")
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION
|
||||
*/
|
||||
PHP_MINIT_FUNCTION(pdo_user)
|
||||
{
|
||||
#ifdef ZTS
|
||||
ts_allocate_id(&pdo_user_globals_id, sizeof(zend_pdo_user_globals), NULL, NULL);
|
||||
#endif
|
||||
|
||||
if (FAILURE == PHP_MINIT(php_pdo_user_class)(INIT_FUNC_ARGS_PASSTHRU)) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return php_pdo_register_driver(&pdo_user_driver);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_RINIT_FUNCTION
|
||||
*/
|
||||
PHP_RINIT_FUNCTION(pdo_user)
|
||||
{
|
||||
PDO_USER_G(ptr_map) = NULL;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_RSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_RSHUTDOWN_FUNCTION(pdo_user)
|
||||
{
|
||||
if (PDO_USER_G(ptr_map)) {
|
||||
php_pdo_user_ptrmap_destroy(TSRMLS_C);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo_user)
|
||||
{
|
||||
php_pdo_unregister_driver(&pdo_user_driver);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
PHP_MINFO_FUNCTION(pdo_user)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "PDO Driver for Userspace data sources", "enabled");
|
||||
php_info_print_table_end();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ pdo_user_module_entry */
|
||||
zend_module_entry pdo_user_module_entry = {
|
||||
#if ZEND_MODULE_API_NO >= 20050922
|
||||
STANDARD_MODULE_HEADER_EX, NULL,
|
||||
pdo_user_deps,
|
||||
#else
|
||||
STANDARD_MODULE_HEADER,
|
||||
#endif
|
||||
PHP_PDO_USER_EXTNAME,
|
||||
NULL, /* procedural functions */
|
||||
PHP_MINIT(pdo_user),
|
||||
PHP_MSHUTDOWN(pdo_user),
|
||||
PHP_RINIT(pdo_user),
|
||||
PHP_RSHUTDOWN(pdo_user),
|
||||
PHP_MINFO(pdo_user),
|
||||
PHP_PDO_USER_EXTVER,
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_PDO_USER
|
||||
ZEND_GET_MODULE(pdo_user)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
474
pdo_user_driver.c
Normal file
474
pdo_user_driver.c
Normal file
@@ -0,0 +1,474 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2006 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Sara Golemon <pollita@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include "php_pdo_user_int.h"
|
||||
#include "zend_exceptions.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
/* ******************
|
||||
* Driver Methods *
|
||||
****************** */
|
||||
|
||||
#define PHP_PDO_USER_DRV_CLOSER "pdo_close"
|
||||
#define PHP_PDO_USER_DRV_PREPARER "pdo_prepare"
|
||||
#define PHP_PDO_USER_DRV_DOER "pdo_do"
|
||||
#define PHP_PDO_USER_DRV_QUOTER "pdo_quote"
|
||||
#define PHP_PDO_USER_DRV_BEGIN "pdo_begin"
|
||||
#define PHP_PDO_USER_DRV_COMMIT "pdo_commit"
|
||||
#define PHP_PDO_USER_DRV_ROLLBACK "pdo_rollback"
|
||||
#define PHP_PDO_USER_DRV_SET_ATTRIBUTE "pdo_setattribute"
|
||||
#define PHP_PDO_USER_DRV_LAST_INSERT_ID "pdo_lastinsertid"
|
||||
#define PHP_PDO_USER_DRV_FETCH_ERROR_FUNC "pdo_fetcherror"
|
||||
#define PHP_PDO_USER_DRV_GET_ATTRIBUTE "pdo_getattribute"
|
||||
#define PHP_PDO_USER_DRV_CHECK_LIVENESS "pdo_checkliveness"
|
||||
|
||||
static int php_pdo_user_closer(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)dbh->driver_data;
|
||||
|
||||
if (data) {
|
||||
zval fname, retval;
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_DRV_CLOSER, sizeof(PHP_PDO_USER_DRV_CLOSER) - 1, 0);
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 0, NULL TSRMLS_CC) == SUCCESS) {
|
||||
/* Ignore retval */
|
||||
zval_dtor(&retval);
|
||||
}
|
||||
|
||||
php_pdo_user_ptrmap_unmap(data TSRMLS_CC);
|
||||
|
||||
zval_ptr_dtor(&(data->object));
|
||||
efree(data);
|
||||
|
||||
dbh->driver_data = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int php_pdo_user_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)dbh->driver_data;
|
||||
php_pdo_user_data *stmtdata = NULL;
|
||||
zval *args[2], fname, *retval;
|
||||
|
||||
stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_DRV_PREPARER, sizeof(PHP_PDO_USER_DRV_PREPARER) - 1, 0);
|
||||
|
||||
MAKE_STD_ZVAL(args[0]);
|
||||
ZVAL_STRINGL(args[0], sql, sql_len, 1);
|
||||
args[1] = driver_options ? driver_options : EG(uninitialized_zval_ptr);
|
||||
|
||||
ALLOC_INIT_ZVAL(retval);
|
||||
if (call_user_function(EG(function_table), &data->object, &fname, retval, 2, args TSRMLS_CC) == FAILURE) {
|
||||
zval_ptr_dtor(&args[0]);
|
||||
zval_ptr_dtor(&retval);
|
||||
return 0; /* FAILURE */
|
||||
}
|
||||
zval_ptr_dtor(&args[0]);
|
||||
|
||||
if (Z_TYPE_P(retval) != IS_OBJECT ||
|
||||
!php_pdo_user_implements_statement(Z_OBJCE_P(retval))) {
|
||||
/* TODO: Throw exception */
|
||||
zval_ptr_dtor(&retval);
|
||||
|
||||
return 0; /* FAILURE */
|
||||
}
|
||||
|
||||
stmtdata = emalloc(sizeof(php_pdo_user_data));
|
||||
stmtdata->object = retval;
|
||||
stmtdata->dbh = dbh;
|
||||
stmtdata->stmt = stmt;
|
||||
php_pdo_user_ptrmap_map(stmtdata TSRMLS_CC);
|
||||
|
||||
stmt->driver_data = stmtdata;
|
||||
stmt->methods = &php_pdo_user_stmt_methods;
|
||||
|
||||
/* TODO: Allow a way to expose native prepared statements */
|
||||
|
||||
return 1; /* SUCCESS */
|
||||
}
|
||||
|
||||
static long php_pdo_user_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)dbh->driver_data;
|
||||
zval fname, *zsql, retval;
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_DRV_DOER, sizeof(PHP_PDO_USER_DRV_DOER) - 1, 0);
|
||||
|
||||
MAKE_STD_ZVAL(zsql);
|
||||
ZVAL_STRINGL(zsql, (char*)sql, sql_len, 1);
|
||||
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 1, &zsql TSRMLS_CC) == SUCCESS) {
|
||||
if (Z_TYPE(retval) == IS_NULL ||
|
||||
(Z_TYPE(retval) == IS_BOOL && Z_BVAL(retval) == 0)) {
|
||||
/* Convert NULL or FALSE to an error condition */
|
||||
ZVAL_LONG(&retval, -1);
|
||||
} else {
|
||||
/* Anything else is just a number of rows affected */
|
||||
convert_to_long(&retval);
|
||||
}
|
||||
} else {
|
||||
ZVAL_LONG(&retval, -1);
|
||||
}
|
||||
zval_ptr_dtor(&zsql);
|
||||
|
||||
if (Z_LVAL(retval) < 0) {
|
||||
Z_LVAL(retval) = -1;
|
||||
}
|
||||
|
||||
return Z_LVAL(retval);
|
||||
}
|
||||
|
||||
static int php_pdo_user_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)dbh->driver_data;
|
||||
zval fname, *zunq, retval;
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_DRV_QUOTER, sizeof(PHP_PDO_USER_DRV_QUOTER) - 1, 0);
|
||||
|
||||
MAKE_STD_ZVAL(zunq);
|
||||
ZVAL_STRINGL(zunq, (char*)unquoted, unquotedlen, 1);
|
||||
|
||||
/* TODO: paramtype */
|
||||
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 1, &zunq TSRMLS_CC) == SUCCESS) {
|
||||
convert_to_string(&retval);
|
||||
} else {
|
||||
ZVAL_STRINGL(&retval, "", 0, 1);
|
||||
}
|
||||
|
||||
zval_ptr_dtor(&zunq);
|
||||
|
||||
*quoted = Z_STRVAL(retval);
|
||||
*quotedlen = Z_STRLEN(retval);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int php_pdo_user_begin(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)dbh->driver_data;
|
||||
zval fname, retval;
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_DRV_BEGIN, sizeof(PHP_PDO_USER_DRV_BEGIN) - 1, 0);
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 0, NULL TSRMLS_CC) == SUCCESS) {
|
||||
convert_to_boolean(&retval);
|
||||
} else {
|
||||
ZVAL_FALSE(&retval);
|
||||
}
|
||||
|
||||
return Z_BVAL(retval);
|
||||
}
|
||||
|
||||
static int php_pdo_user_commit(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)dbh->driver_data;
|
||||
zval fname, retval;
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_DRV_COMMIT, sizeof(PHP_PDO_USER_DRV_COMMIT) - 1, 0);
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 0, NULL TSRMLS_CC) == SUCCESS) {
|
||||
convert_to_boolean(&retval);
|
||||
} else {
|
||||
ZVAL_FALSE(&retval);
|
||||
}
|
||||
|
||||
return Z_BVAL(retval);
|
||||
}
|
||||
|
||||
static int php_pdo_user_rollback(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)dbh->driver_data;
|
||||
zval fname, retval;
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_DRV_ROLLBACK, sizeof(PHP_PDO_USER_DRV_ROLLBACK) - 1, 0);
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 0, NULL TSRMLS_CC) == SUCCESS) {
|
||||
convert_to_boolean(&retval);
|
||||
} else {
|
||||
ZVAL_FALSE(&retval);
|
||||
}
|
||||
|
||||
return Z_BVAL(retval);
|
||||
}
|
||||
|
||||
static int php_pdo_user_set_attribute(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)dbh->driver_data;
|
||||
zval fname, *zargs[2], retval;
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_DRV_SET_ATTRIBUTE, sizeof(PHP_PDO_USER_DRV_SET_ATTRIBUTE) - 1, 0);
|
||||
|
||||
MAKE_STD_ZVAL(zargs[0]);
|
||||
ZVAL_LONG(zargs[0], attr);
|
||||
|
||||
zargs[1] = val;
|
||||
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 2, zargs TSRMLS_CC) == SUCCESS) {
|
||||
convert_to_boolean(&retval);
|
||||
} else {
|
||||
ZVAL_FALSE(&retval);
|
||||
}
|
||||
|
||||
zval_ptr_dtor(&zargs[0]);
|
||||
|
||||
return Z_BVAL(retval);
|
||||
}
|
||||
|
||||
static char *php_pdo_user_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)dbh->driver_data;
|
||||
zval fname, *zname, retval;
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_DRV_LAST_INSERT_ID, sizeof(PHP_PDO_USER_DRV_LAST_INSERT_ID) - 1, 0);
|
||||
|
||||
MAKE_STD_ZVAL(zname);
|
||||
ZVAL_STRING(zname, (char*)name, 1);
|
||||
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 1, &zname TSRMLS_CC) == SUCCESS) {
|
||||
convert_to_string(&retval);
|
||||
} else {
|
||||
ZVAL_STRINGL(&retval, "", 0, 1);
|
||||
}
|
||||
|
||||
*len = Z_STRLEN(retval);
|
||||
return Z_STRVAL(retval);
|
||||
}
|
||||
|
||||
static int php_pdo_user_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)dbh->driver_data;
|
||||
zval fname, retval;
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_DRV_FETCH_ERROR_FUNC, sizeof(PHP_PDO_USER_DRV_FETCH_ERROR_FUNC) - 1, 0);
|
||||
|
||||
/* TODO: Include statement object (if it exists) */
|
||||
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 0, NULL TSRMLS_CC) == SUCCESS) {
|
||||
if (Z_TYPE(retval) == IS_ARRAY) {
|
||||
zval **tmpzval;
|
||||
|
||||
if (zend_hash_index_find(Z_ARRVAL(retval), 0, (void**)&tmpzval) == SUCCESS) {
|
||||
zval *copyval;
|
||||
|
||||
MAKE_STD_ZVAL(copyval);
|
||||
*copyval = **tmpzval;
|
||||
INIT_PZVAL(copyval);
|
||||
zval_copy_ctor(copyval);
|
||||
convert_to_long(copyval);
|
||||
add_next_index_zval(info, copyval);
|
||||
} else {
|
||||
add_next_index_long(info, 0);
|
||||
}
|
||||
|
||||
if (zend_hash_index_find(Z_ARRVAL(retval), 0, (void**)&tmpzval) == SUCCESS) {
|
||||
zval *copyval;
|
||||
|
||||
MAKE_STD_ZVAL(copyval);
|
||||
*copyval = **tmpzval;
|
||||
INIT_PZVAL(copyval);
|
||||
zval_copy_ctor(copyval);
|
||||
convert_to_string(copyval);
|
||||
add_next_index_zval(info, copyval);
|
||||
} else {
|
||||
add_next_index_string(info, "", 1);
|
||||
}
|
||||
} else {
|
||||
add_next_index_long(info, 0);
|
||||
add_next_index_string(info, "", 1);
|
||||
}
|
||||
zval_dtor(&retval);
|
||||
} else {
|
||||
add_next_index_long(info, 0);
|
||||
add_next_index_string(info, "", 1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int php_pdo_user_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)dbh->driver_data;
|
||||
zval fname, *zattr;
|
||||
int ret = 1; /* SUCCESS */
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_DRV_GET_ATTRIBUTE, sizeof(PHP_PDO_USER_DRV_GET_ATTRIBUTE) - 1, 0);
|
||||
|
||||
MAKE_STD_ZVAL(zattr);
|
||||
ZVAL_LONG(zattr, attr);
|
||||
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, return_value, 1, &zattr TSRMLS_CC) == FAILURE) {
|
||||
ZVAL_NULL(return_value);
|
||||
ret = 0; /* FAILURE */
|
||||
}
|
||||
|
||||
zval_ptr_dtor(&zattr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int php_pdo_user_check_liveness(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)dbh->driver_data;
|
||||
zval fname, retval;
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_DRV_CHECK_LIVENESS, sizeof(PHP_PDO_USER_DRV_CHECK_LIVENESS) - 1, 0);
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 0, NULL TSRMLS_CC) == SUCCESS) {
|
||||
convert_to_boolean(&retval);
|
||||
} else {
|
||||
ZVAL_FALSE(&retval);
|
||||
}
|
||||
|
||||
return Z_BVAL(retval);
|
||||
}
|
||||
|
||||
static struct pdo_dbh_methods php_pdo_user_drv_methods = {
|
||||
php_pdo_user_closer,
|
||||
php_pdo_user_preparer,
|
||||
php_pdo_user_doer,
|
||||
php_pdo_user_quoter,
|
||||
php_pdo_user_begin,
|
||||
php_pdo_user_commit,
|
||||
php_pdo_user_rollback,
|
||||
php_pdo_user_set_attribute,
|
||||
php_pdo_user_last_insert_id,
|
||||
php_pdo_user_fetch_error_func,
|
||||
php_pdo_user_get_attribute,
|
||||
php_pdo_user_check_liveness,
|
||||
};
|
||||
|
||||
/* ***********
|
||||
* FACTORY *
|
||||
*********** */
|
||||
|
||||
static void php_pdo_factory_error(int errcode TSRMLS_DC, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *message;
|
||||
|
||||
va_start(args, format);
|
||||
vspprintf(&message, 0, format, args);
|
||||
zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "SQLSTATE[HY000] [%d] %s", errcode, message);
|
||||
va_end(args);
|
||||
efree(message);
|
||||
}
|
||||
|
||||
/* {{{ pdo_user_driver_factory */
|
||||
static int pdo_user_driver_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC)
|
||||
{
|
||||
zend_class_entry *ce;
|
||||
php_pdo_user_data *data = NULL;
|
||||
zval *object = NULL;
|
||||
zend_function *constructor;
|
||||
struct pdo_data_src_parser vars[] = {
|
||||
{ "driver", NULL, 0 }
|
||||
};
|
||||
|
||||
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 1);
|
||||
|
||||
if (!vars[0].optval) {
|
||||
php_pdo_factory_error(-1 TSRMLS_CC, "No driver class specified.");
|
||||
return 0; /* FAILURE */
|
||||
}
|
||||
|
||||
ce = zend_fetch_class(vars[0].optval, strlen(vars[0].optval), ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
|
||||
|
||||
if (!ce) {
|
||||
php_pdo_factory_error(-2 TSRMLS_CC, "Class %s not found.", vars[0].optval);
|
||||
efree(vars[0].optval);
|
||||
return 0; /* FAILURE */
|
||||
}
|
||||
|
||||
if (!php_pdo_user_implements_driver(ce)) {
|
||||
php_pdo_factory_error(-3 TSRMLS_CC, "Class %s does not implement PDO_User_Driver interface.", vars[0].optval);
|
||||
efree(vars[0].optval);
|
||||
return 0; /* FAILURE */
|
||||
}
|
||||
|
||||
ALLOC_INIT_ZVAL(object);
|
||||
if (object_init_ex(object, ce) == FAILURE) {
|
||||
php_pdo_factory_error(-4 TSRMLS_CC, "Failure instantiating class %s", vars[0].optval);
|
||||
efree(vars[0].optval);
|
||||
zval_ptr_dtor(&object);
|
||||
return 0; /* FAILURE */
|
||||
}
|
||||
|
||||
efree(vars[0].optval);
|
||||
|
||||
data = emalloc(sizeof(php_pdo_user_data));
|
||||
data->object = object;
|
||||
data->dbh = dbh;
|
||||
data->stmt = NULL;
|
||||
php_pdo_user_ptrmap_map(data TSRMLS_CC);
|
||||
|
||||
dbh->driver_data = data;
|
||||
dbh->alloc_own_columns = 1;
|
||||
dbh->max_escaped_char_length = 2;
|
||||
dbh->methods = &php_pdo_user_drv_methods;
|
||||
|
||||
constructor = Z_OBJ_HT_P(object)->get_constructor(object TSRMLS_CC);
|
||||
if (constructor) {
|
||||
zval fname, retval, *args[4];
|
||||
|
||||
/* Lazy, but also less problematic */
|
||||
ZVAL_STRING(&fname, constructor->common.function_name, 0);
|
||||
|
||||
/* $dsn */
|
||||
MAKE_STD_ZVAL(args[0]);
|
||||
ZVAL_STRINGL(args[0], dbh->data_source, dbh->data_source_len, 1);
|
||||
|
||||
/* $user */
|
||||
MAKE_STD_ZVAL(args[1]);
|
||||
ZVAL_STRING(args[1], dbh->username ? dbh->username : "", 1);
|
||||
|
||||
/* $pass */
|
||||
MAKE_STD_ZVAL(args[2]);
|
||||
ZVAL_STRING(args[2], dbh->password ? dbh->password : "", 1);
|
||||
|
||||
/* $params */
|
||||
args[3] = driver_options ? driver_options : EG(uninitialized_zval_ptr);
|
||||
|
||||
if (SUCCESS == call_user_function(EG(function_table), &object, &fname, &retval, 4, args TSRMLS_CC)) {
|
||||
zval_dtor(&retval);
|
||||
}
|
||||
|
||||
zval_ptr_dtor(&args[0]);
|
||||
zval_ptr_dtor(&args[1]);
|
||||
zval_ptr_dtor(&args[2]);
|
||||
}
|
||||
|
||||
return 1; /* SUCCESS */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ pdo_user_driver */
|
||||
pdo_driver_t pdo_user_driver = {
|
||||
PDO_DRIVER_HEADER(user),
|
||||
pdo_user_driver_factory
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
344
pdo_user_object.c
Normal file
344
pdo_user_object.c
Normal file
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2006 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Sara Golemon <pollita@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include "php_pdo_user_int.h"
|
||||
|
||||
/* ******************
|
||||
* PDO_User Class *
|
||||
****************** */
|
||||
|
||||
/* PDO_User::CONSTANTS */
|
||||
#define PHP_PDO_USER_DRIVER_PARAM_MAX_ESCAPSED_CHAR_LENGTH 0x00000001
|
||||
#define PHP_PDO_USER_DRIVER_PARAM_DATA_SOURCE 0x00000002
|
||||
#define PHP_PDO_USER_DRIVER_PARAM_SQLSTATE 0x00000003
|
||||
|
||||
#define PHP_PDO_USER_STATEMENT_PARAM_ACTIVE_QUERY 0x00010000
|
||||
#define PHP_PDO_USER_STATEMENT_PARAM_SQLSTATE 0x00010003
|
||||
|
||||
/* {{{ mixed PDO_User::driverParam(object dbh, integer param[, mixed value])
|
||||
- aka mixed PDO_User::statementParam(object stmt, integer param[, mixed value])
|
||||
Get/Set a PDO option on a driver or statement handle
|
||||
Passign value == NULL does a get-only, without changing the original value
|
||||
Returns original value (or NULL on failure) */
|
||||
PHP_METHOD(pdo_user, driverparam)
|
||||
{
|
||||
php_pdo_user_data *data;
|
||||
zval *zobj;
|
||||
long param;
|
||||
zval *val = NULL;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ol|z", &zobj, ¶m, &val) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
data = php_pdo_user_ptrmap_locate(zobj TSRMLS_CC);
|
||||
if (!data) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter 1 must be an active PDO_User driver or statement object");
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
switch (param) {
|
||||
case PHP_PDO_USER_DRIVER_PARAM_MAX_ESCAPSED_CHAR_LENGTH:
|
||||
{
|
||||
zval *longval = val, tmpval;
|
||||
|
||||
RETVAL_LONG(data->dbh->max_escaped_char_length);
|
||||
|
||||
if (longval) {
|
||||
/* Set a new value */
|
||||
|
||||
if (Z_TYPE_P(longval) != IS_LONG) {
|
||||
tmpval = *longval;
|
||||
zval_copy_ctor(&tmpval);
|
||||
convert_to_long(&tmpval);
|
||||
longval = &tmpval;
|
||||
}
|
||||
if (Z_LVAL_P(longval) < 1) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "max_escaped_character_length must be a positive integer");
|
||||
RETVAL_NULL();
|
||||
} else {
|
||||
data->dbh->max_escaped_char_length = Z_LVAL_P(longval);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case PHP_PDO_USER_DRIVER_PARAM_DATA_SOURCE:
|
||||
{
|
||||
if (val) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot override data source");
|
||||
}
|
||||
RETVAL_STRINGL(data->dbh->data_source, data->dbh->data_source_len, 1);
|
||||
|
||||
break;
|
||||
}
|
||||
case PHP_PDO_USER_DRIVER_PARAM_SQLSTATE:
|
||||
{
|
||||
RETVAL_STRING(data->dbh->error_code, 1);
|
||||
if (val) {
|
||||
zval *strval = val, tmpval;
|
||||
|
||||
if (Z_TYPE_P(strval) != IS_STRING) {
|
||||
tmpval = *strval;
|
||||
zval_copy_ctor(&tmpval);
|
||||
convert_to_string(&tmpval);
|
||||
strval = &tmpval;
|
||||
}
|
||||
|
||||
strcpy(data->dbh->error_code, " ");
|
||||
memcpy(data->dbh->error_code, Z_STRVAL_P(strval), Z_STRLEN_P(strval) > 5 ? 5 : Z_STRLEN_P(strval));
|
||||
|
||||
if (strval == &tmpval) {
|
||||
zval_dtor(&tmpval);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
/* Statement params (don't forget to check for data->stmt) */
|
||||
case PHP_PDO_USER_STATEMENT_PARAM_ACTIVE_QUERY:
|
||||
{
|
||||
if (val) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot override data source");
|
||||
}
|
||||
if (!data->stmt) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot return statement params from a driver object");
|
||||
break;
|
||||
}
|
||||
|
||||
if (data->stmt->active_query_string) {
|
||||
RETVAL_STRINGL(data->stmt->active_query_string, data->stmt->active_query_stringlen, 1);
|
||||
} else {
|
||||
RETVAL_NULL();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case PHP_PDO_USER_STATEMENT_PARAM_SQLSTATE:
|
||||
{
|
||||
if (!data->stmt) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot return statement params from a driver object");
|
||||
break;
|
||||
}
|
||||
|
||||
RETVAL_STRING(data->stmt->error_code, 1);
|
||||
if (val) {
|
||||
zval *strval = val, tmpval;
|
||||
|
||||
if (Z_TYPE_P(strval) != IS_STRING) {
|
||||
tmpval = *strval;
|
||||
zval_copy_ctor(&tmpval);
|
||||
convert_to_string(&tmpval);
|
||||
strval = &tmpval;
|
||||
}
|
||||
|
||||
strcpy(data->stmt->error_code, " ");
|
||||
memcpy(data->stmt->error_code, Z_STRVAL_P(strval), Z_STRLEN_P(strval) > 5 ? 5 : Z_STRLEN_P(strval));
|
||||
|
||||
if (strval == &tmpval) {
|
||||
zval_dtor(&tmpval);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown parameter (%ld)", param);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ array PDO_User::parsedsn(string dsn, array params)
|
||||
Parse a DSN string ( var1=val;var2=val;var3=val )
|
||||
Into an associative array */
|
||||
PHP_METHOD(pdo_user,parsedsn)
|
||||
{
|
||||
char *dsn;
|
||||
int dsn_len, num_opts, i;
|
||||
zval *opts, **opt = NULL;
|
||||
struct pdo_data_src_parser *vars;
|
||||
HashPosition pos;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa", &dsn, &dsn_len, &opts) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
array_init(return_value);
|
||||
|
||||
if (!dsn_len || !(num_opts = zend_hash_num_elements(Z_ARRVAL_P(opts)))) {
|
||||
return;
|
||||
}
|
||||
|
||||
vars = safe_emalloc(num_opts, sizeof(struct pdo_data_src_parser), 0);
|
||||
for(zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(opts), &pos), num_opts =0;
|
||||
zend_hash_get_current_data_ex(Z_ARRVAL_P(opts), (void**)&opt, &pos) == SUCCESS;
|
||||
zend_hash_move_forward_ex(Z_ARRVAL_P(opts), &pos)) {
|
||||
zval copyval = **opt;
|
||||
|
||||
/* Some data gets copied here that doesn't need to be (typically all of it I'd think)
|
||||
* But it's more convenient[lazy] than tracking what does... */
|
||||
zval_copy_ctor(©val);
|
||||
convert_to_string(©val);
|
||||
vars[num_opts].optname = Z_STRVAL(copyval);
|
||||
vars[num_opts].optval = NULL;
|
||||
vars[num_opts].freeme = 0;
|
||||
num_opts++;
|
||||
}
|
||||
|
||||
php_pdo_parse_data_source(dsn, dsn_len, vars, num_opts);
|
||||
|
||||
for(i = 0; i < num_opts; i++) {
|
||||
if (vars[i].optval) {
|
||||
add_assoc_string(return_value, (char*)vars[i].optname, vars[i].optval, !vars[i].freeme);
|
||||
} else {
|
||||
add_assoc_null(return_value, (char*)vars[i].optname);
|
||||
}
|
||||
/* This makes that unnecessary copying hurt twice as much...
|
||||
* Must refactor this to track dups and only do them when actually needed */
|
||||
efree((void*)vars[i].optname);
|
||||
}
|
||||
efree(vars);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_class_entry *php_pdo_user_ce;
|
||||
static zend_class_entry *php_pdo_user_driver_interface;
|
||||
static zend_class_entry *php_pdo_user_statement_interface;
|
||||
|
||||
static zend_function_entry php_pdo_user_class_functions[] = {
|
||||
PHP_ME(pdo_user, driverparam, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
|
||||
PHP_MALIAS(pdo_user, statementparam, driverparam, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
|
||||
PHP_ME(pdo_user, parsedsn, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static zend_function_entry php_pdo_user_driver_interface_functions[] = {
|
||||
PHP_ABSTRACT_ME(pdo_user_driver, __construct, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_driver, pdo_close, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_driver, pdo_prepare, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_driver, pdo_do, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_driver, pdo_quote, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_driver, pdo_begin, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_driver, pdo_commit, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_driver, pdo_rollback, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_driver, pdo_setattribute, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_driver, pdo_lastinsertid, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_driver, pdo_fetcherror, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_driver, pdo_getattribute, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_driver, pdo_checkliveness, NULL)
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static zend_function_entry php_pdo_user_statement_interface_functions[] = {
|
||||
PHP_ABSTRACT_ME(pdo_user_statement, pdo_close, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_statement, pdo_execute, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_statement, pdo_fetch, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_statement, pdo_describe, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_statement, pdo_getcol, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_statement, pdo_paramhook, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_statement, pdo_setattribute, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_statement, pdo_getattribute, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_statement, pdo_colmeta, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_statement, pdo_nextrowset, NULL)
|
||||
PHP_ABSTRACT_ME(pdo_user_statement, pdo_closecursor, NULL)
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static inline void _php_pdo_user_declare_long_constant(zend_class_entry *ce, const char *const_name, size_t name_len, long value TSRMLS_DC)
|
||||
{
|
||||
#if PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION >= 1
|
||||
zend_declare_class_constant_long(ce, (char*)const_name, name_len, value TSRMLS_CC);
|
||||
#else
|
||||
zval *constant = malloc(sizeof(*constant));
|
||||
ZVAL_LONG(constant, value);
|
||||
INIT_PZVAL(constant);
|
||||
zend_hash_update(&ce->constants_table, (char*)const_name, name_len+1, &constant, sizeof(zval*), NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define PHP_PDO_USER_DECLARE_LONG_CONSTANT(cnst) \
|
||||
_php_pdo_user_declare_long_constant(php_pdo_user_ce, #cnst , sizeof( #cnst ) - 1, PHP_PDO_USER_##cnst TSRMLS_CC)
|
||||
|
||||
PHP_MINIT_FUNCTION(php_pdo_user_class)
|
||||
{
|
||||
zend_class_entry ce;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "PDO_User", php_pdo_user_class_functions);
|
||||
php_pdo_user_ce = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
php_pdo_user_ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; /* Prevents instantiation */
|
||||
|
||||
PHP_PDO_USER_DECLARE_LONG_CONSTANT(DRIVER_PARAM_MAX_ESCAPSED_CHAR_LENGTH);
|
||||
PHP_PDO_USER_DECLARE_LONG_CONSTANT(DRIVER_PARAM_DATA_SOURCE);
|
||||
PHP_PDO_USER_DECLARE_LONG_CONSTANT(DRIVER_PARAM_SQLSTATE);
|
||||
|
||||
PHP_PDO_USER_DECLARE_LONG_CONSTANT(STATEMENT_PARAM_ACTIVE_QUERY);
|
||||
PHP_PDO_USER_DECLARE_LONG_CONSTANT(STATEMENT_PARAM_SQLSTATE);
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "PDO_User_Driver", php_pdo_user_driver_interface_functions);
|
||||
php_pdo_user_driver_interface = zend_register_internal_interface(&ce TSRMLS_CC);
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "PDO_User_Statement", php_pdo_user_statement_interface_functions);
|
||||
php_pdo_user_statement_interface = zend_register_internal_interface(&ce TSRMLS_CC);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int php_pdo_user_implements_driver(zend_class_entry *ce)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!ce) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(i = 0; i < ce->num_interfaces; i++) {
|
||||
if (ce->interfaces[i] == php_pdo_user_driver_interface) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int php_pdo_user_implements_statement(zend_class_entry *ce)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!ce) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(i = 0; i < ce->num_interfaces; i++) {
|
||||
if (ce->interfaces[i] == php_pdo_user_statement_interface) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
387
pdo_user_statement.c
Normal file
387
pdo_user_statement.c
Normal file
@@ -0,0 +1,387 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2006 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Sara Golemon <pollita@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include "php_pdo_user_int.h"
|
||||
|
||||
/* Even if the userspace describe method doesn't return a proper array
|
||||
* we still need to populate the column metadata with *something*
|
||||
* Generate a name using this prefix and a numeric (colno) suffix */
|
||||
#define PHP_PDO_USER_STMT_UNKNOWN_COL_PREFIX "column_"
|
||||
|
||||
#define PHP_PDO_USER_STMT_CLOSER "pdo_close"
|
||||
#define PHP_PDO_USER_STMT_EXECUTE "pdo_execute"
|
||||
#define PHP_PDO_USER_STMT_FETCH "pdo_fetch"
|
||||
#define PHP_PDO_USER_STMT_DESCRIBE "pdo_describe"
|
||||
#define PHP_PDO_USER_STMT_GET_COL "pdo_getcol"
|
||||
#define PHP_PDO_USER_STMT_PARAM_HOOK "pdo_paramhook"
|
||||
#define PHP_PDO_USER_STMT_SET_ATTR "pdo_setattribute"
|
||||
#define PHP_PDO_USER_STMT_GET_ATTR "pdo_getattribute"
|
||||
#define PHP_PDO_USER_STMT_COL_META "pdo_colmeta"
|
||||
#define PHP_PDO_USER_STMT_NEXT_ROWSET "pdo_nextrowset"
|
||||
#define PHP_PDO_USER_STMT_CURSOR_CLOSER "pdo_closecursor"
|
||||
|
||||
static inline long php_pdo_user_long_from_assoc(HashTable *ht, char *key, size_t key_len)
|
||||
{
|
||||
long ret = 0;
|
||||
zval **tmp;
|
||||
|
||||
if (zend_hash_find(ht, key, key_len, (void**)&tmp) == SUCCESS) {
|
||||
switch (Z_TYPE_PP(tmp)) {
|
||||
case IS_NULL: ret = 0; break;
|
||||
case IS_BOOL: ret = Z_BVAL_PP(tmp) ? 1 : 0; break;
|
||||
case IS_LONG: ret = Z_LVAL_PP(tmp); break;
|
||||
case IS_DOUBLE: ret = (long)Z_DVAL_PP(tmp); break;
|
||||
default:
|
||||
{
|
||||
zval copyval = **tmp;
|
||||
zval_copy_ctor(©val);
|
||||
convert_to_long(©val);
|
||||
ret = Z_LVAL(copyval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline char *php_pdo_user_string_from_assoc(HashTable *ht, char *key, size_t key_len, int *len)
|
||||
{
|
||||
zval **tmp;
|
||||
|
||||
if (zend_hash_find(ht, key, key_len, (void**)&tmp) == SUCCESS) {
|
||||
if (Z_TYPE_PP(tmp) == IS_STRING) {
|
||||
*len = Z_STRLEN_PP(tmp);
|
||||
return estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
|
||||
} else {
|
||||
zval copyval = **tmp;
|
||||
zval_copy_ctor(©val);
|
||||
convert_to_string(©val);
|
||||
*len = Z_STRLEN(copyval);
|
||||
return Z_STRVAL(copyval);
|
||||
}
|
||||
}
|
||||
|
||||
*len = 0;
|
||||
return estrndup("", 0);
|
||||
}
|
||||
|
||||
static int php_pdo_user_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)stmt->driver_data;
|
||||
|
||||
if (data) {
|
||||
zval fname, retval;
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_STMT_CLOSER, sizeof(PHP_PDO_USER_STMT_CLOSER) - 1, 0);
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 0, NULL TSRMLS_CC) == SUCCESS) {
|
||||
/* Ignore retval */
|
||||
zval_dtor(&retval);
|
||||
}
|
||||
|
||||
php_pdo_user_ptrmap_unmap(data TSRMLS_CC);
|
||||
|
||||
zval_ptr_dtor(&(data->object));
|
||||
efree(data);
|
||||
|
||||
stmt->driver_data = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int php_pdo_user_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)stmt->driver_data;
|
||||
zval fname, retval;
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_STMT_EXECUTE, sizeof(PHP_PDO_USER_STMT_EXECUTE) - 1, 0);
|
||||
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 0, NULL TSRMLS_CC) == FAILURE) {
|
||||
return 0; /* FAILURE */
|
||||
}
|
||||
|
||||
if (Z_TYPE(retval) != IS_ARRAY) {
|
||||
/* throw an exception */
|
||||
zval_dtor(&retval);
|
||||
return 0; /* FAILURE */
|
||||
}
|
||||
|
||||
stmt->row_count = php_pdo_user_long_from_assoc(Z_ARRVAL(retval), "rows", sizeof("rows"));
|
||||
stmt->column_count = php_pdo_user_long_from_assoc(Z_ARRVAL(retval), "cols", sizeof("cols"));
|
||||
|
||||
zval_dtor(&retval);
|
||||
|
||||
if (!stmt->column_count) {
|
||||
/* throw an exception */
|
||||
stmt->row_count = 0;
|
||||
return 0; /* FAILURE */
|
||||
}
|
||||
|
||||
return 1; /* SUCCESS */
|
||||
}
|
||||
|
||||
static int php_pdo_user_stmt_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)stmt->driver_data;
|
||||
zval fname, retval, *args[2];
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_STMT_FETCH, sizeof(PHP_PDO_USER_STMT_FETCH) - 1, 0);
|
||||
|
||||
MAKE_STD_ZVAL(args[0]);
|
||||
ZVAL_LONG(args[0], ori);
|
||||
|
||||
MAKE_STD_ZVAL(args[1]);
|
||||
ZVAL_LONG(args[1], offset);
|
||||
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 2, args TSRMLS_CC) == FAILURE) {
|
||||
zval_ptr_dtor(&args[0]);
|
||||
zval_ptr_dtor(&args[1]);
|
||||
return 0; /* FAILURE */
|
||||
}
|
||||
zval_ptr_dtor(&args[0]);
|
||||
zval_ptr_dtor(&args[1]);
|
||||
|
||||
convert_to_boolean(&retval);
|
||||
|
||||
return Z_BVAL(retval);
|
||||
}
|
||||
|
||||
static int php_pdo_user_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)stmt->driver_data;
|
||||
zval fname, retval, *zcolno;
|
||||
int len;
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_STMT_DESCRIBE, sizeof(PHP_PDO_USER_STMT_DESCRIBE) - 1, 0);
|
||||
|
||||
MAKE_STD_ZVAL(zcolno);
|
||||
ZVAL_LONG(zcolno, colno);
|
||||
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 1, &zcolno TSRMLS_CC) == FAILURE) {
|
||||
zval_ptr_dtor(&zcolno);
|
||||
return 0;
|
||||
}
|
||||
zval_ptr_dtor(&zcolno);
|
||||
|
||||
if (Z_TYPE(retval) != IS_ARRAY) {
|
||||
/* throw an exception */
|
||||
zval_dtor(&retval);
|
||||
|
||||
stmt->columns[colno].namelen = spprintf(&stmt->columns[colno].name, 0, PHP_PDO_USER_STMT_UNKNOWN_COL_PREFIX "%d", colno);
|
||||
stmt->columns[colno].maxlen = 0xffffffff;
|
||||
stmt->columns[colno].precision = 0;
|
||||
stmt->columns[colno].param_type = PDO_PARAM_STR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
stmt->columns[colno].name = php_pdo_user_string_from_assoc(Z_ARRVAL(retval), "name", sizeof("name"), &len);
|
||||
stmt->columns[colno].namelen = len;
|
||||
stmt->columns[colno].maxlen = php_pdo_user_long_from_assoc(Z_ARRVAL(retval), "maxlen", sizeof("maxlen"));
|
||||
stmt->columns[colno].precision = php_pdo_user_long_from_assoc(Z_ARRVAL(retval), "precision", sizeof("precision"));
|
||||
stmt->columns[colno].param_type = PDO_PARAM_STR;
|
||||
|
||||
zval_dtor(&retval);
|
||||
|
||||
return 1; /* SUCCESS */
|
||||
}
|
||||
|
||||
static int php_pdo_user_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)stmt->driver_data;
|
||||
zval fname, retval, *zcolno;
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_STMT_GET_COL, sizeof(PHP_PDO_USER_STMT_GET_COL) - 1, 0);
|
||||
|
||||
MAKE_STD_ZVAL(zcolno);
|
||||
ZVAL_LONG(zcolno, colno);
|
||||
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 1, &zcolno TSRMLS_CC) == FAILURE) {
|
||||
zval_ptr_dtor(&zcolno);
|
||||
return 0;
|
||||
}
|
||||
zval_ptr_dtor(&zcolno);
|
||||
|
||||
convert_to_string(&retval);
|
||||
*ptr = Z_STRVAL(retval);
|
||||
*len = Z_STRLEN(retval);
|
||||
*caller_frees = 1;
|
||||
|
||||
return 1; /* SUCCESS */
|
||||
}
|
||||
|
||||
static int php_pdo_user_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, enum pdo_param_event event_type TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)stmt->driver_data;
|
||||
zval fname, *args[5], retval;
|
||||
|
||||
switch(event_type) {
|
||||
case PDO_PARAM_EVT_EXEC_PRE:
|
||||
case PDO_PARAM_EVT_EXEC_POST:
|
||||
case PDO_PARAM_EVT_FETCH_PRE:
|
||||
case PDO_PARAM_EVT_FETCH_POST:
|
||||
break;
|
||||
default:
|
||||
return 1; /* Don't handle other methods */
|
||||
}
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_STMT_PARAM_HOOK, sizeof(PHP_PDO_USER_STMT_PARAM_HOOK) - 1, 0);
|
||||
|
||||
/* $event, $num, $name, $is_param, &$param */
|
||||
MAKE_STD_ZVAL(args[0]);
|
||||
ZVAL_LONG(args[0], event_type);
|
||||
|
||||
MAKE_STD_ZVAL(args[1]);
|
||||
ZVAL_LONG(args[1], param->paramno);
|
||||
|
||||
ALLOC_INIT_ZVAL(args[2]);
|
||||
if (param->name) {
|
||||
ZVAL_STRINGL(args[2], param->name, param->namelen, 1);
|
||||
}
|
||||
|
||||
MAKE_STD_ZVAL(args[3]);
|
||||
ZVAL_BOOL(args[3], param->is_param);
|
||||
|
||||
args[4] = param->parameter;
|
||||
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 5, args TSRMLS_CC) == FAILURE) {
|
||||
zval_ptr_dtor(&args[0]);
|
||||
zval_ptr_dtor(&args[1]);
|
||||
zval_ptr_dtor(&args[2]);
|
||||
zval_ptr_dtor(&args[3]);
|
||||
return 1; /* Soft failure */
|
||||
}
|
||||
zval_ptr_dtor(&args[0]);
|
||||
zval_ptr_dtor(&args[1]);
|
||||
zval_ptr_dtor(&args[2]);
|
||||
zval_ptr_dtor(&args[3]);
|
||||
zval_dtor(&retval); /* Ignore */
|
||||
|
||||
return 1; /* SUCCESS */
|
||||
}
|
||||
|
||||
static int php_pdo_user_stmt_set_attr(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)stmt->driver_data;
|
||||
zval fname, *zargs[2], retval;
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_STMT_SET_ATTR, sizeof(PHP_PDO_USER_STMT_SET_ATTR) - 1, 0);
|
||||
|
||||
MAKE_STD_ZVAL(zargs[0]);
|
||||
ZVAL_LONG(zargs[0], attr);
|
||||
|
||||
zargs[1] = val;
|
||||
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 2, zargs TSRMLS_CC) == SUCCESS) {
|
||||
convert_to_boolean(&retval);
|
||||
} else {
|
||||
ZVAL_FALSE(&retval);
|
||||
}
|
||||
|
||||
zval_ptr_dtor(&zargs[0]);
|
||||
|
||||
return Z_BVAL(retval);
|
||||
}
|
||||
|
||||
static int php_pdo_user_stmt_get_attr(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)stmt->driver_data;
|
||||
zval fname, *zattr;
|
||||
int ret = 1; /* SUCCESS */
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_STMT_GET_ATTR, sizeof(PHP_PDO_USER_STMT_GET_ATTR) - 1, 0);
|
||||
|
||||
MAKE_STD_ZVAL(zattr);
|
||||
ZVAL_LONG(zattr, attr);
|
||||
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, val, 1, &zattr TSRMLS_CC) == FAILURE) {
|
||||
ZVAL_NULL(val);
|
||||
ret = 0; /* FAILURE */
|
||||
}
|
||||
|
||||
zval_ptr_dtor(&zattr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int php_pdo_user_stmt_col_meta(pdo_stmt_t *stmt, long colno, zval *return_value TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)stmt->driver_data;
|
||||
zval fname, *zcolno;
|
||||
int ret = 1; /* SUCCESS */
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_STMT_COL_META, sizeof(PHP_PDO_USER_STMT_COL_META) - 1, 0);
|
||||
|
||||
MAKE_STD_ZVAL(zcolno);
|
||||
ZVAL_LONG(zcolno, colno);
|
||||
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, return_value, 1, &zcolno TSRMLS_CC) == FAILURE) {
|
||||
ZVAL_NULL(return_value);
|
||||
ret = 0; /* FAILURE */
|
||||
}
|
||||
|
||||
zval_ptr_dtor(&zcolno);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int php_pdo_user_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)stmt->driver_data;
|
||||
zval fname, retval;
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_STMT_NEXT_ROWSET, sizeof(PHP_PDO_USER_STMT_NEXT_ROWSET) - 1, 0);
|
||||
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 0, NULL TSRMLS_CC) == FAILURE) {
|
||||
return 0; /* FAILURE */
|
||||
}
|
||||
convert_to_boolean(&retval);
|
||||
|
||||
return Z_BVAL(retval);
|
||||
}
|
||||
|
||||
static int php_pdo_user_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
php_pdo_user_data *data = (php_pdo_user_data*)stmt->driver_data;
|
||||
zval fname, retval;
|
||||
|
||||
ZVAL_STRINGL(&fname, PHP_PDO_USER_STMT_CURSOR_CLOSER, sizeof(PHP_PDO_USER_STMT_CURSOR_CLOSER) - 1, 0);
|
||||
|
||||
if (call_user_function(EG(function_table), &(data->object), &fname, &retval, 0, NULL TSRMLS_CC) == FAILURE) {
|
||||
return 0; /* FAILURE */
|
||||
}
|
||||
convert_to_boolean(&retval);
|
||||
|
||||
return Z_BVAL(retval);
|
||||
}
|
||||
|
||||
struct pdo_stmt_methods php_pdo_user_stmt_methods = {
|
||||
php_pdo_user_stmt_dtor,
|
||||
php_pdo_user_stmt_execute,
|
||||
php_pdo_user_stmt_fetch,
|
||||
php_pdo_user_stmt_describe,
|
||||
php_pdo_user_stmt_get_col,
|
||||
php_pdo_user_stmt_param_hook,
|
||||
php_pdo_user_stmt_set_attr,
|
||||
php_pdo_user_stmt_get_attr,
|
||||
php_pdo_user_stmt_col_meta,
|
||||
php_pdo_user_stmt_next_rowset,
|
||||
php_pdo_user_stmt_cursor_closer
|
||||
};
|
||||
|
||||
46
php_pdo_user.h
Normal file
46
php_pdo_user.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2006 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Sara Golemon <pollita@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef PHP_PDO_USER_H
|
||||
#define PHP_PDO_USER_H
|
||||
|
||||
#define PHP_PDO_USER_EXTNAME "pdo_user"
|
||||
#define PHP_PDO_USER_EXTVER "0.1"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
|
||||
extern zend_module_entry pdo_user_module_entry;
|
||||
#define phpext_pdo_user_ptr &pdo_user_module_entry
|
||||
|
||||
#endif /* PHP_PDO_USER_H */
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
68
php_pdo_user_int.h
Normal file
68
php_pdo_user_int.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2006 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Sara Golemon <pollita@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef PHP_PDO_USER_INT_H
|
||||
#define PHP_PDO_USER_INT_H
|
||||
|
||||
#include "php_pdo_user.h"
|
||||
#include "pdo/php_pdo.h"
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
|
||||
typedef struct _php_pdo_user_llist php_pdo_user_llist;
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(pdo_user)
|
||||
php_pdo_user_llist *ptr_map;
|
||||
ZEND_END_MODULE_GLOBALS(pdo_user)
|
||||
|
||||
extern ZEND_DECLARE_MODULE_GLOBALS(pdo_user);
|
||||
|
||||
#ifdef ZTS
|
||||
#define PDO_USER_G(v) TSRMG(pdo_user_globals_id, zend_pdo_user_globals *, v)
|
||||
#else
|
||||
#define PDO_USER_G(v) (pdo_user_globals.v)
|
||||
#endif
|
||||
|
||||
typedef struct _php_pdo_user_data {
|
||||
zval *object;
|
||||
pdo_dbh_t *dbh;
|
||||
pdo_stmt_t *stmt;
|
||||
} php_pdo_user_data;
|
||||
|
||||
int php_pdo_user_ptrmap_map(php_pdo_user_data *data TSRMLS_DC);
|
||||
int php_pdo_user_ptrmap_unmap(php_pdo_user_data *data TSRMLS_DC);
|
||||
void *php_pdo_user_ptrmap_locate(zval *object TSRMLS_DC);
|
||||
void php_pdo_user_ptrmap_destroy(TSRMLS_D);
|
||||
PHP_MINIT_FUNCTION(php_pdo_user_class);
|
||||
int php_pdo_user_implements_driver(zend_class_entry *ce);
|
||||
int php_pdo_user_implements_statement(zend_class_entry *ce);
|
||||
|
||||
extern struct pdo_stmt_methods php_pdo_user_stmt_methods;
|
||||
|
||||
#endif /* PHP_PDO_USER_H */
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
319
tests/globals.phpt
Normal file
319
tests/globals.phpt
Normal file
@@ -0,0 +1,319 @@
|
||||
--TEST--
|
||||
Globals Driver
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo_user')) {
|
||||
die('pdo_user not loaded');
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/* DON'T USE THIS IN THE WILD
|
||||
* It's just a basic driver implementation meant to provide a test framework,
|
||||
* It makes assumptions about the caller that would be unsafe in uncontrolled environments */
|
||||
|
||||
class PDO_User_Globals_Statement implements PDO_User_Statement {
|
||||
private $cursor = NULL;
|
||||
private $varname = NULL;
|
||||
|
||||
function pdo_close() { }
|
||||
|
||||
function pdo_execute() {
|
||||
$query = PDO_User::statementParam($this, PDO_User::STATEMENT_PARAM_ACTIVE_QUERY);
|
||||
if (preg_match('/^SELECT FROM "(.*?)"$/i', $query, $matches)) {
|
||||
$this->fetched = false;
|
||||
if (isset($GLOBALS[$matches[1]])) {
|
||||
$this->varname = $matches[1];
|
||||
$this->cursor = $GLOBALS[$matches[1]];
|
||||
if (is_array($this->cursor)) {
|
||||
reset($this->cursor);
|
||||
return array('rows' => count($this->cursor), 'cols' => 1);
|
||||
}
|
||||
return array('rows' => 1, 'cols' => 1);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function pdo_fetch($ori, $fetch) {
|
||||
switch ($ori) {
|
||||
case PDO::FETCH_ORI_NEXT:
|
||||
if ($this->fetched) {
|
||||
if (is_array($this->cursor)) {
|
||||
next($this->cursor);
|
||||
return true;
|
||||
} else {
|
||||
$this->cursor = NULL;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->fetched = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case PDO::FETCH_ORI_PRIOR:
|
||||
if ($this->fetched) {
|
||||
if (is_array($this->cursor)) {
|
||||
prev($this->cursor);
|
||||
return true;
|
||||
} else {
|
||||
$this->cursor = NULL;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->fetched = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case PDO::FETCH_ORI_FIRST:
|
||||
if ($this->fetched) {
|
||||
if (is_array($this->cursor)) {
|
||||
reset($this->cursor);
|
||||
return true;
|
||||
} else {
|
||||
$this->cursor = NULL;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->fetched = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case PDO::FETCH_ORI_LAST:
|
||||
if ($this->fetched) {
|
||||
if (is_array($this->cursor)) {
|
||||
end($this->cursor);
|
||||
return true;
|
||||
} else {
|
||||
$this->cursor = NULL;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->fetched = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case PDO::FETCH_ORI_ABS:
|
||||
if ($this->fetched) {
|
||||
if (is_array($this->cursor)) {
|
||||
reset($this->cursor);
|
||||
while ($ofs--) next($this->cursor);
|
||||
return true;
|
||||
} else {
|
||||
$this->cursor = NULL;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->fetched = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case PDO::FETCH_ORI_REL:
|
||||
if ($this->fetched) {
|
||||
if (is_array($this->cursor)) {
|
||||
if ($ofs > 0) {
|
||||
while ($ofs--) prev($this->cursor);
|
||||
} elseif ($ofs < 0) {
|
||||
while ($ofs++) next($this->cursor);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
$this->cursor = NULL;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->fetched = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function pdo_describe($col) {
|
||||
return array('name'=>$this->varname,'maxlen'=>0x7FFFFFFF, 'precision'=>0);
|
||||
}
|
||||
|
||||
function pdo_getCol($col) {
|
||||
if (is_array($this->cursor)) {
|
||||
return current($this->cursor);
|
||||
} else {
|
||||
return $this->cursor;
|
||||
}
|
||||
}
|
||||
|
||||
function pdo_paramHook($type, $colno, $paramname, $is_param, &$param) { }
|
||||
function pdo_getAttribute($attr) { return NULL; }
|
||||
function pdo_setAttribute($attr, $val) { return false; }
|
||||
function pdo_colMeta($col) {
|
||||
return array('table'=>'global_symbol_table', 'type'=>gettype($this->cursor));
|
||||
}
|
||||
function pdo_nextRowset() {
|
||||
return $this->fetch(PDO::FETCH_ORI_NEXT, 1);
|
||||
}
|
||||
function pdo_closeCursor() {
|
||||
$this->cursor = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
class PDO_User_Globals_Driver implements PDO_User_Driver {
|
||||
private $errorCode = 0;
|
||||
private $errorDesc = '';
|
||||
private $lastInsert = NULL;
|
||||
|
||||
function insert($key, $value) {
|
||||
if (isset($GLOBALS[$key])) {
|
||||
return 0;
|
||||
}
|
||||
$GLOBALS[$key] = $value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
function update($key, $value) {
|
||||
if (!isset($GLOBALS[$key])) {
|
||||
return 0;
|
||||
}
|
||||
$GLOBALS[$key] = $value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
function delete($key) {
|
||||
if (!isset($GLOBALS[$key])) {
|
||||
return 0;
|
||||
}
|
||||
unset($GLOBALS[$key]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* PDO Driver Implementation */
|
||||
|
||||
function __construct($dsn, $user, $pass, $options) { }
|
||||
function pdo_close() { }
|
||||
|
||||
function pdo_prepare($sql, $options) {
|
||||
return new PDO_User_Globals_Statement($sql, $options);
|
||||
}
|
||||
|
||||
function pdo_do($sql) {
|
||||
if (preg_match('/^INSERT "(.*?)" as "(.*?)"$/i', $sql, $matches)) {
|
||||
return $this->insert($matches[1], $matches[2]);
|
||||
} elseif (preg_match('/^UPDATE "(.*?)" to "(.*?)"$/i', $sql, $matches)) {
|
||||
return $this->update($matches[1], $matches[2]);
|
||||
} elseif (preg_match('/^DELETE "(.*?)"$/i', $sql, $matches)) {
|
||||
return $this->delete($matches[1]);
|
||||
}
|
||||
$this->errorCode = 1000;
|
||||
$this->errorDesc = 'Invalid query: ' . $sql;
|
||||
return false;
|
||||
}
|
||||
|
||||
function pdo_quote($str) {
|
||||
return '"' . addslashes($str) . '"';
|
||||
}
|
||||
|
||||
function pdo_begin() { return false; }
|
||||
function pdo_commit() { return false; }
|
||||
function pdo_rollback() { return false; }
|
||||
function pdo_setAttribute($attr, $val) { return false; }
|
||||
function pdo_getAttribute($attr) { return NULL; }
|
||||
function pdo_lastInsertID($seq) { return $this->lastInsert; }
|
||||
|
||||
function pdo_fetchError() {
|
||||
return array($this->errorCode, $this->errorDesc);
|
||||
}
|
||||
|
||||
function pdo_checkLiveness() { return true; }
|
||||
}
|
||||
|
||||
$preset = 'Some Value';
|
||||
|
||||
$drv = new PDO('user:driver=PDO_User_Globals_Driver');
|
||||
var_dump($drv->exec('INSERT "newvar" as "newvalue"'), $newvar);
|
||||
var_dump($drv->exec('UPDATE "preset" to "Other Value"'), $preset);
|
||||
var_dump($drv->exec('DELETE "preset"'), @$preset);
|
||||
var_dump($drv->exec('DELETE "preset"'));
|
||||
var_dump($drv->exec('Invalid Query'), $drv->errorInfo());
|
||||
|
||||
echo "-*-\n";
|
||||
var_dump($stmt = $drv->prepare('SELECT FROM "newvar"'));
|
||||
var_dump($stmt->execute());
|
||||
var_dump($stmt->columnCount());
|
||||
var_dump($stmt->rowCount());
|
||||
var_dump($stmt->getColumnMeta(0));
|
||||
var_dump($stmt->fetchColumn(0));
|
||||
unset($stmt);
|
||||
|
||||
echo "-*-\n";
|
||||
$foo = 'bar';
|
||||
$baz = NULL;
|
||||
var_dump($stmt = $drv->prepare('SELECT FROM ?'));
|
||||
var_dump($stmt->bindValue(1, 'foo'));
|
||||
var_dump($stmt->bindColumn(1, $baz));
|
||||
var_dump($stmt->execute());
|
||||
var_dump($stmt->fetch(PDO::FETCH_BOUND), $baz);
|
||||
unset($stmt);
|
||||
|
||||
echo "-*-\n";
|
||||
var_dump($stmt = $drv->prepare('INVALID QUERY'));
|
||||
var_dump($stmt->execute());
|
||||
|
||||
--EXPECTF--
|
||||
int(1)
|
||||
string(8) "newvalue"
|
||||
int(1)
|
||||
string(11) "Other Value"
|
||||
int(1)
|
||||
NULL
|
||||
int(0)
|
||||
bool(false)
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(5) "00000"
|
||||
[1]=>
|
||||
int(1000)
|
||||
[2]=>
|
||||
string(4) "1000"
|
||||
}
|
||||
-*-
|
||||
object(PDOStatement)#%d (1) {
|
||||
["queryString"]=>
|
||||
string(20) "SELECT FROM "newvar""
|
||||
}
|
||||
bool(true)
|
||||
int(1)
|
||||
int(1)
|
||||
array(6) {
|
||||
["table"]=>
|
||||
string(19) "global_symbol_table"
|
||||
["type"]=>
|
||||
string(6) "string"
|
||||
["name"]=>
|
||||
string(6) "newvar"
|
||||
["len"]=>
|
||||
int(2147483647)
|
||||
["precision"]=>
|
||||
int(0)
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
}
|
||||
string(8) "newvalue"
|
||||
-*-
|
||||
object(PDOStatement)#%d (1) {
|
||||
["queryString"]=>
|
||||
string(13) "SELECT FROM ?"
|
||||
}
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
string(3) "bar"
|
||||
-*-
|
||||
object(PDOStatement)#%d (1) {
|
||||
["queryString"]=>
|
||||
string(13) "INVALID QUERY"
|
||||
}
|
||||
bool(false)
|
||||
|
||||
Reference in New Issue
Block a user