mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-11 03:00:49 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62e263f01e |
No files matched your search
@@ -0,0 +1,2 @@
|
||||
dbplus
|
||||
Hartmut Holzgraefe
|
||||
@@ -0,0 +1,5 @@
|
||||
this extension is experimental,
|
||||
its functions may change their names
|
||||
or move to extension all together
|
||||
so do not rely to much on them
|
||||
you have been warned!
|
||||
@@ -0,0 +1,3 @@
|
||||
experimental db++ extension
|
||||
for more information on db++ see
|
||||
http://www.concept-asa.de
|
||||
@@ -0,0 +1,47 @@
|
||||
dnl
|
||||
dnl $Id$
|
||||
dnl
|
||||
|
||||
PHP_ARG_WITH(dbplus, for dbplus support,
|
||||
[ --with-dbplus Include dbplus support])
|
||||
|
||||
if test "$PHP_DBPLUS" != "no"; then
|
||||
# --with-dbplus -> check with-path
|
||||
SEARCH_PATH="/usr/dbplus /usr/local/dbplus /opt/dbplus"
|
||||
SEARCH_FOR="/include/dbconfig.h"
|
||||
if test -r $PHP_DBPLUS/; then # path given as parameter
|
||||
DBPLUS_DIR=$PHP_DBPLUS
|
||||
else # search default path list
|
||||
AC_MSG_CHECKING(for dbplus files in default path)
|
||||
for i in $SEARCH_PATH ; do
|
||||
if test -r $i/$SEARCH_FOR; then
|
||||
DBPLUS_DIR=$i
|
||||
AC_MSG_RESULT(found in $i)
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if test -z "$DBPLUS_DIR"; then
|
||||
AC_MSG_RESULT(not found)
|
||||
AC_MSG_ERROR(Please reinstall the dbplus distribution)
|
||||
fi
|
||||
|
||||
# --with-dbplus -> add include path
|
||||
PHP_ADD_INCLUDE($DBPLUS_DIR/include)
|
||||
|
||||
# --with-dbplus -> chech for lib and symbol presence
|
||||
LIBNAME=Ddb
|
||||
LIBSYMBOL=Db_Init
|
||||
old_LIBS=$LIBS
|
||||
LIBS="-L$DBPLUS_DIR/lib -lm -ldl -lDmacc -lDracc"
|
||||
AC_CHECK_LIB($LIBNAME, $LIBSYMBOL, [AC_DEFINE(HAVE_DBPLUSLIB,1,[ ])],
|
||||
[AC_MSG_ERROR(wrong dbplus lib version or lib not found)])
|
||||
LIBS=$old_LIBS
|
||||
|
||||
PHP_SUBST(DBPLUS_SHARED_LIBADD)
|
||||
PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $DBPLUS_DIR/lib, DBPLUS_SHARED_LIBADD)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(Dmacc, $DBPLUS_DIR/lib, DBPLUS_SHARED_LIBADD)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(Dracc, $DBPLUS_DIR/lib, DBPLUS_SHARED_LIBADD)
|
||||
|
||||
PHP_NEW_EXTENSION(dbplus, dbplus.c php_dbplus.c , $ext_shared)
|
||||
fi
|
||||
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2002 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.02 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available at through the world-wide-web at |
|
||||
| http://www.php.net/license/2_02.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: Hartmut Holzgraefe <hartmut@six.de> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "php.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "php_ini.h"
|
||||
#include "php_dbplus.h"
|
||||
|
||||
#include <saccess.h>
|
||||
#include <relation.h>
|
||||
#include <dblight.h>
|
||||
|
||||
|
||||
/* If you declare any globals in php_dbplus.h uncomment this:
|
||||
ZEND_DECLARE_MODULE_GLOBALS(dbplus)
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_DL_DBPLUS
|
||||
ZEND_GET_MODULE(dbplus)
|
||||
#endif
|
||||
|
||||
|
||||
/* {{{ Resource handling */
|
||||
|
||||
/* True global resources - no need for thread safety here */
|
||||
int le_dbplus_relation;
|
||||
int le_dbplus_tupel;
|
||||
|
||||
void dbplus_destruct_relation(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
||||
{
|
||||
relf *conn = (relf *)(rsrc->ptr);
|
||||
|
||||
cdb_close(conn);
|
||||
}
|
||||
|
||||
|
||||
void dbplus_destruct_tupel(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
||||
{
|
||||
tuple *t = (tuple *)(rsrc->ptr);
|
||||
|
||||
efree(t);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ function table */
|
||||
|
||||
/* Every user visible function must have an entry in dbplus_functions[].
|
||||
*/
|
||||
function_entry dbplus_functions[] = {
|
||||
PHP_FE(dbplus_add, NULL)
|
||||
PHP_FE(dbplus_aql, NULL)
|
||||
PHP_FE(dbplus_chdir, NULL)
|
||||
PHP_FE(dbplus_close, NULL)
|
||||
PHP_FE(dbplus_curr, NULL)
|
||||
PHP_FE(dbplus_errno, NULL)
|
||||
PHP_FE(dbplus_errcode, NULL)
|
||||
PHP_FE(dbplus_find, NULL)
|
||||
PHP_FE(dbplus_first, NULL)
|
||||
PHP_FE(dbplus_flush, NULL)
|
||||
PHP_FE(dbplus_freealllocks, NULL)
|
||||
PHP_FE(dbplus_freelock, NULL)
|
||||
PHP_FE(dbplus_freerlocks, NULL)
|
||||
PHP_FE(dbplus_getlock, NULL)
|
||||
PHP_FE(dbplus_getunique, NULL)
|
||||
PHP_FE(dbplus_info, NULL)
|
||||
PHP_FE(dbplus_last, NULL)
|
||||
PHP_FE(dbplus_next, NULL)
|
||||
PHP_FE(dbplus_open, NULL)
|
||||
PHP_FE(dbplus_prev, NULL)
|
||||
PHP_FE(dbplus_rchperm, NULL)
|
||||
PHP_FE(dbplus_rcreate, NULL)
|
||||
PHP_FE(dbplus_rcrtexact, NULL)
|
||||
PHP_FE(dbplus_rcrtlike, NULL)
|
||||
PHP_FE(dbplus_resolve, NULL)
|
||||
PHP_FE(dbplus_restorepos, NULL)
|
||||
PHP_FE(dbplus_rkeys, NULL)
|
||||
PHP_FE(dbplus_ropen, NULL)
|
||||
PHP_FE(dbplus_rquery, NULL)
|
||||
PHP_FE(dbplus_rrename, NULL)
|
||||
PHP_FE(dbplus_rsecindex, NULL)
|
||||
PHP_FE(dbplus_runlink, NULL)
|
||||
PHP_FE(dbplus_rzap, NULL)
|
||||
PHP_FE(dbplus_savepos, NULL)
|
||||
PHP_FE(dbplus_setindex, NULL)
|
||||
PHP_FE(dbplus_setindexbynumber, NULL)
|
||||
PHP_FE(dbplus_sql, NULL)
|
||||
PHP_FE(dbplus_tcl, NULL)
|
||||
PHP_FE(dbplus_tremove, NULL)
|
||||
PHP_FE(dbplus_undo, NULL)
|
||||
PHP_FE(dbplus_undoprepare, NULL)
|
||||
PHP_FE(dbplus_unlockrel, NULL)
|
||||
PHP_FE(dbplus_unselect, NULL)
|
||||
PHP_FE(dbplus_update, NULL)
|
||||
PHP_FE(dbplus_xlockrel, NULL)
|
||||
PHP_FE(dbplus_xunlockrel, NULL)
|
||||
{NULL, NULL, NULL} /* Must be the last line in dbplus_functions[] */
|
||||
};
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ module entry */
|
||||
|
||||
zend_module_entry dbplus_module_entry = {
|
||||
STANDARD_MODULE_HEADER,
|
||||
"dbplus",
|
||||
dbplus_functions,
|
||||
PHP_MINIT(dbplus),
|
||||
PHP_MSHUTDOWN(dbplus),
|
||||
PHP_RINIT(dbplus), /* Replace with NULL if there's nothing to do at request start */
|
||||
PHP_RSHUTDOWN(dbplus), /* Replace with NULL if there's nothing to do at request end */
|
||||
PHP_MINFO(dbplus),
|
||||
NO_VERSION_YET,
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ ini parameters */
|
||||
|
||||
/* Remove comments and fill if you need to have entries in php.ini
|
||||
PHP_INI_BEGIN()
|
||||
PHP_INI_END()
|
||||
*/
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ module init */
|
||||
|
||||
PHP_MINIT_FUNCTION(dbplus)
|
||||
{
|
||||
/* resource id for cdb connections */
|
||||
le_dbplus_relation = zend_register_list_destructors_ex(dbplus_destruct_relation, NULL, "dbplus_relation", module_number);
|
||||
le_dbplus_tupel = zend_register_list_destructors_ex(dbplus_destruct_tupel , NULL, "dbplus_tuple" , module_number);
|
||||
|
||||
/* constants for DBPLUS error codes */
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_NOERR", ERR_NOERR, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_DUPLICATE", ERR_DUPLICATE, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_EOSCAN", ERR_EOSCAN, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_EMPTY", ERR_EMPTY, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_CLOSE", ERR_CLOSE, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_WLOCKED", ERR_WLOCKED, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_LOCKED", ERR_LOCKED, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_NOLOCK", ERR_NOLOCK, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_READ", ERR_READ, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_WRITE", ERR_WRITE, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_CREATE", ERR_CREATE, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_LSEEK", ERR_LSEEK, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_LENGTH", ERR_LENGTH, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_OPEN", ERR_OPEN, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_WOPEN", ERR_WOPEN, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_MAGIC", ERR_MAGIC, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_VERSION", ERR_VERSION, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_PGSIZE", ERR_PGSIZE, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_CRC", ERR_CRC, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_PIPE", ERR_PIPE, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_NIDX", ERR_NIDX, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_MALLOC", ERR_MALLOC, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_NUSERS", ERR_NUSERS, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_PREEXIT", ERR_PREEXIT, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_ONTRAP", ERR_ONTRAP, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_PREPROC", ERR_PREPROC, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_DBPARSE", ERR_DBPARSE, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_DBRUNERR", ERR_DBRUNERR, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_DBPREEXIT", ERR_DBPREEXIT, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_WAIT", ERR_WAIT, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_CORRUPT_TUPLE", ERR_CORRUPT_TUPLE, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_WARNING0", ERR_WARNING0, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_PANIC", ERR_PANIC, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_FIFO", ERR_FIFO, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_PERM", ERR_PERM, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_TCL", ERR_TCL, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_RESTRICTED", ERR_RESTRICTED, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_USER", ERR_USER, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("DBPLUS_ERR_UNKNOWN", ERR_UNKNOWN, CONST_CS | CONST_PERSISTENT);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ module shutdown */
|
||||
|
||||
PHP_MSHUTDOWN_FUNCTION(dbplus)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ request init */
|
||||
|
||||
/* Remove if there's nothing to do at request start */
|
||||
PHP_RINIT_FUNCTION(dbplus)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ request shutdown */
|
||||
|
||||
/* Remove if there's nothing to do at request end */
|
||||
PHP_RSHUTDOWN_FUNCTION(dbplus)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ module information */
|
||||
|
||||
PHP_MINFO_FUNCTION(dbplus)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "dbplus support", "enabled");
|
||||
php_info_print_table_end();
|
||||
|
||||
/* Remove comments if you have entries in php.ini
|
||||
DISPLAY_INI_ENTRIES();
|
||||
*/
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2002 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.02 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available at through the world-wide-web at |
|
||||
| http://www.php.net/license/2_02.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. |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef PHP_DBPLUS_H
|
||||
#define PHP_DBPLUS_H
|
||||
|
||||
|
||||
extern zend_module_entry dbplus_module_entry;
|
||||
#define phpext_dbplus_ptr &dbplus_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_DBPLUS_API __declspec(dllexport)
|
||||
#else
|
||||
#define PHP_DBPLUS_API
|
||||
#endif
|
||||
|
||||
PHP_MINIT_FUNCTION(dbplus);
|
||||
PHP_MSHUTDOWN_FUNCTION(dbplus);
|
||||
PHP_RINIT_FUNCTION(dbplus);
|
||||
PHP_RSHUTDOWN_FUNCTION(dbplus);
|
||||
PHP_MINFO_FUNCTION(dbplus);
|
||||
|
||||
PHP_FUNCTION(dbplus_add);
|
||||
PHP_FUNCTION(dbplus_aql);
|
||||
PHP_FUNCTION(dbplus_chdir);
|
||||
PHP_FUNCTION(dbplus_close);
|
||||
PHP_FUNCTION(dbplus_curr);
|
||||
PHP_FUNCTION(dbplus_errno);
|
||||
PHP_FUNCTION(dbplus_errcode);
|
||||
PHP_FUNCTION(dbplus_find);
|
||||
PHP_FUNCTION(dbplus_first);
|
||||
PHP_FUNCTION(dbplus_flush);
|
||||
PHP_FUNCTION(dbplus_freealllocks);
|
||||
PHP_FUNCTION(dbplus_freelock);
|
||||
PHP_FUNCTION(dbplus_freerlocks);
|
||||
PHP_FUNCTION(dbplus_getlock);
|
||||
PHP_FUNCTION(dbplus_getunique);
|
||||
PHP_FUNCTION(dbplus_info);
|
||||
PHP_FUNCTION(dbplus_last);
|
||||
PHP_FUNCTION(dbplus_next);
|
||||
PHP_FUNCTION(dbplus_open);
|
||||
PHP_FUNCTION(dbplus_prev);
|
||||
PHP_FUNCTION(dbplus_rchperm);
|
||||
PHP_FUNCTION(dbplus_rcreate);
|
||||
PHP_FUNCTION(dbplus_rcrtexact);
|
||||
PHP_FUNCTION(dbplus_rcrtlike);
|
||||
PHP_FUNCTION(dbplus_resolve);
|
||||
PHP_FUNCTION(dbplus_restorepos);
|
||||
PHP_FUNCTION(dbplus_rkeys);
|
||||
PHP_FUNCTION(dbplus_ropen);
|
||||
PHP_FUNCTION(dbplus_rquery);
|
||||
PHP_FUNCTION(dbplus_rrename);
|
||||
PHP_FUNCTION(dbplus_rsecindex);
|
||||
PHP_FUNCTION(dbplus_runlink);
|
||||
PHP_FUNCTION(dbplus_rzap);
|
||||
PHP_FUNCTION(dbplus_savepos);
|
||||
PHP_FUNCTION(dbplus_setindex);
|
||||
PHP_FUNCTION(dbplus_setindexbynumber);
|
||||
PHP_FUNCTION(dbplus_sql);
|
||||
PHP_FUNCTION(dbplus_tcl);
|
||||
PHP_FUNCTION(dbplus_tremove);
|
||||
PHP_FUNCTION(dbplus_undo);
|
||||
PHP_FUNCTION(dbplus_undoprepare);
|
||||
PHP_FUNCTION(dbplus_unlockrel);
|
||||
PHP_FUNCTION(dbplus_unselect);
|
||||
PHP_FUNCTION(dbplus_update);
|
||||
PHP_FUNCTION(dbplus_xlockrel);
|
||||
PHP_FUNCTION(dbplus_xunlockrel);
|
||||
|
||||
|
||||
/*
|
||||
Declare any global variables you may need between the BEGIN
|
||||
and END macros here:
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(dbplus)
|
||||
int global_variable;
|
||||
ZEND_END_MODULE_GLOBALS(dbplus)
|
||||
*/
|
||||
|
||||
/* In every function that needs to use variables in php_dbplus_globals,
|
||||
do call DBPLUSLS_FETCH(); after declaring other variables used by
|
||||
that function, and always refer to them as DBPLUSG(variable).
|
||||
You are encouraged to rename these macros something shorter, see
|
||||
examples in any other php module directory.
|
||||
*/
|
||||
|
||||
#ifdef ZTS
|
||||
#define AG(v) TSRMG(dbplus_globals_id, php_dbplus_globals *, v)
|
||||
#else
|
||||
#define DBPLUSG(v) (dbplus_globals.v)
|
||||
#endif
|
||||
|
||||
|
||||
int le_dbplus_relation;
|
||||
int le_dbplus_tuple;
|
||||
|
||||
void dbplus_destruct_relation(zend_rsrc_list_entry *rsrc TSRMLS_DC);
|
||||
void dbplus_destruct_tupel(zend_rsrc_list_entry *rsrc TSRMLS_DC);
|
||||
|
||||
|
||||
#endif /* PHP_DBPLUS_H */
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
@@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
Check for dbplus presence
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("dbplus")) print "skip"; ?>
|
||||
--POST--
|
||||
--GET--
|
||||
--FILE--
|
||||
<?php
|
||||
echo "dbplus extension is available";
|
||||
/*
|
||||
you can add regression tests for your extension here
|
||||
|
||||
the output of your test code has to be equal to the
|
||||
text in the --EXPECT-- section below for the tests
|
||||
to pass, differences between the output and the
|
||||
expected text are interpreted as failure
|
||||
|
||||
see php4/tests/README for further information on
|
||||
writing regression tests
|
||||
*/
|
||||
?>
|
||||
--EXPECT--
|
||||
dbplus extension is available
|
||||
@@ -1,2 +0,0 @@
|
||||
fileinfo
|
||||
Ilia Alshanetsky
|
||||
Whitespace-only changes.
@@ -1,54 +0,0 @@
|
||||
dnl $Id$
|
||||
dnl config.m4 for extension fileinfo
|
||||
|
||||
PHP_ARG_WITH(fileinfo, for fileinfo support,
|
||||
[ --with-fileinfo=DIR Include fileinfo support])
|
||||
|
||||
if test "$PHP_FILEINFO" != "no"; then
|
||||
SEARCH_PATH="/usr/local/include /usr/include /usr/share/file"
|
||||
SEARCH_FOR="/magic.h"
|
||||
if test -r $PHP_FILEINFO/$SEARCH_FOR; then
|
||||
FILEINFO_DIR=$PHP_FILEINFO
|
||||
else
|
||||
AC_MSG_CHECKING([for magic files in default path])
|
||||
for i in $SEARCH_PATH ; do
|
||||
if test -r $i/$SEARCH_FOR; then
|
||||
FILEINFO_DIR=$i
|
||||
AC_MSG_RESULT(found in $i)
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if test -z "$FILEINFO_DIR"; then
|
||||
AC_MSG_RESULT([not found])
|
||||
AC_MSG_ERROR([Please reinstall the libmagic distribution])
|
||||
fi
|
||||
|
||||
PHP_ADD_INCLUDE($FILEINFO_DIR/include)
|
||||
|
||||
LIBNAME=magic
|
||||
LIBSYMBOL=magic_open
|
||||
|
||||
PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
|
||||
[
|
||||
PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $FILEINFO_DIR/lib, FILEINFO_SHARED_LIBADD)
|
||||
AC_DEFINE(HAVE_FILEINFOLIB,1,[ ])
|
||||
],[
|
||||
AC_MSG_ERROR([wrong magic lib version or lib not found])
|
||||
],[
|
||||
-L$FILEINFO_DIR/lib -lm -lz -ldl
|
||||
])
|
||||
|
||||
MAGIC_MIME_LOCATIONS="/usr/local/share/file/magic /usr/share/file/magic /usr/share/misc/file/magic /etc/magic /usr/share/misc"
|
||||
for i in $MAGIC_MIME_LOCATIONS; do
|
||||
if test -f $i; then
|
||||
PHP_DEFAULT_MAGIC_FILE=$i
|
||||
break
|
||||
fi
|
||||
done
|
||||
AC_DEFINE_UNQUOTED(PHP_DEFAULT_MAGIC_FILE,"$PHP_DEFAULT_MAGIC_FILE",[magic file path])
|
||||
|
||||
PHP_SUBST(FILEINFO_SHARED_LIBADD)
|
||||
|
||||
PHP_NEW_EXTENSION(fileinfo, fileinfo.c, $ext_shared)
|
||||
fi
|
||||
@@ -1,433 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 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_0.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: Ilia Alshanetsky <ilia@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <magic.h>
|
||||
/*
|
||||
* HOWMANY specifies the maximum offset libmagic will look at
|
||||
* this is currently hardcoded in the libmagic source but not exported
|
||||
*/
|
||||
#ifndef HOWMANY
|
||||
#define HOWMANY 65536
|
||||
#endif
|
||||
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "ext/standard/file.h" /* needed for context stuff */
|
||||
#include "php_fileinfo.h"
|
||||
#include "fopen_wrappers.h" /* needed for is_url */
|
||||
|
||||
struct php_fileinfo {
|
||||
long options;
|
||||
struct magic_set *magic;
|
||||
};
|
||||
|
||||
#ifndef PHP_DEFAULT_MAGIC_FILE
|
||||
#define PHP_DEFAULT_MAGIC_FILE NULL
|
||||
#endif
|
||||
|
||||
#ifdef ZEND_ENGINE_2
|
||||
|
||||
static zend_object_handlers finfo_object_handlers;
|
||||
zend_class_entry *finfo_class_entry;
|
||||
|
||||
struct finfo_object {
|
||||
zend_object zo;
|
||||
struct php_fileinfo *ptr;
|
||||
};
|
||||
|
||||
#define FILEINFO_DECLARE_INIT_OBJECT(object) \
|
||||
zval *object = getThis();
|
||||
|
||||
#define FILEINFO_REGISTER_OBJECT(_object, _ptr) \
|
||||
{ \
|
||||
struct finfo_object *obj; \
|
||||
obj = (struct finfo_object*)zend_object_store_get_object(_object TSRMLS_CC); \
|
||||
obj->ptr = _ptr; \
|
||||
}
|
||||
|
||||
#define FILEINFO_FROM_OBJECT(finfo, object) \
|
||||
{ \
|
||||
struct finfo_object *obj = zend_object_store_get_object(object TSRMLS_CC); \
|
||||
finfo = obj->ptr; \
|
||||
if (!finfo) { \
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The invalid fileinfo object."); \
|
||||
RETURN_FALSE; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* {{{ finfo_objects_dtor
|
||||
*/
|
||||
static void finfo_objects_dtor(void *object, zend_object_handle handle TSRMLS_DC)
|
||||
{
|
||||
struct finfo_object *intern = (struct finfo_object *) object;
|
||||
|
||||
if (intern->ptr) {
|
||||
magic_close(intern->ptr->magic);
|
||||
efree(intern->ptr);
|
||||
}
|
||||
|
||||
efree(intern);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ finfo_objects_new
|
||||
*/
|
||||
PHP_FILEINFO_API zend_object_value finfo_objects_new(zend_class_entry *class_type TSRMLS_DC)
|
||||
{
|
||||
zend_object_value retval;
|
||||
struct finfo_object *intern;
|
||||
|
||||
intern = emalloc(sizeof(struct finfo_object));
|
||||
intern->zo.ce = class_type;
|
||||
intern->zo.in_get = 0;
|
||||
intern->zo.in_set = 0;
|
||||
intern->zo.properties = NULL;
|
||||
intern->ptr = NULL;
|
||||
|
||||
retval.handle = zend_objects_store_put(intern, finfo_objects_dtor, NULL, NULL TSRMLS_CC);
|
||||
retval.handlers = (zend_object_handlers *) &finfo_object_handlers;
|
||||
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ finfo_class_functions
|
||||
*/
|
||||
function_entry finfo_class_functions[] = {
|
||||
ZEND_ME_MAPPING(finfo, finfo_open, NULL)
|
||||
ZEND_ME_MAPPING(set_flags, finfo_set_flags,NULL)
|
||||
ZEND_ME_MAPPING(file, finfo_file, NULL)
|
||||
ZEND_ME_MAPPING(buffer, finfo_buffer, NULL)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#else
|
||||
|
||||
#define FILEINFO_REGISTER_OBJECT(_object, _ptr) {}
|
||||
#define FILEINFO_FROM_OBJECT(socket_id, object) {}
|
||||
|
||||
#define FILEINFO_DECLARE_INIT_OBJECT(object)
|
||||
#define object 0
|
||||
|
||||
#endif
|
||||
|
||||
#define FINFO_SET_OPTION(magic, options) \
|
||||
if (magic_setflags(magic, options) == -1) { \
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to set option '%ld' %d:%s", \
|
||||
options, magic_errno(magic), magic_error(magic)); \
|
||||
RETURN_FALSE; \
|
||||
}
|
||||
|
||||
/* True global resources - no need for thread safety here */
|
||||
static int le_fileinfo;
|
||||
|
||||
void finfo_resource_destructor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
||||
{
|
||||
if (rsrc->ptr) {
|
||||
struct php_fileinfo *finfo = (struct php_fileinfo *) rsrc->ptr;
|
||||
magic_close(finfo->magic);
|
||||
efree(rsrc->ptr);
|
||||
rsrc->ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ fileinfo_functions[]
|
||||
*/
|
||||
function_entry fileinfo_functions[] = {
|
||||
PHP_FE(finfo_open, NULL)
|
||||
PHP_FE(finfo_close, NULL)
|
||||
PHP_FE(finfo_set_flags, NULL)
|
||||
PHP_FE(finfo_file, NULL)
|
||||
PHP_FE(finfo_buffer, NULL)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION
|
||||
*/
|
||||
PHP_MINIT_FUNCTION(finfo)
|
||||
{
|
||||
#ifdef ZEND_ENGINE_2
|
||||
zend_class_entry _finfo_class_entry;
|
||||
INIT_CLASS_ENTRY(_finfo_class_entry, "finfo", finfo_class_functions);
|
||||
_finfo_class_entry.create_object = finfo_objects_new;
|
||||
finfo_class_entry = zend_register_internal_class(&_finfo_class_entry TSRMLS_CC);
|
||||
|
||||
/* copy the standard object handlers to you handler table */
|
||||
memcpy(&finfo_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
|
||||
#endif /* ZEND_ENGINE_2 */
|
||||
|
||||
le_fileinfo = zend_register_list_destructors_ex(finfo_resource_destructor, NULL, "file_info", module_number);
|
||||
|
||||
REGISTER_LONG_CONSTANT("FILEINFO_NONE", MAGIC_NONE, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILEINFO_SYMLINK", MAGIC_SYMLINK, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILEINFO_MIME", MAGIC_MIME, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILEINFO_COMPRESS", MAGIC_COMPRESS, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILEINFO_DEVICES", MAGIC_DEVICES, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILEINFO_CONTINUE", MAGIC_CONTINUE, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILEINFO_PRESERVE_ATIME", MAGIC_PRESERVE_ATIME, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILEINFO_RAW", MAGIC_RAW, CONST_CS|CONST_PERSISTENT);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ fileinfo_module_entry
|
||||
*/
|
||||
zend_module_entry fileinfo_module_entry = {
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
STANDARD_MODULE_HEADER,
|
||||
#endif
|
||||
"fileinfo",
|
||||
fileinfo_functions,
|
||||
PHP_MINIT(finfo),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
PHP_MINFO(fileinfo),
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
"0.1", /* Replace with version number for your extension */
|
||||
#endif
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_FILEINFO
|
||||
ZEND_GET_MODULE(fileinfo)
|
||||
#endif
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
PHP_MINFO_FUNCTION(fileinfo)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "fileinfo support", "enabled");
|
||||
php_info_print_table_end();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto resource finfo_open([int options [, string arg]])
|
||||
Create a new fileinfo resource. */
|
||||
PHP_FUNCTION(finfo_open)
|
||||
{
|
||||
long options = MAGIC_NONE;
|
||||
char *file = PHP_DEFAULT_MAGIC_FILE;
|
||||
int file_len = 0;
|
||||
struct php_fileinfo *finfo;
|
||||
FILEINFO_DECLARE_INIT_OBJECT(object)
|
||||
char resolved_path[MAXPATHLEN];
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ls", &options, &file, &file_len) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (file_len) { /* user specified filed, perform open_basedir checks */
|
||||
if (!VCWD_REALPATH(file, resolved_path)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
file = resolved_path;
|
||||
|
||||
if ((PG(safe_mode) && (!php_checkuid(file, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(file TSRMLS_CC)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
finfo = emalloc(sizeof(struct php_fileinfo));
|
||||
|
||||
finfo->options = options;
|
||||
finfo->magic = magic_open(options);
|
||||
|
||||
if (finfo->magic == NULL) {
|
||||
efree(finfo);
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid mode '%ld'.", options);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (magic_load(finfo->magic, file) == -1) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to load magic database at '%s'.", file);
|
||||
magic_close(finfo->magic);
|
||||
efree(finfo);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (object) {
|
||||
FILEINFO_REGISTER_OBJECT(object, finfo);
|
||||
} else {
|
||||
ZEND_REGISTER_RESOURCE(return_value, finfo, le_fileinfo);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto resource finfo_close(resource finfo)
|
||||
Close fileinfo resource. */
|
||||
PHP_FUNCTION(finfo_close)
|
||||
{
|
||||
struct php_fileinfo *finfo;
|
||||
zval *zfinfo;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zfinfo) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
ZEND_FETCH_RESOURCE(finfo, struct php_fileinfo *, &zfinfo, -1, "file_info", le_fileinfo);
|
||||
|
||||
zend_list_delete(Z_RESVAL_P(zfinfo));
|
||||
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool finfo_set_flags(resource finfo, int options)
|
||||
Set libmagic configuration options. */
|
||||
PHP_FUNCTION(finfo_set_flags)
|
||||
{
|
||||
long options;
|
||||
struct php_fileinfo *finfo;
|
||||
zval *zfinfo;
|
||||
FILEINFO_DECLARE_INIT_OBJECT(object)
|
||||
|
||||
if (object) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &options) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
FILEINFO_FROM_OBJECT(finfo, object);
|
||||
} else {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl", &zfinfo, &options) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
ZEND_FETCH_RESOURCE(finfo, struct php_fileinfo *, &zfinfo, -1, "file_info", le_fileinfo);
|
||||
}
|
||||
|
||||
FINFO_SET_OPTION(finfo->magic, options)
|
||||
finfo->options = options;
|
||||
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void _php_finfo_get_type(INTERNAL_FUNCTION_PARAMETERS, int mode)
|
||||
{
|
||||
long options = 0;
|
||||
char *buffer, *tmp, *ret_val;
|
||||
int buffer_len;
|
||||
struct php_fileinfo *finfo;
|
||||
zval *zfinfo, *zcontext = NULL;
|
||||
FILEINFO_DECLARE_INIT_OBJECT(object)
|
||||
|
||||
if (object) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lbz", &buffer, &buffer_len, &options, &zcontext) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
FILEINFO_FROM_OBJECT(finfo, object);
|
||||
} else {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs|lbz", &zfinfo, &buffer, &buffer_len, &options, &zcontext) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
ZEND_FETCH_RESOURCE(finfo, struct php_fileinfo *, &zfinfo, -1, "file_info", le_fileinfo);
|
||||
}
|
||||
|
||||
/* Set options for the current file/buffer. */
|
||||
if (options) {
|
||||
FINFO_SET_OPTION(finfo->magic, options)
|
||||
}
|
||||
|
||||
if (mode) { /* file */
|
||||
/* determine if the file is a local file or remote URL */
|
||||
char *tmp2;
|
||||
php_stream_wrapper *wrap = php_stream_locate_url_wrapper(buffer, &tmp2, 0 TSRMLS_CC);
|
||||
if (wrap && wrap->is_url) {
|
||||
#ifdef ZEND_ENGINE_2
|
||||
php_stream_context *context = php_stream_context_from_zval(zcontext, 0);
|
||||
#else
|
||||
php_stream_context *context = NULL;
|
||||
#endif
|
||||
php_stream *stream = php_stream_open_wrapper_ex(buffer, "rb",
|
||||
ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
|
||||
if (!stream) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
buffer_len = php_stream_copy_to_mem(stream, &tmp, HOWMANY, 0);
|
||||
php_stream_close(stream);
|
||||
|
||||
if (buffer_len == 0) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
} else { /* local file */
|
||||
char resolved_path[MAXPATHLEN];
|
||||
if (!VCWD_REALPATH(buffer, resolved_path)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
ret_val = (char *) magic_file(finfo->magic, buffer);
|
||||
goto common;
|
||||
}
|
||||
} else { /* buffer */
|
||||
tmp = buffer;
|
||||
}
|
||||
|
||||
ret_val = (char *) magic_buffer(finfo->magic, tmp, buffer_len);
|
||||
if (mode) {
|
||||
efree(tmp);
|
||||
}
|
||||
common:
|
||||
/* Restore options */
|
||||
if (options) {
|
||||
FINFO_SET_OPTION(finfo->magic, finfo->options)
|
||||
}
|
||||
|
||||
if (!ret_val) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed identify data %d:%s",
|
||||
magic_errno(finfo->magic), magic_error(finfo->magic));
|
||||
RETURN_FALSE;
|
||||
} else {
|
||||
RETURN_STRING(ret_val, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ proto string finfo_file(resource finfo, char *file_name [, int options [, resource context]])
|
||||
Return information about a file. */
|
||||
PHP_FUNCTION(finfo_file)
|
||||
{
|
||||
_php_finfo_get_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string finfo_buffer(resource finfo, char *string [, int options])
|
||||
Return infromation about a string buffer. */
|
||||
PHP_FUNCTION(finfo_buffer)
|
||||
{
|
||||
_php_finfo_get_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, 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
|
||||
*/
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
if(!extension_loaded('fileinfo')) {
|
||||
dl('fileinfo.' . PHP_SHLIB_SUFFIX);
|
||||
}
|
||||
if(!extension_loaded('fileinfo')) {
|
||||
die("fileinfo extension is not avaliable, please compile it.\n");
|
||||
}
|
||||
|
||||
// normal operation
|
||||
$res = finfo_open(FILEINFO_MIME); /* return mime type ala mimetype extension */
|
||||
$files = glob("*");
|
||||
foreach ($files as $file) {
|
||||
echo finfo_file($res, $file) . "\n";
|
||||
}
|
||||
finfo_close($res);
|
||||
|
||||
// OO mode
|
||||
/*
|
||||
* FILEINFO_PRESERVE_ATIME - if possible preserve the original access time
|
||||
* FILEINFO_SYMLINK - follow symlinks
|
||||
* FILEINFO_DEVICES - look at the contents of blocks or character special devices
|
||||
* FILEINFO_COMPRESS - decompress compressed files
|
||||
*/
|
||||
$fi = new finfo(FILEINFO_PRESERVE_ATIME|FILEINFO_SYMLINK|FILEINFO_DEVICES|FILEINFO_COMPRESS);
|
||||
$files = glob("*");
|
||||
foreach ($files as $file) {
|
||||
echo $fi->buffer(file_get_contents($file)) . "\n";
|
||||
}
|
||||
?>
|
||||
@@ -1,43 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!DOCTYPE package SYSTEM "../pear/package.dtd">
|
||||
<package>
|
||||
<name>Fileinfo</name>
|
||||
<summary>libmagic bindings</summary>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>iliaa</user>
|
||||
<name>Ilia Alshanetsky</name>
|
||||
<email>ilia@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
<description>
|
||||
This extension allows retrieval of information regarding vast majority of file.
|
||||
This information may include dimensions, quality, length etc...
|
||||
|
||||
Additionally it can also be used to retrieve the mime type for a particular
|
||||
file and for text files proper language encoding.
|
||||
</description>
|
||||
<license>PHP</license>
|
||||
<release>
|
||||
<state>beta</state>
|
||||
<version>0.2</version>
|
||||
<date>2004-05-26</date>
|
||||
<notes>
|
||||
Fixed bug that caused PHP to refuse to recognize fileinfo.so.
|
||||
</notes>
|
||||
<filelist>
|
||||
<file role="src" name="config.m4"/>
|
||||
<file role="src" name="fileinfo.c"/>
|
||||
<file role="src" name="php_fileinfo.h"/>
|
||||
<file role="doc" name="CREDITS"/>
|
||||
<file role="doc" name="EXPERIMENTAL"/>
|
||||
<file role="doc" name="fileinfo.php"/>
|
||||
</filelist>
|
||||
<deps>
|
||||
</deps>
|
||||
</release>
|
||||
</package>
|
||||
<!--
|
||||
vim:et:ts=1:sw=1
|
||||
-->
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 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_0.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: Ilia Alshanetsky <ilia@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef PHP_FILEINFO_H
|
||||
#define PHP_FILEINFO_H
|
||||
|
||||
extern zend_module_entry fileinfo_module_entry;
|
||||
#define phpext_fileinfo_ptr &fileinfo_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_FILEINFO_API __declspec(dllexport)
|
||||
#else
|
||||
#define PHP_FILEINFO_API
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
PHP_MINFO_FUNCTION(fileinfo);
|
||||
|
||||
PHP_FUNCTION(finfo_open);
|
||||
PHP_FUNCTION(finfo_close);
|
||||
PHP_FUNCTION(finfo_set_flags);
|
||||
PHP_FUNCTION(finfo_file);
|
||||
PHP_FUNCTION(finfo_buffer);
|
||||
|
||||
#ifdef ZTS
|
||||
#define FILEINFO_G(v) TSRMG(fileinfo_globals_id, zend_fileinfo_globals *, v)
|
||||
#else
|
||||
#define FILEINFO_G(v) (fileinfo_globals.v)
|
||||
#endif
|
||||
|
||||
#endif /* PHP_FILEINFO_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
|
||||
*/
|
||||
@@ -1,2 +0,0 @@
|
||||
PHP Data Objects
|
||||
Wez Furlong, Marcus Boerger, Sterling Hughes, George Schlossnagle
|
||||
@@ -1,32 +0,0 @@
|
||||
phpincludedir=$(prefix)/include/php
|
||||
|
||||
PDO_HEADER_FILES= \
|
||||
php_pdo.h \
|
||||
php_pdo_driver.h
|
||||
|
||||
install-pdo-headers:
|
||||
@echo "Installing PDO headers: $(INSTALL_ROOT)$(phpincludedir)/ext/pdo/"
|
||||
@$(mkinstalldirs) $(INSTALL_ROOT)$(phpincludedir)/ext/pdo
|
||||
@for f in $(PDO_HEADER_FILES); do \
|
||||
if test -f "$(top_srcdir)/$$f"; then \
|
||||
$(INSTALL_DATA) $(top_srcdir)/$$f $(INSTALL_ROOT)$(phpincludedir)/ext/pdo; \
|
||||
elif test -f "$(top_builddir)/$$f"; then \
|
||||
$(INSTALL_DATA) $(top_builddir)/$$f $(INSTALL_ROOT)$(phpincludedir)/ext/pdo; \
|
||||
elif test -f "$(top_srcdir)/ext/pdo/$$f"; then \
|
||||
$(INSTALL_DATA) $(top_srcdir)/ext/pdo/$$f $(INSTALL_ROOT)$(phpincludedir)/ext/pdo; \
|
||||
elif test -f "$(top_builddir)/ext/pdo/$$f"; then \
|
||||
$(INSTALL_DATA) $(top_builddir)/ext/pdo/$$f $(INSTALL_ROOT)$(phpincludedir)/ext/pdo; \
|
||||
else \
|
||||
echo "hmmm"; \
|
||||
fi \
|
||||
done;
|
||||
|
||||
# mini hack
|
||||
install: $(all_targets) $(install_targets) install-pdo-headers
|
||||
|
||||
#$(top_srcdir)/ext/pdo/pdo_sql_parser.c: $(top_srcdir)/ext/pdo/pdo_sql_parser.re
|
||||
# exit 0; re2c -b $(top_srcdir)/ext/pdo/pdo_sql_parser.re > $@
|
||||
|
||||
#$(srcdir)/pdo_sql_parser.c: $(srcdir)/pdo_sql_parser.re
|
||||
# exit 0; re2c -b $(srcdir)/pdo_sql_parser.re > $@
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
$Id$
|
||||
|
||||
PHP Data Objects
|
||||
================
|
||||
|
||||
Concept: Data Access Abstraction
|
||||
|
||||
Goals:
|
||||
|
||||
1/ Be light-weight
|
||||
2/ Provide common API for common database operations
|
||||
3/ Be performant
|
||||
4/ Keep majority of PHP specific stuff in the PDO core (such as persistent
|
||||
resource management); drivers should only have to worry about getting the
|
||||
data and not about PHP internals.
|
||||
|
||||
|
||||
Transactions and autocommit
|
||||
===========================
|
||||
|
||||
When you create a database handle, you *should* specify the autocommit
|
||||
behaviour that you require. PDO will default to autocommit on.
|
||||
|
||||
$dbh = new PDO("...", $user, $pass, array(PDO_ATTR_AUTOCOMMIT => true));
|
||||
|
||||
When auto-commit is on, the driver will implicitly commit each query as it is
|
||||
executed. This works fine for most simple tasks but can be significantly
|
||||
slower when you are making a large number of udpates.
|
||||
|
||||
$dbh = new PDO("...", $user, $pass, array(PDO_ATTR_AUTOCOMMIT => false));
|
||||
|
||||
When auto-commit is off, you must then use $dbh->beginTransaction() to
|
||||
initiate a transaction. When your work is done, you then call $dbh->commit()
|
||||
or $dbh->rollBack() to persist or abort your changes respectively. Not all
|
||||
databases support transactions.
|
||||
|
||||
You can change the auto-commit mode at run-time:
|
||||
|
||||
$dbh->setAttribute(PDO_ATTR_AUTOCOMMIT, false);
|
||||
|
||||
Regardless of the error handling mode set on the database handle, if the
|
||||
autocommit mode cannot be changed, an exception will be thrown.
|
||||
|
||||
Some drivers will allow you to temporarily disable autocommit if you call
|
||||
$dbh->beginTransaction(). When you commit() or rollBack() such a transaction,
|
||||
the handle will switch back to autocommit mode again. If the mode could not
|
||||
be changed, an exception will be raised, as noted above.
|
||||
|
||||
When the database handle is closed or destroyed (or at request end for
|
||||
persistent handles), the driver will implicitly rollBack(). It is your
|
||||
responsibility to call commit() when you are done making changes and
|
||||
autocommit is turned off.
|
||||
|
||||
vim:tw=78:et
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
$Id$
|
||||
|
||||
In no particular order:
|
||||
|
||||
Probable Bugs:
|
||||
- persistent connections with bound parameters might segv on subsequent
|
||||
requests
|
||||
|
||||
Low-level:
|
||||
|
||||
- $dbh->quote()
|
||||
- LOB support via Streams API
|
||||
- make errors generated at the pdo level (as opposed to driver level) use the
|
||||
selected error mode.
|
||||
|
||||
Not-so-low-level:
|
||||
- fetchAll(), single row, single column fetches etc.
|
||||
|
||||
Could be more...
|
||||
|
||||
vim:tw=78:et
|
||||
@@ -1,50 +0,0 @@
|
||||
dnl $Id$
|
||||
dnl config.m4 for extension pdo
|
||||
dnl vim:se ts=2 sw=2 et:
|
||||
|
||||
pdo_running_under_pear=0
|
||||
case `pwd` in
|
||||
/var/tmp/pear-build-*)
|
||||
pdo_running_under_pear=1
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$pdo_running_under_pear$PHP_PEAR_VERSION" = "1"; then
|
||||
# we're running in an environment that smells like pear,
|
||||
# and the PHP_PEAR_VERSION env var is not set. That implies
|
||||
# that we're running under a slightly broken pear installer
|
||||
AC_MSG_ERROR([
|
||||
PDO requires that you upgrade your PEAR installer tools. Please
|
||||
do so now by running:
|
||||
|
||||
% sudo pear upgrade pear
|
||||
|
||||
or by manually downloading and installing PEAR version 1.3.5 or higher.
|
||||
|
||||
Once you've upgraded, please re-try your PDO install.
|
||||
])
|
||||
fi
|
||||
|
||||
PHP_ARG_ENABLE(pdo, whether to enable PDO support,
|
||||
[ --enable-pdo=yes Enable PHP Data Objects support (recommended)], yes)
|
||||
|
||||
if test "$PHP_PDO" != "no"; then
|
||||
if test "$ext_shared" = "yes" ; then
|
||||
case $host_alias in
|
||||
*darwin*)
|
||||
if test "$pdo_running_under_pear" = "1"; then
|
||||
AC_MSG_ERROR([
|
||||
Due to the way that loadable modules work on OSX/Darwin, you need to
|
||||
compile the PDO package statically into the PHP core.
|
||||
|
||||
Please follow the instructions at: http://netevil.org/node.php?nid=202
|
||||
for more detail on this issue.
|
||||
])
|
||||
fi
|
||||
ext_shared=no
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
PHP_NEW_EXTENSION(pdo, pdo.c pdo_dbh.c pdo_stmt.c pdo_sql_parser.c pdo_sqlstate.c, $ext_shared)
|
||||
PHP_ADD_MAKEFILE_FRAGMENT
|
||||
fi
|
||||
@@ -1,9 +0,0 @@
|
||||
// $Id$
|
||||
// vim:ft=javascript
|
||||
|
||||
ARG_ENABLE("pdo", "Enable PHP Data Objects support", "no");
|
||||
|
||||
if (PHP_PDO != "no") {
|
||||
EXTENSION('pdo', 'pdo.c pdo_dbh.c pdo_stmt.c pdo_sql_parser.c pdo_sqlstate.c');
|
||||
}
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE package SYSTEM "../pear/package.dtd">
|
||||
<package version="1.0">
|
||||
<name>PDO</name>
|
||||
<summary>PHP Data Objects Interface</summary>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>wez</user>
|
||||
<name>Wez Furlong</name>
|
||||
<email>wez@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<user>helly</user>
|
||||
<name>Marcus Boerger</name>
|
||||
<email>helly@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<user>iliaa</user>
|
||||
<name>Ilia Alshanetsky</name>
|
||||
<email>iliaa@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<user>gschlossnagle</user>
|
||||
<name>George Schlossnagle</name>
|
||||
<email>george@omniti.com</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
|
||||
<description>
|
||||
PDO provides a uniform data access interface, sporting advanced features such
|
||||
as prepared statements and bound parameters. PDO drivers are dynamically
|
||||
loadable and may be developed independently from the core, but still accessed
|
||||
using the same API.
|
||||
|
||||
Read the documentation at http://www.php.net/pdo for more information.
|
||||
</description>
|
||||
<license>PHP</license>
|
||||
<release>
|
||||
<state>beta</state>
|
||||
<version>0.3</version>
|
||||
<date>2005-03-09</date>
|
||||
|
||||
<notes>
|
||||
You need to install a PDO database driver to make use of PDO,
|
||||
check http://pecl.php.net/package-search.php?pkg_name=PDO
|
||||
for a list of available PDO drivers.
|
||||
|
||||
It is highly recommended that you update to the latest stable PHP 5 snapshot
|
||||
before using PDO.
|
||||
You can obtain it from http://snaps.php.net.
|
||||
|
||||
If you are running on Windows, you should download:
|
||||
http://snaps.php.net/win32/php5.0-win32-latest.zip
|
||||
http://snaps.php.net/win32/PECL_5_0/php_pdo.dll
|
||||
|
||||
You can find additional PDO drivers at:
|
||||
http://snaps.php.net/win32/PECL_5_0/
|
||||
|
||||
- New fetch modes:
|
||||
PDO_FETCH_FUNC, PDO_FETCH_GROUP, PDO_FETCH_UNIQUE, PDO_FETCH_CLASSTYPE
|
||||
- New fetch mode for PHP 5.1 and higher: PDO_FETCH_SERIALIZE
|
||||
- Changed signature for PDO::lastInsertId(); it is now:
|
||||
string PDO::lastInsertId([string name])
|
||||
this allows arbitrary unique identifiers to be returned, and allows for
|
||||
better support for RDBMS with sequences.
|
||||
- Improved bound parameter emulation when using non-string types.
|
||||
- PDOStatement implements SPL Traversable interface when SPL is present.
|
||||
|
||||
- Added PDO::quote($string). Closes PECL Bug #3393
|
||||
- Fixed PDO::query() for drivers using bound parameter emulation.
|
||||
- Fixed PECL Bug #3434, crash when using odbc with named parameters.
|
||||
- Added PDOStatement::fetchObject(string class_name [, NULL|array ctor_args]])
|
||||
- PDO_FETCH_CLASS now passes args through to the class constructor
|
||||
- Now builds directly via "pear install PDO" (upgrade to PEAR 1.3.5 first)
|
||||
|
||||
** Note **
|
||||
|
||||
You should uninstall and re-install your individual database drivers whenever
|
||||
you upgrade the base PDO package, otherwise you will see an error about PDO API
|
||||
numbers when you run your PHP scripts.
|
||||
|
||||
</notes>
|
||||
|
||||
<filelist>
|
||||
<file role="src" name="config.m4"/>
|
||||
<file role="src" name="config.w32"/>
|
||||
<file role="src" name="pdo.c"/>
|
||||
<file role="src" name="pdo_dbh.c"/>
|
||||
<file role="src" name="pdo_stmt.c"/>
|
||||
<file role="src" name="php_pdo.h"/>
|
||||
<file role="src" name="php_pdo_driver.h"/>
|
||||
<file role="src" name="php_pdo_int.h"/>
|
||||
<file role="src" name="pdo_sql_parser.re"/>
|
||||
<file role="src" name="pdo_sql_parser.c"/>
|
||||
<file role="src" name="pdo_sqlstate.c"/>
|
||||
<file role="src" name="Makefile.frag"/>
|
||||
|
||||
<file role="doc" name="README"/>
|
||||
<file role="doc" name="TODO"/>
|
||||
<file role="doc" name="pdo.php"/>
|
||||
<file role="doc" name="CREDITS"/>
|
||||
</filelist>
|
||||
<deps>
|
||||
<dep type="php" rel="ge" version="5.0.3"/>
|
||||
</deps>
|
||||
</release>
|
||||
</package>
|
||||
-409
@@ -1,409 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2005 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 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_0.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: Wez Furlong <wez@php.net> |
|
||||
| Marcus Boerger <helly@php.net> |
|
||||
| Sterling Hughes <sterling@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "php_pdo.h"
|
||||
#include "php_pdo_driver.h"
|
||||
#include "php_pdo_int.h"
|
||||
#include "zend_exceptions.h"
|
||||
#include "zend_interfaces.h"
|
||||
|
||||
#if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
|
||||
extern PHPAPI zend_class_entry *spl_ce_RuntimeException;
|
||||
#endif
|
||||
|
||||
ZEND_DECLARE_MODULE_GLOBALS(pdo)
|
||||
|
||||
/* True global resources - no need for thread safety here */
|
||||
|
||||
/* the registry of PDO drivers */
|
||||
static HashTable pdo_driver_hash;
|
||||
|
||||
/* we use persistent resources for the driver connection stuff */
|
||||
static int le_ppdo;
|
||||
|
||||
int php_pdo_list_entry(void)
|
||||
{
|
||||
return le_ppdo;
|
||||
}
|
||||
|
||||
/* for exceptional circumstances */
|
||||
zend_class_entry *pdo_exception_ce;
|
||||
|
||||
PDO_API zend_class_entry *php_pdo_get_exception(void)
|
||||
{
|
||||
return pdo_exception_ce;
|
||||
}
|
||||
|
||||
zend_class_entry *pdo_dbh_ce, *pdo_dbstmt_ce, *pdo_row_ce;
|
||||
|
||||
/* {{{ pdo_functions[] */
|
||||
function_entry pdo_functions[] = {
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ pdo_module_entry */
|
||||
zend_module_entry pdo_module_entry = {
|
||||
STANDARD_MODULE_HEADER,
|
||||
"PDO",
|
||||
pdo_functions,
|
||||
PHP_MINIT(pdo),
|
||||
PHP_MSHUTDOWN(pdo),
|
||||
PHP_RINIT(pdo),
|
||||
PHP_RSHUTDOWN(pdo),
|
||||
PHP_MINFO(pdo),
|
||||
"0.3",
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_PDO
|
||||
ZEND_GET_MODULE(pdo)
|
||||
#endif
|
||||
|
||||
/* {{{ PHP_INI */
|
||||
PHP_INI_BEGIN()
|
||||
STD_PHP_INI_ENTRY("pdo.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_pdo_globals, pdo_globals)
|
||||
PHP_INI_END()
|
||||
/* }}} */
|
||||
|
||||
/* {{{ php_pdo_init_globals */
|
||||
static void php_pdo_init_globals(zend_pdo_globals *pdo_globals)
|
||||
{
|
||||
pdo_globals->global_value = 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PDO_API int php_pdo_register_driver(pdo_driver_t *driver)
|
||||
{
|
||||
if (driver->api_version != PDO_DRIVER_API) {
|
||||
zend_error(E_ERROR, "PDO: driver %s requires PDO API version %ld; this is PDO version %d",
|
||||
driver->driver_name, driver->api_version, PDO_DRIVER_API);
|
||||
return FAILURE;
|
||||
}
|
||||
if (!zend_hash_exists(&module_registry, "pdo", sizeof("pdo"))) {
|
||||
zend_error(E_ERROR, "You MUST load PDO before loading any PDO drivers");
|
||||
return FAILURE; /* NOTREACHED */
|
||||
}
|
||||
|
||||
return zend_hash_add(&pdo_driver_hash, (char*)driver->driver_name, driver->driver_name_len,
|
||||
(void**)&driver, sizeof(driver), NULL);
|
||||
}
|
||||
|
||||
PDO_API void php_pdo_unregister_driver(pdo_driver_t *driver)
|
||||
{
|
||||
if (!zend_hash_exists(&module_registry, "pdo", sizeof("pdo"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
zend_hash_del(&pdo_driver_hash, (char*)driver->driver_name, driver->driver_name_len);
|
||||
}
|
||||
|
||||
pdo_driver_t *pdo_find_driver(const char *name, int namelen)
|
||||
{
|
||||
pdo_driver_t **driver = NULL;
|
||||
|
||||
zend_hash_find(&pdo_driver_hash, (char*)name, namelen, (void**)&driver);
|
||||
|
||||
return driver ? *driver : NULL;
|
||||
}
|
||||
|
||||
PDO_API int php_pdo_parse_data_source(const char *data_source,
|
||||
unsigned long data_source_len, struct pdo_data_src_parser *parsed,
|
||||
int nparams)
|
||||
{
|
||||
int i, j;
|
||||
int valstart = -1;
|
||||
int semi = -1;
|
||||
int optstart = 0;
|
||||
int nlen;
|
||||
int n_matches = 0;
|
||||
|
||||
i = 0;
|
||||
while (i < data_source_len) {
|
||||
/* looking for NAME= */
|
||||
|
||||
if (data_source[i] == '\0') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (data_source[i] != '=') {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
valstart = ++i;
|
||||
|
||||
/* now we're looking for VALUE; or just VALUE<NUL> */
|
||||
semi = -1;
|
||||
while (i < data_source_len) {
|
||||
if (data_source[i] == '\0') {
|
||||
semi = i++;
|
||||
break;
|
||||
}
|
||||
if (data_source[i] == ';') {
|
||||
semi = i++;
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
if (semi == -1) {
|
||||
semi = i;
|
||||
}
|
||||
|
||||
/* find the entry in the array */
|
||||
nlen = valstart - optstart - 1;
|
||||
for (j = 0; j < nparams; j++) {
|
||||
if (0 == strncmp(data_source + optstart, parsed[j].optname, nlen) && parsed[j].optname[nlen] == '\0') {
|
||||
/* got a match */
|
||||
if (parsed[j].freeme) {
|
||||
efree(parsed[j].optval);
|
||||
}
|
||||
parsed[j].optval = estrndup(data_source + valstart, semi - valstart);
|
||||
parsed[j].freeme = 1;
|
||||
++n_matches;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (i < data_source_len && isspace(data_source[i])) {
|
||||
i++;
|
||||
}
|
||||
|
||||
optstart = i;
|
||||
}
|
||||
|
||||
return n_matches;
|
||||
}
|
||||
|
||||
static const char digit_vec[] = "0123456789";
|
||||
PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC)
|
||||
{
|
||||
char buffer[65];
|
||||
char outbuf[65] = "";
|
||||
register char *p;
|
||||
long long_val;
|
||||
char *dst = outbuf;
|
||||
|
||||
if (i64 < 0) {
|
||||
i64 = -i64;
|
||||
*dst++ = '-';
|
||||
}
|
||||
|
||||
if (i64 == 0) {
|
||||
*dst++ = '0';
|
||||
*dst++ = '\0';
|
||||
return estrdup(outbuf);
|
||||
}
|
||||
|
||||
p = &buffer[sizeof(buffer)-1];
|
||||
*p = '\0';
|
||||
|
||||
while ((pdo_uint64_t)i64 > (pdo_uint64_t)LONG_MAX) {
|
||||
pdo_uint64_t quo = (pdo_uint64_t)i64 / (unsigned int)10;
|
||||
unsigned int rem = (unsigned int)(i64 - quo*10U);
|
||||
*--p = digit_vec[rem];
|
||||
i64 = (pdo_int64_t)quo;
|
||||
}
|
||||
long_val = (long)i64;
|
||||
while (long_val != 0) {
|
||||
long quo = long_val / 10;
|
||||
*--p = digit_vec[(unsigned int)(long_val - quo * 10)];
|
||||
long_val = quo;
|
||||
}
|
||||
while ((*dst++ = *p++) != 0)
|
||||
;
|
||||
*dst = '\0';
|
||||
return estrdup(outbuf);
|
||||
}
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION */
|
||||
PHP_MINIT_FUNCTION(pdo)
|
||||
{
|
||||
zend_class_entry ce;
|
||||
|
||||
ZEND_INIT_MODULE_GLOBALS(pdo, php_pdo_init_globals, NULL);
|
||||
REGISTER_INI_ENTRIES();
|
||||
|
||||
if (FAILURE == pdo_sqlstate_init_error_table()) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
zend_hash_init(&pdo_driver_hash, 0, NULL, NULL, 1);
|
||||
|
||||
le_ppdo = zend_register_list_destructors_ex(NULL, php_pdo_pdbh_dtor,
|
||||
"PDO persistent database", module_number);
|
||||
|
||||
REGISTER_LONG_CONSTANT("PDO_PARAM_NULL", (long)PDO_PARAM_NULL, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_PARAM_INT", (long)PDO_PARAM_INT, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_PARAM_STR", (long)PDO_PARAM_STR, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_PARAM_LOB", (long)PDO_PARAM_LOB, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_PARAM_STMT", (long)PDO_PARAM_STMT, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_PARAM_INPUT_OUTPUT", (long)PDO_PARAM_INPUT_OUTPUT, CONST_CS|CONST_PERSISTENT);
|
||||
|
||||
REGISTER_LONG_CONSTANT("PDO_FETCH_LAZY", (long)PDO_FETCH_LAZY, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_FETCH_ASSOC",(long)PDO_FETCH_ASSOC, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_FETCH_NUM", (long)PDO_FETCH_NUM, CONST_CS|CONST_PERSISTENT);
|
||||
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_FETCH_FUNC", (long)PDO_FETCH_FUNC, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_FETCH_GROUP",(long)PDO_FETCH_GROUP, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_FETCH_UNIQUE",(long)PDO_FETCH_UNIQUE, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_FETCH_CLASSTYPE",(long)PDO_FETCH_CLASSTYPE, CONST_CS|CONST_PERSISTENT);
|
||||
#if PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION >= 1
|
||||
REGISTER_LONG_CONSTANT("PDO_FETCH_SERIALIZE",(long)PDO_FETCH_SERIALIZE, CONST_CS|CONST_PERSISTENT);
|
||||
#endif
|
||||
|
||||
REGISTER_LONG_CONSTANT("PDO_ATTR_AUTOCOMMIT", (long)PDO_ATTR_AUTOCOMMIT, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ATTR_PREFETCH", (long)PDO_ATTR_PREFETCH, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ATTR_TIMEOUT", (long)PDO_ATTR_TIMEOUT, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ATTR_ERRMODE", (long)PDO_ATTR_ERRMODE, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ATTR_SERVER_VERSION", (long)PDO_ATTR_SERVER_VERSION, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ATTR_CLIENT_VERSION", (long)PDO_ATTR_CLIENT_VERSION, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ATTR_SERVER_INFO", (long)PDO_ATTR_SERVER_INFO, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ATTR_CONNECTION_STATUS", (long)PDO_ATTR_CONNECTION_STATUS, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ATTR_CASE", (long)PDO_ATTR_CASE, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ATTR_CURSOR_NAME", (long)PDO_ATTR_CURSOR_NAME, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ATTR_CURSOR", (long)PDO_ATTR_CURSOR, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ATTR_ORACLE_NULLS", (long)PDO_ATTR_ORACLE_NULLS, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ATTR_PERSISTENT", (long)PDO_ATTR_PERSISTENT, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ATTR_STATEMENT_CLASS", (long)PDO_ATTR_STATEMENT_CLASS, CONST_CS|CONST_PERSISTENT);
|
||||
|
||||
REGISTER_LONG_CONSTANT("PDO_ERRMODE_SILENT", (long)PDO_ERRMODE_SILENT, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ERRMODE_WARNING", (long)PDO_ERRMODE_WARNING, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ERRMODE_EXCEPTION", (long)PDO_ERRMODE_EXCEPTION, CONST_CS|CONST_PERSISTENT);
|
||||
|
||||
REGISTER_LONG_CONSTANT("PDO_CASE_NATURAL", (long)PDO_CASE_NATURAL, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_CASE_LOWER", (long)PDO_CASE_LOWER, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_CASE_UPPER", (long)PDO_CASE_UPPER, CONST_CS|CONST_PERSISTENT);
|
||||
|
||||
REGISTER_STRING_CONSTANT("PDO_ERR_NONE", PDO_ERR_NONE, CONST_CS|CONST_PERSISTENT);
|
||||
|
||||
REGISTER_LONG_CONSTANT("PDO_FETCH_ORI_NEXT", (long)PDO_FETCH_ORI_NEXT, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_FETCH_ORI_PRIOR", (long)PDO_FETCH_ORI_PRIOR, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_FETCH_ORI_FIRST", (long)PDO_FETCH_ORI_FIRST, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_FETCH_ORI_LAST", (long)PDO_FETCH_ORI_LAST, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_FETCH_ORI_ABS", (long)PDO_FETCH_ORI_ABS, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_FETCH_ORI_REL", (long)PDO_FETCH_ORI_REL, CONST_CS|CONST_PERSISTENT);
|
||||
|
||||
REGISTER_LONG_CONSTANT("PDO_CURSOR_FWDONLY", (long)PDO_CURSOR_FWDONLY,CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_CURSOR_SCROLL", (long)PDO_CURSOR_SCROLL,CONST_CS|CONST_PERSISTENT);
|
||||
|
||||
#if 0
|
||||
REGISTER_LONG_CONSTANT("PDO_ERR_CANT_MAP", (long)PDO_ERR_CANT_MAP, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ERR_SYNTAX", (long)PDO_ERR_SYNTAX, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ERR_CONSTRAINT", (long)PDO_ERR_CONSTRAINT, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ERR_NOT_FOUND", (long)PDO_ERR_NOT_FOUND, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ERR_ALREADY_EXISTS", (long)PDO_ERR_ALREADY_EXISTS, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ERR_NOT_IMPLEMENTED", (long)PDO_ERR_NOT_IMPLEMENTED, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ERR_MISMATCH", (long)PDO_ERR_MISMATCH, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ERR_TRUNCATED", (long)PDO_ERR_TRUNCATED, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ERR_DISCONNECTED", (long)PDO_ERR_DISCONNECTED, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ERR_NO_PERM", (long)PDO_ERR_NO_PERM, CONST_CS|CONST_PERSISTENT);
|
||||
#endif
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "PDOException", NULL);
|
||||
#if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
|
||||
pdo_exception_ce = zend_register_internal_class_ex(&ce, spl_ce_RuntimeException, NULL TSRMLS_CC);
|
||||
#else
|
||||
pdo_exception_ce = zend_register_internal_class_ex(&ce, zend_exception_get_default(), NULL TSRMLS_CC);
|
||||
#endif
|
||||
zend_declare_property_null(pdo_exception_ce, "errorInfo", sizeof("errorInfo")-1, ZEND_ACC_PUBLIC TSRMLS_CC);
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "PDO", pdo_dbh_functions);
|
||||
pdo_dbh_ce = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
pdo_dbh_ce->create_object = pdo_dbh_new;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "PDOStatement", pdo_dbstmt_functions);
|
||||
pdo_dbstmt_ce = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
pdo_dbstmt_ce->get_iterator = pdo_stmt_iter_get;
|
||||
pdo_dbstmt_ce->create_object = pdo_dbstmt_new;
|
||||
zend_class_implements(pdo_dbstmt_ce TSRMLS_CC, 1, zend_ce_traversable);
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "PDORow", pdo_row_functions);
|
||||
pdo_row_ce = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
pdo_row_ce->create_object = pdo_row_new;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION */
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo)
|
||||
{
|
||||
UNREGISTER_INI_ENTRIES();
|
||||
zend_hash_destroy(&pdo_driver_hash);
|
||||
pdo_sqlstate_fini_error_table();
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_RINIT_FUNCTION */
|
||||
PHP_RINIT_FUNCTION(pdo)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_RSHUTDOWN_FUNCTION */
|
||||
PHP_RSHUTDOWN_FUNCTION(pdo)
|
||||
{
|
||||
/* TODO: visit persistent handles: for each persistent statement handle,
|
||||
* remove bound parameter associations */
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION */
|
||||
PHP_MINFO_FUNCTION(pdo)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "pdo support", "enabled");
|
||||
php_info_print_table_end();
|
||||
|
||||
#if 0
|
||||
DISPLAY_INI_ENTRIES();
|
||||
#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
|
||||
*/
|
||||
@@ -1,62 +0,0 @@
|
||||
<?php
|
||||
dl('pdo.so');
|
||||
dl('pdo_sqlite.so');
|
||||
|
||||
//$x = new PDO("oci:dbname=hostname", 'php', 'php');
|
||||
$x = new PDO("sqlite::memory:");
|
||||
|
||||
$x->query("create table test(name string, value string)");
|
||||
debug_zval_dump($x);
|
||||
|
||||
$stmt = $x->prepare("INSERT INTO test (NAME, VALUE) VALUES (:name, :value)");
|
||||
|
||||
$stmt->bindParam(":name", $the_name, PDO_PARAM_STR, 32);
|
||||
$stmt->bindParam(":value", $the_value, PDO_PARAM_STR, 32);
|
||||
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$the_name = "foo" . rand();
|
||||
$the_value = "bar" . rand();
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$stmt = null;
|
||||
|
||||
echo "DEFAULT:\n";
|
||||
foreach ($x->query("select NAME, VALUE from test") as $row) {
|
||||
print_r($row);
|
||||
}
|
||||
|
||||
echo "OBJ:\n";
|
||||
|
||||
class Foo {
|
||||
public $NAME = "Don't change me";
|
||||
}
|
||||
|
||||
$foo = new foo;
|
||||
|
||||
foreach ($x->query("select NAME, VALUE from test", PDO_FETCH_COLUMN, 1) as $row) {
|
||||
debug_zval_dump($row);
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
exit;
|
||||
|
||||
$stmt = $x->prepare("select NAME, VALUE from test where value like ?");
|
||||
$the_name = 'bar%';
|
||||
$stmt->execute(array($the_name)) or die("failed to execute!");
|
||||
$stmt->bindColumn('VALUE', $value);
|
||||
|
||||
while ($row = $stmt->fetch()) {
|
||||
echo "name=$row[NAME] value=$row[VALUE]\n";
|
||||
echo "value is $value\n";
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
echo "Let's try an update\n";
|
||||
|
||||
echo "All done\n";
|
||||
|
||||
?>
|
||||
-1240
File diff suppressed because it is too large.
Load diff
@@ -1,592 +0,0 @@
|
||||
/* Generated by re2c 0.9.3 on Sat Feb 26 11:03:39 2005 */
|
||||
#line 1 "pdo_sql_parser.re"
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 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_0.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: George Schlossnagle <george@omniti.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include "php.h"
|
||||
#include "php_pdo_driver.h"
|
||||
|
||||
#define PDO_PARSER_TEXT 1
|
||||
#define PDO_PARSER_BIND 2
|
||||
#define PDO_PARSER_BIND_POS 3
|
||||
#define PDO_PARSER_EOI 4
|
||||
|
||||
#define RET(i) {s->cur = cursor; return i; }
|
||||
|
||||
#define YYCTYPE char
|
||||
#define YYCURSOR cursor
|
||||
#define YYLIMIT s->lim
|
||||
#define YYMARKER s->ptr
|
||||
#define YYFILL(n)
|
||||
|
||||
typedef struct Scanner {
|
||||
char *lim, *ptr, *cur, *tok;
|
||||
} Scanner;
|
||||
|
||||
static int scan(Scanner *s)
|
||||
{
|
||||
char *cursor = s->cur;
|
||||
std:
|
||||
s->tok = cursor;
|
||||
#line 54 "pdo_sql_parser.re"
|
||||
|
||||
|
||||
|
||||
#line 7 "<stdout>"
|
||||
{
|
||||
YYCTYPE yych;
|
||||
unsigned int yyaccept;
|
||||
static unsigned char yybm[] = {
|
||||
0, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 0, 168, 168, 168, 168, 192,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
184, 184, 184, 184, 184, 184, 184, 184,
|
||||
184, 184, 160, 168, 168, 168, 168, 160,
|
||||
168, 184, 184, 184, 184, 184, 184, 184,
|
||||
184, 184, 184, 184, 184, 184, 184, 184,
|
||||
184, 184, 184, 184, 184, 184, 184, 184,
|
||||
184, 184, 184, 168, 8, 168, 168, 184,
|
||||
168, 184, 184, 184, 184, 184, 184, 184,
|
||||
184, 184, 184, 184, 184, 184, 184, 184,
|
||||
184, 184, 184, 184, 184, 184, 184, 184,
|
||||
184, 184, 184, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168,
|
||||
};
|
||||
goto yy0;
|
||||
yy1: ++YYCURSOR;
|
||||
yy0:
|
||||
if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
|
||||
yych = *YYCURSOR;
|
||||
if(yybm[0+yych] & 8) goto yy8;
|
||||
if(yych <= '\000') goto yy11;
|
||||
if(yych <= '&') goto yy2;
|
||||
if(yych <= '\'') goto yy4;
|
||||
if(yych <= '>') goto yy5;
|
||||
goto yy6;
|
||||
yy2: yyaccept = 0;
|
||||
yych = *(YYMARKER = ++YYCURSOR);
|
||||
if(yych >= '\001') goto yy24;
|
||||
goto yy3;
|
||||
yy3:
|
||||
#line 61 "pdo_sql_parser.re"
|
||||
{ RET(PDO_PARSER_TEXT); }
|
||||
#line 63 "<stdout>"
|
||||
yy4: yyaccept = 0;
|
||||
yych = *(YYMARKER = ++YYCURSOR);
|
||||
if(yych <= '\000') goto yy3;
|
||||
if(yych == '"') goto yy3;
|
||||
goto yy17;
|
||||
yy5: yych = *++YYCURSOR;
|
||||
if(yybm[0+yych] & 16) goto yy13;
|
||||
goto yy3;
|
||||
yy6: ++YYCURSOR;
|
||||
goto yy7;
|
||||
yy7:
|
||||
#line 60 "pdo_sql_parser.re"
|
||||
{ RET(PDO_PARSER_BIND_POS); }
|
||||
#line 77 "<stdout>"
|
||||
yy8: ++YYCURSOR;
|
||||
if(YYLIMIT == YYCURSOR) YYFILL(1);
|
||||
yych = *YYCURSOR;
|
||||
goto yy9;
|
||||
yy9: if(yybm[0+yych] & 8) goto yy8;
|
||||
goto yy10;
|
||||
yy10:
|
||||
#line 62 "pdo_sql_parser.re"
|
||||
{ RET(PDO_PARSER_TEXT); }
|
||||
#line 88 "<stdout>"
|
||||
yy11: ++YYCURSOR;
|
||||
goto yy12;
|
||||
yy12:
|
||||
#line 63 "pdo_sql_parser.re"
|
||||
{ RET(PDO_PARSER_EOI); }
|
||||
#line 94 "<stdout>"
|
||||
yy13: ++YYCURSOR;
|
||||
if(YYLIMIT == YYCURSOR) YYFILL(1);
|
||||
yych = *YYCURSOR;
|
||||
goto yy14;
|
||||
yy14: if(yybm[0+yych] & 16) goto yy13;
|
||||
goto yy15;
|
||||
yy15:
|
||||
#line 59 "pdo_sql_parser.re"
|
||||
{ RET(PDO_PARSER_BIND); }
|
||||
#line 105 "<stdout>"
|
||||
yy16: ++YYCURSOR;
|
||||
if(YYLIMIT == YYCURSOR) YYFILL(1);
|
||||
yych = *YYCURSOR;
|
||||
goto yy17;
|
||||
yy17: if(yybm[0+yych] & 32) goto yy16;
|
||||
if(yych <= '&') goto yy18;
|
||||
if(yych <= '\'') goto yy19;
|
||||
goto yy22;
|
||||
yy18: YYCURSOR = YYMARKER;
|
||||
switch(yyaccept){
|
||||
case 1: goto yy21;
|
||||
case 0: goto yy3;
|
||||
}
|
||||
yy19: yyaccept = 1;
|
||||
YYMARKER = ++YYCURSOR;
|
||||
if(YYLIMIT == YYCURSOR) YYFILL(1);
|
||||
yych = *YYCURSOR;
|
||||
goto yy20;
|
||||
yy20: if(yybm[0+yych] & 32) goto yy16;
|
||||
if(yych <= '&') goto yy21;
|
||||
if(yych <= '\'') goto yy19;
|
||||
goto yy22;
|
||||
yy21:
|
||||
#line 58 "pdo_sql_parser.re"
|
||||
{ RET(PDO_PARSER_TEXT); }
|
||||
#line 132 "<stdout>"
|
||||
yy22: ++YYCURSOR;
|
||||
if(YYLIMIT == YYCURSOR) YYFILL(1);
|
||||
yych = *YYCURSOR;
|
||||
if(yych == '\'') goto yy16;
|
||||
goto yy18;
|
||||
yy23: ++YYCURSOR;
|
||||
if(YYLIMIT == YYCURSOR) YYFILL(1);
|
||||
yych = *YYCURSOR;
|
||||
goto yy24;
|
||||
yy24: if(yybm[0+yych] & 128) goto yy23;
|
||||
if(yych <= '\000') goto yy18;
|
||||
if(yych <= '[') goto yy26;
|
||||
goto yy25;
|
||||
yy25: ++YYCURSOR;
|
||||
if(YYLIMIT == YYCURSOR) YYFILL(1);
|
||||
yych = *YYCURSOR;
|
||||
if(yych == '"') goto yy23;
|
||||
goto yy18;
|
||||
yy26: ++YYCURSOR;
|
||||
goto yy27;
|
||||
yy27:
|
||||
#line 57 "pdo_sql_parser.re"
|
||||
{ RET(PDO_PARSER_TEXT); }
|
||||
#line 159 "<stdout>"
|
||||
}
|
||||
#line 64 "pdo_sql_parser.re"
|
||||
|
||||
}
|
||||
|
||||
struct placeholder {
|
||||
char *pos;
|
||||
int len;
|
||||
int bindno;
|
||||
int qlen; /* quoted length of value */
|
||||
char *quoted; /* quoted value */
|
||||
int freeq;
|
||||
struct placeholder *next;
|
||||
};
|
||||
|
||||
PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
|
||||
char **outquery, int *outquery_len TSRMLS_DC)
|
||||
{
|
||||
Scanner s;
|
||||
char *ptr, *newbuffer;
|
||||
int t;
|
||||
int bindno = 0;
|
||||
int ret = 0;
|
||||
int newbuffer_len;
|
||||
HashTable *params;
|
||||
struct pdo_bound_param_data *param;
|
||||
int query_type = PDO_PLACEHOLDER_NONE;
|
||||
struct placeholder *placeholders = NULL, *placetail = NULL, *plc = NULL;
|
||||
|
||||
ptr = *outquery;
|
||||
s.cur = inquery;
|
||||
s.lim = inquery + inquery_len;
|
||||
|
||||
/* phase 1: look for args */
|
||||
while((t = scan(&s)) != PDO_PARSER_EOI) {
|
||||
if (t == PDO_PARSER_BIND || t == PDO_PARSER_BIND_POS) {
|
||||
if (t == PDO_PARSER_BIND) {
|
||||
query_type |= PDO_PLACEHOLDER_NAMED;
|
||||
} else {
|
||||
query_type |= PDO_PLACEHOLDER_POSITIONAL;
|
||||
}
|
||||
|
||||
plc = emalloc(sizeof(*plc));
|
||||
memset(plc, 0, sizeof(*plc));
|
||||
plc->next = NULL;
|
||||
plc->pos = s.tok;
|
||||
plc->len = s.cur - s.tok;
|
||||
plc->bindno = bindno++;
|
||||
|
||||
if (placetail) {
|
||||
placetail->next = plc;
|
||||
} else {
|
||||
placeholders = plc;
|
||||
}
|
||||
placetail = plc;
|
||||
}
|
||||
}
|
||||
|
||||
if (bindno == 0) {
|
||||
/* nothing to do; good! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* did the query make sense to me? */
|
||||
if (query_type == (PDO_PLACEHOLDER_NAMED|PDO_PLACEHOLDER_POSITIONAL)) {
|
||||
/* they mixed both types; punt */
|
||||
pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "mixed named and positional parameters" TSRMLS_CC);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stmt->supports_placeholders == query_type) {
|
||||
/* query matches native syntax */
|
||||
ret = 0;
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
params = stmt->bound_params;
|
||||
|
||||
/* Do we have placeholders but no bound params */
|
||||
if (bindno && !params && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
|
||||
pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "no parameters were bound" TSRMLS_CC);
|
||||
ret = -1;
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
/* what are we going to do ? */
|
||||
|
||||
if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
|
||||
/* query generation */
|
||||
|
||||
newbuffer_len = inquery_len;
|
||||
|
||||
/* let's quote all the values */
|
||||
for (plc = placeholders; plc; plc = plc->next) {
|
||||
if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
|
||||
ret = zend_hash_index_find(params, plc->bindno, (void**) ¶m);
|
||||
} else {
|
||||
ret = zend_hash_find(params, plc->pos, plc->len, (void**) ¶m);
|
||||
}
|
||||
if (ret == FAILURE) {
|
||||
/* parameter was not defined */
|
||||
ret = -1;
|
||||
pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined" TSRMLS_CC);
|
||||
goto clean_up;
|
||||
}
|
||||
if (stmt->dbh->methods->quoter) {
|
||||
if (param->param_type == PDO_PARAM_LOB && Z_TYPE_P(param->parameter) == IS_RESOURCE) {
|
||||
php_stream *stm;
|
||||
|
||||
php_stream_from_zval_no_verify(stm, ¶m->parameter);
|
||||
if (stm) {
|
||||
size_t len;
|
||||
char *buf = NULL;
|
||||
|
||||
len = php_stream_copy_to_mem(stm, &buf, PHP_STREAM_COPY_ALL, 0);
|
||||
if (!stmt->dbh->methods->quoter(stmt->dbh, buf, len, &plc->quoted, &plc->qlen,
|
||||
param->param_type TSRMLS_CC)) {
|
||||
/* bork */
|
||||
ret = -1;
|
||||
strcpy(stmt->error_code, stmt->dbh->error_code);
|
||||
efree(buf);
|
||||
goto clean_up;
|
||||
}
|
||||
efree(buf);
|
||||
|
||||
} else {
|
||||
pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource" TSRMLS_CC);
|
||||
ret = -1;
|
||||
goto clean_up;
|
||||
}
|
||||
plc->freeq = 1;
|
||||
} else {
|
||||
switch (Z_TYPE_P(param->parameter)) {
|
||||
case IS_NULL:
|
||||
plc->quoted = "NULL";
|
||||
plc->qlen = sizeof("NULL")-1;
|
||||
plc->freeq = 0;
|
||||
break;
|
||||
|
||||
case IS_BOOL:
|
||||
convert_to_long(param->parameter);
|
||||
case IS_LONG:
|
||||
case IS_DOUBLE:
|
||||
convert_to_string(param->parameter);
|
||||
plc->qlen = Z_STRLEN_P(param->parameter);
|
||||
plc->quoted = Z_STRVAL_P(param->parameter);
|
||||
plc->freeq = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
convert_to_string(param->parameter);
|
||||
if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
|
||||
Z_STRLEN_P(param->parameter), &plc->quoted, &plc->qlen,
|
||||
param->param_type TSRMLS_CC)) {
|
||||
/* bork */
|
||||
ret = -1;
|
||||
strcpy(stmt->error_code, stmt->dbh->error_code);
|
||||
goto clean_up;
|
||||
}
|
||||
plc->freeq = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
plc->quoted = Z_STRVAL_P(param->parameter);
|
||||
plc->qlen = Z_STRLEN_P(param->parameter);
|
||||
}
|
||||
newbuffer_len += plc->qlen;
|
||||
}
|
||||
|
||||
rewrite:
|
||||
/* allocate output buffer */
|
||||
newbuffer = emalloc(newbuffer_len + 1);
|
||||
*outquery = newbuffer;
|
||||
|
||||
/* and build the query */
|
||||
plc = placeholders;
|
||||
ptr = inquery;
|
||||
|
||||
do {
|
||||
t = plc->pos - ptr;
|
||||
if (t) {
|
||||
memcpy(newbuffer, ptr, t);
|
||||
newbuffer += t;
|
||||
}
|
||||
memcpy(newbuffer, plc->quoted, plc->qlen);
|
||||
newbuffer += plc->qlen;
|
||||
ptr = plc->pos + plc->len;
|
||||
|
||||
plc = plc->next;
|
||||
} while (plc);
|
||||
|
||||
t = (inquery + inquery_len) - ptr;
|
||||
if (t) {
|
||||
memcpy(newbuffer, ptr, t);
|
||||
newbuffer += t;
|
||||
}
|
||||
*newbuffer = '\0';
|
||||
*outquery_len = newbuffer - *outquery;
|
||||
|
||||
ret = 1;
|
||||
goto clean_up;
|
||||
|
||||
} else if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
|
||||
/* rewrite ? to :pdoX */
|
||||
char idxbuf[32];
|
||||
|
||||
newbuffer_len = inquery_len;
|
||||
|
||||
for (plc = placeholders; plc; plc = plc->next) {
|
||||
snprintf(idxbuf, sizeof(idxbuf), ":pdo%d", plc->bindno);
|
||||
plc->quoted = estrdup(idxbuf);
|
||||
plc->qlen = strlen(plc->quoted);
|
||||
plc->freeq = 1;
|
||||
newbuffer_len += plc->qlen;
|
||||
}
|
||||
|
||||
goto rewrite;
|
||||
|
||||
} else {
|
||||
/* rewrite :name to ? */
|
||||
|
||||
newbuffer_len = inquery_len;
|
||||
|
||||
if (stmt->bound_param_map == NULL) {
|
||||
ALLOC_HASHTABLE(stmt->bound_param_map);
|
||||
zend_hash_init(stmt->bound_param_map, 13, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
for (plc = placeholders; plc; plc = plc->next) {
|
||||
char *name;
|
||||
|
||||
name = estrndup(plc->pos, plc->len);
|
||||
zend_hash_index_update(stmt->bound_param_map, plc->bindno, name, plc->len + 1, NULL);
|
||||
efree(name);
|
||||
plc->quoted = "?";
|
||||
plc->qlen = 1;
|
||||
}
|
||||
|
||||
goto rewrite;
|
||||
}
|
||||
|
||||
clean_up:
|
||||
|
||||
while (placeholders) {
|
||||
plc = placeholders;
|
||||
placeholders = plc->next;
|
||||
|
||||
if (plc->freeq) {
|
||||
efree(plc->quoted);
|
||||
}
|
||||
|
||||
efree(plc);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int old_pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **outquery,
|
||||
int *outquery_len TSRMLS_DC)
|
||||
{
|
||||
Scanner s;
|
||||
char *ptr;
|
||||
int t;
|
||||
int bindno = 0;
|
||||
int newbuffer_len;
|
||||
int padding;
|
||||
HashTable *params = stmt->bound_params;
|
||||
struct pdo_bound_param_data *param;
|
||||
/* allocate buffer for query with expanded binds, ptr is our writing pointer */
|
||||
newbuffer_len = inquery_len;
|
||||
|
||||
/* calculate the possible padding factor due to quoting */
|
||||
if(stmt->dbh->max_escaped_char_length) {
|
||||
padding = stmt->dbh->max_escaped_char_length;
|
||||
} else {
|
||||
padding = 3;
|
||||
}
|
||||
if(params) {
|
||||
zend_hash_internal_pointer_reset(params);
|
||||
while (SUCCESS == zend_hash_get_current_data(params, (void**)¶m)) {
|
||||
if(param->parameter) {
|
||||
convert_to_string(param->parameter);
|
||||
/* accomodate a string that needs to be fully quoted
|
||||
bind placeholders are at least 2 characters, so
|
||||
the accomodate their own "'s
|
||||
*/
|
||||
newbuffer_len += padding * Z_STRLEN_P(param->parameter);
|
||||
}
|
||||
zend_hash_move_forward(params);
|
||||
}
|
||||
}
|
||||
*outquery = (char *) emalloc(newbuffer_len + 1);
|
||||
*outquery_len = 0;
|
||||
|
||||
ptr = *outquery;
|
||||
s.cur = inquery;
|
||||
s.lim = inquery + inquery_len;
|
||||
while((t = scan(&s)) != PDO_PARSER_EOI) {
|
||||
if(t == PDO_PARSER_TEXT) {
|
||||
memcpy(ptr, s.tok, s.cur - s.tok);
|
||||
ptr += (s.cur - s.tok);
|
||||
*outquery_len += (s.cur - s.tok);
|
||||
}
|
||||
else if(t == PDO_PARSER_BIND) {
|
||||
if(!params) {
|
||||
/* error */
|
||||
efree(*outquery);
|
||||
*outquery = NULL;
|
||||
return (int) (s.cur - inquery);
|
||||
}
|
||||
/* lookup bind first via hash and then index */
|
||||
/* stupid keys need to be null-terminated, even though we know their length */
|
||||
if((SUCCESS == zend_hash_find(params, s.tok, s.cur-s.tok,(void **)¶m))
|
||||
||
|
||||
(SUCCESS == zend_hash_index_find(params, bindno, (void **)¶m)))
|
||||
{
|
||||
char *quotedstr;
|
||||
int quotedstrlen;
|
||||
/* restore the in-string key, doesn't need null-termination here */
|
||||
/* currently everything is a string here */
|
||||
|
||||
/* quote the bind value if necessary */
|
||||
if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
|
||||
Z_STRLEN_P(param->parameter), "edstr, "edstrlen TSRMLS_CC))
|
||||
{
|
||||
memcpy(ptr, quotedstr, quotedstrlen);
|
||||
ptr += quotedstrlen;
|
||||
*outquery_len += quotedstrlen;
|
||||
efree(quotedstr);
|
||||
} else {
|
||||
memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter));
|
||||
ptr += Z_STRLEN_P(param->parameter);
|
||||
*outquery_len += (Z_STRLEN_P(param->parameter));
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* error and cleanup */
|
||||
efree(*outquery);
|
||||
*outquery = NULL;
|
||||
return (int) (s.cur - inquery);
|
||||
}
|
||||
bindno++;
|
||||
}
|
||||
else if(t == PDO_PARSER_BIND_POS) {
|
||||
if(!params) {
|
||||
/* error */
|
||||
efree(*outquery);
|
||||
*outquery = NULL;
|
||||
return (int) (s.cur - inquery);
|
||||
}
|
||||
/* lookup bind by index */
|
||||
if(SUCCESS == zend_hash_index_find(params, bindno, (void **)¶m))
|
||||
{
|
||||
char *quotedstr;
|
||||
int quotedstrlen;
|
||||
/* currently everything is a string here */
|
||||
|
||||
/* quote the bind value if necessary */
|
||||
if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
|
||||
Z_STRLEN_P(param->parameter), "edstr, "edstrlen TSRMLS_CC))
|
||||
{
|
||||
memcpy(ptr, quotedstr, quotedstrlen);
|
||||
ptr += quotedstrlen;
|
||||
*outquery_len += quotedstrlen;
|
||||
efree(quotedstr);
|
||||
} else {
|
||||
memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter));
|
||||
ptr += Z_STRLEN_P(param->parameter);
|
||||
*outquery_len += (Z_STRLEN_P(param->parameter));
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* error and cleanup */
|
||||
efree(*outquery);
|
||||
*outquery = NULL;
|
||||
return (int) (s.cur - inquery);
|
||||
}
|
||||
bindno++;
|
||||
}
|
||||
}
|
||||
*ptr = '\0';
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker ft=c
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,455 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 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_0.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: George Schlossnagle <george@omniti.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include "php.h"
|
||||
#include "php_pdo_driver.h"
|
||||
|
||||
#define PDO_PARSER_TEXT 1
|
||||
#define PDO_PARSER_BIND 2
|
||||
#define PDO_PARSER_BIND_POS 3
|
||||
#define PDO_PARSER_EOI 4
|
||||
|
||||
#define RET(i) {s->cur = cursor; return i; }
|
||||
|
||||
#define YYCTYPE char
|
||||
#define YYCURSOR cursor
|
||||
#define YYLIMIT s->lim
|
||||
#define YYMARKER s->ptr
|
||||
#define YYFILL(n)
|
||||
|
||||
typedef struct Scanner {
|
||||
char *lim, *ptr, *cur, *tok;
|
||||
} Scanner;
|
||||
|
||||
static int scan(Scanner *s)
|
||||
{
|
||||
char *cursor = s->cur;
|
||||
std:
|
||||
s->tok = cursor;
|
||||
/*!re2c
|
||||
BINDCHR = [:][a-zA-Z0-9_]+;
|
||||
QUESTION = [?];
|
||||
SPECIALS = [:?"'];
|
||||
ESCQQ = [\\]["];
|
||||
ESCQ = [\\]['];
|
||||
EOF = [\000];
|
||||
ANYNOEOF = [\001-\377];
|
||||
*/
|
||||
|
||||
/*!re2c
|
||||
(["] (ESCQQ|ANYNOEOF\[\\"])* ["]) { RET(PDO_PARSER_TEXT); }
|
||||
(['] (ESCQ|ANYNOEOF\[\\"])* [']) { RET(PDO_PARSER_TEXT); }
|
||||
BINDCHR { RET(PDO_PARSER_BIND); }
|
||||
QUESTION { RET(PDO_PARSER_BIND_POS); }
|
||||
SPECIALS { RET(PDO_PARSER_TEXT); }
|
||||
(ANYNOEOF\SPECIALS)+ { RET(PDO_PARSER_TEXT); }
|
||||
EOF { RET(PDO_PARSER_EOI); }
|
||||
*/
|
||||
}
|
||||
|
||||
struct placeholder {
|
||||
char *pos;
|
||||
int len;
|
||||
int bindno;
|
||||
int qlen; /* quoted length of value */
|
||||
char *quoted; /* quoted value */
|
||||
int freeq;
|
||||
struct placeholder *next;
|
||||
};
|
||||
|
||||
PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
|
||||
char **outquery, int *outquery_len TSRMLS_DC)
|
||||
{
|
||||
Scanner s;
|
||||
char *ptr, *newbuffer;
|
||||
int t;
|
||||
int bindno = 0;
|
||||
int ret = 0;
|
||||
int newbuffer_len;
|
||||
HashTable *params;
|
||||
struct pdo_bound_param_data *param;
|
||||
int query_type = PDO_PLACEHOLDER_NONE;
|
||||
struct placeholder *placeholders = NULL, *placetail = NULL, *plc = NULL;
|
||||
|
||||
ptr = *outquery;
|
||||
s.cur = inquery;
|
||||
s.lim = inquery + inquery_len;
|
||||
|
||||
/* phase 1: look for args */
|
||||
while((t = scan(&s)) != PDO_PARSER_EOI) {
|
||||
if (t == PDO_PARSER_BIND || t == PDO_PARSER_BIND_POS) {
|
||||
if (t == PDO_PARSER_BIND) {
|
||||
query_type |= PDO_PLACEHOLDER_NAMED;
|
||||
} else {
|
||||
query_type |= PDO_PLACEHOLDER_POSITIONAL;
|
||||
}
|
||||
|
||||
plc = emalloc(sizeof(*plc));
|
||||
memset(plc, 0, sizeof(*plc));
|
||||
plc->next = NULL;
|
||||
plc->pos = s.tok;
|
||||
plc->len = s.cur - s.tok;
|
||||
plc->bindno = bindno++;
|
||||
|
||||
if (placetail) {
|
||||
placetail->next = plc;
|
||||
} else {
|
||||
placeholders = plc;
|
||||
}
|
||||
placetail = plc;
|
||||
}
|
||||
}
|
||||
|
||||
if (bindno == 0) {
|
||||
/* nothing to do; good! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* did the query make sense to me? */
|
||||
if (query_type == (PDO_PLACEHOLDER_NAMED|PDO_PLACEHOLDER_POSITIONAL)) {
|
||||
/* they mixed both types; punt */
|
||||
pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "mixed named and positional parameters" TSRMLS_CC);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stmt->supports_placeholders == query_type) {
|
||||
/* query matches native syntax */
|
||||
ret = 0;
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
params = stmt->bound_params;
|
||||
|
||||
/* Do we have placeholders but no bound params */
|
||||
if (bindno && !params && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
|
||||
pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "no parameters were bound" TSRMLS_CC);
|
||||
ret = -1;
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
/* what are we going to do ? */
|
||||
|
||||
if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
|
||||
/* query generation */
|
||||
|
||||
newbuffer_len = inquery_len;
|
||||
|
||||
/* let's quote all the values */
|
||||
for (plc = placeholders; plc; plc = plc->next) {
|
||||
if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
|
||||
ret = zend_hash_index_find(params, plc->bindno, (void**) ¶m);
|
||||
} else {
|
||||
ret = zend_hash_find(params, plc->pos, plc->len, (void**) ¶m);
|
||||
}
|
||||
if (ret == FAILURE) {
|
||||
/* parameter was not defined */
|
||||
ret = -1;
|
||||
pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined" TSRMLS_CC);
|
||||
goto clean_up;
|
||||
}
|
||||
if (stmt->dbh->methods->quoter) {
|
||||
if (param->param_type == PDO_PARAM_LOB && Z_TYPE_P(param->parameter) == IS_RESOURCE) {
|
||||
php_stream *stm;
|
||||
|
||||
php_stream_from_zval_no_verify(stm, ¶m->parameter);
|
||||
if (stm) {
|
||||
size_t len;
|
||||
char *buf = NULL;
|
||||
|
||||
len = php_stream_copy_to_mem(stm, &buf, PHP_STREAM_COPY_ALL, 0);
|
||||
if (!stmt->dbh->methods->quoter(stmt->dbh, buf, len, &plc->quoted, &plc->qlen,
|
||||
param->param_type TSRMLS_CC)) {
|
||||
/* bork */
|
||||
ret = -1;
|
||||
strcpy(stmt->error_code, stmt->dbh->error_code);
|
||||
efree(buf);
|
||||
goto clean_up;
|
||||
}
|
||||
efree(buf);
|
||||
|
||||
} else {
|
||||
pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource" TSRMLS_CC);
|
||||
ret = -1;
|
||||
goto clean_up;
|
||||
}
|
||||
plc->freeq = 1;
|
||||
} else {
|
||||
switch (Z_TYPE_P(param->parameter)) {
|
||||
case IS_NULL:
|
||||
plc->quoted = "NULL";
|
||||
plc->qlen = sizeof("NULL")-1;
|
||||
plc->freeq = 0;
|
||||
break;
|
||||
|
||||
case IS_BOOL:
|
||||
convert_to_long(param->parameter);
|
||||
case IS_LONG:
|
||||
case IS_DOUBLE:
|
||||
convert_to_string(param->parameter);
|
||||
plc->qlen = Z_STRLEN_P(param->parameter);
|
||||
plc->quoted = Z_STRVAL_P(param->parameter);
|
||||
plc->freeq = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
convert_to_string(param->parameter);
|
||||
if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
|
||||
Z_STRLEN_P(param->parameter), &plc->quoted, &plc->qlen,
|
||||
param->param_type TSRMLS_CC)) {
|
||||
/* bork */
|
||||
ret = -1;
|
||||
strcpy(stmt->error_code, stmt->dbh->error_code);
|
||||
goto clean_up;
|
||||
}
|
||||
plc->freeq = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
plc->quoted = Z_STRVAL_P(param->parameter);
|
||||
plc->qlen = Z_STRLEN_P(param->parameter);
|
||||
}
|
||||
newbuffer_len += plc->qlen;
|
||||
}
|
||||
|
||||
rewrite:
|
||||
/* allocate output buffer */
|
||||
newbuffer = emalloc(newbuffer_len + 1);
|
||||
*outquery = newbuffer;
|
||||
|
||||
/* and build the query */
|
||||
plc = placeholders;
|
||||
ptr = inquery;
|
||||
|
||||
do {
|
||||
t = plc->pos - ptr;
|
||||
if (t) {
|
||||
memcpy(newbuffer, ptr, t);
|
||||
newbuffer += t;
|
||||
}
|
||||
memcpy(newbuffer, plc->quoted, plc->qlen);
|
||||
newbuffer += plc->qlen;
|
||||
ptr = plc->pos + plc->len;
|
||||
|
||||
plc = plc->next;
|
||||
} while (plc);
|
||||
|
||||
t = (inquery + inquery_len) - ptr;
|
||||
if (t) {
|
||||
memcpy(newbuffer, ptr, t);
|
||||
newbuffer += t;
|
||||
}
|
||||
*newbuffer = '\0';
|
||||
*outquery_len = newbuffer - *outquery;
|
||||
|
||||
ret = 1;
|
||||
goto clean_up;
|
||||
|
||||
} else if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
|
||||
/* rewrite ? to :pdoX */
|
||||
char idxbuf[32];
|
||||
|
||||
newbuffer_len = inquery_len;
|
||||
|
||||
for (plc = placeholders; plc; plc = plc->next) {
|
||||
snprintf(idxbuf, sizeof(idxbuf), ":pdo%d", plc->bindno);
|
||||
plc->quoted = estrdup(idxbuf);
|
||||
plc->qlen = strlen(plc->quoted);
|
||||
plc->freeq = 1;
|
||||
newbuffer_len += plc->qlen;
|
||||
}
|
||||
|
||||
goto rewrite;
|
||||
|
||||
} else {
|
||||
/* rewrite :name to ? */
|
||||
|
||||
newbuffer_len = inquery_len;
|
||||
|
||||
if (stmt->bound_param_map == NULL) {
|
||||
ALLOC_HASHTABLE(stmt->bound_param_map);
|
||||
zend_hash_init(stmt->bound_param_map, 13, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
for (plc = placeholders; plc; plc = plc->next) {
|
||||
char *name;
|
||||
|
||||
name = estrndup(plc->pos, plc->len);
|
||||
zend_hash_index_update(stmt->bound_param_map, plc->bindno, name, plc->len + 1, NULL);
|
||||
efree(name);
|
||||
plc->quoted = "?";
|
||||
plc->qlen = 1;
|
||||
}
|
||||
|
||||
goto rewrite;
|
||||
}
|
||||
|
||||
clean_up:
|
||||
|
||||
while (placeholders) {
|
||||
plc = placeholders;
|
||||
placeholders = plc->next;
|
||||
|
||||
if (plc->freeq) {
|
||||
efree(plc->quoted);
|
||||
}
|
||||
|
||||
efree(plc);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int old_pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **outquery,
|
||||
int *outquery_len TSRMLS_DC)
|
||||
{
|
||||
Scanner s;
|
||||
char *ptr;
|
||||
int t;
|
||||
int bindno = 0;
|
||||
int newbuffer_len;
|
||||
int padding;
|
||||
HashTable *params = stmt->bound_params;
|
||||
struct pdo_bound_param_data *param;
|
||||
/* allocate buffer for query with expanded binds, ptr is our writing pointer */
|
||||
newbuffer_len = inquery_len;
|
||||
|
||||
/* calculate the possible padding factor due to quoting */
|
||||
if(stmt->dbh->max_escaped_char_length) {
|
||||
padding = stmt->dbh->max_escaped_char_length;
|
||||
} else {
|
||||
padding = 3;
|
||||
}
|
||||
if(params) {
|
||||
zend_hash_internal_pointer_reset(params);
|
||||
while (SUCCESS == zend_hash_get_current_data(params, (void**)¶m)) {
|
||||
if(param->parameter) {
|
||||
convert_to_string(param->parameter);
|
||||
/* accomodate a string that needs to be fully quoted
|
||||
bind placeholders are at least 2 characters, so
|
||||
the accomodate their own "'s
|
||||
*/
|
||||
newbuffer_len += padding * Z_STRLEN_P(param->parameter);
|
||||
}
|
||||
zend_hash_move_forward(params);
|
||||
}
|
||||
}
|
||||
*outquery = (char *) emalloc(newbuffer_len + 1);
|
||||
*outquery_len = 0;
|
||||
|
||||
ptr = *outquery;
|
||||
s.cur = inquery;
|
||||
s.lim = inquery + inquery_len;
|
||||
while((t = scan(&s)) != PDO_PARSER_EOI) {
|
||||
if(t == PDO_PARSER_TEXT) {
|
||||
memcpy(ptr, s.tok, s.cur - s.tok);
|
||||
ptr += (s.cur - s.tok);
|
||||
*outquery_len += (s.cur - s.tok);
|
||||
}
|
||||
else if(t == PDO_PARSER_BIND) {
|
||||
if(!params) {
|
||||
/* error */
|
||||
efree(*outquery);
|
||||
*outquery = NULL;
|
||||
return (int) (s.cur - inquery);
|
||||
}
|
||||
/* lookup bind first via hash and then index */
|
||||
/* stupid keys need to be null-terminated, even though we know their length */
|
||||
if((SUCCESS == zend_hash_find(params, s.tok, s.cur-s.tok,(void **)¶m))
|
||||
||
|
||||
(SUCCESS == zend_hash_index_find(params, bindno, (void **)¶m)))
|
||||
{
|
||||
char *quotedstr;
|
||||
int quotedstrlen;
|
||||
/* restore the in-string key, doesn't need null-termination here */
|
||||
/* currently everything is a string here */
|
||||
|
||||
/* quote the bind value if necessary */
|
||||
if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
|
||||
Z_STRLEN_P(param->parameter), "edstr, "edstrlen TSRMLS_CC))
|
||||
{
|
||||
memcpy(ptr, quotedstr, quotedstrlen);
|
||||
ptr += quotedstrlen;
|
||||
*outquery_len += quotedstrlen;
|
||||
efree(quotedstr);
|
||||
} else {
|
||||
memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter));
|
||||
ptr += Z_STRLEN_P(param->parameter);
|
||||
*outquery_len += (Z_STRLEN_P(param->parameter));
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* error and cleanup */
|
||||
efree(*outquery);
|
||||
*outquery = NULL;
|
||||
return (int) (s.cur - inquery);
|
||||
}
|
||||
bindno++;
|
||||
}
|
||||
else if(t == PDO_PARSER_BIND_POS) {
|
||||
if(!params) {
|
||||
/* error */
|
||||
efree(*outquery);
|
||||
*outquery = NULL;
|
||||
return (int) (s.cur - inquery);
|
||||
}
|
||||
/* lookup bind by index */
|
||||
if(SUCCESS == zend_hash_index_find(params, bindno, (void **)¶m))
|
||||
{
|
||||
char *quotedstr;
|
||||
int quotedstrlen;
|
||||
/* currently everything is a string here */
|
||||
|
||||
/* quote the bind value if necessary */
|
||||
if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
|
||||
Z_STRLEN_P(param->parameter), "edstr, "edstrlen TSRMLS_CC))
|
||||
{
|
||||
memcpy(ptr, quotedstr, quotedstrlen);
|
||||
ptr += quotedstrlen;
|
||||
*outquery_len += quotedstrlen;
|
||||
efree(quotedstr);
|
||||
} else {
|
||||
memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter));
|
||||
ptr += Z_STRLEN_P(param->parameter);
|
||||
*outquery_len += (Z_STRLEN_P(param->parameter));
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* error and cleanup */
|
||||
efree(*outquery);
|
||||
*outquery = NULL;
|
||||
return (int) (s.cur - inquery);
|
||||
}
|
||||
bindno++;
|
||||
}
|
||||
}
|
||||
*ptr = '\0';
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker ft=c
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,190 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2005 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 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_0.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: Wez Furlong <wez@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "php_pdo.h"
|
||||
#include "php_pdo_driver.h"
|
||||
|
||||
struct pdo_sqlstate_info {
|
||||
char state[6];
|
||||
const char *desc;
|
||||
};
|
||||
|
||||
static HashTable err_hash;
|
||||
|
||||
static struct pdo_sqlstate_info err_initializer[] = {
|
||||
{ "00000", "No error" },
|
||||
{ "01001", "Cursor operation conflict" },
|
||||
{ "01002", "Disconnect error" },
|
||||
{ "01003", "NULL value eliminated in set function" },
|
||||
{ "01004", "String data, right truncated" },
|
||||
{ "01006", "Privilege not revoked" },
|
||||
{ "01007", "Privilege not granted" },
|
||||
{ "01S00", "Invalid connection string attribute" },
|
||||
{ "01S01", "Error in row" },
|
||||
{ "01S02", "Option value changed" },
|
||||
{ "01S06", "Attempt to fetch before the result set returned the first rowset" },
|
||||
{ "01S07", "Fractional truncation" },
|
||||
{ "01S08", "Error saving File DSN" },
|
||||
{ "01S09", "Invalid keyword" },
|
||||
{ "07002", "COUNT field incorrect" },
|
||||
{ "07005", "Prepared statement not a cursor-specification" },
|
||||
{ "07006", "Restricted data type attribute violation" },
|
||||
{ "07009", "Invalid descriptor index" },
|
||||
{ "07S01", "Invalid use of default parameter" },
|
||||
{ "08001", "Client unable to establish connection" },
|
||||
{ "08002", "Connection name in use" },
|
||||
{ "08003", "Connection does not exist" },
|
||||
{ "08004", "Server rejected the connection" },
|
||||
{ "08007", "Connection failure during transaction" },
|
||||
{ "08S01", "Communication link failure" },
|
||||
{ "21S01", "Insert value list does not match column list" },
|
||||
{ "21S02", "Degree of derived table does not match column list" },
|
||||
{ "22001", "String data, right truncated" },
|
||||
{ "22002", "Indicator variable required but not supplied" },
|
||||
{ "22003", "Numeric value out of range" },
|
||||
{ "22007", "Invalid datetime format" },
|
||||
{ "22008", "Datetime field overflow" },
|
||||
{ "22012", "Division by zero" },
|
||||
{ "22015", "Interval field overflow" },
|
||||
{ "22018", "Invalid character value for cast specification" },
|
||||
{ "22019", "Invalid escape character" },
|
||||
{ "22025", "Invalid escape sequence" },
|
||||
{ "22026", "String data, length mismatch" },
|
||||
{ "23000", "Integrity constraint violation" },
|
||||
{ "24000", "Invalid cursor state" },
|
||||
{ "25000", "Invalid transaction state" },
|
||||
{ "25S01", "Transaction state" },
|
||||
{ "25S02", "Transaction is still active" },
|
||||
{ "25S03", "Transaction is rolled back" },
|
||||
{ "28000", "Invalid authorization specification" },
|
||||
{ "34000", "Invalid cursor name" },
|
||||
{ "3C000", "Duplicate cursor name" },
|
||||
{ "3D000", "Invalid catalog name" },
|
||||
{ "3F000", "Invalid schema name" },
|
||||
{ "40001", "Serialization failure" },
|
||||
{ "40003", "Statement completion unknown" },
|
||||
{ "42000", "Syntax error or access violation" },
|
||||
{ "42S01", "Base table or view already exists" },
|
||||
{ "42S02", "Base table or view not found" },
|
||||
{ "42S11", "Index already exists" },
|
||||
{ "42S12", "Index not found" },
|
||||
{ "42S21", "Column already exists" },
|
||||
{ "42S22", "Column not found" },
|
||||
{ "44000", "WITH CHECK OPTION violation" },
|
||||
{ "HY000", "General error" },
|
||||
{ "HY001", "Memory allocation error" },
|
||||
{ "HY003", "Invalid application buffer type" },
|
||||
{ "HY004", "Invalid SQL data type" },
|
||||
{ "HY007", "Associated statement is not prepared" },
|
||||
{ "HY008", "Operation canceled" },
|
||||
{ "HY009", "Invalid use of null pointer" },
|
||||
{ "HY010", "Function sequence error" },
|
||||
{ "HY011", "Attribute cannot be set now" },
|
||||
{ "HY012", "Invalid transaction operation code" },
|
||||
{ "HY013", "Memory management error" },
|
||||
{ "HY014", "Limit on the number of handles exceeded" },
|
||||
{ "HY015", "No cursor name available" },
|
||||
{ "HY016", "Cannot modify an implementation row descriptor" },
|
||||
{ "HY017", "Invalid use of an automatically allocated descriptor handle" },
|
||||
{ "HY018", "Server declined cancel request" },
|
||||
{ "HY019", "Non-character and non-binary data sent in pieces" },
|
||||
{ "HY020", "Attempt to concatenate a null value" },
|
||||
{ "HY021", "Inconsistent descriptor information" },
|
||||
{ "HY024", "Invalid attribute value" },
|
||||
{ "HY090", "Invalid string or buffer length" },
|
||||
{ "HY091", "Invalid descriptor field identifier" },
|
||||
{ "HY092", "Invalid attribute/option identifier" },
|
||||
{ "HY093", "Invalid parameter number" },
|
||||
{ "HY095", "Function type out of range" },
|
||||
{ "HY096", "Invalid information type" },
|
||||
{ "HY097", "Column type out of range" },
|
||||
{ "HY098", "Scope type out of range" },
|
||||
{ "HY099", "Nullable type out of range" },
|
||||
{ "HY100", "Uniqueness option type out of range" },
|
||||
{ "HY101", "Accuracy option type out of range" },
|
||||
{ "HY103", "Invalid retrieval code" },
|
||||
{ "HY104", "Invalid precision or scale value" },
|
||||
{ "HY105", "Invalid parameter type" },
|
||||
{ "HY106", "Fetch type out of range" },
|
||||
{ "HY107", "Row value out of range" },
|
||||
{ "HY109", "Invalid cursor position" },
|
||||
{ "HY110", "Invalid driver completion" },
|
||||
{ "HY111", "Invalid bookmark value" },
|
||||
{ "HYC00", "Optional feature not implemented" },
|
||||
{ "HYT00", "Timeout expired" },
|
||||
{ "HYT01", "Connection timeout expired" },
|
||||
{ "IM001", "Driver does not support this function" },
|
||||
{ "IM002", "Data source name not found and no default driver specified" },
|
||||
{ "IM003", "Specified driver could not be loaded" },
|
||||
{ "IM004", "Driver's SQLAllocHandle on SQL_HANDLE_ENV failed" },
|
||||
{ "IM005", "Driver's SQLAllocHandle on SQL_HANDLE_DBC failed" },
|
||||
{ "IM006", "Driver's SQLSetConnectAttr failed" },
|
||||
{ "IM007", "No data source or driver specified; dialog prohibited" },
|
||||
{ "IM008", "Dialog failed" },
|
||||
{ "IM009", "Unable to load translation DLL" },
|
||||
{ "IM010", "Data source name too long" },
|
||||
{ "IM011", "Driver name too long" },
|
||||
{ "IM012", "DRIVER keyword syntax error" },
|
||||
{ "IM013", "Trace file error" },
|
||||
{ "IM014", "Invalid name of File DSN" },
|
||||
{ "IM015", "Corrupt file data source" }
|
||||
};
|
||||
|
||||
void pdo_sqlstate_fini_error_table(void)
|
||||
{
|
||||
zend_hash_destroy(&err_hash);
|
||||
}
|
||||
|
||||
int pdo_sqlstate_init_error_table(void)
|
||||
{
|
||||
int i;
|
||||
struct pdo_sqlstate_info *info;
|
||||
|
||||
if (FAILURE == zend_hash_init(&err_hash,
|
||||
sizeof(err_initializer)/sizeof(err_initializer[0]), NULL, NULL, 1)) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(err_initializer)/sizeof(err_initializer[0]); i++) {
|
||||
info = &err_initializer[i];
|
||||
|
||||
zend_hash_add(&err_hash, info->state, sizeof(info->state), &info, sizeof(info), NULL);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
const char *pdo_sqlstate_state_to_description(char *state)
|
||||
{
|
||||
struct pdo_sqlstate_info **info;
|
||||
if (SUCCESS == zend_hash_find(&err_hash, state, sizeof(err_initializer[0].state),
|
||||
(void**)&info)) {
|
||||
return (*info)->desc;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-2222
File diff suppressed because it is too large.
Load diff
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2005 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 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_0.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: Wez Furlong <wez@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef PHP_PDO_H
|
||||
#define PHP_PDO_H
|
||||
|
||||
#include "zend.h"
|
||||
|
||||
extern zend_module_entry pdo_module_entry;
|
||||
#define phpext_pdo_ptr &pdo_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
# if defined(PDO_EXPORTS) || (!defined(COMPILE_DL_PDO))
|
||||
# define PDO_API __declspec(dllexport)
|
||||
# elif defined(COMPILE_DL_PDO)
|
||||
# define PDO_API __declspec(dllimport)
|
||||
# else
|
||||
# define PDO_API /* nothing special */
|
||||
# endif
|
||||
#else
|
||||
# define PDO_API /* nothing special */
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
# include "TSRM.h"
|
||||
#endif
|
||||
|
||||
PHP_MINIT_FUNCTION(pdo);
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo);
|
||||
PHP_RINIT_FUNCTION(pdo);
|
||||
PHP_RSHUTDOWN_FUNCTION(pdo);
|
||||
PHP_MINFO_FUNCTION(pdo);
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(pdo)
|
||||
long global_value;
|
||||
ZEND_END_MODULE_GLOBALS(pdo)
|
||||
|
||||
#ifdef ZTS
|
||||
# define PDOG(v) TSRMG(pdo_globals_id, zend_pdo_globals *, v)
|
||||
#else
|
||||
# define PDOG(v) (pdo_globals.v)
|
||||
#endif
|
||||
|
||||
#endif /* PHP_PDO_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
|
||||
*/
|
||||
@@ -1,616 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2005 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 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_0.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: Wez Furlong <wez@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef PHP_PDO_DRIVER_H
|
||||
#define PHP_PDO_DRIVER_H
|
||||
|
||||
#include "php_pdo.h"
|
||||
|
||||
/* forward declarations */
|
||||
typedef struct _pdo_dbh_t pdo_dbh_t;
|
||||
typedef struct _pdo_stmt_t pdo_stmt_t;
|
||||
struct pdo_bound_param_data;
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
typedef __int64 pdo_int64_t;
|
||||
typedef unsigned __int64 pdo_uint64_t;
|
||||
#else
|
||||
typedef long long int pdo_int64_t;
|
||||
typedef unsigned long long int pdo_uint64_t;
|
||||
#endif
|
||||
PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC);
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
# define FALSE 0
|
||||
#endif
|
||||
|
||||
#define PDO_DRIVER_API 20050227
|
||||
|
||||
enum pdo_param_type {
|
||||
PDO_PARAM_NULL,
|
||||
|
||||
/* int as in long (the php native int type).
|
||||
* If you mark a column as an int, PDO expects get_col to return
|
||||
* a pointer to a long */
|
||||
PDO_PARAM_INT,
|
||||
|
||||
/* get_col ptr should point to start of the string buffer */
|
||||
PDO_PARAM_STR,
|
||||
|
||||
/* get_col: when len is 0 ptr should point to a php_stream *,
|
||||
* otherwise it should behave like a string. Indicate a NULL field
|
||||
* value by setting the ptr to NULL */
|
||||
PDO_PARAM_LOB,
|
||||
|
||||
/* get_col: will expect the ptr to point to a new PDOStatement object handle,
|
||||
* but this isn't wired up yet */
|
||||
PDO_PARAM_STMT, /* hierarchical result set */
|
||||
|
||||
/* get_col ptr should point to a zend_bool */
|
||||
PDO_PARAM_BOOL,
|
||||
|
||||
/* magic flag to denote a parameter as being input/output */
|
||||
PDO_PARAM_INPUT_OUTPUT = 0x80000000
|
||||
};
|
||||
|
||||
#define PDO_PARAM_FLAGS 0xFFFF0000
|
||||
|
||||
#define PDO_PARAM_TYPE(x) ((x) & ~PDO_PARAM_FLAGS)
|
||||
|
||||
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_FUNC, /* fetch into function and return its result */
|
||||
PDO_FETCH__MAX /* must be last */
|
||||
};
|
||||
|
||||
#define PDO_FETCH_FLAGS 0xFFFF0000 /* fetchAll() modes or'd to PDO_FETCH_XYZ */
|
||||
#define PDO_FETCH_GROUP 0x00010000 /* fetch into groups */
|
||||
#define PDO_FETCH_UNIQUE 0x00030000 /* fetch into groups assuming first col is unique */
|
||||
#define PDO_FETCH_CLASSTYPE 0x00040000 /* fetch class gets its class name from 1st column */
|
||||
#define PDO_FETCH_SERIALIZE 0x00080000 /* fetch class instances by calling serialize */
|
||||
|
||||
/* fetch orientation for scrollable cursors */
|
||||
enum pdo_fetch_orientation {
|
||||
PDO_FETCH_ORI_NEXT, /* default: fetch the next available row */
|
||||
PDO_FETCH_ORI_PRIOR, /* scroll back to prior row and fetch that */
|
||||
PDO_FETCH_ORI_FIRST, /* scroll to the first row and fetch that */
|
||||
PDO_FETCH_ORI_LAST, /* scroll to the last row and fetch that */
|
||||
PDO_FETCH_ORI_ABS, /* scroll to an absolute numbered row and fetch that */
|
||||
PDO_FETCH_ORI_REL, /* scroll relative to the current row, and fetch that */
|
||||
};
|
||||
|
||||
enum pdo_attribute_type {
|
||||
PDO_ATTR_AUTOCOMMIT, /* use to turn on or off auto-commit mode */
|
||||
PDO_ATTR_PREFETCH, /* configure the prefetch size for drivers that support it. Size is in KB */
|
||||
PDO_ATTR_TIMEOUT, /* connection timeout in seconds */
|
||||
PDO_ATTR_ERRMODE, /* control how errors are handled */
|
||||
PDO_ATTR_SERVER_VERSION, /* database server version */
|
||||
PDO_ATTR_CLIENT_VERSION, /* client library version */
|
||||
PDO_ATTR_SERVER_INFO, /* server information */
|
||||
PDO_ATTR_CONNECTION_STATUS, /* connection status */
|
||||
PDO_ATTR_CASE, /* control case folding for portability */
|
||||
PDO_ATTR_CURSOR_NAME, /* name a cursor for use in "WHERE CURRENT OF <name>" */
|
||||
PDO_ATTR_CURSOR, /* cursor type */
|
||||
PDO_ATTR_ORACLE_NULLS, /* convert empty strings to NULL */
|
||||
PDO_ATTR_PERSISTENT, /* pconnect style connection */
|
||||
PDO_ATTR_STATEMENT_CLASS, /* array(classname, array(ctor_args)) to specify the class of the constructed statement */
|
||||
|
||||
/* this defines the start of the range for driver specific options.
|
||||
* Drivers should define their own attribute constants beginning with this
|
||||
* value. */
|
||||
PDO_ATTR_DRIVER_SPECIFIC = 1000
|
||||
};
|
||||
|
||||
enum pdo_cursor_type {
|
||||
PDO_CURSOR_FWDONLY, /* forward only cursor (default) */
|
||||
PDO_CURSOR_SCROLL, /* scrollable cursor */
|
||||
};
|
||||
|
||||
/* SQL-92 SQLSTATE error codes.
|
||||
|
||||
The character string value returned for an SQLSTATE consists of a two-character
|
||||
class value followed by a three-character subclass value. A class value of 01
|
||||
indicates a warning and is accompanied by a return code of
|
||||
SQL_SUCCESS_WITH_INFO.
|
||||
|
||||
Class values other than '01', except for the class 'IM',
|
||||
indicate an error and are accompanied by a return code of SQL_ERROR. The class
|
||||
'IM' is specific to warnings and errors that derive from the implementation of
|
||||
ODBC itself.
|
||||
|
||||
The subclass value '000' in any class indicates that there is no
|
||||
subclass for that SQLSTATE. The assignment of class and subclass values is
|
||||
defined by SQL-92.
|
||||
*/
|
||||
|
||||
typedef char pdo_error_type[6]; /* SQLSTATE */
|
||||
|
||||
|
||||
#define PDO_ERR_NONE "00000"
|
||||
#if 0
|
||||
/* generic error code values.
|
||||
* Don't want to go overboard with these.
|
||||
* */
|
||||
#define PDO_ERR_SYNTAX "42000"
|
||||
#define PDO_ERR_CONSTRAINT "23000"
|
||||
#define PDO_ERR_NOT_FOUND ""
|
||||
#define PDO_ERR_ALREADY_EXISTS,
|
||||
#define PDO_ERR_NOT_IMPLEMENTED,
|
||||
#define PDO_ERR_MISMATCH,
|
||||
#define PDO_ERR_TRUNCATED,
|
||||
#define PDO_ERR_DISCONNECTED,
|
||||
#define PDO_ERR_NO_PERM,
|
||||
|
||||
PDO_ERR_CANT_MAP, /* no way to map native error to the generic
|
||||
* codes; consult the native error for more info */
|
||||
};
|
||||
#endif
|
||||
|
||||
enum pdo_error_mode {
|
||||
PDO_ERRMODE_SILENT, /* just set error codes */
|
||||
PDO_ERRMODE_WARNING, /* raise E_WARNING */
|
||||
PDO_ERRMODE_EXCEPTION, /* throw exceptions */
|
||||
};
|
||||
|
||||
enum pdo_case_conversion {
|
||||
PDO_CASE_NATURAL,
|
||||
PDO_CASE_UPPER,
|
||||
PDO_CASE_LOWER
|
||||
};
|
||||
|
||||
/* {{{ utils for reading attributes set as driver_options */
|
||||
static inline long pdo_attr_lval(zval *options, enum pdo_fetch_type option_name, long defval TSRMLS_DC)
|
||||
{
|
||||
zval **v;
|
||||
|
||||
if (options && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), option_name, (void**)&v)) {
|
||||
convert_to_long_ex(v);
|
||||
return Z_LVAL_PP(v);
|
||||
}
|
||||
return defval;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* This structure is registered with PDO when a PDO driver extension is
|
||||
* initialized */
|
||||
typedef struct {
|
||||
const char *driver_name;
|
||||
unsigned long driver_name_len;
|
||||
unsigned long api_version; /* needs to be compatible with PDO */
|
||||
|
||||
#define PDO_DRIVER_HEADER(name) \
|
||||
#name, sizeof(#name)-1, \
|
||||
PDO_DRIVER_API
|
||||
|
||||
/* create driver specific portion of the database handle and stash it into
|
||||
* the dbh. dbh contains the data source string and flags for this
|
||||
* instance. You MUST respect dbh->is_persistent and pass that flag to
|
||||
* pemalloc() for all allocations that are stored in the dbh or your instance
|
||||
* data in the db, otherwise you will crash PHP when persistent connections
|
||||
* are used.
|
||||
*/
|
||||
int (*db_handle_factory)(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC);
|
||||
|
||||
} pdo_driver_t;
|
||||
|
||||
/* {{{ methods for a database handle */
|
||||
|
||||
/* close or otherwise disconnect the database */
|
||||
typedef int (*pdo_dbh_close_func)(pdo_dbh_t *dbh TSRMLS_DC);
|
||||
|
||||
/* prepare a statement and stash driver specific portion into stmt */
|
||||
typedef int (*pdo_dbh_prepare_func)(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC);
|
||||
|
||||
/* execute a statement (that does not return a result set) */
|
||||
typedef long (*pdo_dbh_do_func)(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC);
|
||||
|
||||
/* quote a string */
|
||||
typedef int (*pdo_dbh_quote_func)(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype TSRMLS_DC);
|
||||
|
||||
/* transaction related */
|
||||
typedef int (*pdo_dbh_txn_func)(pdo_dbh_t *dbh TSRMLS_DC);
|
||||
|
||||
/* setting of attributes */
|
||||
typedef int (*pdo_dbh_set_attr_func)(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC);
|
||||
|
||||
/* return last insert id. NULL indicates error condition, otherwise, the return value
|
||||
* MUST be an emalloc'd NULL terminated string. */
|
||||
typedef char *(*pdo_dbh_last_id_func)(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC);
|
||||
|
||||
/* fetch error information. if stmt is not null, fetch information pertaining
|
||||
* to the statement, otherwise fetch global error information. The driver
|
||||
* should add the following information to the array "info" in this order:
|
||||
* - native error code
|
||||
* - string representation of the error code ... any other optional driver
|
||||
* specific data ... */
|
||||
typedef int (*pdo_dbh_fetch_error_func)(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC);
|
||||
|
||||
/* fetching of attributes */
|
||||
typedef int (*pdo_dbh_get_attr_func)(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC);
|
||||
|
||||
/* checking/pinging persistent connections; return SUCCESS if the connection
|
||||
* is still alive and ready to be used, FAILURE otherwise.
|
||||
* You may set this handler to NULL, which is equivalent to returning SUCCESS. */
|
||||
typedef int (*pdo_dbh_check_liveness_func)(pdo_dbh_t *dbh TSRMLS_DC);
|
||||
|
||||
/* 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
|
||||
reduce the chance of collisions with future functionality in the
|
||||
PDO class or in user code (they can extend the PDO object).
|
||||
*/
|
||||
enum {
|
||||
PDO_DBH_DRIVER_METHOD_KIND_DBH = 0,
|
||||
PDO_DBH_DRIVER_METHOD_KIND_STMT,
|
||||
PDO_DBH_DRIVER_METHOD_KIND__MAX
|
||||
};
|
||||
|
||||
typedef function_entry *(*pdo_dbh_get_driver_methods_func)(pdo_dbh_t *dbh, int kind TSRMLS_DC);
|
||||
|
||||
struct pdo_dbh_methods {
|
||||
pdo_dbh_close_func closer;
|
||||
pdo_dbh_prepare_func preparer;
|
||||
pdo_dbh_do_func doer;
|
||||
pdo_dbh_quote_func quoter;
|
||||
pdo_dbh_txn_func begin;
|
||||
pdo_dbh_txn_func commit;
|
||||
pdo_dbh_txn_func rollback;
|
||||
pdo_dbh_set_attr_func set_attribute;
|
||||
pdo_dbh_last_id_func last_id;
|
||||
pdo_dbh_fetch_error_func fetch_err;
|
||||
pdo_dbh_get_attr_func get_attribute;
|
||||
pdo_dbh_check_liveness_func check_liveness;
|
||||
pdo_dbh_get_driver_methods_func get_driver_methods;
|
||||
};
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ methods for a statement handle */
|
||||
|
||||
/* free the statement handle */
|
||||
typedef int (*pdo_stmt_dtor_func)(pdo_stmt_t *stmt TSRMLS_DC);
|
||||
|
||||
/* start the query */
|
||||
typedef int (*pdo_stmt_execute_func)(pdo_stmt_t *stmt TSRMLS_DC);
|
||||
|
||||
/* causes the next row in the set to be fetched; indicates if there are no
|
||||
* more rows. The ori and offset params modify which row should be returned,
|
||||
* if the stmt represents a scrollable cursor */
|
||||
typedef int (*pdo_stmt_fetch_func)(pdo_stmt_t *stmt,
|
||||
enum pdo_fetch_orientation ori, long offset TSRMLS_DC);
|
||||
|
||||
/* queries information about the type of a column, by index (0 based).
|
||||
* Driver should populate stmt->columns[colno] with appropriate info */
|
||||
typedef int (*pdo_stmt_describe_col_func)(pdo_stmt_t *stmt, int colno TSRMLS_DC);
|
||||
|
||||
/* retrieves pointer and size of the value for a column.
|
||||
* Note that PDO expects the driver to manage the lifetime of this data;
|
||||
* it will copy the value into a zval on behalf of the script.
|
||||
* If the driver sets caller_frees, ptr should point to emalloc'd memory
|
||||
* and PDO will free it as soon as it is done using it.
|
||||
*/
|
||||
typedef int (*pdo_stmt_get_col_data_func)(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC);
|
||||
|
||||
/* hook for bound params */
|
||||
enum pdo_param_event {
|
||||
PDO_PARAM_EVT_ALLOC,
|
||||
PDO_PARAM_EVT_FREE,
|
||||
PDO_PARAM_EVT_EXEC_PRE,
|
||||
PDO_PARAM_EVT_EXEC_POST,
|
||||
PDO_PARAM_EVT_FETCH_PRE,
|
||||
PDO_PARAM_EVT_FETCH_POST,
|
||||
};
|
||||
|
||||
typedef int (*pdo_stmt_param_hook_func)(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, enum pdo_param_event event_type TSRMLS_DC);
|
||||
|
||||
/* setting of attributes */
|
||||
typedef int (*pdo_stmt_set_attr_func)(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC);
|
||||
|
||||
/* fetching of attributes */
|
||||
typedef int (*pdo_stmt_get_attr_func)(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC);
|
||||
|
||||
/* retrieves meta data for a numbered column.
|
||||
* Returns SUCCESS/FAILURE.
|
||||
* On SUCCESS, fill in return_value with an array with the following fields.
|
||||
* If a particular field is not supported, then the driver simply does not add it to
|
||||
* the array, so that scripts can use isset() to check for it.
|
||||
*
|
||||
* ### this is just a rough first cut, and subject to change ###
|
||||
*
|
||||
* these are added by PDO itself, based on data from the describe handler:
|
||||
* name => the column name
|
||||
* len => the length/size of the column
|
||||
* precision => precision of the column
|
||||
* pdo_type => an integer, one of the PDO_PARAM_XXX values
|
||||
*
|
||||
* scale => the floating point scale
|
||||
* table => the table for that column
|
||||
* type => a string representation of the type, mapped to the PHP equivalent type name
|
||||
* native_type => a string representation of the type, native style, if different from
|
||||
* the mapped name.
|
||||
* flags => an array of flags including zero or more of the following:
|
||||
* primary_key, not_null, unique_key, multiple_key, unsigned, auto_increment, blob
|
||||
*
|
||||
* Any driver specific data should be returned using a prefixed key or value.
|
||||
* Eg: custom data for the mysql driver would use either
|
||||
* 'mysql:foobar' => 'some data' // to add a new key to the array
|
||||
* or
|
||||
* 'flags' => array('not_null', 'mysql:some_flag'); // to add data to an existing key
|
||||
*/
|
||||
typedef int (*pdo_stmt_get_column_meta_func)(pdo_stmt_t *stmt, long colno, zval *return_value TSRMLS_DC);
|
||||
|
||||
/* advances the statement to the next rowset of the batch.
|
||||
* If it returns 1, PDO will tear down its idea of columns
|
||||
* and meta data. If it returns 0, PDO will indicate an error
|
||||
* to the caller. */
|
||||
typedef int (*pdo_stmt_next_rowset_func)(pdo_stmt_t *stmt TSRMLS_DC);
|
||||
|
||||
struct pdo_stmt_methods {
|
||||
pdo_stmt_dtor_func dtor;
|
||||
pdo_stmt_execute_func executer;
|
||||
pdo_stmt_fetch_func fetcher;
|
||||
pdo_stmt_describe_col_func describer;
|
||||
pdo_stmt_get_col_data_func get_col;
|
||||
pdo_stmt_param_hook_func param_hook;
|
||||
pdo_stmt_set_attr_func set_attribute;
|
||||
pdo_stmt_get_attr_func get_attribute;
|
||||
pdo_stmt_get_column_meta_func get_column_meta;
|
||||
pdo_stmt_next_rowset_func next_rowset;
|
||||
};
|
||||
|
||||
/* }}} */
|
||||
|
||||
enum pdo_placeholder_support {
|
||||
PDO_PLACEHOLDER_NONE=0,
|
||||
PDO_PLACEHOLDER_NAMED=1,
|
||||
PDO_PLACEHOLDER_POSITIONAL=2
|
||||
};
|
||||
|
||||
/* represents a connection to a database */
|
||||
struct _pdo_dbh_t {
|
||||
/* these items must appear in this order at the beginning of the
|
||||
struct so that this can be cast as a zend_object. we need this
|
||||
to allow the extending class to escape all the custom handlers
|
||||
that PDO declares.
|
||||
*/
|
||||
zend_class_entry *ce;
|
||||
HashTable *properties;
|
||||
unsigned int in_get:1;
|
||||
unsigned int in_set:1;
|
||||
|
||||
/* driver specific methods */
|
||||
struct pdo_dbh_methods *methods;
|
||||
/* driver specific data */
|
||||
void *driver_data;
|
||||
|
||||
/* credentials */
|
||||
char *username, *password;
|
||||
|
||||
/* if true, then data stored and pointed at by this handle must all be
|
||||
* persistently allocated */
|
||||
unsigned is_persistent:1;
|
||||
|
||||
/* if true, driver should act as though a COMMIT were executed between
|
||||
* each executed statement; otherwise, COMMIT must be carried out manually
|
||||
* */
|
||||
unsigned auto_commit:1;
|
||||
|
||||
/* if true, the handle has been closed and will not function anymore */
|
||||
unsigned is_closed:1;
|
||||
|
||||
/* if true, the driver requires that memory be allocated explicitly for
|
||||
* the columns that are returned */
|
||||
unsigned alloc_own_columns:1;
|
||||
|
||||
/* if true, commit or rollBack is allowed to be called */
|
||||
unsigned in_txn:1;
|
||||
|
||||
/* max length a single character can become after correct quoting */
|
||||
unsigned max_escaped_char_length:3;
|
||||
|
||||
/* when set, convert empty strings to NULL */
|
||||
unsigned oracle_nulls:1;
|
||||
|
||||
/* the sum of the number of bits here and the bit fields preceeding should
|
||||
* equal 32 */
|
||||
unsigned _reserved_flags:23;
|
||||
|
||||
/* data source string used to open this handle */
|
||||
const char *data_source;
|
||||
unsigned long data_source_len;
|
||||
|
||||
/* the global error code. */
|
||||
pdo_error_type error_code;
|
||||
|
||||
enum pdo_error_mode error_mode;
|
||||
|
||||
enum pdo_case_conversion native_case, desired_case;
|
||||
|
||||
/* persistent hash key associated with this handle */
|
||||
const char *persistent_id;
|
||||
int persistent_id_len;
|
||||
unsigned int refcount;
|
||||
|
||||
/* driver specific "class" methods for the dbh and stmt */
|
||||
HashTable *cls_methods[PDO_DBH_DRIVER_METHOD_KIND__MAX];
|
||||
};
|
||||
|
||||
/* describes a column */
|
||||
struct pdo_column_data {
|
||||
char *name;
|
||||
long namelen;
|
||||
unsigned long maxlen;
|
||||
enum pdo_param_type param_type;
|
||||
unsigned long precision;
|
||||
|
||||
/* don't touch this unless your name is dbdo */
|
||||
void *dbdo_stuff;
|
||||
};
|
||||
|
||||
/* describes a bound parameter */
|
||||
struct pdo_bound_param_data {
|
||||
long paramno; /* if -1, then it has a name, and we don't know the index *yet* */
|
||||
char *name;
|
||||
long namelen;
|
||||
|
||||
long max_value_len; /* as a hint for pre-allocation */
|
||||
|
||||
zval *parameter; /* the variable itself */
|
||||
enum pdo_param_type param_type; /* desired or suggested type */
|
||||
|
||||
zval *driver_params; /* optional parameter(s) for the driver */
|
||||
void *driver_data;
|
||||
|
||||
pdo_stmt_t *stmt; /* for convenience in dtor */
|
||||
int is_param; /* parameter or column ? */
|
||||
};
|
||||
|
||||
/* represents a prepared statement */
|
||||
struct _pdo_stmt_t {
|
||||
/* these items must appear in this order at the beginning of the
|
||||
struct so that this can be cast as a zend_object. we need this
|
||||
to allow the extending class to escape all the custom handlers
|
||||
that PDO declares.
|
||||
*/
|
||||
zend_class_entry *ce;
|
||||
HashTable *properties;
|
||||
unsigned int in_get:1;
|
||||
unsigned int in_set:1;
|
||||
|
||||
/* driver specifics */
|
||||
struct pdo_stmt_methods *methods;
|
||||
void *driver_data;
|
||||
|
||||
/* if true, we've already successfully executed this statement at least
|
||||
* once */
|
||||
unsigned executed:1;
|
||||
/* if true, the statement supports placeholders and can implement
|
||||
* bindParam() for its prepared statements, if false, PDO should
|
||||
* emulate prepare and bind on its behalf */
|
||||
unsigned supports_placeholders:2;
|
||||
|
||||
unsigned _reserved:29;
|
||||
|
||||
/* the number of columns in the result set; not valid until after
|
||||
* the statement has been executed at least once. In some cases, might
|
||||
* not be valid until fetch (at the driver level) has been called at least once.
|
||||
* */
|
||||
int column_count;
|
||||
struct pdo_column_data *columns;
|
||||
|
||||
/* we want to keep the dbh alive while we live, so we own a reference */
|
||||
zval database_object_handle;
|
||||
pdo_dbh_t *dbh;
|
||||
|
||||
/* keep track of bound input parameters. Some drivers support
|
||||
* input/output parameters, but you can't rely on that working */
|
||||
HashTable *bound_params;
|
||||
/* When rewriting from named to positional, this maps positions to names */
|
||||
HashTable *bound_param_map;
|
||||
/* keep track of PHP variables bound to named (or positional) columns
|
||||
* in the result set */
|
||||
HashTable *bound_columns;
|
||||
|
||||
/* not always meaningful */
|
||||
long row_count;
|
||||
|
||||
/* used to hold the statement's current query */
|
||||
char *query_string;
|
||||
int query_stringlen;
|
||||
|
||||
/* the copy of the query with expanded binds ONLY for emulated-prepare drivers */
|
||||
char *active_query_string;
|
||||
int active_query_stringlen;
|
||||
|
||||
/* the cursor specific error code. */
|
||||
pdo_error_type error_code;
|
||||
|
||||
/* for lazy fetches, we always return the same lazy object handle.
|
||||
* 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; /* freed */
|
||||
zval *retval_ptr;
|
||||
zend_fcall_info fci;
|
||||
zend_fcall_info_cache fcc;
|
||||
} cls;
|
||||
struct {
|
||||
zval *function;
|
||||
zval *fetch_args; /* freed */
|
||||
zval *object;
|
||||
zend_fcall_info fci;
|
||||
zend_fcall_info_cache fcc;
|
||||
zval **values; /* freed */
|
||||
} func;
|
||||
zval *into;
|
||||
} fetch;
|
||||
};
|
||||
|
||||
/* call this in MINIT to register your PDO driver */
|
||||
PDO_API int php_pdo_register_driver(pdo_driver_t *driver);
|
||||
/* call this in MSHUTDOWN to unregister your PDO driver */
|
||||
PDO_API void php_pdo_unregister_driver(pdo_driver_t *driver);
|
||||
|
||||
/* For the convenience of drivers, this function will parse a data source
|
||||
* string, of the form "name=value; name2=value2" and populate variables
|
||||
* according to the data you pass in and array of pdo_data_src_parser structures */
|
||||
struct pdo_data_src_parser {
|
||||
const char *optname;
|
||||
char *optval;
|
||||
int freeme;
|
||||
};
|
||||
|
||||
PDO_API int php_pdo_parse_data_source(const char *data_source,
|
||||
unsigned long data_source_len, struct pdo_data_src_parser *parsed,
|
||||
int nparams);
|
||||
|
||||
PDO_API zend_class_entry *php_pdo_get_exception(void);
|
||||
|
||||
PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
|
||||
char **outquery, int *outquery_len TSRMLS_DC);
|
||||
|
||||
#endif /* PHP_PDO_DRIVER_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
|
||||
*/
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2005 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 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_0.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: Wez Furlong <wez@php.net> |
|
||||
| Marcus Boerger <helly@php.net> |
|
||||
| Sterling Hughes <sterling@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/* Stuff private to the PDO extension and not for consumption by PDO drivers
|
||||
* */
|
||||
extern zend_class_entry *pdo_exception_ce;
|
||||
int php_pdo_list_entry(void);
|
||||
|
||||
extern zend_object_value pdo_dbh_new(zend_class_entry *ce TSRMLS_DC);
|
||||
extern function_entry pdo_dbh_functions[];
|
||||
extern zend_class_entry *pdo_dbh_ce;
|
||||
extern ZEND_RSRC_DTOR_FUNC(php_pdo_pdbh_dtor);
|
||||
|
||||
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[];
|
||||
extern zend_class_entry *pdo_row_ce;
|
||||
void pdo_row_free_storage(zend_object *object TSRMLS_DC);
|
||||
extern zend_object_handlers pdo_row_object_handlers;
|
||||
|
||||
zend_object_iterator *php_pdo_dbstmt_iter_get(zend_class_entry *ce, zval *object TSRMLS_DC);
|
||||
|
||||
extern pdo_driver_t *pdo_find_driver(const char *name, int namelen);
|
||||
|
||||
extern void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC);
|
||||
extern void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *sqlstate, const char *supp TSRMLS_DC);
|
||||
|
||||
#define PDO_DBH_CLEAR_ERR() strcpy(dbh->error_code, PDO_ERR_NONE)
|
||||
#define PDO_STMT_CLEAR_ERR() strcpy(stmt->error_code, PDO_ERR_NONE)
|
||||
#define PDO_HANDLE_DBH_ERR() if (strcmp(dbh->error_code, PDO_ERR_NONE)) { pdo_handle_error(dbh, NULL TSRMLS_CC); }
|
||||
#define PDO_HANDLE_STMT_ERR() if (strcmp(stmt->error_code, PDO_ERR_NONE)) { pdo_handle_error(stmt->dbh, stmt TSRMLS_CC); }
|
||||
|
||||
int pdo_sqlstate_init_error_table(void);
|
||||
void pdo_sqlstate_fini_error_table(void);
|
||||
const char *pdo_sqlstate_state_to_description(char *state);
|
||||
int pdo_hash_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC);
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
Reference in new issue
Block a user