mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-10 02:30:50 +00:00
Compare commits
2
Commits
php-7.2.11
...
php-5.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c1949d4e7 | ||
|
|
8091552925 |
No files matched your search
@@ -1,166 +1,3 @@
|
||||
2004-07-14 Edin Kadribasic <edink@emini.dk>
|
||||
|
||||
* (PHP_4_3)
|
||||
sapi/cgi/cgi_main.c
|
||||
sapi/cli/php_cli.c:
|
||||
MFH: Made php -m output sorted case-insensitevly
|
||||
|
||||
* sapi/cgi/cgi_main.c
|
||||
sapi/cli/php_cli.c:
|
||||
Made php -m output sorted case-insensitevly
|
||||
|
||||
2004-07-14 Stefan Esser <sesser@suspekt.org>
|
||||
|
||||
* (PHP_4_3)
|
||||
ext/standard/tests/strings/strip_tags.phpt:
|
||||
Ups... CAN-2004-0595 regression test went into wrong branch...
|
||||
|
||||
* (PHP_4_3_7)
|
||||
ext/standard/tests/strings/strip_tags.phpt:
|
||||
Add CAN-2004-0595 regression test. (modified from Joe Ortons version)
|
||||
|
||||
* sapi/apache_hooks/mod_php5.c:
|
||||
same bug.
|
||||
|
||||
2004-07-14 Derick Rethans <php@derickrethans.nl>
|
||||
|
||||
* ext/iconv/config.m4:
|
||||
- Fixed text.
|
||||
|
||||
2004-07-14 Stefan Esser <sesser@suspekt.org>
|
||||
|
||||
* sapi/apache/mod_php5.c:
|
||||
Security Fix broken! Destroyed Basic auth. Blame: me
|
||||
4.3.x not affected
|
||||
|
||||
2004-07-14 Stanislav Malyshev <stas@zend.com>
|
||||
|
||||
* ZendEngine2/zend_object_handlers.c:
|
||||
be consistent with write_dimension
|
||||
|
||||
* ZendEngine2/zend_object_handlers.c:
|
||||
fix #28957
|
||||
|
||||
2004-07-14 Sara Golemon <php@alphaweb.net>
|
||||
|
||||
* NEWS
|
||||
ext/bcmath/bcmath.c
|
||||
ext/bcmath/php_bcmath.h:
|
||||
Bugfix# 28829 bcmath values for 0, 1, and 2 initialized/freed at wrong time
|
||||
for threaded sapis.
|
||||
|
||||
2004-07-13 Andi Gutmans <andi@zend.com>
|
||||
|
||||
* NEWS
|
||||
configure.in
|
||||
ZendEngine2/zend.h
|
||||
main/php_version.h:
|
||||
- 5.0.1-dev
|
||||
|
||||
2004-07-13 Marcus Boerger <marcus.boerger@post.rwth-aachen.de>
|
||||
|
||||
* (PHP_4_3)
|
||||
NEWS
|
||||
NEWS:
|
||||
BFN
|
||||
|
||||
* ZendEngine2/zend_constants.c:
|
||||
Bugfix #29116 Zend constant warning uses memory after free (jdolecek at
|
||||
NetBSD dot org)
|
||||
|
||||
2004-07-13 Andi Gutmans <andi@zend.com>
|
||||
|
||||
* (php_5_0_0)
|
||||
NEWS
|
||||
configure.in
|
||||
ZendEngine2/zend.h
|
||||
main/php_version.h:
|
||||
- Roll PHP 5.0.0
|
||||
|
||||
2004-07-13 Wez Furlong <wez.php@thebrainroom.net>
|
||||
|
||||
* (php_5_0_0)
|
||||
ext/standard/html.c:
|
||||
add missing break
|
||||
|
||||
2004-07-13 Georg Richter <georg@mysql.com>
|
||||
|
||||
* (php_5_0_0)
|
||||
ext/mysqli/mysqli_api.c:
|
||||
prototype fixes
|
||||
|
||||
2004-07-13 Wez Furlong <wez.php@thebrainroom.net>
|
||||
|
||||
* (php_5_0_0)
|
||||
main/streams/streams.c:
|
||||
Looks like Sara forgot to change this too.
|
||||
|
||||
2004-07-13 Georg Richter <georg@mysql.com>
|
||||
|
||||
* ext/mysqli/mysqli_api.c:
|
||||
changed mysqli_stmt_reset (returns now bool instead of void)
|
||||
|
||||
2004-07-13 Ilia Alshanetsky <ilia@prohost.org>
|
||||
|
||||
* (PHP_4_3_7)
|
||||
NEWS
|
||||
configure.in
|
||||
Zend/zend_alloc.c
|
||||
Zend/zend_constants.c
|
||||
Zend/zend_execute.c
|
||||
Zend/zend_hash.c
|
||||
Zend/zend_variables.c
|
||||
ext/imap/php_imap.c
|
||||
ext/msession/msession.c
|
||||
ext/mssql/php_mssql.c
|
||||
ext/mysql/php_mysql.c
|
||||
ext/pcntl/pcntl.c
|
||||
ext/session/mod_mm.c
|
||||
ext/session/session.c
|
||||
ext/standard/ftok.c
|
||||
ext/standard/iptc.c
|
||||
ext/standard/string.c
|
||||
ext/sybase/php_sybase_db.c
|
||||
ext/sybase_ct/php_sybase_ct.c
|
||||
ext/w32api/w32api.c
|
||||
ext/wddx/wddx.c
|
||||
main/main.c
|
||||
main/php_version.h
|
||||
main/rfc1867.c:
|
||||
4.3.8 patches.
|
||||
|
||||
2004-07-13 Derick Rethans <php@derickrethans.nl>
|
||||
|
||||
* (PHP_4_3_7)
|
||||
main/php_version.h:
|
||||
- Fixed typo
|
||||
|
||||
* (PHP_4_3)
|
||||
configure.in
|
||||
main/php_version.h:
|
||||
- Bump version numbers in the PHP_4_3 branch.
|
||||
|
||||
* (PHP_4_3_7)
|
||||
configure.in
|
||||
main/php_version.h:
|
||||
- Create a branch PHP_4_3_7 based on php 4.3.7 to form 4.3.8
|
||||
- Updated version numbers in branch
|
||||
|
||||
2004-07-13 Stefan Esser <sesser@suspekt.org>
|
||||
|
||||
* (php_5_0_0)
|
||||
tests/lang/038.phpt:
|
||||
Fixed typo
|
||||
|
||||
2004-07-13 Alan Knowles <alan@akbkhome.com>
|
||||
|
||||
* (php_5_0_0)
|
||||
tests/lang/039.phpt:
|
||||
remove test dependance on postgres ** this still fails however
|
||||
|
||||
* tests/lang/038.phpt:
|
||||
ensure that test passes on systems without postgres built in.
|
||||
|
||||
2004-07-12 Ilia Alshanetsky <ilia@prohost.org>
|
||||
|
||||
* (PHP_4_3)
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
PHP NEWS
|
||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
?? ??? 2004, PHP 5.0.1
|
||||
- Fixed bug #28829 (Thread-unsafety in bcmath elementary values). (Sara)
|
||||
|
||||
13 Jul 2004, PHP 5.0.0
|
||||
- Updated PCRE to provide better error handling in certain cases. (Andrei)
|
||||
- Changed doc comments to require a single white space after '/**'. (Marcus)
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
2004-07-14 Stanislav Malyshev <stas@zend.com>
|
||||
|
||||
* zend_object_handlers.c:
|
||||
be consistent with write_dimension
|
||||
|
||||
* zend_object_handlers.c:
|
||||
fix #28957
|
||||
|
||||
2004-07-13 Andi Gutmans <andi@zend.com>
|
||||
|
||||
* zend.h:
|
||||
- 5.0.1-dev
|
||||
|
||||
2004-07-13 Marcus Boerger <marcus.boerger@post.rwth-aachen.de>
|
||||
|
||||
* zend_constants.c:
|
||||
Bugfix #29116 Zend constant warning uses memory after free (jdolecek at
|
||||
NetBSD dot org)
|
||||
|
||||
2004-07-13 Andi Gutmans <andi@zend.com>
|
||||
|
||||
* (php_5_0_0)
|
||||
zend.h:
|
||||
- Roll PHP 5.0.0
|
||||
|
||||
2004-07-12 Ilia Alshanetsky <ilia@prohost.org>
|
||||
|
||||
* (php_5_0_0RC4)
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@
|
||||
#ifndef ZEND_H
|
||||
#define ZEND_H
|
||||
|
||||
#define ZEND_VERSION "2.0.1-dev"
|
||||
#define ZEND_VERSION "2.0.0"
|
||||
|
||||
#define ZEND_ENGINE_2
|
||||
|
||||
|
||||
@@ -317,11 +317,11 @@ ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)
|
||||
}
|
||||
|
||||
if (zend_hash_add(EG(zend_constants), name, c->name_len, (void *) c, sizeof(zend_constant), NULL)==FAILURE) {
|
||||
zend_error(E_NOTICE,"Constant %s already defined", name);
|
||||
free(c->name);
|
||||
if (!(c->flags & CONST_PERSISTENT)) {
|
||||
zval_dtor(&c->value);
|
||||
}
|
||||
zend_error(E_NOTICE,"Constant %s already defined", name);
|
||||
ret = FAILURE;
|
||||
}
|
||||
if (lowercase_name) {
|
||||
|
||||
@@ -30,7 +30,7 @@ typedef struct _dynamic_array {
|
||||
} dynamic_array;
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
ZEND_API int zend_dynamic_array_init(dynamic_array *da, unsigned int element_size, unsigned int size);
|
||||
ZEND_API int zend_dynamic_array_init(dynamic_array *da);
|
||||
ZEND_API void *zend_dynamic_array_push(dynamic_array *da);
|
||||
ZEND_API void *zend_dynamic_array_pop(dynamic_array *da);
|
||||
ZEND_API void *zend_dynamic_array_get_element(dynamic_array *da, unsigned int index);
|
||||
|
||||
@@ -381,14 +381,7 @@ zval *zend_std_read_dimension(zval *object, zval *offset, int type TSRMLS_DC)
|
||||
zval *retval;
|
||||
|
||||
if (instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC)) {
|
||||
if(offset == NULL) {
|
||||
/* [] construct */
|
||||
zval offset_null;
|
||||
INIT_ZVAL(offset_null);
|
||||
offset = &offset_null;
|
||||
}
|
||||
zend_call_method_with_1_params(&object, ce, NULL, "offsetget", &retval, offset);
|
||||
|
||||
if (!retval) {
|
||||
if (!EG(exception)) {
|
||||
zend_error(E_ERROR, "Undefined offset for object of type %s used as array", ce->name);
|
||||
|
||||
+2
-2
@@ -40,8 +40,8 @@ AC_CONFIG_HEADER(main/php_config.h)
|
||||
|
||||
MAJOR_VERSION=5
|
||||
MINOR_VERSION=0
|
||||
RELEASE_VERSION=1
|
||||
EXTRA_VERSION="-dev"
|
||||
RELEASE_VERSION=0
|
||||
EXTRA_VERSION=""
|
||||
VERSION="$MAJOR_VERSION.$MINOR_VERSION.$RELEASE_VERSION$EXTRA_VERSION"
|
||||
|
||||
dnl Define where extension directories are located in the configure context
|
||||
|
||||
+8
-24
@@ -53,8 +53,8 @@ zend_module_entry bcmath_module_entry = {
|
||||
bcmath_functions,
|
||||
PHP_MINIT(bcmath),
|
||||
PHP_MSHUTDOWN(bcmath),
|
||||
PHP_RINIT(bcmath),
|
||||
PHP_RSHUTDOWN(bcmath),
|
||||
NULL,
|
||||
NULL,
|
||||
PHP_MINFO(bcmath),
|
||||
NO_VERSION_YET,
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
@@ -86,6 +86,8 @@ PHP_MINIT_FUNCTION(bcmath)
|
||||
|
||||
REGISTER_INI_ENTRIES();
|
||||
|
||||
bc_init_numbers(TSRMLS_C);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -94,33 +96,15 @@ PHP_MINIT_FUNCTION(bcmath)
|
||||
*/
|
||||
PHP_MSHUTDOWN_FUNCTION(bcmath)
|
||||
{
|
||||
_bc_free_num_ex(&BCG(_zero_), 1);
|
||||
_bc_free_num_ex(&BCG(_one_), 1);
|
||||
_bc_free_num_ex(&BCG(_two_), 1);
|
||||
|
||||
UNREGISTER_INI_ENTRIES();
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_RINIT_FUNCTION
|
||||
*/
|
||||
PHP_RINIT_FUNCTION(bcmath)
|
||||
{
|
||||
bc_init_numbers(TSRMLS_C);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_RSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_RSHUTDOWN_FUNCTION(bcmath)
|
||||
{
|
||||
_bc_free_num_ex(&BCG(_zero_), 1);
|
||||
_bc_free_num_ex(&BCG(_one_), 1);
|
||||
_bc_free_num_ex(&BCG(_two_), 1);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
|
||||
@@ -30,8 +30,6 @@ extern zend_module_entry bcmath_module_entry;
|
||||
|
||||
PHP_MINIT_FUNCTION(bcmath);
|
||||
PHP_MSHUTDOWN_FUNCTION(bcmath);
|
||||
PHP_RINIT_FUNCTION(bcmath);
|
||||
PHP_RSHUTDOWN_FUNCTION(bcmath);
|
||||
PHP_MINFO_FUNCTION(bcmath);
|
||||
|
||||
PHP_FUNCTION(bcadd);
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
enchant
|
||||
Pierre-Alain Joye, Ilia Alshanetsky
|
||||
@@ -1,36 +0,0 @@
|
||||
dnl
|
||||
dnl $Id$
|
||||
dnl
|
||||
|
||||
PHP_ARG_WITH(enchant,for ENCHANT support,
|
||||
[ --with-enchant[=DIR] Include enchant support.
|
||||
GNU Aspell version 1.1.3 or higher required.])
|
||||
|
||||
if test "$PHP_ENCHANT" != "no"; then
|
||||
PHP_NEW_EXTENSION(enchant, enchant.c, $ext_shared)
|
||||
if test "$PHP_ENCHANT" != "yes"; then
|
||||
ENCHANT_SEARCH_DIRS=$PHP_ENCHANT
|
||||
else
|
||||
ENCHANT_SEARCH_DIRS="/usr/local /usr"
|
||||
fi
|
||||
for i in $ENCHANT_SEARCH_DIRS; do
|
||||
if test -f $i/include/enchant/enchant.h; then
|
||||
ENCHANT_DIR=$i
|
||||
ENCHANT_INCDIR=$i/include/enchant
|
||||
elif test -f $i/include/enchant.h; then
|
||||
ENCHANT_DIR=$i
|
||||
ENCHANT_INCDIR=$i/include
|
||||
fi
|
||||
done
|
||||
|
||||
if test -z "$ENCHANT_DIR"; then
|
||||
AC_MSG_ERROR(Cannot find enchant)
|
||||
fi
|
||||
|
||||
ENCHANT_LIBDIR=$ENCHANT_DIR/lib
|
||||
|
||||
AC_DEFINE(HAVE_ENCHANT,1,[ ])
|
||||
PHP_SUBST(ENCHANT_SHARED_LIBADD)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(enchant, $ENCHANT_LIBDIR, ENCHANT_SHARED_LIBADD)
|
||||
PHP_ADD_INCLUDE($ENCHANT_INCDIR)
|
||||
fi
|
||||
@@ -1,9 +0,0 @@
|
||||
// $Id$
|
||||
// vim:ft=javascript
|
||||
|
||||
ARG_ENABLE("enchant", "Enchant Support", "no");
|
||||
|
||||
if (PHP_ENCHANT == "yes") {
|
||||
EXTENSION("enchant", "enchant.c");
|
||||
AC_DEFINE('HAVE_ENCHANT', 1, 'Have Enchant support', false);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
$tag = 'en_US';
|
||||
$r = enchant_broker_init();
|
||||
$bprovides = enchant_broker_describe($r);
|
||||
echo "Current broker provides the following backend(s):\n";
|
||||
print_r($bprovides);
|
||||
|
||||
|
||||
if (enchant_broker_dict_exists($r,$tag)) {
|
||||
$d = enchant_broker_request_dict($r, $tag);
|
||||
$dprovides = enchant_dict_describe($d);
|
||||
echo "dictionary $tag provides:\n";
|
||||
$spellerrors = enchant_dict_check($d, "soong");
|
||||
print_r($dprovides);
|
||||
echo "found $spellerrors spell errors\n";
|
||||
if ($spellerrors) {
|
||||
$suggs = enchant_dict_suggest($d, "soong");
|
||||
echo "Suggestions for 'soong':";
|
||||
print_r($suggs);
|
||||
}
|
||||
enchant_broker_free_dict($d);
|
||||
} else {
|
||||
}
|
||||
enchant_broker_free($r);
|
||||
?>
|
||||
@@ -1,731 +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 at through the world-wide-web at |
|
||||
| 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: Pierre-Alain Joye <paj@pearfr.org> |
|
||||
| Ilia Alshanetsky <ilia@prohost.org> |
|
||||
+----------------------------------------------------------------------+
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include "enchant.h"
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "php_enchant.h"
|
||||
|
||||
|
||||
typedef EnchantBroker * EnchantBrokerPtr;
|
||||
typedef struct _broker_struct enchant_broker;
|
||||
typedef struct _dict_struct enchant_dict;
|
||||
|
||||
typedef enchant_broker * enchant_brokerPtr;
|
||||
typedef enchant_dict * enchant_dictPtr;
|
||||
|
||||
typedef struct _broker_struct {
|
||||
EnchantBroker *pbroker;
|
||||
enchant_dict **dict;
|
||||
unsigned int dictcnt;
|
||||
zval *rsrc_id;
|
||||
} _enchant_broker;
|
||||
|
||||
typedef struct _dict_struct {
|
||||
unsigned int id;
|
||||
EnchantDict *pdict;
|
||||
enchant_broker *pbroker;
|
||||
zval *rsrc_id;
|
||||
enchant_dict *next;
|
||||
enchant_dict *prev;
|
||||
} _enchant_dict;
|
||||
|
||||
|
||||
/* True global resources - no need for thread safety here */
|
||||
static int le_enchant_broker;
|
||||
static int le_enchant_dict;
|
||||
|
||||
/* If you declare any globals in php_enchant.h uncomment this:*/
|
||||
/*ZEND_DECLARE_MODULE_GLOBALS(enchant)*/
|
||||
|
||||
/* {{{ enchant_functions[]
|
||||
*
|
||||
* Every user visible function must have an entry in enchant_functions[].
|
||||
*/
|
||||
function_entry enchant_functions[] = {
|
||||
PHP_FE(enchant_broker_init, NULL)
|
||||
PHP_FE(enchant_broker_free, NULL)
|
||||
PHP_FE(enchant_broker_get_error, NULL)
|
||||
PHP_FE(enchant_broker_request_dict, NULL)
|
||||
PHP_FE(enchant_broker_request_pwl_dict, NULL)
|
||||
PHP_FE(enchant_broker_free_dict, NULL)
|
||||
PHP_FE(enchant_broker_dict_exists, NULL)
|
||||
PHP_FE(enchant_broker_set_ordering, NULL)
|
||||
PHP_FE(enchant_broker_describe, NULL)
|
||||
PHP_FE(enchant_dict_check, NULL)
|
||||
PHP_FE(enchant_dict_suggest, NULL)
|
||||
PHP_FE(enchant_dict_add_to_personal, NULL)
|
||||
PHP_FE(enchant_dict_add_to_session, NULL)
|
||||
PHP_FE(enchant_dict_is_in_session, NULL)
|
||||
PHP_FE(enchant_dict_store_replacement, NULL)
|
||||
PHP_FE(enchant_dict_get_error, NULL)
|
||||
PHP_FE(enchant_dict_describe, NULL)
|
||||
PHP_FE(enchant_dict_quick_check, third_arg_force_ref)
|
||||
|
||||
{NULL, NULL, NULL} /* Must be the last line in enchant_functions[] */
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ enchant_module_entry
|
||||
*/
|
||||
zend_module_entry enchant_module_entry = {
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
STANDARD_MODULE_HEADER,
|
||||
#endif
|
||||
"enchant",
|
||||
enchant_functions,
|
||||
PHP_MINIT(enchant),
|
||||
PHP_MSHUTDOWN(enchant),
|
||||
NULL, /* Replace with NULL if there's nothing to do at request start */
|
||||
NULL, /* Replace with NULL if there's nothing to do at request end */
|
||||
PHP_MINFO(enchant),
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
"0.1", /* Replace with version number for your extension */
|
||||
#endif
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_ENCHANT
|
||||
ZEND_GET_MODULE(enchant)
|
||||
#endif
|
||||
|
||||
static void
|
||||
enumerate_providers_fn (const char * const name,
|
||||
const char * const desc,
|
||||
const char * const file,
|
||||
void * ud)
|
||||
{
|
||||
zval *zdesc = (zval *) ud;
|
||||
zval *tmp_array;
|
||||
|
||||
MAKE_STD_ZVAL(tmp_array);
|
||||
array_init(tmp_array);
|
||||
|
||||
add_assoc_string(tmp_array, "name", (char *)name, 1);
|
||||
add_assoc_string(tmp_array, "desc", (char *)desc, 1);
|
||||
add_assoc_string(tmp_array, "file", (char *)file, 1);
|
||||
|
||||
if (Z_TYPE_P(zdesc)!=IS_ARRAY) {
|
||||
array_init(zdesc);
|
||||
}
|
||||
|
||||
add_next_index_zval(zdesc, tmp_array);
|
||||
}
|
||||
|
||||
static void
|
||||
describe_dict_fn (const char * const lang,
|
||||
const char * const name,
|
||||
const char * const desc,
|
||||
const char * const file,
|
||||
void * ud)
|
||||
{
|
||||
zval *zdesc = (zval *) ud;
|
||||
array_init(zdesc);
|
||||
add_assoc_string(zdesc, "lang", (char *)lang, 1);
|
||||
add_assoc_string(zdesc, "name", (char *)name, 1);
|
||||
add_assoc_string(zdesc, "desc", (char *)desc, 1);
|
||||
add_assoc_string(zdesc, "file", (char *)file, 1);
|
||||
}
|
||||
|
||||
static void php_enchant_broker_free(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
||||
{
|
||||
if (rsrc->ptr) {
|
||||
enchant_broker *broker = (enchant_broker *)rsrc->ptr;
|
||||
if (broker) {
|
||||
if (broker->pbroker) {
|
||||
if (broker->dictcnt && broker->dict) {
|
||||
if (broker->dict) {
|
||||
int total, tofree;
|
||||
tofree = total = broker->dictcnt-1;
|
||||
do {
|
||||
zend_list_delete(Z_RESVAL_P(broker->dict[total]->rsrc_id));
|
||||
efree(broker->dict[total]);
|
||||
total--;
|
||||
} while (total>=0);
|
||||
}
|
||||
efree(broker->dict);
|
||||
broker->dict = NULL;
|
||||
}
|
||||
enchant_broker_free(broker->pbroker);
|
||||
}
|
||||
efree(broker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void php_enchant_dict_free(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
||||
{
|
||||
if (rsrc->ptr) {
|
||||
enchant_dict *pdict = (enchant_dict *)rsrc->ptr;
|
||||
if (pdict) {
|
||||
if (pdict->pdict && pdict->pbroker) {
|
||||
enchant_broker_free_dict(pdict->pbroker->pbroker, pdict->pdict);
|
||||
}
|
||||
if (pdict->id) {
|
||||
pdict->pbroker->dict[pdict->id-1]->next = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION
|
||||
*/
|
||||
PHP_MINIT_FUNCTION(enchant)
|
||||
{
|
||||
le_enchant_broker = zend_register_list_destructors_ex(php_enchant_broker_free, NULL, "enchant broker", module_number);
|
||||
le_enchant_dict = zend_register_list_destructors_ex(php_enchant_dict_free, NULL, "enchant dict", module_number);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_MSHUTDOWN_FUNCTION(enchant)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
static void __enumerate_providers_fn (const char * const name,
|
||||
const char * const desc,
|
||||
const char * const file,
|
||||
void * ud)
|
||||
{
|
||||
php_info_print_table_row(3, name, desc, file);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
PHP_MINFO_FUNCTION(enchant)
|
||||
{
|
||||
EnchantBroker *pbroker;
|
||||
|
||||
pbroker = enchant_broker_init();
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "enchant support", "enabled");
|
||||
php_info_print_table_row(2, "Version", "@version@");
|
||||
php_info_print_table_row(2, "Revision", "$Revision$");
|
||||
php_info_print_table_end();
|
||||
|
||||
php_info_print_table_start();
|
||||
enchant_broker_describe(pbroker, __enumerate_providers_fn, NULL);
|
||||
php_info_print_table_end();
|
||||
enchant_broker_free(pbroker);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#define PHP_ENCHANT_GET_BROKER \
|
||||
ZEND_FETCH_RESOURCE(pbroker, enchant_broker *, &broker, -1, "enchant_broker", le_enchant_broker); \
|
||||
if (!pbroker || !pbroker->pbroker) { \
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", "Resource broker invalid"); \
|
||||
RETURN_FALSE; \
|
||||
}
|
||||
|
||||
#define PHP_ENCHANT_GET_DICT \
|
||||
ZEND_FETCH_RESOURCE(pdict, enchant_dict *, &dict, -1, "enchant dict", le_enchant_dict); \
|
||||
if (!pdict || !pdict->pdict) { \
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", "Invalid dictionary resource."); \
|
||||
RETURN_FALSE; \
|
||||
}
|
||||
|
||||
/* {{{ proto resource enchant_broker_init()
|
||||
create a new broker object capable of requesting */
|
||||
PHP_FUNCTION(enchant_broker_init)
|
||||
{
|
||||
enchant_broker *broker;
|
||||
EnchantBroker *pbroker;
|
||||
|
||||
if (ZEND_NUM_ARGS()) {
|
||||
ZEND_WRONG_PARAM_COUNT();
|
||||
}
|
||||
|
||||
pbroker = enchant_broker_init();
|
||||
|
||||
if (pbroker) {
|
||||
broker = (enchant_broker *) emalloc(sizeof(enchant_broker));
|
||||
broker->pbroker = pbroker;
|
||||
broker->dict = NULL;
|
||||
broker->dictcnt = 0;
|
||||
ZEND_REGISTER_RESOURCE(return_value, broker, le_enchant_broker);
|
||||
broker->rsrc_id = return_value;
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto boolean enchant_free(resource broker)
|
||||
Destroys the broker object and its dictionnaries */
|
||||
PHP_FUNCTION(enchant_broker_free)
|
||||
{
|
||||
zval *broker;
|
||||
enchant_broker *pbroker;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &broker) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
PHP_ENCHANT_GET_BROKER;
|
||||
|
||||
zend_list_delete(Z_RESVAL_P(broker));
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string enchant_broker_get_error(resource broker)
|
||||
Returns the last error of the broker */
|
||||
PHP_FUNCTION(enchant_broker_get_error)
|
||||
{
|
||||
zval *broker;
|
||||
enchant_broker *pbroker;
|
||||
char *msg;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &broker) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_BROKER;
|
||||
|
||||
msg = enchant_broker_get_error(pbroker->pbroker);
|
||||
if (msg) {
|
||||
RETURN_STRING((char *)msg, 1);
|
||||
}
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto resource enchant_broker_request_dict(resource broker, string tag)
|
||||
create a new dictionary using tag, the non-empty language tag you wish to request
|
||||
a dictionary for ("en_US", "de_DE", ...) */
|
||||
PHP_FUNCTION(enchant_broker_request_dict)
|
||||
{
|
||||
zval *broker;
|
||||
enchant_broker *pbroker;
|
||||
enchant_dict *dict;
|
||||
EnchantDict *d;
|
||||
char *tag;
|
||||
int taglen;
|
||||
int pos;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &broker, &tag, &taglen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_BROKER;
|
||||
|
||||
d = enchant_broker_request_dict(pbroker->pbroker, (const char *)tag);
|
||||
if (d) {
|
||||
if (pbroker->dictcnt) {
|
||||
pbroker->dict = (enchant_dict **)erealloc(pbroker->dict, sizeof(enchant_dict *) * pbroker->dictcnt);
|
||||
pos = pbroker->dictcnt++;
|
||||
} else {
|
||||
pbroker->dict = (enchant_dict **)emalloc(sizeof(enchant_dict *));
|
||||
pos = 0;
|
||||
pbroker->dictcnt++;
|
||||
}
|
||||
|
||||
dict = pbroker->dict[pos] = (enchant_dict *)emalloc(sizeof(enchant_dict));
|
||||
dict->id = pos;
|
||||
dict->pbroker = pbroker;
|
||||
dict->pdict = d;
|
||||
dict->rsrc_id = return_value;
|
||||
dict->prev = pos ? pbroker->dict[pos-1] : NULL;
|
||||
dict->next = NULL;
|
||||
pbroker->dict[pos] = dict;
|
||||
|
||||
if (pos) {
|
||||
pbroker->dict[pos-1]->next = dict;
|
||||
}
|
||||
|
||||
ZEND_REGISTER_RESOURCE(return_value, dict, le_enchant_dict);
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto resource enchant_broker_request_pwl_dict(resource dict, string filename)
|
||||
creates a dictionary using a PWL file. A PWL file is personal word file one word per line.
|
||||
It must exist before the call.*/
|
||||
PHP_FUNCTION(enchant_broker_request_pwl_dict)
|
||||
{
|
||||
zval *broker;
|
||||
enchant_broker *pbroker;
|
||||
enchant_dict *dict;
|
||||
EnchantDict *d;
|
||||
char *pwl;
|
||||
int pwllen;
|
||||
int pos;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &broker, &pwl, &pwllen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if ((PG(safe_mode) && (!php_checkuid(pwl, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(pwl TSRMLS_CC)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_BROKER;
|
||||
|
||||
d = enchant_broker_request_pwl_dict(pbroker->pbroker, (const char *)pwl);
|
||||
if (d) {
|
||||
if (pbroker->dictcnt) {
|
||||
pos = pbroker->dictcnt++;
|
||||
pbroker->dict = (enchant_dict **)erealloc(pbroker->dict, sizeof(enchant_dict *) * pbroker->dictcnt);
|
||||
} else {
|
||||
pbroker->dict = (enchant_dict **)emalloc(sizeof(enchant_dict *));
|
||||
pos = 0;
|
||||
pbroker->dictcnt++;
|
||||
}
|
||||
dict = pbroker->dict[pos] = (enchant_dict *)emalloc(sizeof(enchant_dict));
|
||||
dict->id = pos;
|
||||
dict->pbroker = pbroker;
|
||||
dict->pdict = d;
|
||||
dict->rsrc_id = return_value;
|
||||
dict->prev = pos?pbroker->dict[pos-1]:NULL;
|
||||
dict->next = NULL;
|
||||
pbroker->dict[pos] = dict;
|
||||
if (pos) {
|
||||
pbroker->dict[pos-1]->next = dict;
|
||||
}
|
||||
ZEND_REGISTER_RESOURCE(return_value, dict, le_enchant_dict);
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto resource enchant_broker_free_dict(resource dict)
|
||||
Free the dictionary resource */
|
||||
PHP_FUNCTION(enchant_broker_free_dict)
|
||||
{
|
||||
zval *dict;
|
||||
enchant_dict *pdict;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &dict) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
zend_list_delete(Z_RESVAL_P(dict));
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool enchant_broker_dict_exists(resource broker, string tag)
|
||||
Wether a dictionary exists or not. Using non-empty tag */
|
||||
PHP_FUNCTION(enchant_broker_dict_exists)
|
||||
{
|
||||
zval *broker;
|
||||
char *tag;
|
||||
int taglen;
|
||||
enchant_broker * pbroker;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &broker, &tag, &taglen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_BROKER;
|
||||
|
||||
RETURN_BOOL(enchant_broker_dict_exists(pbroker->pbroker, tag));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ proto bool enchant_broker_set_ordering(resource broker, string tag, string ordering)
|
||||
Declares a preference of dictionaries to use for the language
|
||||
described/referred to by 'tag'. The ordering is a comma delimited
|
||||
list of provider names. As a special exception, the "*" tag can
|
||||
be used as a language tag to declare a default ordering for any
|
||||
language that does not explictly declare an ordering. */
|
||||
|
||||
PHP_FUNCTION(enchant_broker_set_ordering)
|
||||
{
|
||||
zval *broker;
|
||||
char *pordering;
|
||||
int porderinglen;
|
||||
char *ptag;
|
||||
int ptaglen;
|
||||
enchant_broker * pbroker;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &broker, &ptag, &ptaglen, &pordering, &porderinglen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_BROKER;
|
||||
|
||||
enchant_broker_set_ordering(pbroker->pbroker, ptag, pordering);
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto array enchant_broker_describe(resource broker)
|
||||
Enumerates the Enchant providers and tells
|
||||
you some rudimentary information about them. The same info is provided through phpinfo() */
|
||||
PHP_FUNCTION(enchant_broker_describe)
|
||||
{
|
||||
EnchantBrokerDescribeFn describetozval = enumerate_providers_fn;
|
||||
zval *broker;
|
||||
enchant_broker * pbroker;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &broker) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_BROKER;
|
||||
|
||||
enchant_broker_describe(pbroker->pbroker, describetozval, (void *)return_value);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool enchant_dict_quick_check(resource dict, string word [, array &suggestions])
|
||||
If the word is correctly spelled return true, otherwise return false, if suggestions variable
|
||||
is provided, fill it with spelling alternatives. */
|
||||
PHP_FUNCTION(enchant_dict_quick_check)
|
||||
{
|
||||
zval *dict, *sugg = NULL;
|
||||
char *word;
|
||||
int wordlen;
|
||||
enchant_dict *pdict;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|z/", &dict, &word, &wordlen, &sugg) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (sugg) {
|
||||
zval_dtor(sugg);
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
if (enchant_dict_check(pdict->pdict, word, wordlen) > 0) {
|
||||
if (!sugg && ZEND_NUM_ARGS() == 2) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
int n_sugg;
|
||||
char **suggs;
|
||||
|
||||
array_init(sugg);
|
||||
|
||||
suggs = enchant_dict_suggest(pdict->pdict, word, wordlen, &n_sugg);
|
||||
if (suggs && n_sugg) {
|
||||
int i;
|
||||
for (i = 0; i < n_sugg; i++) {
|
||||
add_next_index_string(sugg, suggs[i], 1);
|
||||
}
|
||||
enchant_dict_free_suggestions(pdict->pdict, suggs);
|
||||
}
|
||||
|
||||
|
||||
RETURN_FALSE;
|
||||
}
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool enchant_dict_check(resource dict, string word)
|
||||
If the word is correctly spelled return true, otherwise return false */
|
||||
PHP_FUNCTION(enchant_dict_check)
|
||||
{
|
||||
zval *dict;
|
||||
char *word;
|
||||
int wordlen;
|
||||
enchant_dict *pdict;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &dict, &word, &wordlen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
RETURN_BOOL(!enchant_dict_check(pdict->pdict, word, wordlen));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto array enchant_dict_suggest(resource dict, string word)
|
||||
Will return a list of values if any of those pre-conditions are not met.*/
|
||||
PHP_FUNCTION(enchant_dict_suggest)
|
||||
{
|
||||
zval *dict;
|
||||
char *word;
|
||||
int wordlen;
|
||||
char **suggs;
|
||||
enchant_dict *pdict;
|
||||
int n_sugg;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &dict, &word, &wordlen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
suggs = enchant_dict_suggest(pdict->pdict, word, wordlen, &n_sugg);
|
||||
if (suggs && n_sugg) {
|
||||
int i;
|
||||
|
||||
array_init(return_value);
|
||||
for (i = 0; i < n_sugg; i++) {
|
||||
add_next_index_string(return_value, suggs[i], 1);
|
||||
}
|
||||
|
||||
enchant_dict_free_suggestions(pdict->pdict, suggs);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto void enchant_dict_add_to_personal(resource dict, string word)
|
||||
add 'word' to personal word list */
|
||||
PHP_FUNCTION(enchant_dict_add_to_personal)
|
||||
{
|
||||
zval *dict;
|
||||
char *word;
|
||||
int wordlen;
|
||||
enchant_dict *pdict;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &dict, &word, &wordlen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
enchant_dict_add_to_personal(pdict->pdict, word, wordlen);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto void enchant_dict_add_to_session(resource dict, string word)
|
||||
add 'word' to this spell-checking session */
|
||||
PHP_FUNCTION(enchant_dict_add_to_session)
|
||||
{
|
||||
zval *dict;
|
||||
char *word;
|
||||
int wordlen;
|
||||
enchant_dict *pdict;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &dict, &word, &wordlen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
enchant_dict_add_to_session(pdict->pdict, word, wordlen);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool enchant_dict_is_in_session(resource dict, string word)
|
||||
whether or not 'word' exists in this spelling-session */
|
||||
PHP_FUNCTION(enchant_dict_is_in_session)
|
||||
{
|
||||
zval *dict;
|
||||
char *word;
|
||||
int wordlen;
|
||||
enchant_dict *pdict;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &dict, &word, &wordlen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
RETURN_BOOL(enchant_dict_is_in_session(pdict->pdict, word, wordlen));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto void enchant_dict_store_replacement(resource dict, string mis, string cor)
|
||||
add a correction for 'mis' using 'cor'.
|
||||
Notes that you replaced @mis with @cor, so it's possibly more likely
|
||||
that future occurrences of @mis will be replaced with @cor. So it might
|
||||
bump @cor up in the suggestion list.*/
|
||||
PHP_FUNCTION(enchant_dict_store_replacement)
|
||||
{
|
||||
zval *dict;
|
||||
char *mis, *cor;
|
||||
int mislen, corlen;
|
||||
|
||||
enchant_dict *pdict;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &dict, &mis, &mislen, &cor, &corlen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
enchant_dict_store_replacement(pdict->pdict, mis, mislen, cor, corlen);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string enchant_dict_get_error(resource dict)
|
||||
Returns the last error of the current spelling-session */
|
||||
PHP_FUNCTION(enchant_dict_get_error)
|
||||
{
|
||||
zval *dict;
|
||||
enchant_dict *pdict;
|
||||
char *msg;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &dict) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
msg = enchant_dict_get_error(pdict->pdict);
|
||||
if (msg) {
|
||||
RETURN_STRING((char *)msg, 1);
|
||||
}
|
||||
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto array enchant_dict_describe(resource dict)
|
||||
Describes an individual dictionary 'dict' */
|
||||
PHP_FUNCTION(enchant_dict_describe)
|
||||
{
|
||||
zval *dict;
|
||||
enchant_dict *pdict;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &dict) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
enchant_dict_describe(pdict->pdict, describe_dict_fn, (void *)return_value);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* 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 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!DOCTYPE package SYSTEM "../pear/package.dtd">
|
||||
<package>
|
||||
<name>enchant</name>
|
||||
<summary>libenchant binder, support near all spelling tools</summary>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>pajoye</user>
|
||||
<name>Pierre-Alain Joye</name>
|
||||
<email>paj@pearfr.org</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<user>iliaa</user>
|
||||
<name>Ilia Alshanetsky</name>
|
||||
<email>ilia@php.net</email>
|
||||
<role>developer</role>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
<description>Enchant is a binder for libenchant. Libenchant provides a common
|
||||
API for many spell libraries:
|
||||
- aspell/pspell (intended to replace ispell)
|
||||
- hspell (hebrew)
|
||||
- ispell
|
||||
- myspell (OpenOffice project, mozilla)
|
||||
- uspell (primarily Yiddish, Hebrew, and Eastern European languages)
|
||||
A plugin system allows to add custom spell support.
|
||||
see www.abisource.com/enchant/</description>
|
||||
<license>PHP</license>
|
||||
<release>
|
||||
<state>beta</state>
|
||||
<version>0.2.1</version>
|
||||
<date>2004-03-11</date>
|
||||
<notes>- Fix possible leak in suggestions result
|
||||
- Move to beta status</notes>
|
||||
<filelist>
|
||||
<file role="src" name="config.m4"/>
|
||||
<file role="src" name="config.w32"/>
|
||||
<file role="src" name="enchant.c"/>
|
||||
<file role="src" name="php_enchant.h"/>
|
||||
<file role="doc" name="CREDITS"/>
|
||||
<dir name="docs" role="doc">
|
||||
<dir name="examples">
|
||||
<file name="example1.php"/>
|
||||
</dir>
|
||||
</dir>
|
||||
</filelist>
|
||||
<configureoptions>
|
||||
<configureoption name="with-enchant" default="shared" prompt="libenchant prefix?"/>
|
||||
</configureoptions>
|
||||
<deps>
|
||||
<dep type="php" rel="ge" version="5" />
|
||||
</deps>
|
||||
</release>
|
||||
<changelog>
|
||||
<release>
|
||||
<state>alpha</state>
|
||||
<version>0.2.0</version>
|
||||
<notes>- Add Ilia Alshanetsky as maintainer
|
||||
- Cleanup sources codes (ilia)
|
||||
- Add enchant_dict_quick_check (ilia)</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>0.1</version>
|
||||
<state>alpha</state>
|
||||
<date>2003-03-08</date>
|
||||
<notes>Initial release</notes>
|
||||
</release>
|
||||
</changelog>
|
||||
</package>
|
||||
<!--
|
||||
vim:et:ts=1:sw=1
|
||||
-->
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2003 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 at through the world-wide-web at |
|
||||
| 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: Pierre-Alain Joye <paj@pearfr.org> |
|
||||
+----------------------------------------------------------------------+
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef PHP_ENCHANT_H
|
||||
#define PHP_ENCHANT_H
|
||||
|
||||
extern zend_module_entry enchant_module_entry;
|
||||
#define phpext_enchant_ptr &enchant_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_ENCHANT_API __declspec(dllexport)
|
||||
#else
|
||||
#define PHP_ENCHANT_API
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
static void php_enchant_broker_free(zend_rsrc_list_entry *rsrc TSRMLS_DC);
|
||||
static void php_enchant_dict_free(zend_rsrc_list_entry *rsrc TSRMLS_DC);
|
||||
|
||||
PHP_MINIT_FUNCTION(enchant);
|
||||
PHP_MSHUTDOWN_FUNCTION(enchant);
|
||||
PHP_MINFO_FUNCTION(enchant);
|
||||
|
||||
PHP_FUNCTION(enchant_broker_init);
|
||||
PHP_FUNCTION(enchant_broker_free);
|
||||
PHP_FUNCTION(enchant_broker_get_error);
|
||||
PHP_FUNCTION(enchant_broker_request_dict);
|
||||
PHP_FUNCTION(enchant_broker_request_pwl_dict);
|
||||
PHP_FUNCTION(enchant_broker_free_dict);
|
||||
PHP_FUNCTION(enchant_broker_dict_exists);
|
||||
PHP_FUNCTION(enchant_broker_set_ordering);
|
||||
PHP_FUNCTION(enchant_broker_describe);
|
||||
|
||||
PHP_FUNCTION(enchant_dict_check);
|
||||
PHP_FUNCTION(enchant_dict_suggest);
|
||||
PHP_FUNCTION(enchant_dict_add_to_personal);
|
||||
PHP_FUNCTION(enchant_dict_add_to_session);
|
||||
PHP_FUNCTION(enchant_dict_is_in_session);
|
||||
PHP_FUNCTION(enchant_dict_store_replacement);
|
||||
PHP_FUNCTION(enchant_dict_get_error);
|
||||
PHP_FUNCTION(enchant_dict_describe);
|
||||
PHP_FUNCTION(enchant_dict_quick_check);
|
||||
|
||||
#ifdef ZTS
|
||||
#define ENCHANT_G(v) TSRMG(enchant_globals_id, zend_enchant_globals *, v)
|
||||
#else
|
||||
#define ENCHANT_G(v) (enchant_globals.v)
|
||||
#endif
|
||||
|
||||
#endif /* PHP_ENCHANT_H */
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
|
||||
@@ -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 /usr"
|
||||
SEARCH_FOR="/include/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 -ldl
|
||||
])
|
||||
|
||||
MAGIC_MIME_LOCATIONS="/usr/local/share/file/magic /usr/share/file/magic /etc/magic"
|
||||
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);
|
||||
efree(finfo);
|
||||
magic_close(finfo->magic);
|
||||
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_DC);
|
||||
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
-1
@@ -3,7 +3,7 @@ dnl $Id$
|
||||
dnl
|
||||
|
||||
PHP_ARG_WITH(iconv, for iconv support,
|
||||
[ --without-iconv[=DIR] Exclude iconv support], yes)
|
||||
[ --without-iconv[=DIR] Include iconv support], yes)
|
||||
|
||||
if test "$PHP_ICONV" != "no"; then
|
||||
|
||||
|
||||
-103
@@ -1,103 +0,0 @@
|
||||
#ifndef _INCLUDED_IMAP_H
|
||||
#define _INCLUDED_IMAP_H
|
||||
|
||||
#if COMPILE_DL
|
||||
#undef HAVE_IMAP
|
||||
#define HAVE_IMAP 1
|
||||
#endif
|
||||
|
||||
#if HAVE_IMAP
|
||||
|
||||
#ifndef PHP_WIN32
|
||||
#include "build-defs.h"
|
||||
#endif
|
||||
|
||||
/* Functions accessable to PHP */
|
||||
extern zend_module_entry imap_module_entry;
|
||||
#define imap_module_ptr &imap_module_entry
|
||||
|
||||
extern PHP_MINIT_FUNCTION(imap);
|
||||
extern PHP_RINIT_FUNCTION(imap);
|
||||
extern PHP_RSHUTDOWN_FUNCTION(imap);
|
||||
PHP_MINFO_FUNCTION(imap);
|
||||
PHP_FUNCTION(imap_open);
|
||||
PHP_FUNCTION(imap_popen);
|
||||
PHP_FUNCTION(imap_reopen);
|
||||
PHP_FUNCTION(imap_num_msg);
|
||||
PHP_FUNCTION(imap_num_recent);
|
||||
PHP_FUNCTION(imap_headers);
|
||||
PHP_FUNCTION(imap_headerinfo);
|
||||
PHP_FUNCTION(imap_rfc822_parse_headers);
|
||||
PHP_FUNCTION(imap_body);
|
||||
PHP_FUNCTION(imap_fetchstructure);
|
||||
PHP_FUNCTION(imap_fetchbody);
|
||||
PHP_FUNCTION(imap_expunge);
|
||||
PHP_FUNCTION(imap_delete);
|
||||
PHP_FUNCTION(imap_undelete);
|
||||
PHP_FUNCTION(imap_check);
|
||||
PHP_FUNCTION(imap_close);
|
||||
PHP_FUNCTION(imap_mail_copy);
|
||||
PHP_FUNCTION(imap_mail_move);
|
||||
PHP_FUNCTION(imap_createmailbox);
|
||||
PHP_FUNCTION(imap_renamemailbox);
|
||||
PHP_FUNCTION(imap_deletemailbox);
|
||||
PHP_FUNCTION(imap_listmailbox);
|
||||
PHP_FUNCTION(imap_scanmailbox);
|
||||
PHP_FUNCTION(imap_subscribe);
|
||||
PHP_FUNCTION(imap_unsubscribe);
|
||||
PHP_FUNCTION(imap_append);
|
||||
PHP_FUNCTION(imap_ping);
|
||||
PHP_FUNCTION(imap_base64);
|
||||
PHP_FUNCTION(imap_qprint);
|
||||
PHP_FUNCTION(imap_8bit);
|
||||
PHP_FUNCTION(imap_binary);
|
||||
PHP_FUNCTION(imap_mailboxmsginfo);
|
||||
PHP_FUNCTION(imap_rfc822_write_address);
|
||||
PHP_FUNCTION(imap_rfc822_parse_adrlist);
|
||||
PHP_FUNCTION(imap_setflag_full);
|
||||
PHP_FUNCTION(imap_clearflag_full);
|
||||
PHP_FUNCTION(imap_sort);
|
||||
PHP_FUNCTION(imap_fetchheader);
|
||||
PHP_FUNCTION(imap_fetchtext);
|
||||
PHP_FUNCTION(imap_uid);
|
||||
PHP_FUNCTION(imap_msgno);
|
||||
PHP_FUNCTION(imap_list);
|
||||
PHP_FUNCTION(imap_list_full);
|
||||
PHP_FUNCTION(imap_listscan);
|
||||
PHP_FUNCTION(imap_lsub);
|
||||
PHP_FUNCTION(imap_lsub_full);
|
||||
PHP_FUNCTION(imap_create);
|
||||
PHP_FUNCTION(imap_rename);
|
||||
PHP_FUNCTION(imap_status);
|
||||
PHP_FUNCTION(imap_bodystruct);
|
||||
PHP_FUNCTION(imap_fetch_overview);
|
||||
PHP_FUNCTION(imap_mail_compose);
|
||||
PHP_FUNCTION(imap_alerts);
|
||||
PHP_FUNCTION(imap_errors);
|
||||
PHP_FUNCTION(imap_last_error);
|
||||
PHP_FUNCTION(imap_mail);
|
||||
PHP_FUNCTION(imap_search);
|
||||
PHP_FUNCTION(imap_utf8);
|
||||
PHP_FUNCTION(imap_utf7_decode);
|
||||
PHP_FUNCTION(imap_utf7_encode);
|
||||
PHP_FUNCTION(imap_mime_header_decode);
|
||||
#else
|
||||
#define imap_module_ptr NULL
|
||||
#endif /* HAVE_IMAP */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define phpext_imap_ptr imap_module_ptr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -2673,13 +2673,13 @@ static oci_session *_oci_open_session(oci_server* server,char *username,char *pa
|
||||
smart_str_0(&hashed_details);
|
||||
|
||||
if (!exclusive) {
|
||||
mutex_lock(mx_lock);
|
||||
if (zend_ts_hash_find(persistent_sessions, hashed_details.c, hashed_details.len+1, (void **) &session_list) != SUCCESS) {
|
||||
zend_llist tmp;
|
||||
/* first session, set up a session list */
|
||||
zend_llist_init(&tmp, sizeof(oci_session), (llist_dtor_func_t) _session_pcleanup, 1);
|
||||
zend_ts_hash_update(persistent_sessions, hashed_details.c, hashed_details.len+1, &tmp, sizeof(zend_llist), (void **) &session_list);
|
||||
} else {
|
||||
mutex_lock(mx_lock);
|
||||
|
||||
/* session list found, search for an idle session or an already opened session by the current thread */
|
||||
session = zend_llist_get_first(session_list);
|
||||
@@ -2692,6 +2692,7 @@ static oci_session *_oci_open_session(oci_server* server,char *username,char *pa
|
||||
session->thread = thread_id();
|
||||
}
|
||||
|
||||
mutex_unlock(mx_lock);
|
||||
}
|
||||
|
||||
if (session) {
|
||||
@@ -2706,7 +2707,6 @@ static oci_session *_oci_open_session(oci_server* server,char *username,char *pa
|
||||
/* breakthru to open */
|
||||
}
|
||||
}
|
||||
mutex_unlock(mx_lock);
|
||||
}
|
||||
|
||||
session = ecalloc(1,sizeof(oci_session));
|
||||
|
||||
+1
-1
@@ -3038,7 +3038,7 @@ PHP_FUNCTION(odbc_foreignkeys)
|
||||
fschema = Z_STRVAL_PP(pv_fschema);
|
||||
convert_to_string_ex(pv_ftable);
|
||||
ftable = Z_STRVAL_PP(pv_ftable);
|
||||
#if defined(HAVE_DBMAKER) || defined (HAVE_IBMDB2)
|
||||
#ifdef HAVE_DBMAKER
|
||||
#define EMPTY_TO_NULL(xstr) \
|
||||
if ((int)strlen((xstr)) == 0) (xstr) = NULL
|
||||
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
dnl
|
||||
dnl $Id$
|
||||
dnl
|
||||
|
||||
dnl By default we'll compile and link against the bundled PCRE library
|
||||
dnl if DIR is supplied, we'll use that for linking
|
||||
|
||||
PHP_ARG_WITH(pcre-regex,for PCRE support,
|
||||
[ --without-pcre-regex Do not include Perl Compatible Regular Expressions
|
||||
support. Use --with-pcre-regex=DIR to specify DIR
|
||||
where PCRE's include and library files are located,
|
||||
if not using bundled library.],yes)
|
||||
|
||||
if test "$PHP_PCRE_REGEX" != "no"; then
|
||||
if test "$PHP_PCRE_REGEX" = "yes"; then
|
||||
PHP_NEW_EXTENSION(pcre, pcrelib/maketables.c pcrelib/get.c pcrelib/study.c pcrelib/pcre.c php_pcre.c, $ext_shared,,-DSUPPORT_UTF8 -DLINK_SIZE=2 -DPOSIX_MALLOC_THRESHOLD=10 -I@ext_srcdir@/pcrelib)
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/pcrelib)
|
||||
AC_DEFINE(HAVE_BUNDLED_PCRE, 1, [ ])
|
||||
else
|
||||
for i in $PHP_PCRE_REGEX $PHP_PCRE_REGEX/include $PHP_PCRE_REGEX/include/pcre; do
|
||||
test -f $i/pcre.h && PCRE_INCDIR=$i
|
||||
done
|
||||
|
||||
if test -z "$PCRE_INCDIR"; then
|
||||
AC_MSG_ERROR([Could not find pcre.h in $PHP_PCRE_REGEX])
|
||||
fi
|
||||
|
||||
for j in $PHP_PCRE_REGEX $PHP_PCRE_REGEX/lib; do
|
||||
test -f $j/libpcre.a -o -f $j/libpcre.$SHLIB_SUFFIX_NAME && PCRE_LIBDIR=$j
|
||||
done
|
||||
|
||||
if test -z "$PCRE_LIBDIR" ; then
|
||||
AC_MSG_ERROR([Could not find libpcre.(a|$SHLIB_SUFFIX_NAME) in $PHP_PCRE_REGEX])
|
||||
fi
|
||||
|
||||
changequote({,})
|
||||
pcre_major=`grep PCRE_MAJOR $PCRE_INCDIR/pcre.h | sed -e 's/[^0-9]//g'`
|
||||
pcre_minor=`grep PCRE_MINOR $PCRE_INCDIR/pcre.h | sed -e 's/[^0-9]//g'`
|
||||
changequote([,])
|
||||
pcre_minor_length=`echo "$pcre_minor" | wc -c | sed -e 's/[^0-9]//g'`
|
||||
if test "$pcre_minor_length" -eq 2 ; then
|
||||
pcre_minor="$pcre_minor"0
|
||||
fi
|
||||
pcre_version=$pcre_major$pcre_minor
|
||||
if test "$pcre_version" -lt 208; then
|
||||
AC_MSG_ERROR([The PCRE extension requires PCRE library version >= 2.08])
|
||||
fi
|
||||
|
||||
PHP_ADD_LIBRARY_WITH_PATH(pcre, $PCRE_LIBDIR, PCRE_SHARED_LIBADD)
|
||||
|
||||
AC_DEFINE(HAVE_PCRE, 1, [ ])
|
||||
PHP_ADD_INCLUDE($PCRE_INCDIR)
|
||||
PHP_NEW_EXTENSION(pcre, php_pcre.c, $ext_shared,,-DSUPPORT_UTF8 -DLINK_SIZE=2 -DPOSIX_MALLOC_THRESHOLD=10)
|
||||
fi
|
||||
PHP_SUBST(PCRE_SHARED_LIBADD)
|
||||
fi
|
||||
@@ -1,2 +0,0 @@
|
||||
PHP Data Objects
|
||||
Wez Furlong, Marcus Boerger, Sterling Hughes, George Schlossnagle
|
||||
Whitespace-only changes.
@@ -1,31 +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
|
||||
re2c -b $(top_srcdir)/ext/pdo/pdo_sql_parser.re > $@
|
||||
|
||||
$(srcdir)/pdo_sql_parser.c: $(srcdir)/pdo_sql_parser.re
|
||||
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->beginWork() 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->beginWork(). 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,25 +0,0 @@
|
||||
$Id$
|
||||
|
||||
In no particular order:
|
||||
|
||||
Low-level:
|
||||
|
||||
- Scanner for :named placeholders and prepare()/execute() emulation (George)
|
||||
- $dbh->quote()
|
||||
- Exceptions and unified error API
|
||||
- Scrollable cursors
|
||||
- meta data from driver, such as server version and supported features
|
||||
- field meta data from statement handles
|
||||
- $dbh->exec() for one-shot SQL
|
||||
- LOB support via Streams API
|
||||
- persistent handles
|
||||
- iterator support
|
||||
- "lazy" fetch support
|
||||
|
||||
Not-so-low-level:
|
||||
- hash key case folding for portabilitiy, ala sqlite.assoc_case, but not using an ini option.
|
||||
- fetchAll(), single row, single column fetches etc.
|
||||
|
||||
Could be more...
|
||||
|
||||
vim:tw=78:et
|
||||
@@ -1,10 +0,0 @@
|
||||
dnl $Id$
|
||||
dnl config.m4 for extension pdo
|
||||
|
||||
PHP_ARG_ENABLE(pdo, whether to enable PDO support,
|
||||
[ --enable-pdo Enable PHP Data Objects support])
|
||||
|
||||
if test "$PHP_PDO" != "no"; then
|
||||
PHP_NEW_EXTENSION(pdo, pdo.c pdo_dbh.c pdo_stmt.c pdo_sql_parser.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');
|
||||
}
|
||||
|
||||
@@ -1,84 +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.
|
||||
</description>
|
||||
<license>PHP</license>
|
||||
<release>
|
||||
<state>alpha</state>
|
||||
<version>0.1.1</version>
|
||||
<date>2004-05-21</date>
|
||||
|
||||
<notes>
|
||||
Note that PDO on its own is useless.
|
||||
You need to install a PDO database driver to make use of it,
|
||||
check http://pecl.php.net for a list of available PDO drivers.
|
||||
|
||||
It is highly recommended that you update to the latest 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-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/
|
||||
|
||||
</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="php_pdo_sql_parser.h"/>
|
||||
<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.0RC3-dev"/>
|
||||
</deps>
|
||||
</release>
|
||||
</package>
|
||||
-315
@@ -1,315 +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: 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"
|
||||
|
||||
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;
|
||||
|
||||
/* 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.1.1",
|
||||
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, "failed api version check");
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION */
|
||||
PHP_MINIT_FUNCTION(pdo)
|
||||
{
|
||||
zend_class_entry ce;
|
||||
|
||||
ZEND_INIT_MODULE_GLOBALS(pdo, php_pdo_init_globals, NULL);
|
||||
REGISTER_INI_ENTRIES();
|
||||
|
||||
zend_hash_init(&pdo_driver_hash, 0, NULL, NULL, 1);
|
||||
|
||||
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_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_ATTR_AUTOCOMMIT", (long)PDO_ATTR_AUTOCOMMIT, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ATTR_SCROLL", (long)PDO_ATTR_SCROLL, 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_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_LONG_CONSTANT("PDO_ERR_NONE", (long)PDO_ERR_NONE, CONST_CS|CONST_PERSISTENT);
|
||||
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);
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "PDOException", NULL);
|
||||
pdo_exception_ce = zend_register_internal_class_ex(&ce, zend_exception_get_default(), NULL TSRMLS_CC);
|
||||
zend_declare_property_null(pdo_exception_ce, "errorInfo", sizeof("errorInfo")-1, ZEND_ACC_PUBLIC TSRMLS_CC);
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "PDO", pdo_dbh_functions);
|
||||
ce.create_object = pdo_dbh_new;
|
||||
pdo_dbh_ce = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "PDOStatement", pdo_dbstmt_functions);
|
||||
ce.create_object = pdo_dbstmt_new;
|
||||
pdo_dbstmt_ce = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "PDORow", pdo_row_functions);
|
||||
ce.create_object = pdo_row_new;
|
||||
pdo_row_ce = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION */
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo)
|
||||
{
|
||||
UNREGISTER_INI_ENTRIES();
|
||||
zend_hash_destroy(&pdo_driver_hash);
|
||||
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();
|
||||
|
||||
DISPLAY_INI_ENTRIES();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* 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,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
//$x = new PDO("oci:dbname=hostname", 'php', 'php');
|
||||
$x = new PDO("odbc:ram", 'php', 'php', array(PDO_ATTR_AUTOCOMMIT => 0));
|
||||
$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";
|
||||
|
||||
$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;
|
||||
}
|
||||
}
|
||||
|
||||
echo "All done\n";
|
||||
|
||||
?>
|
||||
@@ -1,703 +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: Wez Furlong <wez@php.net> |
|
||||
| Marcus Boerger <helly@php.net> |
|
||||
| Sterling Hughes <sterling@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/* The PDO Database Handle Class */
|
||||
|
||||
#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"
|
||||
#include "php_pdo_int.h"
|
||||
#include "zend_exceptions.h"
|
||||
|
||||
void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
enum pdo_error_type *pdo_err = &dbh->error_code;
|
||||
const char *msg = "<<Unknown>>";
|
||||
char *supp = NULL;
|
||||
long native_code = 0;
|
||||
char *message = NULL;
|
||||
zval *info = NULL;
|
||||
|
||||
if (dbh->error_mode == PDO_ERRMODE_SILENT) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (stmt) {
|
||||
pdo_err = &stmt->error_code;
|
||||
}
|
||||
|
||||
switch (*pdo_err) {
|
||||
case PDO_ERR_NONE: msg = "No error"; break;
|
||||
case PDO_ERR_CANT_MAP: msg = "Consult errorInfo() for more details"; break;
|
||||
case PDO_ERR_SYNTAX: msg = "Syntax Error"; break;
|
||||
case PDO_ERR_CONSTRAINT:msg = "Constraint violation"; break;
|
||||
case PDO_ERR_NOT_FOUND: msg = "Not found"; break;
|
||||
case PDO_ERR_ALREADY_EXISTS: msg = "Already exists"; break;
|
||||
case PDO_ERR_NOT_IMPLEMENTED: msg = "Not Implemented"; break;
|
||||
case PDO_ERR_MISMATCH: msg = "Mismatch"; break;
|
||||
case PDO_ERR_TRUNCATED: msg = "Truncated"; break;
|
||||
case PDO_ERR_DISCONNECTED: msg = "Disconnected"; break;
|
||||
default: msg = "<<Invalid>>";
|
||||
}
|
||||
|
||||
if (dbh->methods->fetch_err) {
|
||||
|
||||
MAKE_STD_ZVAL(info);
|
||||
array_init(info);
|
||||
|
||||
add_next_index_long(info, *pdo_err);
|
||||
|
||||
if (dbh->methods->fetch_err(dbh, stmt, info TSRMLS_CC)) {
|
||||
zval **item;
|
||||
|
||||
if (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(info), 1, (void**)&item)) {
|
||||
native_code = Z_LVAL_PP(item);
|
||||
}
|
||||
|
||||
if (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(info), 2, (void**)&item)) {
|
||||
supp = estrndup(Z_STRVAL_PP(item), Z_STRLEN_PP(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (supp && *pdo_err == PDO_ERR_CANT_MAP) {
|
||||
spprintf(&message, 0, "%ld %s", native_code, supp);
|
||||
} else if (supp) {
|
||||
spprintf(&message, 0, "%s: %ld %s", msg, native_code, supp);
|
||||
} else {
|
||||
spprintf(&message, 0, "%s", msg);
|
||||
}
|
||||
|
||||
if (dbh->error_mode == PDO_ERRMODE_WARNING) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", message);
|
||||
|
||||
if (info) {
|
||||
zval_ptr_dtor(&info);
|
||||
}
|
||||
} else {
|
||||
zval *ex;
|
||||
zend_class_entry *def_ex = zend_exception_get_default(), *pdo_ex = php_pdo_get_exception();
|
||||
|
||||
MAKE_STD_ZVAL(ex);
|
||||
object_init_ex(ex, pdo_ex);
|
||||
|
||||
zend_update_property_string(def_ex, ex, "message", sizeof("message")-1, message TSRMLS_CC);
|
||||
zend_update_property_long(def_ex, ex, "code", sizeof("code")-1, *pdo_err TSRMLS_CC);
|
||||
|
||||
if (info) {
|
||||
zend_update_property(pdo_ex, ex, "errorInfo", sizeof("errorInfo")-1, info TSRMLS_CC);
|
||||
}
|
||||
|
||||
zend_throw_exception_object(ex TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (message) {
|
||||
efree(message);
|
||||
}
|
||||
|
||||
if (supp) {
|
||||
efree(supp);
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ proto object PDO::__construct(string dsn, string username, string passwd [, array driver_opts])
|
||||
*/
|
||||
static PHP_FUNCTION(dbh_constructor)
|
||||
{
|
||||
zval *object = getThis();
|
||||
pdo_dbh_t *dbh = NULL;
|
||||
zend_bool is_persistent = FALSE;
|
||||
char *data_source;
|
||||
int data_source_len;
|
||||
char *colon;
|
||||
char *username=NULL, *password=NULL;
|
||||
int usernamelen, passwordlen;
|
||||
pdo_driver_t *driver = NULL;
|
||||
zval *driver_options = NULL;
|
||||
|
||||
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ssa!", &data_source, &data_source_len,
|
||||
&username, &usernamelen, &password, &passwordlen, &driver_options)) {
|
||||
ZVAL_NULL(object);
|
||||
return;
|
||||
}
|
||||
|
||||
/* parse the data source name */
|
||||
colon = strchr(data_source, ':');
|
||||
|
||||
if (!colon) {
|
||||
zend_throw_exception_ex(php_pdo_get_exception(), PDO_ERR_SYNTAX TSRMLS_CC, "invalid data source name");
|
||||
ZVAL_NULL(object);
|
||||
return;
|
||||
}
|
||||
|
||||
driver = pdo_find_driver(data_source, colon - data_source);
|
||||
|
||||
if (!driver) {
|
||||
/* NB: don't want to include the data_source in the error message as
|
||||
* it might contain a password */
|
||||
zend_throw_exception_ex(php_pdo_get_exception(), PDO_ERR_NOT_FOUND TSRMLS_CC, "could not find driver");
|
||||
ZVAL_NULL(object);
|
||||
return;
|
||||
}
|
||||
|
||||
dbh = (pdo_dbh_t *) zend_object_store_get_object(object TSRMLS_CC);
|
||||
|
||||
if (dbh == NULL) {
|
||||
/* need this check for persistent allocations */
|
||||
zend_throw_exception_ex(php_pdo_get_exception(), PDO_ERR_NONE TSRMLS_CC, "out of memory!?");
|
||||
}
|
||||
dbh->is_persistent = is_persistent;
|
||||
dbh->data_source_len = strlen(colon + 1);
|
||||
/* when persistent stuff is done, we should check the return values here
|
||||
* too */
|
||||
dbh->data_source = (const char*)pestrdup(colon + 1, is_persistent);
|
||||
dbh->username = username ? pestrdup(username, is_persistent) : NULL;
|
||||
dbh->password = password ? pestrdup(password, is_persistent) : NULL;
|
||||
|
||||
dbh->auto_commit = pdo_attr_lval(driver_options, PDO_ATTR_AUTOCOMMIT, 1 TSRMLS_CC);
|
||||
|
||||
if (driver->db_handle_factory(dbh, driver_options TSRMLS_CC)) {
|
||||
/* all set */
|
||||
|
||||
if (is_persistent) {
|
||||
/* register in the persistent list etc. */
|
||||
/* we should also need to replace the object store entry,
|
||||
since it was created with emalloc */
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* the connection failed; things will tidy up in free_storage */
|
||||
/* XXX raise exception */
|
||||
ZVAL_NULL(object);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto object PDO::prepare(string statment [, int options [, array driver_options]])
|
||||
Prepares a statement for execution and returns a statement object */
|
||||
/* TODO: options will be a PDO specific bitmask controlling such things as
|
||||
* cursor type. */
|
||||
static PHP_METHOD(PDO, prepare)
|
||||
{
|
||||
pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
pdo_stmt_t *stmt;
|
||||
char *statement;
|
||||
int statement_len;
|
||||
zval *driver_options = NULL;
|
||||
long options = 0;
|
||||
|
||||
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|la", &statement,
|
||||
&statement_len, &options, &driver_options)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PDO_DBH_CLEAR_ERR();
|
||||
stmt = ecalloc(1, sizeof(*stmt));
|
||||
/* unconditionally keep this for later reference */
|
||||
stmt->query_string = estrndup(statement, statement_len);
|
||||
stmt->query_stringlen = statement_len;
|
||||
if (dbh->methods->preparer(dbh, statement, statement_len, stmt, options, driver_options TSRMLS_CC)) {
|
||||
/* prepared; create a statement object for PHP land to access it */
|
||||
Z_TYPE_P(return_value) = IS_OBJECT;
|
||||
Z_OBJ_HANDLE_P(return_value) = zend_objects_store_put(stmt, NULL, pdo_dbstmt_free_storage, NULL TSRMLS_CC);
|
||||
Z_OBJ_HT_P(return_value) = &pdo_dbstmt_object_handlers;
|
||||
|
||||
/* give it a reference to me */
|
||||
stmt->database_object_handle = *getThis();
|
||||
zend_objects_store_add_ref(getThis() TSRMLS_CC);
|
||||
stmt->dbh = dbh;
|
||||
|
||||
/* we haven't created a lazy object yet */
|
||||
ZVAL_NULL(&stmt->lazy_object_ref);
|
||||
|
||||
stmt->refcount = 1;
|
||||
return;
|
||||
}
|
||||
efree(stmt);
|
||||
PDO_HANDLE_DBH_ERR();
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool PDO::beginTransaction()
|
||||
Initiates a transaction */
|
||||
static PHP_METHOD(PDO, beginTransaction)
|
||||
{
|
||||
pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (dbh->in_txn) {
|
||||
zend_throw_exception_ex(php_pdo_get_exception(), PDO_ERR_NONE TSRMLS_CC, "There is already an active transaction");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (!dbh->methods->begin) {
|
||||
/* TODO: this should be an exception; see the auto-commit mode
|
||||
* comments below */
|
||||
zend_throw_exception_ex(php_pdo_get_exception(), PDO_ERR_NONE TSRMLS_CC, "This driver doesn't support transactions");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (dbh->methods->begin(dbh TSRMLS_CC)) {
|
||||
dbh->in_txn = 1;
|
||||
RETURN_TRUE;
|
||||
}
|
||||
|
||||
PDO_HANDLE_DBH_ERR();
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool PDO::commit()
|
||||
Commit a transaction */
|
||||
static PHP_METHOD(PDO, commit)
|
||||
{
|
||||
pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (!dbh->in_txn) {
|
||||
zend_throw_exception_ex(php_pdo_get_exception(), PDO_ERR_NONE TSRMLS_CC, "There is no active transaction");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (dbh->methods->commit(dbh TSRMLS_CC)) {
|
||||
dbh->in_txn = 0;
|
||||
RETURN_TRUE;
|
||||
}
|
||||
|
||||
PDO_HANDLE_DBH_ERR();
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool PDO::rollBack()
|
||||
roll back a transaction */
|
||||
static PHP_METHOD(PDO, rollBack)
|
||||
{
|
||||
pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (!dbh->in_txn) {
|
||||
zend_throw_exception_ex(php_pdo_get_exception(), PDO_ERR_NONE TSRMLS_CC, "There is no active transaction");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (dbh->methods->rollback(dbh TSRMLS_CC)) {
|
||||
dbh->in_txn = 0;
|
||||
RETURN_TRUE;
|
||||
}
|
||||
|
||||
PDO_HANDLE_DBH_ERR();
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool PDO::setAttribute(long attribute, mixed value)
|
||||
Set an attribute */
|
||||
static PHP_METHOD(PDO, setAttribute)
|
||||
{
|
||||
pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
long attr;
|
||||
zval *value = NULL;
|
||||
|
||||
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz!", &attr, &value)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
switch (attr) {
|
||||
case PDO_ATTR_ERRMODE:
|
||||
convert_to_long(value);
|
||||
switch (Z_LVAL_P(value)) {
|
||||
case PDO_ERRMODE_SILENT:
|
||||
case PDO_ERRMODE_WARNING:
|
||||
case PDO_ERRMODE_EXCEPTION:
|
||||
dbh->error_mode = Z_LVAL_P(value);
|
||||
RETURN_TRUE;
|
||||
default:
|
||||
zend_throw_exception_ex(php_pdo_get_exception(), PDO_ERR_SYNTAX TSRMLS_CC, "Error mode %d is invalid", Z_LVAL_P(value));
|
||||
}
|
||||
RETURN_FALSE;
|
||||
|
||||
case PDO_ATTR_CASE:
|
||||
convert_to_long(value);
|
||||
switch (Z_LVAL_P(value)) {
|
||||
case PDO_CASE_NATURAL:
|
||||
case PDO_CASE_UPPER:
|
||||
case PDO_CASE_LOWER:
|
||||
dbh->desired_case = Z_LVAL_P(value);
|
||||
RETURN_TRUE;
|
||||
default:
|
||||
zend_throw_exception_ex(php_pdo_get_exception(), PDO_ERR_SYNTAX TSRMLS_CC, "Case folding mode %d is invalid", Z_LVAL_P(value));
|
||||
}
|
||||
RETURN_FALSE;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
if (!dbh->methods->set_attribute) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
PDO_DBH_CLEAR_ERR();
|
||||
if (dbh->methods->set_attribute(dbh, attr, value TSRMLS_CC)) {
|
||||
RETURN_TRUE;
|
||||
}
|
||||
|
||||
fail:
|
||||
if (attr == PDO_ATTR_AUTOCOMMIT) {
|
||||
zend_throw_exception_ex(php_pdo_get_exception(), PDO_ERR_NONE TSRMLS_CC, "The auto-commit mode cannot be changed for this driver");
|
||||
} else if (!dbh->methods->set_attribute) {
|
||||
/* XXX: do something better here */
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "This driver doesn't support setting attributes");
|
||||
} else {
|
||||
PDO_HANDLE_DBH_ERR();
|
||||
}
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto mixed PDO::getAttribute(long attribute)
|
||||
Get an attribute */
|
||||
static PHP_METHOD(PDO, getAttribute)
|
||||
{
|
||||
pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
long attr;
|
||||
|
||||
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &attr)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (!dbh->methods->get_attribute) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "This driver doesn't support fetching attributes");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PDO_DBH_CLEAR_ERR();
|
||||
switch (dbh->methods->get_attribute(dbh, attr, return_value TSRMLS_CC)) {
|
||||
case -1:
|
||||
PDO_HANDLE_DBH_ERR();
|
||||
RETURN_FALSE;
|
||||
|
||||
case 0:
|
||||
/* XXX: should do something better here */
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "This driver doesn't support fetching %ld attribute", attr);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto long PDO::exec(string query)
|
||||
Execute a query that does not return a row set, returning the number of affected rows */
|
||||
static PHP_METHOD(PDO, exec)
|
||||
{
|
||||
pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
char *statement;
|
||||
int statement_len;
|
||||
long ret;
|
||||
|
||||
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &statement, &statement_len)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (!statement_len) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
PDO_DBH_CLEAR_ERR();
|
||||
ret = dbh->methods->doer(dbh, statement, statement_len TSRMLS_CC);
|
||||
if(ret == -1) {
|
||||
PDO_HANDLE_DBH_ERR();
|
||||
RETURN_FALSE;
|
||||
} else {
|
||||
RETURN_LONG(ret);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ proto int PDO::lastInsertId()
|
||||
Returns the number id of rows that we affected by the last call to PDO::exec(). Not always meaningful. */
|
||||
static PHP_METHOD(PDO, lastInsertId)
|
||||
{
|
||||
pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (ZEND_NUM_ARGS()) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PDO_DBH_CLEAR_ERR();
|
||||
if (!dbh->methods->last_id) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "This driver does not support last inserted id retrieval.");
|
||||
} else {
|
||||
RETURN_LONG(dbh->methods->last_id(dbh TSRMLS_CC));
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto int PDO::errorCode()
|
||||
Fetch the error code associated with the last operation on the database handle */
|
||||
static PHP_METHOD(PDO, errorCode)
|
||||
{
|
||||
pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (ZEND_NUM_ARGS()) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
RETURN_LONG(dbh->error_code);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto int PDO::errorInfo()
|
||||
Fetch extended error information associated with the last operation on the database handle */
|
||||
static PHP_METHOD(PDO, errorInfo)
|
||||
{
|
||||
pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (ZEND_NUM_ARGS()) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
array_init(return_value);
|
||||
add_next_index_long(return_value, dbh->error_code);
|
||||
|
||||
if (dbh->methods->fetch_err) {
|
||||
dbh->methods->fetch_err(dbh, NULL, return_value TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
function_entry pdo_dbh_functions[] = {
|
||||
PHP_ME_MAPPING(__construct, dbh_constructor, NULL)
|
||||
PHP_ME(PDO, prepare, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(PDO, beginTransaction,NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(PDO, commit, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(PDO, rollBack, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(PDO, setAttribute, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(PDO, exec, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(PDO, lastInsertId, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(PDO, errorCode, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(PDO, errorInfo, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(PDO, getAttribute, NULL, ZEND_ACC_PUBLIC)
|
||||
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
/* {{{ overloaded object handlers for PDO class */
|
||||
static zval *dbh_prop_read(zval *object, zval *member, int type TSRMLS_DC)
|
||||
{
|
||||
zval *return_value;
|
||||
|
||||
MAKE_STD_ZVAL(return_value);
|
||||
ZVAL_NULL(return_value);
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
static void dbh_prop_write(zval *object, zval *member, zval *value TSRMLS_DC)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static zval *dbh_read_dim(zval *object, zval *offset, int type TSRMLS_DC)
|
||||
{
|
||||
zval *return_value;
|
||||
|
||||
MAKE_STD_ZVAL(return_value);
|
||||
ZVAL_NULL(return_value);
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
static void dbh_write_dim(zval *object, zval *offset, zval *value TSRMLS_DC)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static int dbh_prop_exists(zval *object, zval *member, int check_empty TSRMLS_DC)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dbh_dim_exists(zval *object, zval *member, int check_empty TSRMLS_DC)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dbh_prop_delete(zval *object, zval *offset TSRMLS_DC)
|
||||
{
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot delete properties from a PDO DBH");
|
||||
}
|
||||
|
||||
static void dbh_dim_delete(zval *object, zval *offset TSRMLS_DC)
|
||||
{
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot delete dimensions from a PDO DBH");
|
||||
}
|
||||
|
||||
static HashTable *dbh_get_properties(zval *object TSRMLS_DC)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static union _zend_function *dbh_method_get(zval *object, char *method_name, int method_len TSRMLS_DC)
|
||||
{
|
||||
zend_function *fbc;
|
||||
char *lc_method_name;
|
||||
|
||||
lc_method_name = emalloc(method_len + 1);
|
||||
zend_str_tolower_copy(lc_method_name, method_name, method_len);
|
||||
|
||||
if (zend_hash_find(&pdo_dbh_ce->function_table, lc_method_name, method_len+1, (void**)&fbc) == FAILURE) {
|
||||
efree(lc_method_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
efree(lc_method_name);
|
||||
return fbc;
|
||||
}
|
||||
|
||||
static int dbh_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
|
||||
static union _zend_function *dbh_get_ctor(zval *object TSRMLS_DC)
|
||||
{
|
||||
pdo_dbh_t *dbh = zend_object_store_get_object(object TSRMLS_CC);
|
||||
|
||||
if(dbh->ce != pdo_dbh_ce) {
|
||||
return dbh->ce->constructor;
|
||||
} else {
|
||||
static zend_internal_function ctor = {0};
|
||||
|
||||
ctor.type = ZEND_INTERNAL_FUNCTION;
|
||||
ctor.function_name = "__construct";
|
||||
ctor.scope = pdo_dbh_ce;
|
||||
ctor.handler = ZEND_FN(dbh_constructor);
|
||||
|
||||
return (union _zend_function*)&ctor;
|
||||
}
|
||||
}
|
||||
|
||||
static zend_class_entry *dbh_get_ce(zval *object TSRMLS_DC)
|
||||
{
|
||||
return pdo_dbh_ce;
|
||||
}
|
||||
|
||||
static int dbh_get_classname(zval *object, char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC)
|
||||
{
|
||||
*class_name = estrndup("PDO", sizeof("PDO")-1);
|
||||
*class_name_len = sizeof("PDO")-1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dbh_compare(zval *object1, zval *object2 TSRMLS_DC)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static zend_object_handlers pdo_dbh_object_handlers = {
|
||||
ZEND_OBJECTS_STORE_HANDLERS,
|
||||
dbh_prop_read,
|
||||
dbh_prop_write,
|
||||
dbh_read_dim,
|
||||
dbh_write_dim,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
dbh_prop_exists,
|
||||
dbh_prop_delete,
|
||||
dbh_dim_exists,
|
||||
dbh_dim_delete,
|
||||
dbh_get_properties,
|
||||
dbh_method_get,
|
||||
dbh_call_method,
|
||||
dbh_get_ctor,
|
||||
dbh_get_ce,
|
||||
dbh_get_classname,
|
||||
dbh_compare,
|
||||
NULL, /* cast */
|
||||
NULL
|
||||
};
|
||||
|
||||
static void pdo_dbh_free_storage(zend_object *object TSRMLS_DC)
|
||||
{
|
||||
pdo_dbh_t *dbh = (pdo_dbh_t*)object;
|
||||
|
||||
if (!dbh) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dbh->is_persistent) {
|
||||
/* XXX: don't really free it, just delete the rsrc id */
|
||||
return;
|
||||
}
|
||||
|
||||
dbh->methods->closer(dbh TSRMLS_CC);
|
||||
|
||||
if (dbh->data_source) {
|
||||
pefree((char *)dbh->data_source, dbh->is_persistent);
|
||||
}
|
||||
if (dbh->username) {
|
||||
pefree(dbh->username, dbh->is_persistent);
|
||||
}
|
||||
if (dbh->password) {
|
||||
pefree(dbh->password, dbh->is_persistent);
|
||||
}
|
||||
|
||||
pefree(dbh, dbh->is_persistent);
|
||||
}
|
||||
|
||||
zend_object_value pdo_dbh_new(zend_class_entry *ce TSRMLS_DC)
|
||||
{
|
||||
zend_object_value retval;
|
||||
pdo_dbh_t *dbh;
|
||||
|
||||
dbh = emalloc(sizeof(*dbh));
|
||||
memset(dbh, 0, sizeof(*dbh));
|
||||
dbh->ce = ce;
|
||||
|
||||
retval.handle = zend_objects_store_put(dbh, NULL, pdo_dbh_free_storage, NULL TSRMLS_CC);
|
||||
retval.handlers = &pdo_dbh_object_handlers;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* 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,317 +0,0 @@
|
||||
/* Generated by re2c 0.5 on Fri May 21 17:33:58 2004 */
|
||||
#line 1 "/home/george/src/pecl/pdo/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
|
||||
|
||||
|
||||
{
|
||||
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;
|
||||
yy3:
|
||||
#line 61
|
||||
{ RET(PDO_PARSER_TEXT); }
|
||||
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: yych = *++YYCURSOR;
|
||||
yy7:
|
||||
#line 60
|
||||
{ RET(PDO_PARSER_BIND_POS); }
|
||||
yy8: ++YYCURSOR;
|
||||
if(YYLIMIT == YYCURSOR) YYFILL(1);
|
||||
yych = *YYCURSOR;
|
||||
yy9: if(yybm[0+yych] & 8) goto yy8;
|
||||
yy10:
|
||||
#line 62
|
||||
{ RET(PDO_PARSER_TEXT); }
|
||||
yy11: yych = *++YYCURSOR;
|
||||
yy12:
|
||||
#line 63
|
||||
{ RET(PDO_PARSER_EOI); }
|
||||
yy13: ++YYCURSOR;
|
||||
if(YYLIMIT == YYCURSOR) YYFILL(1);
|
||||
yych = *YYCURSOR;
|
||||
yy14: if(yybm[0+yych] & 16) goto yy13;
|
||||
yy15:
|
||||
#line 59
|
||||
{ RET(PDO_PARSER_BIND); }
|
||||
yy16: ++YYCURSOR;
|
||||
if(YYLIMIT == YYCURSOR) YYFILL(1);
|
||||
yych = *YYCURSOR;
|
||||
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;
|
||||
yy20: if(yybm[0+yych] & 32) goto yy16;
|
||||
if(yych <= '&') goto yy21;
|
||||
if(yych <= '\'') goto yy19;
|
||||
goto yy22;
|
||||
yy21:
|
||||
#line 58
|
||||
{ RET(PDO_PARSER_TEXT); }
|
||||
yy22: ++YYCURSOR;
|
||||
if(YYLIMIT == YYCURSOR) YYFILL(1);
|
||||
yych = *YYCURSOR;
|
||||
if(yych == '\'') goto yy16;
|
||||
goto yy18;
|
||||
yy23: ++YYCURSOR;
|
||||
if(YYLIMIT == YYCURSOR) YYFILL(1);
|
||||
yych = *YYCURSOR;
|
||||
yy24: if(yybm[0+yych] & 128) goto yy23;
|
||||
if(yych <= '\000') goto yy18;
|
||||
if(yych <= '[') goto yy26;
|
||||
yy25: ++YYCURSOR;
|
||||
if(YYLIMIT == YYCURSOR) YYFILL(1);
|
||||
yych = *YYCURSOR;
|
||||
if(yych == '"') goto yy23;
|
||||
goto yy18;
|
||||
yy26: yych = *++YYCURSOR;
|
||||
yy27:
|
||||
#line 57
|
||||
{ RET(PDO_PARSER_TEXT); }
|
||||
}
|
||||
#line 64
|
||||
|
||||
}
|
||||
|
||||
int 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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,201 +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); }
|
||||
*/
|
||||
}
|
||||
|
||||
int 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
-1111
File diff suppressed because it is too large.
Load diff
@@ -1,69 +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: Wez Furlong <wez@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef PHP_PDO_H
|
||||
#define PHP_PDO_H
|
||||
|
||||
extern zend_module_entry pdo_module_entry;
|
||||
#define phpext_pdo_ptr &pdo_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
# ifdef PDO_EXPORTS
|
||||
# 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,415 +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: 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;
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
# define FALSE 0
|
||||
#endif
|
||||
|
||||
#define PDO_DRIVER_API 20040513
|
||||
|
||||
enum pdo_param_type {
|
||||
PDO_PARAM_NULL,
|
||||
PDO_PARAM_INT,
|
||||
PDO_PARAM_STR,
|
||||
PDO_PARAM_LOB,
|
||||
PDO_PARAM_STMT, /* hierarchical result set */
|
||||
|
||||
};
|
||||
|
||||
enum pdo_fetch_type {
|
||||
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 */
|
||||
};
|
||||
|
||||
enum pdo_attribute_type {
|
||||
PDO_ATTR_AUTOCOMMIT, /* use to turn on or off auto-commit mode */
|
||||
PDO_ATTR_SCROLL, /* ask for a scrollable cursor (when you prepare()) */
|
||||
PDO_ATTR_PREFETCH, /* configure the prefetch size for drivers that support it */
|
||||
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 */
|
||||
|
||||
/* 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 */
|
||||
};
|
||||
|
||||
/* generic error code values.
|
||||
* Don't want to go overboard with these.
|
||||
* */
|
||||
enum pdo_error_type {
|
||||
PDO_ERR_NONE, /* no error condition */
|
||||
PDO_ERR_CANT_MAP, /* no way to map native error to the generic codes; consult the native error for more info */
|
||||
PDO_ERR_SYNTAX,
|
||||
PDO_ERR_CONSTRAINT,
|
||||
PDO_ERR_NOT_FOUND,
|
||||
PDO_ERR_ALREADY_EXISTS,
|
||||
PDO_ERR_NOT_IMPLEMENTED,
|
||||
PDO_ERR_MISMATCH,
|
||||
PDO_ERR_TRUNCATED,
|
||||
PDO_ERR_DISCONNECTED,
|
||||
};
|
||||
|
||||
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 */
|
||||
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, long options, 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 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 */
|
||||
typedef long (*pdo_dbh_last_id_func)(pdo_dbh_t *dbh 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);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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 */
|
||||
typedef int (*pdo_stmt_fetch_func)(pdo_stmt_t *stmt 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 */
|
||||
typedef int (*pdo_stmt_get_col_data_func)(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len 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);
|
||||
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
/* }}} */
|
||||
|
||||
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 {
|
||||
/* 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, the driver 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;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* the sum of the number of bits here and the bit fields preceeding should
|
||||
* equal 32 */
|
||||
unsigned _reserved_flags:22;
|
||||
|
||||
/* data source string used to open this handle */
|
||||
const char *data_source;
|
||||
unsigned long data_source_len;
|
||||
|
||||
/* the global error code. */
|
||||
enum pdo_error_type error_code;
|
||||
|
||||
enum pdo_error_mode error_mode;
|
||||
|
||||
enum pdo_case_conversion native_case, desired_case;
|
||||
|
||||
/* needed for inheritance to work */
|
||||
zend_class_entry *ce;
|
||||
#if 0
|
||||
/* persistent hash key associated with this handle */
|
||||
const char *persistent_id;
|
||||
/* and the list id associated with it */
|
||||
int persistent_rsrc_id;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* describes a column */
|
||||
struct pdo_column_data {
|
||||
char *name;
|
||||
long namelen;
|
||||
unsigned long maxlen;
|
||||
enum pdo_param_type param_type;
|
||||
unsigned long precision;
|
||||
};
|
||||
|
||||
/* 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 {
|
||||
/* 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;
|
||||
unsigned _reserved:31;
|
||||
|
||||
/* 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;
|
||||
/* 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. */
|
||||
enum 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;
|
||||
};
|
||||
|
||||
/* 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);
|
||||
|
||||
#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,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: 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;
|
||||
|
||||
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_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);
|
||||
extern zend_object_handlers pdo_dbstmt_object_handlers;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
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);
|
||||
|
||||
#define PDO_DBH_CLEAR_ERR() dbh->error_code = PDO_ERR_NONE
|
||||
#define PDO_STMT_CLEAR_ERR() stmt->error_code = PDO_ERR_NONE
|
||||
#define PDO_HANDLE_DBH_ERR() if (dbh->error_code) { pdo_handle_error(dbh, NULL TSRMLS_CC); }
|
||||
#define PDO_HANDLE_STMT_ERR() if (stmt->error_code) { pdo_handle_error(stmt->dbh, stmt TSRMLS_CC); }
|
||||
|
||||
|
||||
/*
|
||||
* 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,27 +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$ */
|
||||
|
||||
#ifndef PHP_PDO_MYSQL_SQL_PARSER_H
|
||||
#define PHP_PDO_MYSQL_SQL_PARSER_H
|
||||
#include "php.h"
|
||||
int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **outquery,
|
||||
int *outquery_len);
|
||||
|
||||
#endif
|
||||
@@ -1,2 +0,0 @@
|
||||
Firebird/InterBase driver for PDO
|
||||
Ard Biesheuvel
|
||||
Whitespace-only changes.
@@ -1,49 +0,0 @@
|
||||
dnl
|
||||
dnl $Id$
|
||||
dnl
|
||||
|
||||
PHP_ARG_WITH(pdo-firebird,for Firebird support for PDO,
|
||||
[ --with-pdo-firebird[=DIR] Include Firebird support for PDO. DIR is the Firebird base
|
||||
install directory, defaults to /opt/firebird])
|
||||
|
||||
if test "$PHP_PDO_FIREBIRD" != "no"; then
|
||||
if test "$PHP_PDO_FIREBIRD" = "yes"; then
|
||||
FIREBIRD_INCDIR=/opt/firebird/include
|
||||
FIREBIRD_LIBDIR=/opt/firebird/lib
|
||||
else
|
||||
FIREBIRD_INCDIR=$PHP_PDO_FIREBIRD/include
|
||||
FIREBIRD_LIBDIR=$PHP_PDO_FIREBIRD/lib
|
||||
fi
|
||||
|
||||
PHP_CHECK_LIBRARY(gds, isc_detach_database,
|
||||
[
|
||||
FIREBIRD_LIBNAME=gds
|
||||
], [
|
||||
PHP_CHECK_LIBRARY(ib_util, isc_detach_database,
|
||||
[
|
||||
FIREBIRD_LIBNAME=ib_util
|
||||
], [
|
||||
AC_MSG_ERROR([libgds or libib_util not found! Check config.log for more information.])
|
||||
], [
|
||||
-L$FIREBIRD_LIBDIR
|
||||
])
|
||||
], [
|
||||
-L$FIREBIRD_LIBDIR
|
||||
])
|
||||
|
||||
if test -f $prefix/include/php/ext/pdo/php_pdo_driver.h; then
|
||||
pdo_inc_path=$prefix/include/php/ext
|
||||
elif test -f $abs_srcdir/include/php/ext/pdo/php_pdo_driver.h; then
|
||||
pdo_inc_path=$abs_srcdir/ext
|
||||
elif test -f ext/pdo/php_pdo_driver.h; then
|
||||
pdo_inc_path=ext
|
||||
else
|
||||
AC_MSG_ERROR([Cannot find php_pdo_driver.h.])
|
||||
fi
|
||||
|
||||
PHP_ADD_LIBRARY_WITH_PATH($FIREBIRD_LIBNAME, $FIREBIRD_LIBDIR, PDO_FIREBIRD_SHARED_LIBADD)
|
||||
PHP_ADD_INCLUDE($FIREBIRD_INCDIR)
|
||||
AC_DEFINE(HAVE_PDO_FIREBIRD,1,[ ])
|
||||
PHP_NEW_EXTENSION(pdo_firebird, pdo_firebird.c firebird_driver.c firebird_statement.c, $ext_shared,,-I$pdo_inc_path)
|
||||
PHP_SUBST(PDO_FIREBIRD_SHARED_LIBADD)
|
||||
fi
|
||||
@@ -1,18 +0,0 @@
|
||||
// $Id$
|
||||
// vim:ft=javascript
|
||||
|
||||
ARG_WITH("pdo-firebird", "Firebird support for PDO", "no");
|
||||
|
||||
if (PHP_PDO_FIREBIRD != "no") {
|
||||
|
||||
if ((CHECK_LIB("fbclient_ms.lib", "pdo_firebird", PHP_PHP_BUILD + "\\interbase\\lib_ms;" + PHP_PDO_FIREBIRD)
|
||||
|| CHECK_LIB("gds32_ms.lib", "pdo_firebird", PHP_PHP_BUILD + "\\interbase\\lib_ms;" + PHP_PDO_FIREBIRD)
|
||||
) && CHECK_HEADER_ADD_INCLUDE("ibase.h", "CFLAGS_PDO_FIREBIRD", PHP_PHP_BUILD + "\\interbase\\include;" + PHP_PDO_FIREBIRD)) {
|
||||
|
||||
EXTENSION("pdo_firebird", "pdo_firebird.c firebird_driver.c firebird_statement.c");
|
||||
ADD_FLAG('CFLAGS_PDO_FIREBIRD', "/I ..\\pecl");
|
||||
} else {
|
||||
WARNING("pdo_firebird not enabled; libraries and headers not found");
|
||||
}
|
||||
ADD_EXTENSION_DEP('pdo_firebird', 'pdo');
|
||||
}
|
||||
@@ -1,659 +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: Ard Biesheuvel <abies@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "pdo/php_pdo.h"
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_firebird.h"
|
||||
#include "php_pdo_firebird_int.h"
|
||||
|
||||
static int firebird_alloc_prepare_stmt(pdo_dbh_t*, const char*, long, XSQLDA*, isc_stmt_handle*,
|
||||
HashTable* TSRMLS_DC);
|
||||
|
||||
/* map driver specific error message to PDO error */
|
||||
void _firebird_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, char const *file, long line TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_firebird_db_handle *H = stmt ? ((pdo_firebird_stmt *)stmt->driver_data)->H
|
||||
: (pdo_firebird_db_handle *)dbh->driver_data;
|
||||
enum pdo_error_type *const error_code = stmt ? &stmt->error_code : &dbh->error_code;
|
||||
|
||||
switch (isc_sqlcode(H->isc_status)) {
|
||||
|
||||
case 0:
|
||||
*error_code = PDO_ERR_NONE;
|
||||
break;
|
||||
default:
|
||||
*error_code = PDO_ERR_CANT_MAP;
|
||||
break;
|
||||
case -104:
|
||||
*error_code = PDO_ERR_SYNTAX;
|
||||
break;
|
||||
case -530:
|
||||
case -803:
|
||||
*error_code = PDO_ERR_CONSTRAINT;
|
||||
break;
|
||||
case -204:
|
||||
case -205:
|
||||
case -206:
|
||||
case -829:
|
||||
*error_code = PDO_ERR_NOT_FOUND;
|
||||
break;
|
||||
|
||||
*error_code = PDO_ERR_ALREADY_EXISTS;
|
||||
break;
|
||||
|
||||
*error_code = PDO_ERR_NOT_IMPLEMENTED;
|
||||
break;
|
||||
case -313:
|
||||
case -804:
|
||||
*error_code = PDO_ERR_MISMATCH;
|
||||
break;
|
||||
case -303:
|
||||
case -314:
|
||||
case -413:
|
||||
*error_code = PDO_ERR_TRUNCATED;
|
||||
break;
|
||||
|
||||
*error_code = PDO_ERR_DISCONNECTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#define RECORD_ERROR(dbh) _firebird_error(dbh, NULL, __FILE__, __LINE__ TSRMLS_CC)
|
||||
|
||||
/* called by PDO to close a db handle */
|
||||
static int firebird_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
|
||||
|
||||
if (dbh->in_txn) {
|
||||
if (dbh->auto_commit) {
|
||||
if (isc_commit_transaction(H->isc_status, &H->tr)) {
|
||||
RECORD_ERROR(dbh);
|
||||
}
|
||||
} else {
|
||||
if (isc_rollback_transaction(H->isc_status, &H->tr)) {
|
||||
RECORD_ERROR(dbh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isc_detach_database(H->isc_status, &H->db)) {
|
||||
RECORD_ERROR(dbh);
|
||||
}
|
||||
|
||||
pefree(H, dbh->is_persistent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* called by PDO to prepare an SQL query */
|
||||
static int firebird_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, /* {{{ */
|
||||
pdo_stmt_t *stmt, long options, zval *driver_options TSRMLS_DC)
|
||||
{
|
||||
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
|
||||
pdo_firebird_stmt *S = NULL;
|
||||
HashTable *np;
|
||||
|
||||
do {
|
||||
isc_stmt_handle s = NULL;
|
||||
XSQLDA num_sqlda;
|
||||
static char const info[] = { isc_info_sql_stmt_type };
|
||||
char result[8];
|
||||
|
||||
num_sqlda.version = PDO_FB_SQLDA_VERSION;
|
||||
num_sqlda.sqln = 1;
|
||||
|
||||
ALLOC_HASHTABLE(np);
|
||||
zend_hash_init(np, 8, NULL, NULL, 0);
|
||||
|
||||
/* allocate and prepare statement */
|
||||
if (!firebird_alloc_prepare_stmt(dbh, sql, sql_len, &num_sqlda, &s, np TSRMLS_CC)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* allocate a statement handle struct of the right size (struct out_sqlda is inlined) */
|
||||
S = ecalloc(1, sizeof(*S)-sizeof(XSQLDA) + XSQLDA_LENGTH(num_sqlda.sqld));
|
||||
S->H = H;
|
||||
S->stmt = s;
|
||||
S->fetch_buf = ecalloc(1,sizeof(char*) * num_sqlda.sqld);
|
||||
S->out_sqlda.version = PDO_FB_SQLDA_VERSION;
|
||||
S->out_sqlda.sqln = stmt->column_count = num_sqlda.sqld;
|
||||
S->named_params = np;
|
||||
|
||||
/* determine the statement type */
|
||||
if (isc_dsql_sql_info(H->isc_status, &s, sizeof(info), const_cast(info), sizeof(result),
|
||||
result)) {
|
||||
break;
|
||||
}
|
||||
S->statement_type = result[3];
|
||||
|
||||
/* fill the output sqlda with information about the prepared query */
|
||||
if (isc_dsql_describe(H->isc_status, &s, PDO_FB_SQLDA_VERSION, &S->out_sqlda)) {
|
||||
RECORD_ERROR(dbh);
|
||||
break;
|
||||
}
|
||||
|
||||
/* allocate the input descriptors */
|
||||
if (isc_dsql_describe_bind(H->isc_status, &s, PDO_FB_SQLDA_VERSION, &num_sqlda)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (num_sqlda.sqld) {
|
||||
S->in_sqlda = ecalloc(1,XSQLDA_LENGTH(num_sqlda.sqld));
|
||||
S->in_sqlda->version = PDO_FB_SQLDA_VERSION;
|
||||
S->in_sqlda->sqln = num_sqlda.sqld;
|
||||
|
||||
if (isc_dsql_describe_bind(H->isc_status, &s, PDO_FB_SQLDA_VERSION, S->in_sqlda)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stmt->driver_data = S;
|
||||
stmt->methods = &firebird_stmt_methods;
|
||||
|
||||
return 1;
|
||||
|
||||
} while (0);
|
||||
|
||||
RECORD_ERROR(dbh);
|
||||
|
||||
zend_hash_destroy(np);
|
||||
FREE_HASHTABLE(np);
|
||||
|
||||
if (S) {
|
||||
if (S->in_sqlda) {
|
||||
efree(S->in_sqlda);
|
||||
}
|
||||
efree(S);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* called by PDO to execute a statement that doesn't produce a result set */
|
||||
static long firebird_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
|
||||
isc_stmt_handle stmt = NULL;
|
||||
static char const info_count[] = { isc_info_sql_records };
|
||||
char result[64];
|
||||
int ret = 0;
|
||||
XSQLDA in_sqlda, out_sqlda;
|
||||
|
||||
/* TODO no placeholders in exec() for now */
|
||||
in_sqlda.version = out_sqlda.version = PDO_FB_SQLDA_VERSION;
|
||||
in_sqlda.sqld = out_sqlda.sqld = 0;
|
||||
|
||||
/* allocate and prepare statement */
|
||||
if (!firebird_alloc_prepare_stmt(dbh, sql, sql_len, &out_sqlda, &stmt, 0 TSRMLS_CC)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* execute the statement */
|
||||
if (isc_dsql_execute2(H->isc_status, &H->tr, &stmt, PDO_FB_SQLDA_VERSION, &in_sqlda, &out_sqlda)) {
|
||||
RECORD_ERROR(dbh);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* find out how many rows were affected */
|
||||
if (isc_dsql_sql_info(H->isc_status, &stmt, sizeof(info_count), const_cast(info_count),
|
||||
sizeof(result), result)) {
|
||||
RECORD_ERROR(dbh);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (result[0] == isc_info_sql_records) {
|
||||
unsigned i = 3, result_size = isc_vax_integer(&result[1],2);
|
||||
|
||||
while (result[i] != isc_info_end && i < result_size) {
|
||||
short len = (short)isc_vax_integer(&result[i+1],2);
|
||||
if (result[i] != isc_info_req_select_count) {
|
||||
ret += isc_vax_integer(&result[i+3],len);
|
||||
}
|
||||
i += len+3;
|
||||
}
|
||||
}
|
||||
|
||||
/* commit if we're in auto_commit mode */
|
||||
if (dbh->auto_commit && isc_commit_retaining(H->isc_status, &H->tr)) {
|
||||
RECORD_ERROR(dbh);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* called by the PDO SQL parser to add quotes to values that are copied into SQL */
|
||||
static int firebird_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, /* {{{ */
|
||||
char **quoted, int *quotedlen TSRMLS_DC)
|
||||
{
|
||||
int qcount = 0;
|
||||
char const *c;
|
||||
|
||||
/* Firebird only requires single quotes to be doubled if string lengths are used */
|
||||
|
||||
/* count the number of ' characters */
|
||||
for (c = unquoted; (c = strchr(c,'\'')); qcount++, c++);
|
||||
|
||||
if (!qcount) {
|
||||
return 0;
|
||||
} else {
|
||||
char const *l, *r;
|
||||
char *c;
|
||||
|
||||
*quotedlen = unquotedlen + qcount;
|
||||
*quoted = c = emalloc(*quotedlen+1);
|
||||
|
||||
/* foreach (chunk that ends in a quote) */
|
||||
for (l = unquoted; (r = strchr(l,'\'')); l = r+1) {
|
||||
|
||||
/* copy the chunk */
|
||||
strncpy(c, l, r-l);
|
||||
c += (r-l);
|
||||
|
||||
/* add the second quote */
|
||||
*c++ = '\'';
|
||||
}
|
||||
|
||||
/* copy the remainder */
|
||||
strncpy(c, l, *quotedlen-(c-*quoted));
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* called by PDO to start a transaction */
|
||||
static int firebird_handle_begin(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
|
||||
char tpb[8] = { isc_tpb_version3 }, *ptpb = tpb+1;
|
||||
#if abies_0
|
||||
if (dbh->transaction_flags & PDO_TRANS_ISOLATION_LEVEL) {
|
||||
if (dbh->transaction_flags & PDO_TRANS_READ_UNCOMMITTED) {
|
||||
/* this is a poor fit, but it's all we have */
|
||||
*ptpb++ = isc_tpb_read_committed;
|
||||
*ptpb++ = isc_tpb_rec_version;
|
||||
dbh->transaction_flags &= ~(PDO_TRANS_ISOLATION_LEVEL^PDO_TRANS_READ_UNCOMMITTED);
|
||||
} else if (dbh->transaction_flags & PDO_TRANS_READ_COMMITTED) {
|
||||
*ptpb++ = isc_tpb_read_committed;
|
||||
*ptpb++ = isc_tpb_no_rec_version;
|
||||
dbh->transaction_flags &= ~(PDO_TRANS_ISOLATION_LEVEL^PDO_TRANS_READ_COMMITTED);
|
||||
} else if (dbh->transaction_flags & PDO_TRANS_REPEATABLE_READ) {
|
||||
*ptpb++ = isc_tpb_concurrency;
|
||||
dbh->transaction_flags &= ~(PDO_TRANS_ISOLATION_LEVEL^PDO_TRANS_REPEATABLE_READ);
|
||||
} else {
|
||||
*ptpb++ = isc_tpb_consistency;
|
||||
dbh->transaction_flags &= ~(PDO_TRANS_ISOLATION_LEVEL^PDO_TRANS_SERIALIZABLE);
|
||||
}
|
||||
}
|
||||
|
||||
if (dbh->transaction_flags & PDO_TRANS_ACCESS_MODE) {
|
||||
if (dbh->transaction_flags & PDO_TRANS_READONLY) {
|
||||
*ptpb++ = isc_tpb_read;
|
||||
dbh->transaction_flags &= ~(PDO_TRANS_ACCESS_MODE^PDO_TRANS_READONLY);
|
||||
} else {
|
||||
*ptpb++ = isc_tpb_write;
|
||||
dbh->transaction_flags &= ~(PDO_TRANS_ACCESS_MODE^PDO_TRANS_READWRITE);
|
||||
}
|
||||
}
|
||||
|
||||
if (dbh->transaction_flags & PDO_TRANS_CONFLICT_RESOLUTION) {
|
||||
if (dbh->transaction_flags & PDO_TRANS_RETRY) {
|
||||
*ptpb++ = isc_tpb_wait;
|
||||
dbh->transaction_flags &= ~(PDO_TRANS_CONFLICT_RESOLUTION^PDO_TRANS_RETRY);
|
||||
} else {
|
||||
*ptpb++ = isc_tpb_nowait;
|
||||
dbh->transaction_flags &= ~(PDO_TRANS_CONFLICT_RESOLUTION^PDO_TRANS_ABORT);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (isc_start_transaction(H->isc_status, &H->tr, 1, &H->db, (unsigned short)(ptpb-tpb), tpb)) {
|
||||
RECORD_ERROR(dbh);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* called by PDO to commit a transaction */
|
||||
static int firebird_handle_commit(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
|
||||
|
||||
if (isc_commit_transaction(H->isc_status, &H->tr)) {
|
||||
RECORD_ERROR(dbh);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* called by PDO to rollback a transaction */
|
||||
static int firebird_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
|
||||
|
||||
if (isc_rollback_transaction(H->isc_status, &H->tr)) {
|
||||
RECORD_ERROR(dbh);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* used by prepare and exec to allocate a statement handle and prepare the SQL */
|
||||
static int firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const char *sql, long sql_len, /* {{{ */
|
||||
XSQLDA *out_sqlda, isc_stmt_handle *s, HashTable *named_params TSRMLS_DC)
|
||||
{
|
||||
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
|
||||
char *c, *new_sql, in_quote, in_param, pname[64], *ppname;
|
||||
long l, pindex = -1;
|
||||
|
||||
/* Firebird allows SQL statements up to 64k, so bail if it doesn't fit */
|
||||
if (sql_len > SHORT_MAX) {
|
||||
dbh->error_code = PDO_ERR_TRUNCATED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* start a new transaction implicitly if auto_commit is enabled and no transaction is open */
|
||||
if (dbh->auto_commit && !dbh->in_txn) {
|
||||
/* dbh->transaction_flags = PDO_TRANS_READ_UNCOMMITTED; */
|
||||
|
||||
if (!firebird_handle_begin(dbh TSRMLS_CC)) {
|
||||
return 0;
|
||||
}
|
||||
dbh->in_txn = 1;
|
||||
}
|
||||
|
||||
/* allocate the statement */
|
||||
if (isc_dsql_allocate_statement(H->isc_status, &H->db, s)) {
|
||||
RECORD_ERROR(dbh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* in order to support named params, which Firebird itself doesn't,
|
||||
we need to replace :foo by ?, and store the name we just replaced */
|
||||
new_sql = c = emalloc(sql_len+1);
|
||||
|
||||
for (l = in_quote = in_param = 0; l <= sql_len; ++l) {
|
||||
if ( !(in_quote ^= (sql[l] == '\''))) {
|
||||
if (!in_param) {
|
||||
switch (sql[l]) {
|
||||
case ':':
|
||||
in_param = 1;
|
||||
ppname = pname;
|
||||
case '?':
|
||||
*c++ = '?';
|
||||
++pindex;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if ((in_param &= (sql[l] == '_') || (sql[l] >= 'A' && sql[l] <= 'Z')
|
||||
|| (sql[l] >= 'a' && sql[l] <= 'z') || (sql[l] >= '0' && sql[l] <= '9'))) {
|
||||
*ppname++ = sql[l];
|
||||
continue;
|
||||
} else {
|
||||
*ppname++ = 0;
|
||||
if (named_params) {
|
||||
zend_hash_update(named_params, pname, (unsigned int)(ppname-pname),
|
||||
(void*)&pindex, sizeof(long)+1,NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*c++ = sql[l];
|
||||
}
|
||||
|
||||
/* prepare the statement */
|
||||
if (isc_dsql_prepare(H->isc_status, &H->tr, s, 0, new_sql, PDO_FB_DIALECT, out_sqlda)) {
|
||||
RECORD_ERROR(dbh);
|
||||
efree(new_sql);
|
||||
return 0;
|
||||
}
|
||||
|
||||
efree(new_sql);
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* called by PDO to set a driver-specific dbh attribute */
|
||||
static int firebird_handle_set_attribute(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
|
||||
|
||||
switch (attr) {
|
||||
case PDO_ATTR_AUTOCOMMIT:
|
||||
|
||||
convert_to_boolean(val);
|
||||
|
||||
/* ignore if the new value equals the old one */
|
||||
if (dbh->auto_commit ^ Z_BVAL_P(val)) {
|
||||
if (dbh->in_txn) {
|
||||
if (Z_BVAL_P(val)) {
|
||||
/* turning on auto_commit with an open transaction is illegal, because
|
||||
we won't know what to do with it */
|
||||
H->last_app_error = "Cannot enable auto-commit while a transaction is already open";
|
||||
return 0;
|
||||
} else {
|
||||
/* close the transaction */
|
||||
if (!firebird_handle_commit(dbh TSRMLS_CC)) {
|
||||
break;
|
||||
}
|
||||
dbh->in_txn = 0;
|
||||
}
|
||||
}
|
||||
dbh->auto_commit = Z_BVAL_P(val);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* callback to used to report database server info */
|
||||
static void firebird_info_cb(void *arg, char const *s) /* {{{ */
|
||||
{
|
||||
if (arg) {
|
||||
if (*(char*)arg) { /* second call */
|
||||
strcat(arg, " ");
|
||||
}
|
||||
strcat(arg, s);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* called by PDO to get a driver-specific dbh attribute */
|
||||
static int firebird_handle_get_attribute(pdo_dbh_t const *dbh, long attr, zval *val TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
|
||||
|
||||
switch (attr) {
|
||||
char tmp[200];
|
||||
|
||||
case PDO_ATTR_AUTOCOMMIT:
|
||||
ZVAL_LONG(val,dbh->auto_commit);
|
||||
return 1;
|
||||
|
||||
case PDO_ATTR_CONNECTION_STATUS:
|
||||
ZVAL_BOOL(val, !isc_version(&H->db, firebird_info_cb, NULL));
|
||||
return 1;
|
||||
|
||||
case PDO_ATTR_CLIENT_VERSION: {
|
||||
#if defined(__GNUC__) || defined(PHP_WIN32)
|
||||
info_func_t info_func = NULL;
|
||||
#ifdef __GNUC__
|
||||
info_func = (info_func_t)dlsym(RTLD_DEFAULT, "isc_get_client_version");
|
||||
#else
|
||||
HMODULE l = GetModuleHandle("fbclient");
|
||||
|
||||
if (!l && !(l = GetModuleHandle("gds32"))) {
|
||||
break;
|
||||
}
|
||||
info_func = (info_func_t)GetProcAddress(l, "isc_get_client_version");
|
||||
#endif
|
||||
if (info_func) {
|
||||
info_func(tmp);
|
||||
ZVAL_STRING(val,tmp,1);
|
||||
} else {
|
||||
ZVAL_STRING(val,"Firebird 1.0/Interbase 6",1);
|
||||
}
|
||||
#else
|
||||
ZVAL_NULL(val);
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
|
||||
case PDO_ATTR_SERVER_VERSION:
|
||||
case PDO_ATTR_SERVER_INFO:
|
||||
*tmp = 0;
|
||||
|
||||
if (!isc_version(&H->db, firebird_info_cb, (void*)tmp)) {
|
||||
ZVAL_STRING(val,tmp,1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* called by PDO to retrieve driver-specific information about an error that has occurred */
|
||||
static int pdo_firebird_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
|
||||
ISC_STATUS *s = H->isc_status;
|
||||
char buf[400];
|
||||
long i = 0, l, sqlcode = isc_sqlcode(s);
|
||||
|
||||
if (sqlcode) {
|
||||
add_next_index_long(info, sqlcode);
|
||||
|
||||
while ((l = isc_interprete(&buf[i],&s))) {
|
||||
i += l;
|
||||
strcpy(&buf[i++], " ");
|
||||
}
|
||||
add_next_index_string(info, buf, 1);
|
||||
} else {
|
||||
add_next_index_long(info, -999);
|
||||
add_next_index_string(info, const_cast(H->last_app_error),1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static struct pdo_dbh_methods firebird_methods = { /* {{{ */
|
||||
firebird_handle_closer,
|
||||
firebird_handle_preparer,
|
||||
firebird_handle_doer,
|
||||
firebird_handle_quoter,
|
||||
firebird_handle_begin,
|
||||
firebird_handle_commit,
|
||||
firebird_handle_rollback,
|
||||
firebird_handle_set_attribute,
|
||||
NULL, /* last_id not supported */
|
||||
pdo_firebird_fetch_error_func,
|
||||
firebird_handle_get_attribute,
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* the driver-specific PDO handle constructor */
|
||||
static int pdo_firebird_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
struct pdo_data_src_parser vars[] = {
|
||||
{ "dbname", NULL, 0 },
|
||||
{ "charset", NULL, 0 },
|
||||
{ "role", NULL, 0 }
|
||||
};
|
||||
int i, ret = 0;
|
||||
pdo_firebird_db_handle *H = dbh->driver_data = pecalloc(1,sizeof(*H),dbh->is_persistent);
|
||||
|
||||
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 2);
|
||||
|
||||
do {
|
||||
static char const dpb_flags[] = {
|
||||
isc_dpb_user_name, isc_dpb_password, isc_dpb_lc_ctype, isc_dpb_sql_role_name };
|
||||
char const *dpb_values[] = { dbh->username, dbh->password, vars[1].optval, vars[2].optval };
|
||||
char dpb_buffer[256] = { isc_dpb_version1 }, *dpb;
|
||||
|
||||
dpb = dpb_buffer + 1;
|
||||
|
||||
/* loop through all the provided arguments and set dpb fields accordingly */
|
||||
for (i = 0; i < sizeof(dpb_flags); ++i) {
|
||||
if (dpb_values[i]) {
|
||||
dpb += sprintf(dpb, "%c%c%s", dpb_flags[i], (unsigned char)strlen(dpb_values[i]),
|
||||
dpb_values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* fire it up baby! */
|
||||
if (isc_attach_database(H->isc_status, 0, vars[0].optval, &H->db,(short)(dpb-dpb_buffer),
|
||||
dpb_buffer)) {
|
||||
break;
|
||||
}
|
||||
|
||||
dbh->methods = &firebird_methods;
|
||||
dbh->supports_placeholders = PDO_PLACEHOLDER_POSITIONAL;
|
||||
dbh->native_case = PDO_CASE_UPPER;
|
||||
dbh->alloc_own_columns = 1;
|
||||
|
||||
ret = 1;
|
||||
|
||||
} while (0);
|
||||
|
||||
for (i = 0; i < sizeof(vars)/sizeof(vars[0]); ++i) {
|
||||
if (vars[i].freeme) {
|
||||
efree(vars[i].optval);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
firebird_handle_closer(dbh TSRMLS_CC);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
pdo_driver_t pdo_firebird_driver = { /* {{{ */
|
||||
PDO_DRIVER_HEADER(firebird),
|
||||
pdo_firebird_handle_factory
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,696 +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: Ard Biesheuvel <abies@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "pdo/php_pdo.h"
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_firebird.h"
|
||||
#include "php_pdo_firebird_int.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#define RECORD_ERROR(stmt) _firebird_error(NULL, stmt, __FILE__, __LINE__ TSRMLS_CC)
|
||||
|
||||
/* free the allocated space for passing field values to the db and back */
|
||||
static void free_sqlda(XSQLDA const *sqlda) /* {{{ */
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sqlda->sqld; ++i) {
|
||||
XSQLVAR const *var = &sqlda->sqlvar[i];
|
||||
|
||||
if (var->sqlind) {
|
||||
efree(var->sqlind);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* called by PDO to clean up a statement handle */
|
||||
static int firebird_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
|
||||
int result = 1, i;
|
||||
|
||||
/* release the statement */
|
||||
if (isc_dsql_free_statement(S->H->isc_status, &S->stmt, DSQL_drop)) {
|
||||
RECORD_ERROR(stmt);
|
||||
result = 0;
|
||||
}
|
||||
|
||||
/* clean up the fetch buffers if they have been used */
|
||||
for (i = 0; i < S->out_sqlda.sqld; ++i) {
|
||||
if (S->fetch_buf[i]) {
|
||||
efree(S->fetch_buf[i]);
|
||||
}
|
||||
}
|
||||
efree(S->fetch_buf);
|
||||
|
||||
zend_hash_destroy(S->named_params);
|
||||
FREE_HASHTABLE(S->named_params);
|
||||
|
||||
/* clean up the input descriptor */
|
||||
if (S->in_sqlda) {
|
||||
free_sqlda(S->in_sqlda);
|
||||
efree(S->in_sqlda);
|
||||
}
|
||||
|
||||
free_sqlda(&S->out_sqlda);
|
||||
efree(S);
|
||||
|
||||
return result;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* called by PDO to execute a prepared query */
|
||||
static int firebird_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
|
||||
pdo_firebird_db_handle *H = S->H;
|
||||
|
||||
do {
|
||||
/* named cursors should be closed first */
|
||||
if (*S->name && isc_dsql_free_statement(H->isc_status, &S->stmt, DSQL_close)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* assume all params have been bound */
|
||||
|
||||
if ((S->statement_type == isc_info_sql_stmt_exec_procedure &&
|
||||
isc_dsql_execute2(H->isc_status, &H->tr, &S->stmt, PDO_FB_SQLDA_VERSION,
|
||||
S->in_sqlda, &S->out_sqlda))
|
||||
|| isc_dsql_execute(H->isc_status, &H->tr, &S->stmt, PDO_FB_SQLDA_VERSION,
|
||||
S->in_sqlda)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* commit? */
|
||||
if (stmt->dbh->auto_commit && isc_commit_retaining(H->isc_status, &H->tr)) {
|
||||
break;
|
||||
}
|
||||
|
||||
*S->name = 0;
|
||||
S->exhausted = 0;
|
||||
|
||||
return 1;
|
||||
} while (0);
|
||||
|
||||
RECORD_ERROR(stmt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* called by PDO to fetch the next row from a statement */
|
||||
static int firebird_stmt_fetch(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
|
||||
pdo_firebird_db_handle *H = S->H;
|
||||
|
||||
if (!stmt->executed) {
|
||||
stmt->error_code = PDO_ERR_CANT_MAP;
|
||||
H->last_app_error = "Cannot fetch from a closed cursor";
|
||||
} else if (!S->exhausted) {
|
||||
|
||||
/* an EXECUTE PROCEDURE statement can be fetched from once, without calling the API, because
|
||||
* the result was returned in the execute call */
|
||||
if (S->statement_type == isc_info_sql_stmt_exec_procedure) {
|
||||
S->exhausted = 1;
|
||||
} else {
|
||||
if (isc_dsql_fetch(H->isc_status, &S->stmt, PDO_FB_SQLDA_VERSION, &S->out_sqlda)) {
|
||||
if (H->isc_status[0] && H->isc_status[1]) {
|
||||
RECORD_ERROR(stmt);
|
||||
}
|
||||
S->exhausted = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* called by PDO to retrieve information about the fields being returned */
|
||||
static int firebird_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
|
||||
struct pdo_column_data *col = &stmt->columns[colno];
|
||||
XSQLVAR *var = &S->out_sqlda.sqlvar[colno];
|
||||
|
||||
/* allocate storage for the column */
|
||||
var->sqlind = (void*)emalloc(var->sqllen + 2*sizeof(short));
|
||||
var->sqldata = &((char*)var->sqlind)[sizeof(short)];
|
||||
|
||||
col->precision = -var->sqlscale;
|
||||
col->maxlen = var->sqllen;
|
||||
col->namelen = var->aliasname_length;
|
||||
col->name = estrndup(var->aliasname,var->aliasname_length);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#if abies_0
|
||||
/* internal function to override return types of parameters */
|
||||
static void set_param_type(enum pdo_param_type *param_type, XSQLVAR const *var) /* {{{ */
|
||||
{
|
||||
/* set the param type after the field type */
|
||||
switch (var->sqltype & ~1) {
|
||||
case SQL_INT64:
|
||||
#if SIZEOF_LONG < 8
|
||||
if (0) /* always a string if its size exceeds native long */
|
||||
#endif
|
||||
case SQL_SHORT:
|
||||
case SQL_LONG:
|
||||
if (var->sqlscale == 0) {
|
||||
*param_type = PDO_PARAM_INT;
|
||||
break;
|
||||
}
|
||||
case SQL_TEXT:
|
||||
case SQL_VARYING:
|
||||
case SQL_TYPE_DATE:
|
||||
case SQL_TYPE_TIME:
|
||||
case SQL_TIMESTAMP:
|
||||
case SQL_BLOB:
|
||||
*param_type = PDO_PARAM_STR;
|
||||
break;
|
||||
case SQL_FLOAT:
|
||||
case SQL_DOUBLE:
|
||||
*param_type = PDO_PARAM_DBL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
#define FETCH_BUF(buf,type,len,lenvar) ((buf) = (buf) ? (buf) : \
|
||||
emalloc((len) ? (len * sizeof(type)) : ((*(unsigned long*)lenvar) = sizeof(type))))
|
||||
|
||||
/* fetch a blob into a fetch buffer */
|
||||
static int firebird_fetch_blob(pdo_stmt_t *stmt, int colno, char **ptr, /* {{{ */
|
||||
unsigned long *len, ISC_QUAD *blob_id TSRMLS_DC)
|
||||
{
|
||||
pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
|
||||
pdo_firebird_db_handle *H = S->H;
|
||||
isc_blob_handle blobh = NULL;
|
||||
char const bl_item = isc_info_blob_total_length;
|
||||
char bl_info[20];
|
||||
unsigned short i;
|
||||
int result = *len = 0;
|
||||
|
||||
if (isc_open_blob(H->isc_status, &H->db, &H->tr, &blobh, blob_id)) {
|
||||
RECORD_ERROR(stmt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (isc_blob_info(H->isc_status, &blobh, 1, const_cast(&bl_item),
|
||||
sizeof(bl_info), bl_info)) {
|
||||
RECORD_ERROR(stmt);
|
||||
goto fetch_blob_end;
|
||||
}
|
||||
|
||||
/* find total length of blob's data */
|
||||
for (i = 0; i < sizeof(bl_info); ) {
|
||||
unsigned short item_len;
|
||||
char item = bl_info[i++];
|
||||
|
||||
if (item == isc_info_end || item == isc_info_truncated || item == isc_info_error
|
||||
|| i >= sizeof(bl_info)) {
|
||||
H->last_app_error = "Couldn't determine BLOB size";
|
||||
goto fetch_blob_end;
|
||||
}
|
||||
|
||||
item_len = (unsigned short) isc_vax_integer(&bl_info[i], 2);
|
||||
|
||||
if (item == isc_info_blob_total_length) {
|
||||
*len = isc_vax_integer(&bl_info[i+2], item_len);
|
||||
break;
|
||||
}
|
||||
i += item_len+2;
|
||||
}
|
||||
|
||||
/* we've found the blob's length, now fetch! */
|
||||
|
||||
if (*len) {
|
||||
unsigned long cur_len;
|
||||
unsigned short seg_len;
|
||||
ISC_STATUS stat;
|
||||
|
||||
*ptr = S->fetch_buf[colno] = erealloc(*ptr, *len+1);
|
||||
|
||||
for (cur_len = stat = 0; (!stat || stat == isc_segment) && cur_len < *len; cur_len += seg_len) {
|
||||
|
||||
unsigned short chunk_size = (*len-cur_len) > USHRT_MAX ? USHRT_MAX
|
||||
: (unsigned short)(*len-cur_len);
|
||||
|
||||
stat = isc_get_segment(H->isc_status, &blobh, &seg_len, chunk_size, &(*ptr)[cur_len]);
|
||||
}
|
||||
|
||||
(*ptr)[*len++] = '\0';
|
||||
|
||||
if (H->isc_status[0] == 1 && (stat != 0 && stat != isc_segstr_eof && stat != isc_segment)) {
|
||||
H->last_app_error = "Error reading from BLOB";
|
||||
goto fetch_blob_end;
|
||||
}
|
||||
}
|
||||
result = 1;
|
||||
|
||||
fetch_blob_end:
|
||||
if (isc_close_blob(H->isc_status, &blobh)) {
|
||||
RECORD_ERROR(stmt);
|
||||
return 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int firebird_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, /* {{{ */
|
||||
unsigned long *len TSRMLS_DC)
|
||||
{
|
||||
pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
|
||||
XSQLVAR const *var = &S->out_sqlda.sqlvar[colno];
|
||||
|
||||
if (*var->sqlind == -1) {
|
||||
/* A NULL value */
|
||||
*ptr = NULL;
|
||||
*len = 0;
|
||||
} else {
|
||||
/* override the column param type */
|
||||
/* set_param_type(&stmt->columns[colno].param_type,var); */
|
||||
stmt->columns[colno].param_type = PDO_PARAM_STR;
|
||||
|
||||
if (var->sqlscale < 0) {
|
||||
static ISC_INT64 const scales[] = { 1, 10, 100, 1000, 10000, 100000, 1000000,
|
||||
100000000, 1000000000, 1000000000, LL_LIT(10000000000),LL_LIT(100000000000),
|
||||
LL_LIT(10000000000000), LL_LIT(100000000000000),LL_LIT(1000000000000000),
|
||||
LL_LIT(1000000000000000),LL_LIT(1000000000000000000) };
|
||||
ISC_INT64 n, f = scales[-var->sqlscale];
|
||||
|
||||
switch (var->sqltype & ~1) {
|
||||
case SQL_SHORT:
|
||||
n = *(short*)var->sqldata;
|
||||
break;
|
||||
case SQL_LONG:
|
||||
n = *(ISC_LONG*)var->sqldata;
|
||||
break;
|
||||
case SQL_INT64:
|
||||
n = *(ISC_INT64*)var->sqldata;
|
||||
}
|
||||
|
||||
*ptr = FETCH_BUF(S->fetch_buf[colno], char, 24, NULL);
|
||||
|
||||
if (n >= 0) {
|
||||
*len = sprintf(*ptr, "%" LL_MASK "d.%0*" LL_MASK "d",
|
||||
n / f, -var->sqlscale, n % f);
|
||||
} else if (n < -f) {
|
||||
*len = sprintf(*ptr, "%" LL_MASK "d.%0*" LL_MASK "d",
|
||||
n / f, -var->sqlscale, -n % f);
|
||||
} else {
|
||||
*len = sprintf(*ptr, "-0.%0*" LL_MASK "d", -var->sqlscale, -n % f);
|
||||
}
|
||||
} else {
|
||||
switch (var->sqltype & ~1) {
|
||||
struct tm t;
|
||||
char *fmt;
|
||||
|
||||
/**
|
||||
* For the time being, this code has been changed to convert every returned value to a string
|
||||
* before passing it back up to the PDO driver.
|
||||
*/
|
||||
|
||||
case SQL_VARYING:
|
||||
*ptr = &var->sqldata[2];
|
||||
*len = *(short*)var->sqldata;
|
||||
break;
|
||||
case SQL_TEXT:
|
||||
*ptr = var->sqldata;
|
||||
*len = var->sqllen;
|
||||
break;
|
||||
// --- cut here ---
|
||||
case SQL_SHORT:
|
||||
*ptr = FETCH_BUF(S->fetch_buf[colno], char, 24, NULL);
|
||||
*len = sprintf(*ptr, "%d", *(short*)var->sqldata);
|
||||
break;
|
||||
case SQL_LONG:
|
||||
*ptr = FETCH_BUF(S->fetch_buf[colno], char, 24, NULL);
|
||||
*len = sprintf(*ptr, "%ld", *(ISC_LONG*)var->sqldata);
|
||||
break;
|
||||
case SQL_INT64:
|
||||
*ptr = FETCH_BUF(S->fetch_buf[colno], char, 24, NULL);
|
||||
*len = sprintf(*ptr, "%" LL_MASK "d", *(ISC_INT64*)var->sqldata);
|
||||
break;
|
||||
case SQL_FLOAT:
|
||||
*ptr = FETCH_BUF(S->fetch_buf[colno], char, 24, NULL);
|
||||
*len = sprintf(*ptr, "%f", *(float*)var->sqldata);
|
||||
break;
|
||||
case SQL_DOUBLE:
|
||||
*ptr = FETCH_BUF(S->fetch_buf[colno], char, 24, NULL);
|
||||
*len = sprintf(*ptr, "%f" , *(double*)var->sqldata);
|
||||
break;
|
||||
// --- cut here ---
|
||||
#if abies_0
|
||||
case SQL_SHORT:
|
||||
*ptr = FETCH_BUF(S->fetch_buf[colno], long, 0, *len);
|
||||
*(long*)*ptr = *(short*)var->sqldata;
|
||||
break;
|
||||
case SQL_LONG:
|
||||
#if SIZEOF_LONG == 8
|
||||
*ptr = FETCH_BUF(S->fetch_buf[colno], long, 0, *len);
|
||||
*(long*)*ptr = *(ISC_LONG*)var->sqldata;
|
||||
#else
|
||||
*ptr = var->sqldata;
|
||||
#endif
|
||||
break;
|
||||
case SQL_INT64:
|
||||
*len = sizeof(long);
|
||||
#if SIZEOF_LONG == 8
|
||||
*ptr = var->sqldata;
|
||||
#else
|
||||
*ptr = FETCH_BUF(S->fetch_buf[colno], char, 20, NULL);
|
||||
*len = sprintf(*ptr, "%" LL_MASK "d", *(ISC_INT64*)var->sqldata);
|
||||
#endif
|
||||
break;
|
||||
case SQL_FLOAT:
|
||||
*ptr = FETCH_BUF(S->fetch_buf[colno], double, 0, *len);
|
||||
*(double*)*ptr = *(float*)var->sqldata;
|
||||
break;
|
||||
case SQL_DOUBLE:
|
||||
*ptr = var->sqldata;
|
||||
*len = sizeof(double);
|
||||
break;
|
||||
#endif
|
||||
case SQL_TYPE_DATE:
|
||||
isc_decode_sql_date((ISC_DATE*)var->sqldata, &t);
|
||||
fmt = INI_STR("ibase.dateformat");
|
||||
if (0) {
|
||||
case SQL_TYPE_TIME:
|
||||
isc_decode_sql_time((ISC_TIME*)var->sqldata, &t);
|
||||
fmt = INI_STR("ibase.timeformat");
|
||||
} else if (0) {
|
||||
case SQL_TIMESTAMP:
|
||||
isc_decode_timestamp((ISC_TIMESTAMP*)var->sqldata, &t);
|
||||
fmt = INI_STR("ibase.timestampformat");
|
||||
}
|
||||
|
||||
/* convert the timestamp into a string */
|
||||
*ptr = FETCH_BUF(S->fetch_buf[colno], char, *len = 80, NULL);
|
||||
*len = strftime(*ptr, *len, fmt, &t);
|
||||
break;
|
||||
case SQL_BLOB:
|
||||
return firebird_fetch_blob(stmt,colno,ptr,len,
|
||||
(ISC_QUAD*)var->sqldata TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int firebird_bind_blob(pdo_stmt_t *stmt, ISC_QUAD *blob_id, zval *param TSRMLS_DC)
|
||||
{
|
||||
pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
|
||||
pdo_firebird_db_handle *H = S->H;
|
||||
isc_blob_handle h = NULL;
|
||||
unsigned long put_cnt = 0, rem_cnt;
|
||||
unsigned short chunk_size;
|
||||
int result = 1;
|
||||
|
||||
if (isc_create_blob(H->isc_status, &H->db, &H->tr, &h, blob_id)) {
|
||||
RECORD_ERROR(stmt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SEPARATE_ZVAL(¶m);
|
||||
|
||||
convert_to_string_ex(¶m);
|
||||
|
||||
for (rem_cnt = Z_STRLEN_P(param); rem_cnt > 0; rem_cnt -= chunk_size) {
|
||||
|
||||
chunk_size = rem_cnt > USHRT_MAX ? USHRT_MAX : (unsigned short)rem_cnt;
|
||||
|
||||
if (isc_put_segment(H->isc_status, &h, chunk_size, &Z_STRVAL_P(param)[put_cnt])) {
|
||||
RECORD_ERROR(stmt);
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
put_cnt += chunk_size;
|
||||
}
|
||||
|
||||
zval_dtor(param);
|
||||
|
||||
if (isc_close_blob(H->isc_status, &h)) {
|
||||
RECORD_ERROR(stmt);
|
||||
return 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, /* {{{ */
|
||||
enum pdo_param_event event_type TSRMLS_DC)
|
||||
{
|
||||
pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
|
||||
XSQLDA *sqlda = param->is_param ? S->in_sqlda : &S->out_sqlda;
|
||||
XSQLVAR *var;
|
||||
|
||||
if (event_type == PDO_PARAM_EVT_FREE) { /* not used */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!sqlda || param->paramno >= sqlda->sqld) {
|
||||
stmt->error_code = PDO_ERR_NOT_FOUND;
|
||||
S->H->last_app_error = "Invalid parameter index";
|
||||
return 0;
|
||||
}
|
||||
if (param->is_param && param->paramno == -1) {
|
||||
long *index;
|
||||
|
||||
/* try to determine the index by looking in the named_params hash */
|
||||
if (SUCCESS == zend_hash_find(S->named_params, param->name, param->namelen+1, (void*)&index)) {
|
||||
param->paramno = *index;
|
||||
} else {
|
||||
/* ... or by looking in the input descriptor */
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sqlda->sqld; ++i) {
|
||||
XSQLVAR *var = &sqlda->sqlvar[i];
|
||||
|
||||
if ((var->aliasname_length && !strncasecmp(param->name, var->aliasname,
|
||||
min(param->namelen, var->aliasname_length)))
|
||||
|| (var->sqlname_length && !strncasecmp(param->name, var->sqlname,
|
||||
min(param->namelen, var->sqlname_length)))) {
|
||||
param->paramno = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= sqlda->sqld) {
|
||||
stmt->error_code = PDO_ERR_NOT_FOUND;
|
||||
S->H->last_app_error = "Invalid parameter name";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var = &sqlda->sqlvar[param->paramno];
|
||||
|
||||
switch (event_type) {
|
||||
char *value;
|
||||
unsigned long value_len;
|
||||
|
||||
case PDO_PARAM_EVT_ALLOC:
|
||||
if (param->is_param) {
|
||||
/* allocate the parameter */
|
||||
var->sqlind = (void*)emalloc(var->sqllen + 2*sizeof(short));
|
||||
var->sqldata = &((char*)var->sqlind)[sizeof(short)];
|
||||
}
|
||||
break;
|
||||
|
||||
case PDO_PARAM_EVT_EXEC_PRE:
|
||||
if (!param->is_param) {
|
||||
break;
|
||||
}
|
||||
|
||||
*var->sqlind = 0;
|
||||
|
||||
switch (var->sqltype & ~1) {
|
||||
case SQL_ARRAY:
|
||||
stmt->error_code = PDO_ERR_NOT_IMPLEMENTED;
|
||||
S->H->last_app_error = "Cannot bind to array field";
|
||||
return 0;
|
||||
|
||||
case SQL_BLOB:
|
||||
return firebird_bind_blob(stmt, (ISC_QUAD*)var->sqldata,
|
||||
param->parameter TSRMLS_CC);
|
||||
}
|
||||
|
||||
/* check if a NULL should be inserted */
|
||||
switch (Z_TYPE_P(param->parameter)) {
|
||||
int force_null;
|
||||
|
||||
case IS_LONG:
|
||||
var->sqltype = sizeof(long) == 8 ? SQL_INT64 : SQL_LONG;
|
||||
var->sqldata = (void*)&Z_LVAL_P(param->parameter);
|
||||
var->sqllen = sizeof(long);
|
||||
break;
|
||||
case IS_DOUBLE:
|
||||
var->sqltype = SQL_DOUBLE;
|
||||
var->sqldata = (void*)&Z_DVAL_P(param->parameter);
|
||||
var->sqllen = sizeof(double);
|
||||
break;
|
||||
case IS_STRING:
|
||||
force_null = 0;
|
||||
|
||||
/* for these types, an empty string can be handled like a NULL value */
|
||||
switch (var->sqltype & ~1) {
|
||||
case SQL_SHORT:
|
||||
case SQL_LONG:
|
||||
case SQL_INT64:
|
||||
case SQL_FLOAT:
|
||||
case SQL_DOUBLE:
|
||||
case SQL_TIMESTAMP:
|
||||
case SQL_TYPE_DATE:
|
||||
case SQL_TYPE_TIME:
|
||||
force_null = (Z_STRLEN_P(param->parameter) == 0);
|
||||
}
|
||||
if (!force_null) {
|
||||
var->sqltype = SQL_TEXT;
|
||||
var->sqldata = Z_STRVAL_P(param->parameter);
|
||||
var->sqllen = Z_STRLEN_P(param->parameter);
|
||||
break;
|
||||
}
|
||||
case IS_NULL:
|
||||
/* complain if this field doesn't allow NULL values */
|
||||
if (~var->sqltype & 1) {
|
||||
stmt->error_code = PDO_ERR_CONSTRAINT;
|
||||
S->H->last_app_error = "Parameter requires non-null value";
|
||||
return 0;
|
||||
}
|
||||
*var->sqlind = -1;
|
||||
break;
|
||||
default:
|
||||
stmt->error_code = PDO_ERR_NOT_IMPLEMENTED;
|
||||
S->H->last_app_error = "Binding arrays/objects is not supported";
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case PDO_PARAM_EVT_FETCH_POST:
|
||||
value = NULL;
|
||||
value_len = 0;
|
||||
|
||||
if (firebird_stmt_get_col(stmt, param->paramno, &value, &value_len TSRMLS_CC)) {
|
||||
switch (param->param_type) {
|
||||
case PDO_PARAM_STR:
|
||||
if (value) {
|
||||
ZVAL_STRINGL(param->parameter, value, value_len, 1);
|
||||
break;
|
||||
}
|
||||
case PDO_PARAM_INT:
|
||||
if (value) {
|
||||
ZVAL_LONG(param->parameter, *(long*)value);
|
||||
break;
|
||||
}
|
||||
#if abies_0
|
||||
case PDO_PARAM_DBL:
|
||||
if (value) {
|
||||
ZVAL_DOUBLE(param->parameter, *(double*)value);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
ZVAL_NULL(param->parameter);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int firebird_stmt_set_attribute(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
|
||||
|
||||
switch (attr) {
|
||||
default:
|
||||
return 0;
|
||||
case PDO_ATTR_CURSOR_NAME:
|
||||
convert_to_string(val);
|
||||
|
||||
if (isc_dsql_set_cursor_name(S->H->isc_status, &S->stmt, Z_STRVAL_P(val),0)) {
|
||||
RECORD_ERROR(stmt);
|
||||
return 0;
|
||||
}
|
||||
strncpy(S->name, Z_STRVAL_P(val), sizeof(S->name));
|
||||
S->name[sizeof(S->name)] = 0;
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int firebird_stmt_get_attribute(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
|
||||
|
||||
switch (attr) {
|
||||
default:
|
||||
return 0;
|
||||
case PDO_ATTR_CURSOR_NAME:
|
||||
if (*S->name) {
|
||||
ZVAL_STRING(val,S->name,1);
|
||||
} else {
|
||||
ZVAL_NULL(val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
struct pdo_stmt_methods firebird_stmt_methods = { /* {{{ */
|
||||
firebird_stmt_dtor,
|
||||
firebird_stmt_execute,
|
||||
firebird_stmt_fetch,
|
||||
firebird_stmt_describe,
|
||||
firebird_stmt_get_col,
|
||||
firebird_stmt_param_hook,
|
||||
firebird_stmt_set_attribute,
|
||||
firebird_stmt_get_attribute
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* 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,55 +0,0 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE package SYSTEM "../pear/package.dtd">
|
||||
<package version="1.0"><!-- $Id: package.xml,v 1.5 2004-06-23 13:42:06 abies Exp $ -->
|
||||
<name>PDO_FIREBIRD</name>
|
||||
<summary>Firebird/InterBase 6 driver for PDO</summary>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>abies</user>
|
||||
<name>Ard Biesheuvel</name>
|
||||
<email>abies@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
<configureoptions>
|
||||
<configureoption name="with-pdo-firebird" prompt="dir"/>
|
||||
</configureoptions>
|
||||
<description>
|
||||
This extension provides a Firebird/InterBase driver for PDO. It supports
|
||||
all versions of Firebird and InterBase versions 6 and up.
|
||||
</description>
|
||||
<license>PHP</license>
|
||||
<release>
|
||||
<state>alpha</state>
|
||||
<version>0.1</version>
|
||||
<date>2004-06-23</date>
|
||||
|
||||
<notes>
|
||||
To compile and run this module, you will need to have the main PDO module and Firebird's
|
||||
or InterBase's client library installed on your system.
|
||||
</notes>
|
||||
|
||||
<filelist>
|
||||
<file role="doc" name="CREDITS"/>
|
||||
|
||||
<file role="src" name="config.m4"/>
|
||||
<file role="src" name="config.w32"/>
|
||||
<file role="src" name="firebird_driver.c"/>
|
||||
<file role="src" name="firebird_statement.c"/>
|
||||
<file role="src" name="pdo_firebird.c"/>
|
||||
<file role="src" name="php_pdo_firebird.h"/>
|
||||
<file role="src" name="php_pdo_firebird_int.h"/>
|
||||
|
||||
<dir name="tests">
|
||||
<file role="test">connect.phpt</file>
|
||||
<file role="test">ddl.phpt</file>
|
||||
<file role="test">execute.phpt</file>
|
||||
</dir>
|
||||
|
||||
</filelist>
|
||||
<deps>
|
||||
<dep type="php" rel="ge" version="5.0.0"/>
|
||||
<dep type="ext" rel="ge" name="pdo" version="0.1"/>
|
||||
</deps>
|
||||
</release>
|
||||
</package>
|
||||
@@ -1,87 +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: Ard Biesheuvel <abies@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "pdo/php_pdo.h"
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_firebird.h"
|
||||
#include "php_pdo_firebird_int.h"
|
||||
|
||||
function_entry pdo_firebird_functions[] = { /* {{{ */
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
zend_module_entry pdo_firebird_module_entry = { /* {{{ */
|
||||
STANDARD_MODULE_HEADER,
|
||||
"PDO_Firebird",
|
||||
pdo_firebird_functions,
|
||||
PHP_MINIT(pdo_firebird),
|
||||
PHP_MSHUTDOWN(pdo_firebird),
|
||||
NULL,
|
||||
NULL,
|
||||
PHP_MINFO(pdo_firebird),
|
||||
"0.1",
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_PDO_FIREBIRD
|
||||
ZEND_GET_MODULE(pdo_firebird)
|
||||
#endif
|
||||
|
||||
PHP_MINIT_FUNCTION(pdo_firebird) /* {{{ */
|
||||
{
|
||||
php_pdo_register_driver(&pdo_firebird_driver);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo_firebird) /* {{{ */
|
||||
{
|
||||
php_pdo_unregister_driver(&pdo_firebird_driver);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHP_MINFO_FUNCTION(pdo_firebird) /* {{{ */
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "PDO Driver for Firebird/InterBase", "enabled");
|
||||
php_info_print_table_end();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* 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,58 +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: Ard Biesheuvel <abies@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef PHP_PDO_FIREBIRD_H
|
||||
#define PHP_PDO_FIREBIRD_H
|
||||
|
||||
extern zend_module_entry pdo_firebird_module_entry;
|
||||
#define phpext_pdo_firebird_ptr &pdo_firebird_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
# ifdef PDO_FIREBIRD_EXPORTS
|
||||
# define PDO_FB_API __declspec(dllexport)
|
||||
# elif defined(COMPILE_DL_PDO_FIREBIRD)
|
||||
# define PDO_FB_API __declspec(dllimport)
|
||||
# else
|
||||
# define PDO_FB_API
|
||||
# endif
|
||||
#else
|
||||
# define PDO_FB_API
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
PHP_MINIT_FUNCTION(pdo_firebird);
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo_firebird);
|
||||
PHP_RINIT_FUNCTION(pdo_firebird);
|
||||
PHP_RSHUTDOWN_FUNCTION(pdo_firebird);
|
||||
PHP_MINFO_FUNCTION(pdo_firebird);
|
||||
|
||||
#endif /* PHP_PDO_FIREBIRD_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,127 +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: Ard Biesheuvel <abies@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef PHP_PDO_FIREBIRD_INT_H
|
||||
#define PHP_PDO_FIREBIRD_INT_H
|
||||
|
||||
#include <ibase.h>
|
||||
|
||||
#ifdef SQLDA_VERSION
|
||||
#define PDO_FB_SQLDA_VERSION SQLDA_VERSION
|
||||
#else
|
||||
#define PDO_FB_SQLDA_VERSION 1
|
||||
#endif
|
||||
|
||||
#define PDO_FB_DIALECT 3
|
||||
|
||||
#define SHORT_MAX (1 << (8*sizeof(short)-1))
|
||||
|
||||
#if SIZEOF_LONG == 8
|
||||
# define LL_MASK l
|
||||
# define LL_LIT(lit) lit ## L
|
||||
#else
|
||||
# ifdef PHP_WIN32
|
||||
# define LL_MASK "I64"
|
||||
# define LL_LIT(lit) lit ## I64
|
||||
# else
|
||||
# define LL_MASK "ll"
|
||||
# define LL_LIT(lit) lit ## LL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Firebird API has a couple of missing const decls in its API */
|
||||
#define const_cast(s) ((char*)(s))
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
typedef void (__stdcall *info_func_t)(char*);
|
||||
#else
|
||||
typedef void (*info_func_t)(char*);
|
||||
#endif
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
|
||||
/* the result of the last API call */
|
||||
ISC_STATUS isc_status[20];
|
||||
|
||||
/* the connection handle */
|
||||
isc_db_handle db;
|
||||
|
||||
/* the transaction handle */
|
||||
isc_tr_handle tr;
|
||||
|
||||
/* the last error that didn't come from the API */
|
||||
char const *last_app_error;
|
||||
|
||||
} pdo_firebird_db_handle;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
/* the link that owns this statement */
|
||||
pdo_firebird_db_handle *H;
|
||||
|
||||
/* the statement handle */
|
||||
isc_stmt_handle stmt;
|
||||
|
||||
/* the name of the cursor (if it has one) */
|
||||
char name[32];
|
||||
|
||||
/* the type of statement that was issued */
|
||||
char statement_type:8;
|
||||
|
||||
/* whether EOF was reached for this statement */
|
||||
unsigned exhausted:1;
|
||||
|
||||
unsigned _reserved:23;
|
||||
|
||||
/* the named params that were converted to ?'s by the driver */
|
||||
HashTable *named_params;
|
||||
|
||||
/* allocated space to convert fields values to other types */
|
||||
char **fetch_buf;
|
||||
|
||||
/* the input SQLDA */
|
||||
XSQLDA *in_sqlda;
|
||||
|
||||
/* the output SQLDA */
|
||||
XSQLDA out_sqlda; /* last member */
|
||||
|
||||
} pdo_firebird_stmt;
|
||||
|
||||
extern pdo_driver_t pdo_firebird_driver;
|
||||
|
||||
extern struct pdo_stmt_methods firebird_stmt_methods;
|
||||
|
||||
void _firebird_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, char const *file, long line TSRMLS_DC);
|
||||
|
||||
#endif /* PHP_PDO_FIREBIRD_INT_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,16 +0,0 @@
|
||||
--TEST--
|
||||
PDO_Firebird: connect/disconnect
|
||||
--SKIPIF--
|
||||
<?php include("skipif.inc"); ?>
|
||||
--FILE--
|
||||
<?php /* $Id$ */
|
||||
|
||||
require("testdb.inc");
|
||||
|
||||
$db = new PDO("firebird:dbname=$test_base",$user,$password) or die;
|
||||
unset($db);
|
||||
echo "done\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
done
|
||||
@@ -1,37 +0,0 @@
|
||||
--TEST--
|
||||
PDO_Firebird: DDL/transactions
|
||||
--SKIPIF--
|
||||
<?php include("skipif.inc"); ?>
|
||||
--FILE--
|
||||
<?php /* $Id$ */
|
||||
|
||||
require("testdb.inc");
|
||||
|
||||
$db = new PDO("firebird:dbname=$test_base",$user,$password) or die;
|
||||
$db->setAttribute(PDO_ATTR_ERRMODE, PDO_ERRMODE_WARNING);
|
||||
|
||||
$db->exec("CREATE TABLE ddl (id INT NOT NULL PRIMARY KEY, text BLOB SUB_TYPE 1)");
|
||||
$db->exec("CREATE GENERATOR gen_ddl_id");
|
||||
$db->exec("CREATE TRIGGER ddl_bi FOR ddl BEFORE INSERT AS
|
||||
BEGIN IF (NEW.id IS NULL) THEN NEW.id=GEN_ID(gen_ddl_id,1); END");
|
||||
|
||||
$db->setAttribute(PDO_ATTR_AUTOCOMMIT,0);
|
||||
|
||||
$db->beginTransaction();
|
||||
var_dump($db->exec("INSERT INTO ddl (text) VALUES ('bla')"));
|
||||
var_dump($db->exec("UPDATE ddl SET text='blabla'"));
|
||||
$db->rollback();
|
||||
|
||||
$db->beginTransaction();
|
||||
var_dump($db->exec("DELETE FROM ddl"));
|
||||
$db->commit();
|
||||
|
||||
unset($db);
|
||||
echo "done\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
int(1)
|
||||
int(0)
|
||||
done
|
||||
@@ -1,65 +0,0 @@
|
||||
--TEST--
|
||||
PDO_Firebird: prepare/execute/binding
|
||||
--SKIPIF--
|
||||
<?php include("skipif.inc"); ?>
|
||||
--INI--
|
||||
ibase.timestampformat=%Y-%m-%d %H:%M:%S
|
||||
--FILE--
|
||||
<?php /* $Id$ */
|
||||
|
||||
require("testdb.inc");
|
||||
|
||||
$db = new PDO("firebird:dbname=$test_base",$user,$password) or die;
|
||||
|
||||
var_dump($db->getAttribute(PDO_ATTR_CONNECTION_STATUS));
|
||||
|
||||
$db->setAttribute(PDO_ATTR_ERRMODE, PDO_ERRMODE_WARNING);
|
||||
|
||||
$db->exec("CREATE TABLE ddl (id SMALLINT NOT NULL PRIMARY KEY, text VARCHAR(32),
|
||||
datetime TIMESTAMP DEFAULT '2000-02-12' NOT NULL)");
|
||||
$db->exec("INSERT INTO ddl (id,text) VALUES (1,'bla')");
|
||||
|
||||
$s = $db->prepare("SELECT * FROM ddl WHERE id=? FOR UPDATE");
|
||||
|
||||
$s->bindParam(1,$id = 0);
|
||||
$s->bindColumn("TEXT",$var = null);
|
||||
$id = 1;
|
||||
$s->execute();
|
||||
$s->setAttribute(PDO_ATTR_CURSOR_NAME, "c");
|
||||
|
||||
var_dump($id);
|
||||
|
||||
var_dump($s->fetch());
|
||||
|
||||
var_dump($var);
|
||||
|
||||
var_dump($db->exec("UPDATE ddl SET id=2 WHERE CURRENT OF c"));
|
||||
|
||||
var_dump($s->fetch());
|
||||
|
||||
unset($s);
|
||||
unset($db);
|
||||
echo "done\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
int(1)
|
||||
array(6) {
|
||||
["ID"]=>
|
||||
string(1) "1"
|
||||
[0]=>
|
||||
string(1) "1"
|
||||
["TEXT"]=>
|
||||
string(3) "bla"
|
||||
[1]=>
|
||||
string(3) "bla"
|
||||
["DATETIME"]=>
|
||||
string(19) "2000-02-12 00:00:00"
|
||||
[2]=>
|
||||
string(19) "2000-02-12 00:00:00"
|
||||
}
|
||||
string(3) "bla"
|
||||
int(1)
|
||||
bool(false)
|
||||
done
|
||||
@@ -1,5 +0,0 @@
|
||||
<?php /* $Id$ */
|
||||
|
||||
if (!extension_loaded("interbase") || !extension_loaded("pdo_firebird")) print "skip";
|
||||
|
||||
?>
|
||||
@@ -1,34 +0,0 @@
|
||||
<?php /* $Id$ */
|
||||
|
||||
$user = 'SYSDBA';
|
||||
$password = 'masterkey';
|
||||
ini_set('ibase.default_user',$user);
|
||||
ini_set('ibase.default_password',$password);
|
||||
|
||||
/* we need just the generated name, not the file itself */
|
||||
unlink($test_base = tempnam('/tmp',"php_ibase_test"));
|
||||
|
||||
function init_db()
|
||||
{
|
||||
global $test_base, $user, $password;
|
||||
|
||||
$test_db = ibase_query(IBASE_CREATE,sprintf("CREATE DATABASE '%s' USER '%s' PASSWORD '%s'",
|
||||
$test_base, $user, $password));
|
||||
$tr = ibase_trans($test_db);
|
||||
ibase_query($tr,"create table test1 (i integer, c varchar(100))");
|
||||
ibase_commit_ret($tr);
|
||||
ibase_query($tr,"insert into test1(i, c) values(1, 'test table not created with isql')");
|
||||
ibase_commit($tr);
|
||||
ibase_close($test_db);
|
||||
}
|
||||
|
||||
function cleanup_db()
|
||||
{
|
||||
global $test_base;
|
||||
|
||||
$r = ibase_connect($test_base);
|
||||
ibase_drop_db($r);
|
||||
}
|
||||
|
||||
register_shutdown_function('cleanup_db');
|
||||
init_db();
|
||||
@@ -1,2 +0,0 @@
|
||||
mySQL 3.x driver for PDO
|
||||
George Schlossnagle
|
||||
@@ -1,70 +0,0 @@
|
||||
dnl
|
||||
dnl $Id$
|
||||
dnl
|
||||
|
||||
AC_DEFUN(MYSQL_LIB_CHK, [
|
||||
str="$MYSQL_DIR/$1/libmysqlclient.*"
|
||||
for j in `echo $str`; do
|
||||
if test -r $j; then
|
||||
MYSQL_LIB_DIR=$MYSQL_DIR/$1
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
])
|
||||
|
||||
PHP_ARG_WITH(pdo_mysql, for MySQL support,
|
||||
[ --with-pdo_mysql[=DIR] Include MySQL support. DIR is the MySQL base directory.])
|
||||
|
||||
if test "$PHP_PDO_MYSQL" != "no"; then
|
||||
AC_DEFINE(HAVE_MYSQL, 1, [Whether you have MySQL])
|
||||
|
||||
for i in $PHP_PDO_MYSQL /usr/local /usr ; do
|
||||
MYSQL_DIR=$i
|
||||
PDO_MYSQL_CONFIG=$MYSQL_DIR/bin/mysql_config
|
||||
if test -r $i/include/mysql; then
|
||||
MYSQL_INC_DIR=$i/include/mysql
|
||||
else
|
||||
MYSQL_INC_DIR=$i/include
|
||||
fi
|
||||
if test -r $i/lib/mysql; then
|
||||
MYSQL_LIBS=$i/lib/mysql
|
||||
else
|
||||
MYSQL_LIBS=$i/lib
|
||||
fi
|
||||
if test -x $PDO_MYSQL_CONFIG; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if test -z "$MYSQL_DIR"; then
|
||||
AC_MSG_ERROR([Cannot find MySQL header files under $PHP_MYSQL.
|
||||
Note that the MySQL client library is not bundled anymore.])
|
||||
fi
|
||||
|
||||
PDO_MYSQL_LIBS=`$PDO_MYSQL_CONFIG --libs`
|
||||
PDO_MYSQL_SOCKET=`$PDO_MYSQL_CONFIG --socket`
|
||||
|
||||
AC_DEFINE_UNQUOTED(PDO_MYSQL_UNIX_ADDR, "$PDO_MYSQL_SOCKET", [ ])
|
||||
|
||||
PHP_ADD_LIBRARY_WITH_PATH(mysqlclient, $MYSQL_LIBS, PDO_MYSQL_SHARED_LIBADD)
|
||||
PHP_ADD_INCLUDE($MYSQL_INC_DIR)
|
||||
|
||||
if test -f $prefix/include/php/ext/pdo/php_pdo_driver.h; then
|
||||
pdo_inc_path=$prefix/include/php/ext
|
||||
elif test -f $abs_srcdir/include/php/ext/pdo/php_pdo_driver.h; then
|
||||
pdo_inc_path=$abs_srcdir/ext
|
||||
elif test -f ext/pdo/php_pdo_driver.h; then
|
||||
pdo_inc_path=ext
|
||||
else
|
||||
AC_MSG_ERROR([Cannot find php_pdo_driver.h.])
|
||||
fi
|
||||
|
||||
PHP_NEW_EXTENSION(pdo_mysql, pdo_mysql.c mysql_driver.c mysql_statement.c, $ext_shared,,-I$pdo_inc_path)
|
||||
PDO_MYSQL_MODULE_TYPE=external
|
||||
PDO_MYSQL_INCLUDE=-I$MYSQL_INC_DIR
|
||||
|
||||
PHP_SUBST(PDO_MYSQL_SHARED_LIBADD)
|
||||
PHP_SUBST_OLD(PDO_MYSQL_MODULE_TYPE)
|
||||
PHP_SUBST_OLD(PDO_MYSQL_LIBS)
|
||||
PHP_SUBST_OLD(PDO_MYSQL_INCLUDE)
|
||||
fi
|
||||
@@ -1,15 +0,0 @@
|
||||
// $Id$
|
||||
// vim:ft=javascript
|
||||
|
||||
ARG_WITH("pdo-mysql", "MySQL support for PDO", "no");
|
||||
|
||||
if (PHP_PDO_MYSQL != "no") {
|
||||
if (CHECK_LIB("libmysql.lib", "pdo_mysql", PHP_PDO_MYSQL) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("mysql.h", "CFLAGS_PDO_MYSQL", PHP_PHP_BUILD + "\\include\\mysql;" + PHP_PDO_MYSQL)) {
|
||||
EXTENSION("pdo_mysql", "pdo_mysql.c mysql_driver.c mysql_statement.c");
|
||||
ADD_FLAG('CFLAGS_PDO_MYSQL', "/I ..\\pecl");
|
||||
} else {
|
||||
WARNING("pdo_mysql not enabled; libraries and headers not found");
|
||||
}
|
||||
ADD_EXTENSION_DEP('pdo_mysql', 'pdo');
|
||||
}
|
||||
@@ -1,341 +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$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "pdo/php_pdo.h"
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_mysql.h"
|
||||
#include "php_pdo_mysql_int.h"
|
||||
|
||||
int _pdo_mysql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int line TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
enum pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code;
|
||||
pdo_mysql_error_info *einfo = &H->einfo;
|
||||
|
||||
einfo->errcode = mysql_errno(H->server);
|
||||
einfo->file = file;
|
||||
einfo->line = line;
|
||||
|
||||
if (einfo->errmsg) {
|
||||
efree(einfo->errmsg);
|
||||
einfo->errmsg = NULL;
|
||||
}
|
||||
|
||||
if (einfo->errcode) {
|
||||
einfo->errmsg = estrdup(mysql_error(H->server));
|
||||
} else { /* no error */
|
||||
*pdo_err = PDO_ERR_NONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (einfo->errcode) {
|
||||
case 1007: /* database already exists */
|
||||
case 1050: /* table already exists */
|
||||
case 1086: /* file already exists */
|
||||
case 1125: /* function already exists */
|
||||
*pdo_err = PDO_ERR_ALREADY_EXISTS;
|
||||
break;
|
||||
|
||||
case 1008: /* database does not exist */
|
||||
case 1029: /* view does not exist */
|
||||
case 1072: /* key column does not exist */
|
||||
case 1091: /* column/key does not exist */
|
||||
case 1146: /* table does not exist */
|
||||
case 1176: /* key not found in table */
|
||||
*pdo_err = PDO_ERR_NOT_FOUND;
|
||||
break;
|
||||
|
||||
case 1152: /* aborted connection */
|
||||
case 1154: /* cannot read from connection pipe */
|
||||
case 1184: /* aborted new connection */
|
||||
case 1159: /* timeout */
|
||||
case 1160: /* timeout */
|
||||
case 1161: /* timeout */
|
||||
*pdo_err = PDO_ERR_DISCONNECTED;
|
||||
break;
|
||||
|
||||
case 1089: /* unsupported sub-key */
|
||||
case 1163: /* blob/text not supported inside table */
|
||||
case 1164: /* no auto-incremenet support */
|
||||
case 1174: /* no RAID support */
|
||||
case 1178: /* table handler does not support something */
|
||||
case 1185: /* binary dump not supported */
|
||||
case 1214: /* FULLTEXT not supported */
|
||||
case 1235: /* something not supported by MySQL version */
|
||||
*pdo_err = PDO_ERR_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case 1252: /* character set mismatch */
|
||||
*pdo_err = PDO_ERR_MISMATCH;
|
||||
break;
|
||||
|
||||
case 1264: /* data truncated */
|
||||
*pdo_err = PDO_ERR_TRUNCATED;
|
||||
break;
|
||||
|
||||
case 1169: /* unique constraint */
|
||||
case 1216: /* foreign key constraint */
|
||||
case 1217: /* foreign key constraint */
|
||||
*pdo_err = PDO_ERR_CONSTRAINT;
|
||||
break;
|
||||
|
||||
case 1064: /* query parse error */
|
||||
case 1065: /* empty query */
|
||||
/* XXX: MySQL has all sorts of errors that can be considered syntax errors, specifically
|
||||
dealing with table creation & modifications, do we want to include them here?
|
||||
*/
|
||||
*pdo_err = PDO_ERR_SYNTAX;
|
||||
break;
|
||||
|
||||
default:
|
||||
*pdo_err = PDO_ERR_CANT_MAP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!dbh->methods) {
|
||||
zend_throw_exception_ex(php_pdo_get_exception(), *pdo_err TSRMLS_CC, "[%d] %s",
|
||||
einfo->errcode, einfo->errmsg);
|
||||
}
|
||||
|
||||
return einfo->errcode;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int pdo_mysql_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
|
||||
{
|
||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
pdo_mysql_error_info *einfo = &H->einfo;
|
||||
|
||||
if (einfo->errcode) {
|
||||
add_next_index_long(info, einfo->errcode);
|
||||
add_next_index_string(info, einfo->errmsg, 1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int mysql_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
|
||||
if (H) {
|
||||
if (H->server) {
|
||||
mysql_close(H->server);
|
||||
H->server = NULL;
|
||||
}
|
||||
if (H->einfo.errmsg) {
|
||||
efree(H->einfo.errmsg);
|
||||
H->einfo.errmsg = NULL;
|
||||
}
|
||||
efree(H);
|
||||
H = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, long options, zval *driver_options TSRMLS_DC)
|
||||
{
|
||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
pdo_mysql_stmt *S = ecalloc(1, sizeof(pdo_mysql_stmt));
|
||||
|
||||
S->H = H;
|
||||
stmt->driver_data = S;
|
||||
stmt->methods = &mysql_stmt_methods;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static long mysql_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
|
||||
{
|
||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
|
||||
if (mysql_real_query(H->server, sql, sql_len)) {
|
||||
pdo_mysql_error(dbh);
|
||||
return -1;
|
||||
} else {
|
||||
return mysql_affected_rows(H->server);
|
||||
}
|
||||
}
|
||||
|
||||
static long pdo_mysql_last_insert_id(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
|
||||
return (long) mysql_insert_id(H->server);
|
||||
}
|
||||
|
||||
static int mysql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen TSRMLS_DC)
|
||||
{
|
||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
*quoted = emalloc(2*unquotedlen + 3);
|
||||
(*quoted)[0] = '"';
|
||||
*quotedlen = mysql_real_escape_string(H->server, *quoted + 1, unquoted, unquotedlen);
|
||||
(*quoted)[*quotedlen + 1] = '"';
|
||||
(*quoted)[*quotedlen + 2] = '\0';
|
||||
*quotedlen += 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pdo_mysql_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC)
|
||||
{
|
||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
|
||||
switch (attr) {
|
||||
case PDO_ATTR_CLIENT_VERSION:
|
||||
ZVAL_STRING(return_value, (char *)mysql_get_client_info(), 1);
|
||||
break;
|
||||
|
||||
case PDO_ATTR_SERVER_VERSION:
|
||||
ZVAL_STRING(return_value, (char *)mysql_get_server_info(H->server), 1);
|
||||
break;
|
||||
|
||||
case PDO_ATTR_CONNECTION_STATUS:
|
||||
ZVAL_STRING(return_value, (char *)mysql_get_host_info(H->server), 1);
|
||||
break;
|
||||
|
||||
case PDO_ATTR_SERVER_INFO: {
|
||||
char *tmp;
|
||||
|
||||
if ((tmp = (char *)mysql_stat(H->server))) {
|
||||
ZVAL_STRING(return_value, tmp, 1);
|
||||
} else {
|
||||
pdo_mysql_error(dbh);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct pdo_dbh_methods mysql_methods = {
|
||||
mysql_handle_closer,
|
||||
mysql_handle_preparer,
|
||||
mysql_handle_doer,
|
||||
mysql_handle_quoter,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
pdo_mysql_last_insert_id,
|
||||
pdo_mysql_fetch_error_func,
|
||||
pdo_mysql_get_attribute
|
||||
};
|
||||
|
||||
#ifndef PDO_MYSQL_UNIX_ADDR
|
||||
# define PDO_MYSQL_UNIX_ADDR "MySQL"
|
||||
#endif
|
||||
|
||||
static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_mysql_db_handle *H;
|
||||
int i, ret = 0;
|
||||
char *host = NULL, *unix_socket = NULL;
|
||||
unsigned int port;
|
||||
char *dbname;
|
||||
struct pdo_data_src_parser vars[] = {
|
||||
{ "charset", NULL, 0 },
|
||||
{ "dbname", "", 0 },
|
||||
{ "host", "localhost", 0 },
|
||||
{ "port", "3306", 0 },
|
||||
{ "unix_socket", PDO_MYSQL_UNIX_ADDR, 0 },
|
||||
};
|
||||
|
||||
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 4);
|
||||
|
||||
H = pecalloc(1, sizeof(pdo_mysql_db_handle), dbh->is_persistent);
|
||||
|
||||
H->einfo.errcode = 0;
|
||||
H->einfo.errmsg = NULL;
|
||||
|
||||
/* allocate an environment */
|
||||
|
||||
/* handle for the server */
|
||||
H->server = mysql_init(NULL);
|
||||
dbh->driver_data = H;
|
||||
|
||||
/* handle MySQL options */
|
||||
if (driver_options) {
|
||||
long connect_timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, 30 TSRMLS_CC);
|
||||
|
||||
if (mysql_options(H->server, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout)) {
|
||||
pdo_mysql_error(dbh);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (vars[2].optval && strcmp("localhost", vars[2].optval)) {
|
||||
host = vars[2].optval;
|
||||
port = atoi(vars[3].optval);
|
||||
} else {
|
||||
host = ".";
|
||||
unix_socket = vars[4].optval;
|
||||
}
|
||||
dbname = vars[1].optval;
|
||||
if (mysql_real_connect(H->server, host, dbh->username, dbh->password, dbname, port, unix_socket, 0) == NULL) {
|
||||
pdo_mysql_error(dbh);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
H->attached = 1;
|
||||
|
||||
dbh->methods = &mysql_methods;
|
||||
dbh->alloc_own_columns = 1;
|
||||
dbh->supports_placeholders = 0;
|
||||
dbh->max_escaped_char_length = 2;
|
||||
|
||||
ret = 1;
|
||||
|
||||
cleanup:
|
||||
for (i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) {
|
||||
if (vars[i].freeme) {
|
||||
efree(vars[i].optval);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
pdo_driver_t pdo_mysql_driver = {
|
||||
PDO_DRIVER_HEADER(mysql),
|
||||
pdo_mysql_handle_factory
|
||||
};
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,169 +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$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "pdo/php_pdo.h"
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_mysql.h"
|
||||
#include "php_pdo_mysql_int.h"
|
||||
|
||||
|
||||
static int pdo_mysql_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
pdo_mysql_stmt *S = (pdo_mysql_stmt*)stmt->driver_data;
|
||||
int i;
|
||||
|
||||
if (S->result) {
|
||||
/* free the resource */
|
||||
mysql_free_result(S->result);
|
||||
S->result = NULL;
|
||||
}
|
||||
if(S->cols) {
|
||||
efree(S->cols);
|
||||
S->cols = NULL;
|
||||
}
|
||||
efree(S);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pdo_mysql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
pdo_dbh_t *dbh = stmt->dbh;
|
||||
pdo_mysql_stmt *S = (pdo_mysql_stmt*)stmt->driver_data;
|
||||
pdo_mysql_db_handle *H = S->H;
|
||||
|
||||
if (stmt->executed) {
|
||||
/* ensure that we free any previous unfetched results */
|
||||
if(S->result) {
|
||||
mysql_free_result(S->result);
|
||||
S->result = NULL;
|
||||
}
|
||||
}
|
||||
if (mysql_real_query(H->server, stmt->active_query_string, stmt->active_query_stringlen) != 0) {
|
||||
pdo_mysql_error_stmt(stmt);
|
||||
return 0;
|
||||
}
|
||||
if ((S->result = mysql_use_result(H->server)) == NULL) {
|
||||
/* could've been INSERT/UPDATE/DELETE query */
|
||||
if (!mysql_affected_rows(H->server)) {
|
||||
pdo_mysql_error_stmt(stmt);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (!stmt->executed) {
|
||||
stmt->column_count = (int) mysql_num_fields(S->result);
|
||||
S->cols = ecalloc(stmt->column_count, sizeof(pdo_mysql_column));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pdo_mysql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
|
||||
enum pdo_param_event event_type TSRMLS_DC)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pdo_mysql_stmt_fetch(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
pdo_mysql_stmt *S = (pdo_mysql_stmt*)stmt->driver_data;
|
||||
if (!S->result) {
|
||||
return 0;
|
||||
}
|
||||
if((S->current_data = mysql_fetch_row(S->result)) == NULL) {
|
||||
/* there seems to be no way of distinguishing 'no data' from 'error' */
|
||||
pdo_mysql_error_stmt(stmt);
|
||||
return 0;
|
||||
}
|
||||
S->current_lengths = mysql_fetch_lengths(S->result);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pdo_mysql_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
|
||||
{
|
||||
pdo_mysql_stmt *S = (pdo_mysql_stmt*)stmt->driver_data;
|
||||
MYSQL_RES *R = S->result;
|
||||
MYSQL_FIELD *F;
|
||||
struct pdo_column_data *cols = stmt->columns;
|
||||
unsigned int num_fields, i;
|
||||
|
||||
if (!S->result) {
|
||||
return 0;
|
||||
}
|
||||
/* fetch all on demand, this seems easiest
|
||||
** if we've been here before bail out
|
||||
*/
|
||||
if(cols[0].name) {
|
||||
return 1;
|
||||
}
|
||||
num_fields = mysql_num_fields(R);
|
||||
F = mysql_fetch_fields(R);
|
||||
for(i=0; i < num_fields; i++) {
|
||||
int namelen;
|
||||
namelen = strlen(F[i].name);
|
||||
cols[i].precision = F[i].decimals;
|
||||
cols[i].maxlen = F[i].length;
|
||||
cols[i].namelen = namelen;
|
||||
/* FIXME where does this get freed? */
|
||||
cols[i].name = estrndup(F[i].name, namelen + 1);
|
||||
cols[i].param_type = PDO_PARAM_STR;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pdo_mysql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len TSRMLS_DC)
|
||||
{
|
||||
pdo_mysql_stmt *S = (pdo_mysql_stmt*)stmt->driver_data;
|
||||
if(S->current_data == NULL || !S->result) {
|
||||
return 0;
|
||||
}
|
||||
if(colno >= mysql_num_fields(S->result)) {
|
||||
/* error invalid column */
|
||||
pdo_mysql_error_stmt(stmt);
|
||||
return 0;
|
||||
}
|
||||
*ptr = S->current_data[colno];
|
||||
*len = S->current_lengths[colno];
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct pdo_stmt_methods mysql_stmt_methods = {
|
||||
pdo_mysql_stmt_dtor,
|
||||
pdo_mysql_stmt_execute,
|
||||
pdo_mysql_stmt_fetch,
|
||||
pdo_mysql_stmt_describe,
|
||||
pdo_mysql_stmt_get_col,
|
||||
pdo_mysql_stmt_param_hook
|
||||
};
|
||||
|
||||
/*
|
||||
* 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,48 +0,0 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE package SYSTEM "../pear/package.dtd">
|
||||
<package version="1.0">
|
||||
<name>pdo_mysql</name>
|
||||
<summary>Mysql 3.x/4.0 driver for PDO</summary>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>gschlossnagle</user>
|
||||
<name>George Schlossnagle</name>
|
||||
<email>george@omniti.com</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<user>iliaa</user>
|
||||
<name>Ilia Alshanetsky</name>
|
||||
<email>iliaa@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
<description>
|
||||
This extension provides a Mysql 3.x/4.0 driver for PDO.
|
||||
</description>
|
||||
<license>PHP</license>
|
||||
<release>
|
||||
<state>alpha</state>
|
||||
<version>0.1</version>
|
||||
<date>2004-05-18</date>
|
||||
|
||||
<notes>
|
||||
Hope it works!
|
||||
</notes>
|
||||
|
||||
<filelist>
|
||||
<file role="src" name="config.m4"/>
|
||||
<file role="src" name="pdo_mysql.c"/>
|
||||
<file role="src" name="mysql_driver.c"/>
|
||||
<file role="src" name="mysql_statement.c"/>
|
||||
<file role="src" name="php_pdo_mysql.h"/>
|
||||
<file role="src" name="php_pdo_mysql_int.h"/>
|
||||
|
||||
<file role="doc" name="CREDITS"/>
|
||||
</filelist>
|
||||
<deps>
|
||||
<dep type="php" rel="ge" version="5.0.0"/>
|
||||
<dep type="ext" name="pdo" rel="ge" version="0.1"/>
|
||||
</deps>
|
||||
</release>
|
||||
</package>
|
||||
@@ -1,94 +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$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "pdo/php_pdo.h"
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_mysql.h"
|
||||
#include "php_pdo_mysql_int.h"
|
||||
|
||||
/* {{{ pdo_mysql_functions[] */
|
||||
function_entry pdo_mysql_functions[] = {
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ pdo_mysql_module_entry */
|
||||
zend_module_entry pdo_mysql_module_entry = {
|
||||
STANDARD_MODULE_HEADER,
|
||||
"pdo_mysql",
|
||||
pdo_mysql_functions,
|
||||
PHP_MINIT(pdo_mysql),
|
||||
PHP_MSHUTDOWN(pdo_mysql),
|
||||
NULL,
|
||||
NULL,
|
||||
PHP_MINFO(pdo_mysql),
|
||||
"0.1",
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_PDO_MYSQL
|
||||
ZEND_GET_MODULE(pdo_mysql)
|
||||
#endif
|
||||
|
||||
/* true global environment */
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION
|
||||
*/
|
||||
PHP_MINIT_FUNCTION(pdo_mysql)
|
||||
{
|
||||
return php_pdo_register_driver(&pdo_mysql_driver);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo_mysql)
|
||||
{
|
||||
php_pdo_unregister_driver(&pdo_mysql_driver);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
PHP_MINFO_FUNCTION(pdo_mysql)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "PDO Driver for MySQL 3.x Client Libraries", "enabled");
|
||||
php_info_print_table_end();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* 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,53 +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$ */
|
||||
|
||||
#ifndef PHP_PDO_MYSQL_H
|
||||
#define PHP_PDO_MYSQL_H
|
||||
|
||||
extern zend_module_entry pdo_mysql_module_entry;
|
||||
#define phpext_pdo_mysql_ptr &pdo_mysql_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_PDO_MYSQL_API __declspec(dllexport)
|
||||
#else
|
||||
#define PHP_PDO_MYSQL_API
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
PHP_MINIT_FUNCTION(pdo_mysql);
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo_mysql);
|
||||
PHP_RINIT_FUNCTION(pdo_mysql);
|
||||
PHP_RSHUTDOWN_FUNCTION(pdo_mysql);
|
||||
PHP_MINFO_FUNCTION(pdo_mysql);
|
||||
|
||||
#endif /* PHP_PDO_MYSQL_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,69 +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$ */
|
||||
|
||||
#ifndef PHP_PDO_MYSQL_INT_H
|
||||
#define PHP_PDO_MYSQL_INT_H
|
||||
|
||||
#include <mysql.h>
|
||||
|
||||
typedef struct {
|
||||
const char *file;
|
||||
int line;
|
||||
unsigned int errcode;
|
||||
char *errmsg;
|
||||
} pdo_mysql_error_info;
|
||||
|
||||
/* stuff we use in a mySQL database handle */
|
||||
typedef struct {
|
||||
MYSQL *server;
|
||||
|
||||
unsigned attached:1;
|
||||
unsigned _reserved:31;
|
||||
|
||||
pdo_mysql_error_info einfo;
|
||||
} pdo_mysql_db_handle;
|
||||
|
||||
typedef struct {
|
||||
MYSQL_FIELD *def;
|
||||
} pdo_mysql_column;
|
||||
|
||||
typedef struct {
|
||||
pdo_mysql_db_handle *H;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW current_data;
|
||||
long *current_lengths;
|
||||
pdo_mysql_column *cols;
|
||||
} pdo_mysql_stmt;
|
||||
|
||||
typedef struct {
|
||||
char *repr;
|
||||
long repr_len;
|
||||
int mysql_type;
|
||||
void *thing; /* for LOBS, REFCURSORS etc. */
|
||||
} pdo_mysql_bound_param;
|
||||
|
||||
extern pdo_driver_t pdo_mysql_driver;
|
||||
|
||||
extern int _pdo_mysql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int line TSRMLS_DC);
|
||||
#define pdo_mysql_error(s) _pdo_mysql_error(s, NULL, __FILE__, __LINE__ TSRMLS_CC)
|
||||
#define pdo_mysql_error_stmt(s) _pdo_mysql_error(stmt->dbh, stmt, __FILE__, __LINE__ TSRMLS_CC)
|
||||
|
||||
extern struct pdo_stmt_methods mysql_stmt_methods;
|
||||
#endif
|
||||
@@ -1,2 +0,0 @@
|
||||
Oracle (OCI) driver for PDO
|
||||
Wez Furlong
|
||||
Whitespace-only changes.
@@ -1,142 +0,0 @@
|
||||
dnl $Id$
|
||||
|
||||
AC_DEFUN(AC_PDO_OCI_VERSION,[
|
||||
AC_MSG_CHECKING([Oracle version])
|
||||
if test -s "$PDO_OCI_DIR/orainst/unix.rgs"; then
|
||||
PDO_OCI_VERSION=`grep '"ocommon"' $PDO_OCI_DIR/orainst/unix.rgs | sed 's/[ ][ ]*/:/g' | cut -d: -f 6 | cut -c 2-4`
|
||||
test -z "$PDO_OCI_VERSION" && PDO_OCI_VERSION=7.3
|
||||
elif test -f $PDO_OCI_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME.10.1; then
|
||||
PDO_OCI_VERSION=10.1
|
||||
elif test -f $PDO_OCI_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME.9.0; then
|
||||
PDO_OCI_VERSION=9.0
|
||||
elif test -f $PDO_OCI_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME.8.0; then
|
||||
PDO_OCI_VERSION=8.1
|
||||
elif test -f $PDO_OCI_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME.1.0; then
|
||||
PDO_OCI_VERSION=8.0
|
||||
elif test -f $PDO_OCI_DIR/lib/libclntsh.a; then
|
||||
if test -f $PDO_OCI_DIR/lib/libcore4.a; then
|
||||
PDO_OCI_VERSION=8.0
|
||||
else
|
||||
PDO_OCI_VERSION=8.1
|
||||
fi
|
||||
else
|
||||
AC_MSG_ERROR(Oracle-OCI needed libraries not found under $PDO_OCI_DIR)
|
||||
fi
|
||||
AC_MSG_RESULT($PDO_OCI_VERSION)
|
||||
])
|
||||
|
||||
PHP_ARG_WITH(pdo-oci, Oracle OCI support for PDO,
|
||||
[ --with-pdo-oci[=DIR] Include Oracle-oci support. Default DIR is ORACLE_HOME.])
|
||||
|
||||
if test "$PHP_PDO_OCI" != "no"; then
|
||||
AC_MSG_CHECKING([Oracle Install-Dir])
|
||||
if test "$PHP_PDO_OCI" = "yes" -o -z "$PHP_PDO_OCI"; then
|
||||
PDO_OCI_DIR=$ORACLE_HOME
|
||||
else
|
||||
PDO_OCI_DIR=$PHP_PDO_OCI
|
||||
fi
|
||||
AC_MSG_RESULT($PDO_OCI_DIR :$PHP_PDO_OCI:)
|
||||
|
||||
if test -d "$PDO_OCI_DIR/rdbms/public"; then
|
||||
PHP_ADD_INCLUDE($PDO_OCI_DIR/rdbms/public)
|
||||
PDO_OCI_INCLUDES="$PDO_OCI_INCLUDES -I$PDO_OCI_DIR/rdbms/public"
|
||||
fi
|
||||
if test -d "$PDO_OCI_DIR/rdbms/demo"; then
|
||||
PHP_ADD_INCLUDE($PDO_OCI_DIR/rdbms/demo)
|
||||
PDO_OCI_INCLUDES="$PDO_OCI_INCLUDES -I$PDO_OCI_DIR/rdbms/demo"
|
||||
fi
|
||||
if test -d "$PDO_OCI_DIR/network/public"; then
|
||||
PHP_ADD_INCLUDE($PDO_OCI_DIR/network/public)
|
||||
PDO_OCI_INCLUDES="$PDO_OCI_INCLUDES -I$PDO_OCI_DIR/network/public"
|
||||
fi
|
||||
if test -d "$PDO_OCI_DIR/plsql/public"; then
|
||||
PHP_ADD_INCLUDE($PDO_OCI_DIR/plsql/public)
|
||||
PDO_OCI_INCLUDES="$PDO_OCI_INCLUDES -I$PDO_OCI_DIR/plsql/public"
|
||||
fi
|
||||
|
||||
if test -f "$PDO_OCI_DIR/lib/sysliblist"; then
|
||||
PHP_EVAL_LIBLINE(`cat $PDO_OCI_DIR/lib/sysliblist`, PDO_OCI_SYSLIB)
|
||||
elif test -f "$PDO_OCI_DIR/rdbms/lib/sysliblist"; then
|
||||
PHP_EVAL_LIBLINE(`cat $PDO_OCI_DIR/rdbms/lib/sysliblist`, PDO_OCI_SYSLIB)
|
||||
fi
|
||||
|
||||
AC_PDO_OCI_VERSION($PDO_OCI_DIR)
|
||||
case $PDO_OCI_VERSION in
|
||||
8.0)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(nlsrtl3, "", PDO_OCI_SHARED_LIBADD)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(core4, "", PDO_OCI_SHARED_LIBADD)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(psa, "", PDO_OCI_SHARED_LIBADD)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(clntsh, $PDO_OCI_DIR/lib, PDO_OCI_SHARED_LIBADD)
|
||||
;;
|
||||
|
||||
8.1)
|
||||
PHP_ADD_LIBRARY(clntsh, 1, PDO_OCI_SHARED_LIBADD)
|
||||
PHP_ADD_LIBPATH($PDO_OCI_DIR/lib, PDO_OCI_SHARED_LIBADD)
|
||||
;;
|
||||
|
||||
9.0)
|
||||
PHP_ADD_LIBRARY(clntsh, 1, PDO_OCI_SHARED_LIBADD)
|
||||
PHP_ADD_LIBPATH($PDO_OCI_DIR/lib, PDO_OCI_SHARED_LIBADD)
|
||||
|
||||
;;
|
||||
|
||||
10.1)
|
||||
PHP_ADD_LIBRARY(clntsh, 1, PDO_OCI_SHARED_LIBADD)
|
||||
PHP_ADD_LIBPATH($PDO_OCI_DIR/lib, PDO_OCI_SHARED_LIBADD)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR(Unsupported Oracle version!)
|
||||
;;
|
||||
esac
|
||||
|
||||
PHP_CHECK_LIBRARY(clntsh, OCIEnvCreate,
|
||||
[
|
||||
AC_DEFINE(HAVE_OCIENVCREATE,1,[ ])
|
||||
], [], [
|
||||
-L$PDO_OCI_DIR/lib $PDO_OCI_SHARED_LIBADD
|
||||
])
|
||||
|
||||
PHP_CHECK_LIBRARY(clntsh, OCIEnvNlsCreate,
|
||||
[
|
||||
AC_DEFINE(HAVE_OCIENVNLSCREATE,1,[ ])
|
||||
], [], [
|
||||
-L$PDO_OCI_DIR/lib $PDO_OCI_SHARED_LIBADD
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Check if we need to add -locijdbc8
|
||||
dnl
|
||||
PHP_CHECK_LIBRARY(clntsh, OCILobIsTemporary,
|
||||
[
|
||||
AC_DEFINE(HAVE_OCILOBISTEMPORARY,1,[ ])
|
||||
], [
|
||||
PHP_CHECK_LIBRARY(ocijdbc8, OCILobIsTemporary,
|
||||
[
|
||||
PHP_ADD_LIBRARY(ocijdbc8, 1, PDO_OCI_SHARED_LIBADD)
|
||||
AC_DEFINE(HAVE_OCILOBISTEMPORARY,1,[ ])
|
||||
], [], [
|
||||
-L$PDO_OCI_DIR/lib $PDO_OCI_SHARED_LIBADD
|
||||
])
|
||||
], [
|
||||
-L$PDO_OCI_DIR/lib $PDO_OCI_SHARED_LIBADD
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Check if we have collections
|
||||
dnl
|
||||
PHP_CHECK_LIBRARY(clntsh, OCICollAssign,
|
||||
[
|
||||
AC_DEFINE(HAVE_OCICOLLASSIGN,1,[ ])
|
||||
], [], [
|
||||
-L$PDO_OCI_DIR/lib $PDO_OCI_SHARED_LIBADD
|
||||
])
|
||||
|
||||
|
||||
|
||||
PHP_NEW_EXTENSION(pdo_oci, pdo_oci.c oci_driver.c oci_statement.c, $ext_shared,,-I\$prefix/include/php/ext)
|
||||
|
||||
PHP_SUBST_OLD(PDO_OCI_SHARED_LIBADD)
|
||||
PHP_SUBST_OLD(PDO_OCI_DIR)
|
||||
PHP_SUBST_OLD(PDO_OCI_VERSION)
|
||||
|
||||
fi
|
||||
@@ -1,42 +0,0 @@
|
||||
// $Id$
|
||||
// vim:ft=javascript
|
||||
|
||||
ARG_WITH("pdo-oci", "Oracle OCI support for PDO", "no");
|
||||
|
||||
if (PHP_PDO_OCI != "no") {
|
||||
|
||||
php_oci_dirs = new Array(
|
||||
PHP_PDO_OCI,
|
||||
PHP_PDO_OCI + "\\oci",
|
||||
PHP_PHP_BUILD + "\\oci92",
|
||||
PHP_PHP_BUILD + "\\oci805"
|
||||
);
|
||||
|
||||
php_oci_lib_paths = "";
|
||||
php_oci_inc_paths = "";
|
||||
|
||||
// find the oracle install
|
||||
for (i = 0; i < php_oci_dirs.length; i++) {
|
||||
php_oci_lib_paths += php_oci_dirs[i] + "\\lib;";
|
||||
php_oci_lib_paths += php_oci_dirs[i] + "\\lib\\msvc;";
|
||||
php_oci_inc_paths += php_oci_dirs[i] + "\\include;";
|
||||
}
|
||||
|
||||
pdo_oci_header = CHECK_HEADER_ADD_INCLUDE("oci.h", "CFLAGS_PDO_OCI", php_oci_inc_paths);
|
||||
|
||||
if (pdo_oci_header && CHECK_LIB("oci.lib", "pdo_oci", php_oci_lib_paths)) {
|
||||
|
||||
EXTENSION('pdo_oci', 'pdo_oci.c oci_driver.c oci_statement.c');
|
||||
ADD_FLAG('CFLAGS_PDO_OCI', "/I ..\\pecl");
|
||||
|
||||
/* probe for some functions not present in older versions */
|
||||
pdo_oci_inc_dir = FSO.GetFolder(pdo_oci_header);
|
||||
CHECK_FUNC_IN_HEADER('oci.h', 'OCIEnvCreate', pdo_oci_inc_dir);
|
||||
CHECK_FUNC_IN_HEADER('ociap.h', 'OCIEnvNlsCreate', pdo_oci_inc_dir);
|
||||
|
||||
} else {
|
||||
WARNING("pdo-oci not enabled; libraries and headers not found");
|
||||
}
|
||||
ADD_EXTENSION_DEP('pdo_oci', 'pdo');
|
||||
}
|
||||
|
||||
@@ -1,480 +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: 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 "pdo/php_pdo.h"
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_oci.h"
|
||||
#include "php_pdo_oci_int.h"
|
||||
|
||||
static int pdo_oci_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_oci_db_handle *H = (pdo_oci_db_handle *)dbh->driver_data;
|
||||
pdo_oci_error_info *einfo;
|
||||
|
||||
einfo = &H->einfo;
|
||||
|
||||
if (stmt) {
|
||||
pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
|
||||
|
||||
if (S->einfo.errmsg) {
|
||||
einfo = &S->einfo;
|
||||
}
|
||||
}
|
||||
|
||||
add_next_index_long(info, einfo->errcode);
|
||||
add_next_index_string(info, einfo->errmsg, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ub4 _oci_error(OCIError *err, pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *what, sword status, const char *file, int line TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
text errbuf[1024] = "<<Unknown>>";
|
||||
pdo_oci_db_handle *H = (pdo_oci_db_handle *)dbh->driver_data;
|
||||
pdo_oci_error_info *einfo;
|
||||
pdo_oci_stmt *S = NULL;
|
||||
enum pdo_error_type *pdo_err = &dbh->error_code;
|
||||
|
||||
einfo = &H->einfo;
|
||||
|
||||
if (stmt) {
|
||||
S = (pdo_oci_stmt*)stmt->driver_data;
|
||||
einfo = &S->einfo;
|
||||
pdo_err = &stmt->error_code;
|
||||
}
|
||||
|
||||
einfo->errcode = 0;
|
||||
einfo->file = file;
|
||||
einfo->line = line;
|
||||
if (einfo->errmsg) {
|
||||
efree(einfo->errmsg);
|
||||
einfo->errmsg = NULL;
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case OCI_SUCCESS:
|
||||
*pdo_err = PDO_ERR_NONE;
|
||||
break;
|
||||
case OCI_ERROR:
|
||||
OCIErrorGet(err, (ub4)1, NULL, &einfo->errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
|
||||
spprintf(&einfo->errmsg, 0, "%s: %s (%s:%d)", what, errbuf, file, line);
|
||||
break;
|
||||
case OCI_SUCCESS_WITH_INFO:
|
||||
OCIErrorGet(err, (ub4)1, NULL, &einfo->errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
|
||||
spprintf(&einfo->errmsg, 0, "%s: OCI_SUCCESS_WITH_INFO: %s (%s:%d)", what, errbuf, file, line);
|
||||
break;
|
||||
case OCI_NEED_DATA:
|
||||
spprintf(&einfo->errmsg, 0, "%s: OCI_NEED_DATA (%s:%d)", what, file, line);
|
||||
break;
|
||||
case OCI_NO_DATA:
|
||||
spprintf(&einfo->errmsg, 0, "%s: OCI_NO_DATA (%s:%d)", what, file, line);
|
||||
break;
|
||||
case OCI_INVALID_HANDLE:
|
||||
spprintf(&einfo->errmsg, 0, "%s: OCI_INVALID_HANDLE (%s:%d)", what, file, line);
|
||||
break;
|
||||
case OCI_STILL_EXECUTING:
|
||||
spprintf(&einfo->errmsg, 0, "%s: OCI_STILL_EXECUTING (%s:%d)", what, file, line);
|
||||
break;
|
||||
case OCI_CONTINUE:
|
||||
spprintf(&einfo->errmsg, 0, "%s: OCI_CONTINUE (%s:%d)", what, file, line);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (einfo->errcode) {
|
||||
case 1013: /* user requested cancel of current operation */
|
||||
zend_bailout();
|
||||
break;
|
||||
|
||||
case 955: /* ORA-00955: name is already used by an existing object */
|
||||
*pdo_err = PDO_ERR_ALREADY_EXISTS;
|
||||
break;
|
||||
|
||||
case 12154: /* ORA-12154: TNS:could not resolve service name */
|
||||
*pdo_err = PDO_ERR_NOT_FOUND;
|
||||
break;
|
||||
|
||||
case 22: /* ORA-00022: invalid session id */
|
||||
case 1012: /* ORA-01012: */
|
||||
case 3113: /* ORA-03133: end of file on communication channel */
|
||||
case 604:
|
||||
case 1041:
|
||||
/* consider the connection closed */
|
||||
dbh->is_closed = 1;
|
||||
H->attached = 0;
|
||||
*pdo_err = PDO_ERR_DISCONNECTED;
|
||||
break;
|
||||
|
||||
default:
|
||||
*pdo_err = PDO_ERR_CANT_MAP;
|
||||
}
|
||||
|
||||
/* little mini hack so that we can use this code from the dbh ctor */
|
||||
if (!dbh->methods) {
|
||||
zend_throw_exception_ex(php_pdo_get_exception(), *pdo_err TSRMLS_CC, einfo->errmsg);
|
||||
}
|
||||
|
||||
return einfo->errcode;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int oci_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_oci_db_handle *H = (pdo_oci_db_handle *)dbh->driver_data;
|
||||
|
||||
if (H->svc) {
|
||||
/* rollback any outstanding work */
|
||||
OCITransRollback(H->svc, H->err, 0);
|
||||
}
|
||||
|
||||
if (H->session) {
|
||||
OCIHandleFree(H->session, OCI_HTYPE_SESSION);
|
||||
H->session = NULL;
|
||||
}
|
||||
|
||||
if (H->svc) {
|
||||
OCIHandleFree(H->svc, OCI_HTYPE_SVCCTX);
|
||||
H->svc = NULL;
|
||||
}
|
||||
|
||||
if (H->server && H->attached) {
|
||||
H->last_err = OCIServerDetach(H->server, H->err, OCI_DEFAULT);
|
||||
if (H->last_err) {
|
||||
oci_drv_error("OCIServerDetach");
|
||||
}
|
||||
H->attached = 0;
|
||||
}
|
||||
|
||||
if (H->server) {
|
||||
OCIHandleFree(H->server, OCI_HTYPE_SERVER);
|
||||
H->server = NULL;
|
||||
}
|
||||
|
||||
OCIHandleFree(H->err, OCI_HTYPE_ERROR);
|
||||
H->err = NULL;
|
||||
|
||||
if (H->charset && H->env) {
|
||||
OCIHandleFree(H->env, OCI_HTYPE_ENV);
|
||||
H->env = NULL;
|
||||
}
|
||||
|
||||
pefree(H, dbh->is_persistent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int oci_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, long options, zval *driver_options TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_oci_db_handle *H = (pdo_oci_db_handle *)dbh->driver_data;
|
||||
pdo_oci_stmt *S = ecalloc(1, sizeof(*S));
|
||||
|
||||
S->H = H;
|
||||
|
||||
/* create an OCI statement handle */
|
||||
OCIHandleAlloc(H->env, (dvoid*)&S->stmt, OCI_HTYPE_STMT, 0, NULL);
|
||||
|
||||
/* and our own private error handle */
|
||||
OCIHandleAlloc(H->env, (dvoid*)&S->err, OCI_HTYPE_ERROR, 0, NULL);
|
||||
|
||||
if (sql_len) {
|
||||
H->last_err = OCIStmtPrepare(S->stmt, H->err, (text*)sql, sql_len, OCI_NTV_SYNTAX, OCI_DEFAULT);
|
||||
|
||||
if (H->last_err) {
|
||||
H->last_err = oci_drv_error("OCIStmtPrepare");
|
||||
OCIHandleFree(S->stmt, OCI_HTYPE_STMT);
|
||||
OCIHandleFree(S->err, OCI_HTYPE_ERROR);
|
||||
efree(S);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
stmt->driver_data = S;
|
||||
stmt->methods = &oci_stmt_methods;
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static long oci_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_oci_db_handle *H = (pdo_oci_db_handle *)dbh->driver_data;
|
||||
OCIStmt *stmt;
|
||||
ub2 stmt_type;
|
||||
ub4 rowcount;
|
||||
int ret = -1;
|
||||
|
||||
OCIHandleAlloc(H->env, (dvoid*)&stmt, OCI_HTYPE_STMT, 0, NULL);
|
||||
|
||||
H->last_err = OCIStmtPrepare(stmt, H->err, (text*)sql, sql_len, OCI_NTV_SYNTAX, OCI_DEFAULT);
|
||||
if (H->last_err) {
|
||||
H->last_err = oci_drv_error("OCIStmtPrepare");
|
||||
OCIHandleFree(stmt, OCI_HTYPE_STMT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
H->last_err = OCIAttrGet(stmt, OCI_HTYPE_STMT, &stmt_type, 0, OCI_ATTR_STMT_TYPE, H->err);
|
||||
|
||||
if (stmt_type == OCI_STMT_SELECT) {
|
||||
/* invalid usage; cancel it */
|
||||
OCIHandleFree(stmt, OCI_HTYPE_STMT);
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "issuing a SELECT query here is invalid");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* now we are good to go */
|
||||
H->last_err = OCIStmtExecute(H->svc, stmt, H->err, 1, 0, NULL, NULL,
|
||||
(dbh->auto_commit && !dbh->in_txn) ? OCI_COMMIT_ON_SUCCESS : OCI_DEFAULT);
|
||||
|
||||
if (H->last_err) {
|
||||
H->last_err = oci_drv_error("OCIStmtExecute");
|
||||
} else {
|
||||
/* return the number of affected rows */
|
||||
H->last_err = OCIAttrGet(stmt, OCI_HTYPE_STMT, &rowcount, 0, OCI_ATTR_ROW_COUNT, H->err);
|
||||
ret = rowcount;
|
||||
}
|
||||
|
||||
OCIHandleFree(stmt, OCI_HTYPE_STMT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int oci_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_oci_db_handle *H = (pdo_oci_db_handle *)dbh->driver_data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int oci_handle_begin(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
/* with Oracle, there is nothing special to be done */
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int oci_handle_commit(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_oci_db_handle *H = (pdo_oci_db_handle *)dbh->driver_data;
|
||||
|
||||
H->last_err = OCITransCommit(H->svc, H->err, 0);
|
||||
|
||||
if (H->last_err) {
|
||||
H->last_err = oci_drv_error("OCITransCommit");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int oci_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_oci_db_handle *H = (pdo_oci_db_handle *)dbh->driver_data;
|
||||
|
||||
H->last_err = OCITransRollback(H->svc, H->err, 0);
|
||||
|
||||
if (H->last_err) {
|
||||
H->last_err = oci_drv_error("OCITransRollback");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int oci_handle_set_attribute(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_oci_db_handle *H = (pdo_oci_db_handle *)dbh->driver_data;
|
||||
|
||||
if (attr == PDO_ATTR_AUTOCOMMIT) {
|
||||
if (dbh->in_txn) {
|
||||
/* Assume they want to commit whatever is outstanding */
|
||||
H->last_err = OCITransCommit(H->svc, H->err, 0);
|
||||
|
||||
if (H->last_err) {
|
||||
H->last_err = oci_drv_error("OCITransCommit");
|
||||
return 0;
|
||||
}
|
||||
dbh->in_txn = 0;
|
||||
}
|
||||
|
||||
convert_to_long(val);
|
||||
|
||||
dbh->auto_commit = Z_LVAL_P(val);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static struct pdo_dbh_methods oci_methods = {
|
||||
oci_handle_closer,
|
||||
oci_handle_preparer,
|
||||
oci_handle_doer,
|
||||
oci_handle_quoter,
|
||||
oci_handle_begin,
|
||||
oci_handle_commit,
|
||||
oci_handle_rollback,
|
||||
oci_handle_set_attribute,
|
||||
NULL,
|
||||
pdo_oci_fetch_error_func,
|
||||
};
|
||||
|
||||
static int pdo_oci_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_oci_db_handle *H;
|
||||
int i, ret = 0;
|
||||
struct pdo_data_src_parser vars[] = {
|
||||
{ "charset", NULL, 0 },
|
||||
{ "dbname", "", 0 }
|
||||
};
|
||||
|
||||
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 4);
|
||||
|
||||
H = pecalloc(1, sizeof(*H), dbh->is_persistent);
|
||||
dbh->driver_data = H;
|
||||
|
||||
/* allocate an environment */
|
||||
#if HAVE_OCIENVNLSCREATE
|
||||
if (vars[0].optval) {
|
||||
H->charset = OCINlsCharSetNameToId(pdo_oci_Env, vars[0].optval);
|
||||
if (H->charset) {
|
||||
OCIEnvNlsCreate(&H->env, PDO_OCI_INIT_MODE, 0, NULL, NULL, NULL, 0, NULL, H->charset, H->charset);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (H->env == NULL) {
|
||||
/* use the global environment */
|
||||
H->env = pdo_oci_Env;
|
||||
}
|
||||
|
||||
/* something to hold errors */
|
||||
OCIHandleAlloc(H->env, (dvoid **)&H->err, OCI_HTYPE_ERROR, 0, NULL);
|
||||
|
||||
/* handle for the server */
|
||||
OCIHandleAlloc(H->env, (dvoid **)&H->server, OCI_HTYPE_SERVER, 0, NULL);
|
||||
|
||||
H->last_err = OCIServerAttach(H->server, H->err, (text*)vars[1].optval,
|
||||
strlen(vars[1].optval), OCI_DEFAULT);
|
||||
|
||||
if (H->last_err) {
|
||||
oci_drv_error("pdo_oci_handle_factory");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
H->attached = 1;
|
||||
|
||||
/* create a service context */
|
||||
H->last_err = OCIHandleAlloc(H->env, (dvoid**)&H->svc, OCI_HTYPE_SVCCTX, 0, NULL);
|
||||
if (H->last_err) {
|
||||
oci_drv_error("OCIHandleAlloc: OCI_HTYPE_SVCCTX");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
H->last_err = OCIHandleAlloc(H->env, (dvoid**)&H->session, OCI_HTYPE_SESSION, 0, NULL);
|
||||
if (H->last_err) {
|
||||
oci_drv_error("OCIHandleAlloc: OCI_HTYPE_SESSION");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* set server handle into service handle */
|
||||
H->last_err = OCIAttrSet(H->svc, OCI_HTYPE_SVCCTX, H->server, 0, OCI_ATTR_SERVER, H->err);
|
||||
if (H->last_err) {
|
||||
oci_drv_error("OCIAttrSet: OCI_ATTR_SERVER");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* username */
|
||||
H->last_err = OCIAttrSet(H->session, OCI_HTYPE_SESSION,
|
||||
dbh->username, strlen(dbh->username),
|
||||
OCI_ATTR_USERNAME, H->err);
|
||||
if (H->last_err) {
|
||||
oci_drv_error("OCIAttrSet: OCI_ATTR_USERNAME");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* password */
|
||||
H->last_err = OCIAttrSet(H->session, OCI_HTYPE_SESSION,
|
||||
dbh->password, strlen(dbh->password),
|
||||
OCI_ATTR_PASSWORD, H->err);
|
||||
if (H->last_err) {
|
||||
oci_drv_error("OCIAttrSet: OCI_ATTR_PASSWORD");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Now fire up the session */
|
||||
H->last_err = OCISessionBegin(H->svc, H->err, H->session, OCI_CRED_RDBMS, OCI_DEFAULT);
|
||||
if (H->last_err) {
|
||||
oci_drv_error("OCISessionBegin:");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* set the server handle into service handle */
|
||||
H->last_err = OCIAttrSet(H->svc, OCI_HTYPE_SVCCTX, H->session, 0, OCI_ATTR_SESSION, H->err);
|
||||
if (H->last_err) {
|
||||
oci_drv_error("OCIAttrSet: OCI_ATTR_SESSION:");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
dbh->methods = &oci_methods;
|
||||
dbh->alloc_own_columns = 1;
|
||||
dbh->supports_placeholders = PDO_PLACEHOLDER_NAMED;
|
||||
dbh->native_case = PDO_CASE_UPPER;
|
||||
|
||||
ret = 1;
|
||||
|
||||
cleanup:
|
||||
for (i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) {
|
||||
if (vars[i].freeme) {
|
||||
efree(vars[i].optval);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
oci_handle_closer(dbh TSRMLS_CC);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
pdo_driver_t pdo_oci_driver = {
|
||||
PDO_DRIVER_HEADER(oci),
|
||||
pdo_oci_handle_factory
|
||||
};
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,420 +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: 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 "pdo/php_pdo.h"
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_oci.h"
|
||||
#include "php_pdo_oci_int.h"
|
||||
|
||||
#define STMT_CALL(name, params) \
|
||||
S->last_err = name params; \
|
||||
S->last_err = _oci_error(S->err, stmt->dbh, stmt, #name, S->last_err, __FILE__, __LINE__ TSRMLS_CC); \
|
||||
if (S->last_err) { \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define STMT_CALL_MSG(name, msg, params) \
|
||||
S->last_err = name params; \
|
||||
S->last_err = _oci_error(S->err, stmt->dbh, stmt, #name ": " #msg, S->last_err, __FILE__, __LINE__ TSRMLS_CC); \
|
||||
if (S->last_err) { \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
|
||||
static int oci_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
|
||||
HashTable *BC = stmt->bound_columns;
|
||||
HashTable *BP = stmt->bound_params;
|
||||
|
||||
int i;
|
||||
|
||||
if (S->stmt) {
|
||||
/* cancel server side resources for the statement if we didn't
|
||||
* fetch it all */
|
||||
OCIStmtFetch(S->stmt, S->err, 0, OCI_FETCH_NEXT, OCI_DEFAULT);
|
||||
|
||||
/* free the handle */
|
||||
OCIHandleFree(S->stmt, OCI_HTYPE_STMT);
|
||||
S->stmt = NULL;
|
||||
}
|
||||
if (S->err) {
|
||||
OCIHandleFree(S->err, OCI_HTYPE_ERROR);
|
||||
S->err = NULL;
|
||||
}
|
||||
|
||||
if (BC) {
|
||||
zend_hash_destroy(BC);
|
||||
efree(stmt->bound_columns);
|
||||
}
|
||||
|
||||
if (BP) {
|
||||
zend_hash_destroy(BP);
|
||||
efree(stmt->bound_params);
|
||||
}
|
||||
|
||||
if (S->cols) {
|
||||
for (i = 0; i < stmt->column_count; i++) {
|
||||
if (S->cols[i].data) {
|
||||
efree(S->cols[i].data);
|
||||
}
|
||||
}
|
||||
efree(S->cols);
|
||||
S->cols = NULL;
|
||||
}
|
||||
efree(S);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int oci_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
|
||||
ub4 rowcount;
|
||||
|
||||
if (!S->stmt_type) {
|
||||
STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_STMT_TYPE",
|
||||
(S->stmt, OCI_HTYPE_STMT, &S->stmt_type, 0, OCI_ATTR_STMT_TYPE, S->err));
|
||||
}
|
||||
|
||||
if (stmt->executed) {
|
||||
/* ensure that we cancel the cursor from a previous fetch */
|
||||
OCIStmtFetch(S->stmt, S->err, 0, OCI_FETCH_NEXT, OCI_DEFAULT);
|
||||
}
|
||||
|
||||
STMT_CALL(OCIStmtExecute, (S->H->svc, S->stmt, S->err,
|
||||
S->stmt_type == OCI_STMT_SELECT ? 0 : 1, 0, NULL, NULL,
|
||||
(stmt->dbh->auto_commit && !stmt->dbh->in_txn) ? OCI_COMMIT_ON_SUCCESS : OCI_DEFAULT));
|
||||
|
||||
if (!stmt->executed) {
|
||||
ub4 colcount;
|
||||
/* do first-time-only definition of bind/mapping stuff */
|
||||
|
||||
/* how many columns do we have ? */
|
||||
STMT_CALL_MSG(OCIAttrGet, "ATTR_PARAM_COUNT",
|
||||
(S->stmt, OCI_HTYPE_STMT, &colcount, 0, OCI_ATTR_PARAM_COUNT, S->err));
|
||||
|
||||
stmt->column_count = (int)colcount;
|
||||
|
||||
S->cols = ecalloc(colcount, sizeof(pdo_oci_column));
|
||||
}
|
||||
|
||||
STMT_CALL_MSG(OCIAttrGet, "ATTR_ROW_COUNT",
|
||||
(S->stmt, OCI_HTYPE_STMT, &rowcount, 0, OCI_ATTR_ROW_COUNT, S->err));
|
||||
stmt->row_count = (long)rowcount;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static sb4 oci_bind_input_cb(dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp,
|
||||
ub4 *alenp, ub1 *piecep, dvoid **indpp)
|
||||
{
|
||||
struct pdo_bound_param_data *param = (struct pdo_bound_param_data*)ctx;
|
||||
pdo_oci_bound_param *P = (pdo_oci_bound_param*)ecalloc(1, sizeof(pdo_oci_bound_param));
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if (!param || !param->parameter) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "param is NULL in oci_bind_input_cb; this should not happen");
|
||||
return OCI_ERROR;
|
||||
}
|
||||
|
||||
*indpp = &P->indicator;
|
||||
|
||||
if (ZVAL_IS_NULL(param->parameter)) {
|
||||
/* insert a NULL value into the column */
|
||||
P->indicator = -1; /* NULL */
|
||||
*bufpp = 0;
|
||||
*alenp = -1;
|
||||
} else if (!P->thing) {
|
||||
/* regular string bind */
|
||||
convert_to_string(param->parameter);
|
||||
*bufpp = Z_STRVAL_P(param->parameter);
|
||||
*alenp = Z_STRLEN_P(param->parameter);
|
||||
} else {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "P->thing should not be set??");
|
||||
return OCI_ERROR;
|
||||
}
|
||||
|
||||
*piecep = OCI_ONE_PIECE;
|
||||
return OCI_CONTINUE;
|
||||
}
|
||||
|
||||
static sb4 oci_bind_output_cb(dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 **alenpp,
|
||||
ub1 *piecep, dvoid **indpp, ub2 **rcodepp)
|
||||
{
|
||||
struct pdo_bound_param_data *param = (struct pdo_bound_param_data*)ctx;
|
||||
pdo_oci_bound_param *P = (pdo_oci_bound_param*)ecalloc(1, sizeof(pdo_oci_bound_param));
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if (!param || !param->parameter) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "param is NULL in oci_bind_output_cb; this should not happen");
|
||||
return OCI_ERROR;
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(param->parameter) == IS_OBJECT || Z_TYPE_P(param->parameter) == IS_RESOURCE) {
|
||||
return OCI_CONTINUE;
|
||||
}
|
||||
|
||||
convert_to_string(param->parameter);
|
||||
zval_dtor(param->parameter);
|
||||
|
||||
Z_STRLEN_P(param->parameter) = param->max_value_len;
|
||||
Z_STRVAL_P(param->parameter) = emalloc(Z_STRLEN_P(param->parameter)+1);
|
||||
|
||||
|
||||
*alenpp = &P->actual_len;
|
||||
*bufpp = Z_STRVAL_P(param->parameter);
|
||||
*piecep = OCI_ONE_PIECE;
|
||||
*rcodepp = &P->retcode;
|
||||
*indpp = &P->indicator;
|
||||
|
||||
return OCI_CONTINUE;
|
||||
}
|
||||
|
||||
static int oci_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
|
||||
enum pdo_param_event event_type TSRMLS_DC)
|
||||
{
|
||||
pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
|
||||
|
||||
/* we're only interested in parameters for prepared SQL right now */
|
||||
if (param->is_param) {
|
||||
pdo_oci_bound_param *P;
|
||||
sb4 value_sz = -1;
|
||||
|
||||
P = (pdo_oci_bound_param*)param->driver_data;
|
||||
|
||||
switch (event_type) {
|
||||
case PDO_PARAM_EVT_ALLOC:
|
||||
P = (pdo_oci_bound_param*)ecalloc(1, sizeof(pdo_oci_bound_param));
|
||||
param->driver_data = P;
|
||||
|
||||
/* figure out what we're doing */
|
||||
switch (param->param_type) {
|
||||
case PDO_PARAM_LOB:
|
||||
case PDO_PARAM_STMT:
|
||||
return 0;
|
||||
|
||||
case PDO_PARAM_STR:
|
||||
default:
|
||||
P->oci_type = SQLT_CHR;
|
||||
convert_to_string(param->parameter);
|
||||
value_sz = param->max_value_len + 1;
|
||||
P->actual_len = Z_STRLEN_P(param->parameter);
|
||||
|
||||
}
|
||||
|
||||
if (param->name) {
|
||||
STMT_CALL(OCIBindByName, (S->stmt,
|
||||
&P->bind, S->err, (text*)param->name,
|
||||
param->namelen, 0, value_sz, P->oci_type,
|
||||
&P->indicator, 0, &P->retcode, 0, 0,
|
||||
OCI_DATA_AT_EXEC));
|
||||
} else {
|
||||
STMT_CALL(OCIBindByPos, (S->stmt,
|
||||
&P->bind, S->err, param->paramno+1,
|
||||
0, value_sz, P->oci_type,
|
||||
&P->indicator, 0, &P->retcode, 0, 0,
|
||||
OCI_DATA_AT_EXEC));
|
||||
}
|
||||
|
||||
STMT_CALL(OCIBindDynamic, (P->bind,
|
||||
S->err,
|
||||
param, oci_bind_input_cb,
|
||||
param, oci_bind_output_cb));
|
||||
|
||||
return 1;
|
||||
|
||||
case PDO_PARAM_EVT_EXEC_PRE:
|
||||
P->indicator = 0;
|
||||
return 1;
|
||||
|
||||
case PDO_PARAM_EVT_EXEC_POST:
|
||||
/* fixup stuff set in motion in oci_bind_output_cb */
|
||||
if (P->indicator == -1) {
|
||||
/* set up a NULL value */
|
||||
if (Z_TYPE_P(param->parameter) == IS_STRING && Z_STRVAL_P(param->parameter) != empty_string) {
|
||||
/* OCI likes to stick non-terminated strings in things */
|
||||
*Z_STRVAL_P(param->parameter) = '\0';
|
||||
}
|
||||
zval_dtor(param->parameter);
|
||||
ZVAL_NULL(param->parameter);
|
||||
} else if (Z_TYPE_P(param->parameter) == IS_STRING && Z_STRVAL_P(param->parameter) != empty_string) {
|
||||
Z_STRLEN_P(param->parameter) = P->actual_len;
|
||||
Z_STRVAL_P(param->parameter) = erealloc(Z_STRVAL_P(param->parameter), P->actual_len+1);
|
||||
Z_STRVAL_P(param->parameter)[P->actual_len] = '\0';
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int oci_stmt_fetch(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
|
||||
|
||||
S->last_err = OCIStmtFetch(S->stmt, S->err, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
|
||||
|
||||
if (S->last_err == OCI_NO_DATA) {
|
||||
/* no (more) data */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (S->last_err == OCI_NEED_DATA) {
|
||||
oci_stmt_error("OCI_NEED_DATA");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (S->last_err == OCI_SUCCESS_WITH_INFO || S->last_err == OCI_SUCCESS) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
oci_stmt_error("OCIStmtFetch");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int oci_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
|
||||
{
|
||||
pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
|
||||
OCIParam *param = NULL;
|
||||
text *colname;
|
||||
ub2 dtype, data_size, scale, precis;
|
||||
ub4 namelen;
|
||||
struct pdo_column_data *col = &stmt->columns[colno];
|
||||
zend_bool dyn = FALSE;
|
||||
|
||||
/* describe the column */
|
||||
STMT_CALL(OCIParamGet, (S->stmt, OCI_HTYPE_STMT, S->err, (dvoid*)¶m, colno+1));
|
||||
|
||||
/* what type ? */
|
||||
STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_DATA_TYPE",
|
||||
(param, OCI_DTYPE_PARAM, &dtype, 0, OCI_ATTR_DATA_TYPE, S->err));
|
||||
|
||||
/* how big ? */
|
||||
STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_DATA_SIZE",
|
||||
(param, OCI_DTYPE_PARAM, &data_size, 0, OCI_ATTR_DATA_SIZE, S->err));
|
||||
|
||||
/* scale ? */
|
||||
STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_SCALE",
|
||||
(param, OCI_DTYPE_PARAM, &scale, 0, OCI_ATTR_SCALE, S->err));
|
||||
|
||||
/* precision ? */
|
||||
STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_PRECISION",
|
||||
(param, OCI_DTYPE_PARAM, &precis, 0, OCI_ATTR_PRECISION, S->err));
|
||||
|
||||
/* name ? */
|
||||
STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_NAME",
|
||||
(param, OCI_DTYPE_PARAM, &colname, &namelen, OCI_ATTR_NAME, S->err));
|
||||
|
||||
col->precision = scale;
|
||||
col->maxlen = data_size;
|
||||
col->namelen = namelen;
|
||||
col->name = estrndup(colname, namelen);
|
||||
|
||||
/* how much room do we need to store the field */
|
||||
switch (dtype) {
|
||||
case SQLT_BIN:
|
||||
default:
|
||||
dyn = FALSE;
|
||||
if (dtype == SQLT_DAT || dtype == SQLT_NUM
|
||||
#ifdef SQLT_TIMESTAMP
|
||||
|| dtype == SQLT_TIMESTAMP
|
||||
#endif
|
||||
#ifdef SQLT_TIMESTAMP_TZ
|
||||
|| dtype == SQLT_TIMESTAMP_TZ
|
||||
#endif
|
||||
) {
|
||||
/* should be big enough for most date formats and numbers */
|
||||
S->cols[colno].datalen = 512;
|
||||
} else {
|
||||
S->cols[colno].datalen = col->maxlen + 1; /* 1 for NUL terminator */
|
||||
}
|
||||
if (dtype == SQLT_BIN) {
|
||||
S->cols[colno].datalen *= 3;
|
||||
}
|
||||
S->cols[colno].data = emalloc(S->cols[colno].datalen);
|
||||
dtype = SQLT_CHR;
|
||||
|
||||
/* returning data as a string */
|
||||
col->param_type = PDO_PARAM_STR;
|
||||
}
|
||||
|
||||
if (!dyn) {
|
||||
STMT_CALL(OCIDefineByPos, (S->stmt, &S->cols[colno].def, S->err, colno+1,
|
||||
S->cols[colno].data, S->cols[colno].datalen, dtype, &S->cols[colno].indicator,
|
||||
&S->cols[colno].fetched_len, &S->cols[colno].retcode, OCI_DEFAULT));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int oci_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len TSRMLS_DC)
|
||||
{
|
||||
pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
|
||||
pdo_oci_column *C = &S->cols[colno];
|
||||
|
||||
/* check the indicator to ensure that the data is intact */
|
||||
if (C->indicator == -1) {
|
||||
/* A NULL value */
|
||||
*ptr = NULL;
|
||||
*len = 0;
|
||||
return 1;
|
||||
} else if (C->indicator == 0) {
|
||||
/* it was stored perfectly */
|
||||
*ptr = C->data;
|
||||
*len = C->fetched_len;
|
||||
return 1;
|
||||
} else {
|
||||
/* it was truncated */
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "column %d data was too large for buffer and was truncated to fit it", colno);
|
||||
|
||||
*ptr = C->data;
|
||||
*len = C->fetched_len;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
struct pdo_stmt_methods oci_stmt_methods = {
|
||||
oci_stmt_dtor,
|
||||
oci_stmt_execute,
|
||||
oci_stmt_fetch,
|
||||
oci_stmt_describe,
|
||||
oci_stmt_get_col,
|
||||
oci_stmt_param_hook
|
||||
};
|
||||
|
||||
/*
|
||||
* 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,47 +0,0 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE package SYSTEM "../pear/package.dtd">
|
||||
<package version="1.0">
|
||||
<name>PDO_OCI</name>
|
||||
<summary>Oracle Call Interface driver for PDO</summary>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>wez</user>
|
||||
<name>Wez Furlong</name>
|
||||
<email>wez@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
<description>
|
||||
This extension provides an Oracle driver for PDO.
|
||||
</description>
|
||||
<license>PHP</license>
|
||||
<release>
|
||||
<state>alpha</state>
|
||||
<version>0.1</version>
|
||||
<date>2004-05-21</date>
|
||||
|
||||
<notes>
|
||||
You need to install the PDO core module before you can make use of this one.
|
||||
You also require Oracle OCI 8 or higher client libraries installed on the machine where you intend to build and/or use it.
|
||||
|
||||
If you are running on windows, you can download the binary from here:
|
||||
http://snaps.php.net/win32/PECL_5_0/php_pdo_oci.dll
|
||||
</notes>
|
||||
|
||||
<filelist>
|
||||
<file role="src" name="config.m4"/>
|
||||
<file role="src" name="config.w32"/>
|
||||
<file role="src" name="pdo_oci.c"/>
|
||||
<file role="src" name="oci_driver.c"/>
|
||||
<file role="src" name="oci_statement.c"/>
|
||||
<file role="src" name="php_pdo_oci.h"/>
|
||||
<file role="src" name="php_pdo_oci_int.h"/>
|
||||
|
||||
<file role="doc" name="CREDITS"/>
|
||||
</filelist>
|
||||
<deps>
|
||||
<dep type="php" rel="ge" version="5.0.0RC3dev"/>
|
||||
<dep type="ext" rel="ge" name="pdo" version="0.1"/>
|
||||
</deps>
|
||||
</release>
|
||||
</package>
|
||||
@@ -1,120 +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: 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 "pdo/php_pdo.h"
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_oci.h"
|
||||
#include "php_pdo_oci_int.h"
|
||||
|
||||
/* {{{ pdo_oci_functions[] */
|
||||
function_entry pdo_oci_functions[] = {
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ pdo_oci_module_entry */
|
||||
zend_module_entry pdo_oci_module_entry = {
|
||||
STANDARD_MODULE_HEADER,
|
||||
"PDO_OCI",
|
||||
pdo_oci_functions,
|
||||
PHP_MINIT(pdo_oci),
|
||||
PHP_MSHUTDOWN(pdo_oci),
|
||||
NULL,
|
||||
NULL,
|
||||
PHP_MINFO(pdo_oci),
|
||||
"0.1",
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_PDO_OCI
|
||||
ZEND_GET_MODULE(pdo_oci)
|
||||
#endif
|
||||
|
||||
const ub4 PDO_OCI_INIT_MODE =
|
||||
#if 0 && defined(OCI_SHARED)
|
||||
/* shared mode is known to be bad for PHP */
|
||||
OCI_SHARED
|
||||
#else
|
||||
OCI_DEFAULT
|
||||
#endif
|
||||
#ifdef OCI_OBJECT
|
||||
|OCI_OBJECT
|
||||
#endif
|
||||
#ifdef ZTS
|
||||
|OCI_THREADED
|
||||
#endif
|
||||
;
|
||||
|
||||
/* true global environment */
|
||||
OCIEnv *pdo_oci_Env = NULL;
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION
|
||||
*/
|
||||
PHP_MINIT_FUNCTION(pdo_oci)
|
||||
{
|
||||
php_pdo_register_driver(&pdo_oci_driver);
|
||||
|
||||
#if HAVE_OCIENVCREATE
|
||||
OCIEnvCreate(&pdo_oci_Env, PDO_OCI_INIT_MODE, NULL, NULL, NULL, NULL, 0, NULL);
|
||||
#else
|
||||
OCIInitialize(PDO_OCI_INIT_MODE, NULL, NULL, NULL, NULL);
|
||||
OCIEnvInit(&pdo_oci_Env, OCI_DEFAULT, 0, NULL);
|
||||
#endif
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo_oci)
|
||||
{
|
||||
php_pdo_unregister_driver(&pdo_oci_driver);
|
||||
OCIHandleFree((dvoid*)pdo_oci_Env, OCI_HTYPE_ENV);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
PHP_MINFO_FUNCTION(pdo_oci)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "PDO Driver for OCI 8 and later", "enabled");
|
||||
php_info_print_table_end();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* 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,53 +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: Wez Furlong <wez@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef PHP_PDO_OCI_H
|
||||
#define PHP_PDO_OCI_H
|
||||
|
||||
extern zend_module_entry pdo_oci_module_entry;
|
||||
#define phpext_pdo_oci_ptr &pdo_oci_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_PDO_OCI_API __declspec(dllexport)
|
||||
#else
|
||||
#define PHP_PDO_OCI_API
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
PHP_MINIT_FUNCTION(pdo_oci);
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo_oci);
|
||||
PHP_RINIT_FUNCTION(pdo_oci);
|
||||
PHP_RSHUTDOWN_FUNCTION(pdo_oci);
|
||||
PHP_MINFO_FUNCTION(pdo_oci);
|
||||
|
||||
#endif /* PHP_PDO_OCI_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,89 +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: Wez Furlong <wez@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include <oci.h>
|
||||
|
||||
typedef struct {
|
||||
const char *file;
|
||||
int line;
|
||||
sb4 errcode;
|
||||
char *errmsg;
|
||||
} pdo_oci_error_info;
|
||||
|
||||
/* stuff we use in an OCI database handle */
|
||||
typedef struct {
|
||||
OCIServer *server;
|
||||
OCISession *session;
|
||||
OCIEnv *env;
|
||||
OCIError *err;
|
||||
OCISvcCtx *svc;
|
||||
/* OCI9; 0 == use NLS_LANG */
|
||||
ub2 charset;
|
||||
sword last_err;
|
||||
|
||||
unsigned attached:1;
|
||||
unsigned _reserved:31;
|
||||
|
||||
pdo_oci_error_info einfo;
|
||||
} pdo_oci_db_handle;
|
||||
|
||||
typedef struct {
|
||||
OCIDefine *def;
|
||||
ub2 fetched_len;
|
||||
ub2 retcode;
|
||||
sb2 indicator;
|
||||
|
||||
char *data;
|
||||
unsigned long datalen;
|
||||
|
||||
} pdo_oci_column;
|
||||
|
||||
typedef struct {
|
||||
pdo_oci_db_handle *H;
|
||||
OCIStmt *stmt;
|
||||
OCIError *err;
|
||||
sword last_err;
|
||||
ub2 stmt_type;
|
||||
|
||||
pdo_oci_column *cols;
|
||||
pdo_oci_error_info einfo;
|
||||
} pdo_oci_stmt;
|
||||
|
||||
typedef struct {
|
||||
OCIBind *bind; /* allocated by OCI */
|
||||
sb2 oci_type;
|
||||
sb2 indicator;
|
||||
ub2 retcode;
|
||||
|
||||
ub4 actual_len;
|
||||
|
||||
dvoid *thing; /* for LOBS, REFCURSORS etc. */
|
||||
} pdo_oci_bound_param;
|
||||
|
||||
extern const ub4 PDO_OCI_INIT_MODE;
|
||||
extern pdo_driver_t pdo_oci_driver;
|
||||
extern OCIEnv *pdo_oci_Env;
|
||||
|
||||
ub4 _oci_error(OCIError *err, pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *what, sword status, const char *file, int line TSRMLS_DC);
|
||||
#define oci_drv_error(w) _oci_error(H->err, dbh, NULL, w, H->last_err, __FILE__, __LINE__ TSRMLS_CC)
|
||||
#define oci_stmt_error(w) _oci_error(S->err, stmt->dbh, stmt, w, S->last_err, __FILE__, __LINE__ TSRMLS_CC)
|
||||
|
||||
extern struct pdo_stmt_methods oci_stmt_methods;
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
--TEST--
|
||||
PDO_OCI: connect
|
||||
--SKIPIF--
|
||||
<?php # vim:ft=php
|
||||
if (!extension_loaded("pdo_oci")) print "skip";
|
||||
?>
|
||||
--FILE--
|
||||
<?php /* $Id$ */
|
||||
|
||||
require "settings.inc";
|
||||
|
||||
$db = new PDO("oci:dbname=$dbase",$user,$password) or die("connect error");
|
||||
echo "done\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
done
|
||||
@@ -1,13 +0,0 @@
|
||||
<?php /* $Id$ */
|
||||
|
||||
/*
|
||||
* Please, change user, password and dbase to match your configuration.
|
||||
* */
|
||||
|
||||
$user = "system";
|
||||
$password = "manager";
|
||||
$dbase = "dbase";
|
||||
|
||||
$schema = "system";
|
||||
|
||||
?>
|
||||
@@ -1,2 +0,0 @@
|
||||
ODBC driver for PDO
|
||||
Wez Furlong
|
||||
Whitespace-only changes.
@@ -1,111 +0,0 @@
|
||||
dnl $Id$
|
||||
dnl config.m4 for extension pdo_odbc
|
||||
|
||||
AC_DEFUN(PDO_ODBC_HELP_TEXT, [[
|
||||
--with-pdo-odbc=flavour,dir Add support for "flavour" ODBC drivers,
|
||||
looking for include and lib dirs under "dir"
|
||||
|
||||
flavour can be one of:
|
||||
ibm-db2, unixODBC
|
||||
|
||||
You may omit the ,dir part to use a reasonable default for
|
||||
the flavour you have selected. e.g.:
|
||||
--with-pdo-odbc=unixODBC
|
||||
will check for unixODBC under /usr/local
|
||||
|
||||
This extension will always be created as a shared extension
|
||||
named pdo_odbc.so
|
||||
]])
|
||||
|
||||
PHP_ARG_WITH(pdo-odbc, ODBC v3 driver for PDO, PDO_ODBC_HELP_TEXT)
|
||||
|
||||
AC_DEFUN([PDO_ODBC_CHECK_HEADER],[
|
||||
if test -f $PDO_ODBC_INCDIR/$1 ; then
|
||||
AC_DEFINE([HAVE_]translit($1,a-z_.-,A-Z___), 1, [ ])
|
||||
fi
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING(which ODBC flavour you want)
|
||||
if test "$PHP_PDO_ODBC" != "no" && test "$PHP_PDO_ODBC" != "yes" ; then
|
||||
pdo_odbc_flavour=`echo $withval | cut -d, -f1`
|
||||
pdo_odbc_dir=`echo $withval | cut -d, -f2`
|
||||
|
||||
if test "$pdo_odbc_dir" = "$withval" ; then
|
||||
pdo_odbc_dir=""
|
||||
fi
|
||||
|
||||
case $pdo_odbc_flavour in
|
||||
ibm-db2)
|
||||
pdo_odbc_def_libdir=/home/db2inst/sqllib/lib
|
||||
pdo_odbc_def_incdir=/home/db2inst1/sqllib/include
|
||||
pdo_odbc_def_lib=-ldb2
|
||||
;;
|
||||
|
||||
unixODBC)
|
||||
pdo_odbc_def_libdir=/usr/local/lib
|
||||
pdo_odbc_def_incdir=/usr/local/include
|
||||
pdo_odbc_def_lib=-lodbc
|
||||
;;
|
||||
|
||||
*)
|
||||
AC_MSG_ERROR(Unknown ODBC flavour $pdo_odbc_flavour
|
||||
PDO_ODBC_HELP_TEXT
|
||||
)
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$pdo_odbc_dir" != "" ; then
|
||||
PDO_ODBC_INCDIR="$pdo_odbc_dir/include"
|
||||
PDO_ODBC_LIBDIR="$pdo_odbc_dir/lib"
|
||||
else
|
||||
PDO_ODBC_INCDIR="$pdo_odbc_def_incdir"
|
||||
PDO_ODBC_LIBDIR="$pdo_odbc_def_libdir"
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([$pdo_odbc_flavour
|
||||
libs $PDO_ODBC_LIBDIR,
|
||||
headers $PDO_ODBC_INCDIR])
|
||||
|
||||
if ! test -d "$PDO_ODBC_LIBDIR" ; then
|
||||
AC_MSG_WARN([library dir $PDO_ODBC_LIBDIR does not exist])
|
||||
fi
|
||||
|
||||
dnl yick time
|
||||
PDO_ODBC_CHECK_HEADER(odbc.h)
|
||||
PDO_ODBC_CHECK_HEADER(iodbc.h)
|
||||
PDO_ODBC_CHECK_HEADER(sqlunix.h)
|
||||
PDO_ODBC_CHECK_HEADER(sqltypes.h)
|
||||
PDO_ODBC_CHECK_HEADER(sqlucode.h)
|
||||
PDO_ODBC_CHECK_HEADER(sql.h)
|
||||
PDO_ODBC_CHECK_HEADER(isql.h)
|
||||
PDO_ODBC_CHECK_HEADER(sqlext.h)
|
||||
PDO_ODBC_CHECK_HEADER(isqlext.h)
|
||||
PDO_ODBC_CHECK_HEADER(udbcext.h)
|
||||
PDO_ODBC_CHECK_HEADER(sqlcli1.h)
|
||||
PDO_ODBC_CHECK_HEADER(LibraryManager.h)
|
||||
PDO_ODBC_CHECK_HEADER(cli0core.h)
|
||||
PDO_ODBC_CHECK_HEADER(cli0ext.h)
|
||||
PDO_ODBC_CHECK_HEADER(cli0cli.h)
|
||||
PDO_ODBC_CHECK_HEADER(cli0defs.h)
|
||||
PDO_ODBC_CHECK_HEADER(cli0env.h)
|
||||
|
||||
PDO_ODBC_INCLUDE="-I$PDO_ODBC_INCDIR -DPDO_ODBC_TYPE=\\\"$pdo_odbc_flavour\\\""
|
||||
PDO_ODBC_LFLAGS="-L$PDO_ODBC_LIBDIR"
|
||||
PDO_ODBC_LIBS="$pdo_odbc_def_lib"
|
||||
|
||||
LDFLAGS="$PDO_ODBC_LFLAGS $PDO_ODBC_LIBS -lm -ldl"
|
||||
AC_TRY_LINK_FUNC([SQLAllocHandle],[],[
|
||||
AC_MSG_ERROR([[Your ODBC libraries either do not exist, or do not appear to be ODBC3 compatible]])
|
||||
])
|
||||
LDFLAGS=$save_old_LDFLAGS
|
||||
PHP_EVAL_LIBLINE($PDO_ODBC_LIBS $PDO_ODBC_LFLAGS, [PDO_ODBC_SHARED_LIBADD])
|
||||
PHP_SUBST(PDO_ODBC_SHARED_LIBADD)
|
||||
|
||||
PHP_NEW_EXTENSION(pdo_odbc, pdo_odbc.c odbc_driver.c odbc_stmt.c, yes,,-I\$prefix/include/php/ext $PDO_ODBC_INCLUDE)
|
||||
else
|
||||
AC_MSG_ERROR(
|
||||
Unknown ODBC flavour $PHP_PDO_ODBC
|
||||
PDO_ODBC_HELP_TEXT
|
||||
)
|
||||
fi
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
// $Id$
|
||||
// vim:ft=javascript
|
||||
|
||||
ARG_WITH("pdo-odbc", "ODBC support for PDO", "no");
|
||||
|
||||
if (PHP_PDO_ODBC != "no") {
|
||||
if (CHECK_LIB("odbc32.lib", "pdo_odbc") && CHECK_LIB("odbccp32.lib", "pdo_odbc")) {
|
||||
EXTENSION("pdo_odbc", "pdo_odbc.c odbc_driver.c odbc_stmt.c");
|
||||
CHECK_HEADER_ADD_INCLUDE('sql.h', 'CFLAGS_PDO_ODBC');
|
||||
CHECK_HEADER_ADD_INCLUDE('sqlext.h', 'CFLAGS_PDO_ODBC');
|
||||
ADD_FLAG('CFLAGS_PDO_ODBC', "/I ..\\pecl");
|
||||
}
|
||||
ADD_EXTENSION_DEP('pdo_odbc', 'pdo');
|
||||
}
|
||||
|
||||
@@ -1,410 +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: 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 "pdo/php_pdo.h"
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_odbc.h"
|
||||
#include "php_pdo_odbc_int.h"
|
||||
|
||||
static struct {
|
||||
char state[6];
|
||||
enum pdo_error_type err;
|
||||
} odbc_to_pdo_err_map[] = {
|
||||
/* this table maps ODBC V3 SQLSTATE codes to PDO_ERR codes */
|
||||
{ "42S01", PDO_ERR_ALREADY_EXISTS },
|
||||
{ "42S11", PDO_ERR_ALREADY_EXISTS },
|
||||
{ "42S21", PDO_ERR_ALREADY_EXISTS },
|
||||
{ "IM001", PDO_ERR_NOT_IMPLEMENTED },
|
||||
{ "42S22", PDO_ERR_NOT_FOUND },
|
||||
{ "42S12", PDO_ERR_NOT_FOUND },
|
||||
{ "42S02", PDO_ERR_NOT_FOUND },
|
||||
{ "42000", PDO_ERR_SYNTAX },
|
||||
{ "23000", PDO_ERR_CONSTRAINT },
|
||||
{ "22025", PDO_ERR_SYNTAX },
|
||||
{ "22019", PDO_ERR_SYNTAX },
|
||||
{ "22018", PDO_ERR_SYNTAX },
|
||||
{ "08S01", PDO_ERR_DISCONNECTED },
|
||||
{ "01S07", PDO_ERR_TRUNCATED },
|
||||
|
||||
};
|
||||
|
||||
static HashTable err_hash;
|
||||
|
||||
void pdo_odbc_fini_error_table(void)
|
||||
{
|
||||
zend_hash_destroy(&err_hash);
|
||||
}
|
||||
|
||||
void pdo_odbc_init_error_table(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
zend_hash_init(&err_hash, 0, NULL, NULL, 1);
|
||||
|
||||
for (i = 0; i < sizeof(odbc_to_pdo_err_map)/sizeof(odbc_to_pdo_err_map[0]); i++) {
|
||||
zend_hash_add(&err_hash, odbc_to_pdo_err_map[i].state, sizeof(odbc_to_pdo_err_map[i].state),
|
||||
&odbc_to_pdo_err_map[i].err, sizeof(odbc_to_pdo_err_map[i].err), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static enum pdo_error_type pdo_odbc_map_error(char *state)
|
||||
{
|
||||
enum pdo_error_type *p_err;
|
||||
if (SUCCESS == zend_hash_find(&err_hash, state, sizeof(odbc_to_pdo_err_map[0].state), (void**)&p_err)) {
|
||||
return *p_err;
|
||||
}
|
||||
return PDO_ERR_CANT_MAP;
|
||||
}
|
||||
|
||||
static int pdo_odbc_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
|
||||
pdo_odbc_errinfo *einfo = &H->einfo;
|
||||
pdo_odbc_stmt *S = NULL;
|
||||
char *message = NULL;
|
||||
|
||||
if (stmt) {
|
||||
S = (pdo_odbc_stmt*)stmt->driver_data;
|
||||
einfo = &S->einfo;
|
||||
}
|
||||
|
||||
spprintf(&message, 0, "%s: %d %s [SQL State %s] (%s:%d)",
|
||||
einfo->what, einfo->last_error, einfo->last_err_msg, einfo->last_state, einfo->file, einfo->line);
|
||||
|
||||
add_next_index_long(info, einfo->last_error);
|
||||
add_next_index_string(info, message, 0);
|
||||
add_next_index_string(info, einfo->last_state, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void pdo_odbc_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, PDO_ODBC_HSTMT statement, char *what, const char *file, int line TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
RETCODE rc;
|
||||
SWORD errmsgsize;
|
||||
pdo_odbc_db_handle *H = (pdo_odbc_db_handle*)dbh->driver_data;
|
||||
pdo_odbc_errinfo *einfo = &H->einfo;
|
||||
pdo_odbc_stmt *S = NULL;
|
||||
enum pdo_error_type *pdo_err = &dbh->error_code;
|
||||
|
||||
if (stmt) {
|
||||
S = (pdo_odbc_stmt*)stmt->driver_data;
|
||||
|
||||
einfo = &S->einfo;
|
||||
pdo_err = &stmt->error_code;
|
||||
}
|
||||
|
||||
if (statement == SQL_NULL_HSTMT && S) {
|
||||
statement = S->stmt;
|
||||
}
|
||||
|
||||
rc = SQLError(H->env, H->dbc, statement, einfo->last_state, &einfo->last_error,
|
||||
einfo->last_err_msg, sizeof(einfo->last_err_msg)-1, &errmsgsize);
|
||||
|
||||
einfo->last_err_msg[errmsgsize] = '\0';
|
||||
einfo->file = file;
|
||||
einfo->line = line;
|
||||
einfo->what = what;
|
||||
|
||||
*pdo_err = pdo_odbc_map_error(einfo->last_state);
|
||||
|
||||
if (!dbh->methods) {
|
||||
zend_throw_exception_ex(php_pdo_get_exception(), *pdo_err TSRMLS_CC, "%s: %d %s [SQL State %s]",
|
||||
what, einfo->last_error, einfo->last_err_msg, einfo->last_state);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int odbc_handle_closer(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_db_handle *H = (pdo_odbc_db_handle*)dbh->driver_data;
|
||||
|
||||
if (H->dbc != SQL_NULL_HANDLE) {
|
||||
SQLEndTran(SQL_HANDLE_DBC, H->dbc, SQL_ROLLBACK);
|
||||
SQLDisconnect(H->dbc);
|
||||
SQLFreeHandle(SQL_HANDLE_DBC, H->dbc);
|
||||
}
|
||||
SQLFreeHandle(SQL_HANDLE_ENV, H->env);
|
||||
pefree(H, dbh->is_persistent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int odbc_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, long options, zval *driver_options TSRMLS_DC)
|
||||
{
|
||||
RETCODE rc;
|
||||
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
|
||||
pdo_odbc_stmt *S = ecalloc(1, sizeof(*S));
|
||||
enum pdo_cursor_type cursor_type = PDO_CURSOR_FWDONLY;
|
||||
|
||||
S->H = H;
|
||||
|
||||
rc = SQLAllocHandle(SQL_HANDLE_STMT, H->dbc, &S->stmt);
|
||||
|
||||
if (rc == SQL_INVALID_HANDLE || rc == SQL_ERROR) {
|
||||
efree(S);
|
||||
pdo_odbc_drv_error("SQLAllocStmt");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cursor_type = pdo_attr_lval(driver_options, PDO_ATTR_CURSOR, PDO_CURSOR_FWDONLY TSRMLS_CC);
|
||||
if (cursor_type != PDO_CURSOR_FWDONLY) {
|
||||
SQLUINTEGER cursor;
|
||||
|
||||
switch (cursor_type) {
|
||||
case PDO_CURSOR_SCROLL:
|
||||
cursor = SQL_CURSOR_STATIC;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
rc = SQLSetStmtAttr(S->stmt, SQL_CURSOR_TYPE, (void*)cursor, SQL_IS_UINTEGER);
|
||||
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
|
||||
pdo_odbc_stmt_error("SQLSetStmtOption: SQL_CURSOR_TYPE");
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, S->stmt);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
rc = SQLPrepare(S->stmt, (char*)sql, SQL_NTS);
|
||||
|
||||
if (rc != SQL_SUCCESS) {
|
||||
pdo_odbc_stmt_error("SQLPrepare");
|
||||
}
|
||||
|
||||
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, S->stmt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
stmt->driver_data = S;
|
||||
stmt->methods = &odbc_stmt_methods;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static long odbc_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
|
||||
RETCODE rc;
|
||||
long row_count = -1;
|
||||
PDO_ODBC_HSTMT stmt;
|
||||
|
||||
rc = SQLAllocHandle(SQL_HANDLE_STMT, H->dbc, &stmt);
|
||||
if (rc != SQL_SUCCESS) {
|
||||
pdo_odbc_drv_error("SQLAllocHandle: STMT");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = SQLExecDirect(stmt, (char *)sql, sql_len);
|
||||
|
||||
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
|
||||
pdo_odbc_doer_error("SQLExecDirect");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = SQLRowCount(stmt, &row_count);
|
||||
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
|
||||
pdo_odbc_doer_error("SQLRowCount");
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
||||
return row_count;
|
||||
}
|
||||
|
||||
static int odbc_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int odbc_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
/* with ODBC, there is nothing special to be done */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int odbc_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
|
||||
RETCODE rc;
|
||||
|
||||
rc = SQLEndTran(SQL_HANDLE_DBC, H->dbc, SQL_COMMIT);
|
||||
|
||||
if (rc != SQL_SUCCESS) {
|
||||
pdo_odbc_drv_error("SQLEndTran: Commit");
|
||||
|
||||
if (rc != SQL_SUCCESS_WITH_INFO) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int odbc_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
|
||||
RETCODE rc;
|
||||
|
||||
rc = SQLEndTran(SQL_HANDLE_DBC, H->dbc, SQL_ROLLBACK);
|
||||
|
||||
if (rc != SQL_SUCCESS) {
|
||||
pdo_odbc_drv_error("SQLEndTran: Rollback");
|
||||
|
||||
if (rc != SQL_SUCCESS_WITH_INFO) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct pdo_dbh_methods odbc_methods = {
|
||||
odbc_handle_closer,
|
||||
odbc_handle_preparer,
|
||||
odbc_handle_doer,
|
||||
odbc_handle_quoter,
|
||||
odbc_handle_begin,
|
||||
odbc_handle_commit,
|
||||
odbc_handle_rollback,
|
||||
NULL, /* set attr */
|
||||
NULL, /* last id */
|
||||
pdo_odbc_fetch_error_func,
|
||||
NULL, /* get attr */
|
||||
};
|
||||
|
||||
static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_odbc_db_handle *H;
|
||||
RETCODE rc;
|
||||
int use_direct = 0;
|
||||
SQLUINTEGER cursor_lib;
|
||||
|
||||
H = pecalloc(1, sizeof(*H), dbh->is_persistent);
|
||||
|
||||
dbh->driver_data = H;
|
||||
|
||||
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &H->env);
|
||||
rc = SQLSetEnvAttr(H->env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
|
||||
|
||||
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
|
||||
pdo_odbc_drv_error("SQLSetEnvAttr: ODBC3");
|
||||
odbc_handle_closer(dbh TSRMLS_CC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef SQL_ATTR_CONNECTION_POOLING
|
||||
if (pdo_odbc_pool_on != SQL_CP_OFF) {
|
||||
rc = SQLSetEnvAttr(H->env, SQL_ATTR_CP_MATCH, (void*)pdo_odbc_pool_mode, 0);
|
||||
if (rc != SQL_SUCCESS) {
|
||||
pdo_odbc_drv_error("SQLSetEnvAttr: SQL_ATTR_CP_MATCH");
|
||||
odbc_handle_closer(dbh TSRMLS_CC);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
rc = SQLAllocHandle(SQL_HANDLE_DBC, H->env, &H->dbc);
|
||||
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
|
||||
pdo_odbc_drv_error("SQLAllocHandle (DBC)");
|
||||
odbc_handle_closer(dbh TSRMLS_CC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!dbh->auto_commit) {
|
||||
rc = SQLSetConnectAttr(H->dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, SQL_IS_UINTEGER);
|
||||
if (rc != SQL_SUCCESS) {
|
||||
pdo_odbc_drv_error("SQLSetConnectAttr AUTOCOMMIT = OFF");
|
||||
odbc_handle_closer(dbh TSRMLS_CC);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* set up the cursor library, if needed, or if configured explicitly */
|
||||
cursor_lib = pdo_attr_lval(driver_options, PDO_ODBC_ATTR_USE_CURSOR_LIBRARY, SQL_CUR_USE_IF_NEEDED TSRMLS_CC);
|
||||
rc = SQLSetConnectAttr(H->dbc, SQL_ODBC_CURSORS, (void*)cursor_lib, SQL_IS_UINTEGER);
|
||||
if (rc != SQL_SUCCESS) {
|
||||
pdo_odbc_drv_error("SQLSetConnectAttr SQL_ODBC_CURSORS");
|
||||
odbc_handle_closer(dbh TSRMLS_CC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (strchr(dbh->data_source, ';')) {
|
||||
char dsnbuf[1024];
|
||||
short dsnbuflen;
|
||||
|
||||
use_direct = 1;
|
||||
|
||||
/* Force UID and PWD to be set in the DSN */
|
||||
if (*dbh->username && !strstr(dbh->data_source, "uid") && !strstr(dbh->data_source, "UID")) {
|
||||
char *dsn = pemalloc(strlen(dbh->data_source) + strlen(dbh->username) + strlen(dbh->password) + sizeof(";UID=;PWD="), dbh->is_persistent);
|
||||
sprintf(dsn, "%s;UID=%s;PWD=%s", dbh->data_source, dbh->username, dbh->password);
|
||||
pefree((char*)dbh->data_source, dbh->is_persistent);
|
||||
dbh->data_source = dsn;
|
||||
}
|
||||
|
||||
rc = SQLDriverConnect(H->dbc, NULL, (char*)dbh->data_source, strlen(dbh->data_source),
|
||||
dsnbuf, sizeof(dsnbuf)-1, &dsnbuflen, SQL_DRIVER_NOPROMPT);
|
||||
}
|
||||
if (!use_direct) {
|
||||
rc = SQLConnect(H->dbc, (char*)dbh->data_source, SQL_NTS, dbh->username, SQL_NTS, dbh->password, SQL_NTS);
|
||||
}
|
||||
|
||||
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
|
||||
pdo_odbc_drv_error(use_direct ? "SQLDriverConnect" : "SQLConnect");
|
||||
odbc_handle_closer(dbh TSRMLS_CC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: if we want to play nicely, we should check to see if the driver really supports ODBC v3 or not */
|
||||
|
||||
dbh->methods = &odbc_methods;
|
||||
dbh->alloc_own_columns = 1;
|
||||
dbh->supports_placeholders = PDO_PLACEHOLDER_POSITIONAL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
pdo_driver_t pdo_odbc_driver = {
|
||||
PDO_DRIVER_HEADER(odbc),
|
||||
pdo_odbc_handle_factory
|
||||
};
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,262 +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: 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 "pdo/php_pdo.h"
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_odbc.h"
|
||||
#include "php_pdo_odbc_int.h"
|
||||
|
||||
static int odbc_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
|
||||
int i;
|
||||
|
||||
if (S->stmt != SQL_NULL_HANDLE) {
|
||||
if (stmt->executed) {
|
||||
SQLCancel(S->stmt);
|
||||
}
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, S->stmt);
|
||||
S->stmt = SQL_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (S->cols) {
|
||||
for (i = 0; i < stmt->column_count; i++) {
|
||||
if (S->cols[i].data) {
|
||||
efree(S->cols[i].data);
|
||||
}
|
||||
}
|
||||
efree(S->cols);
|
||||
S->cols = NULL;
|
||||
}
|
||||
efree(S);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int odbc_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
RETCODE rc;
|
||||
pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
|
||||
|
||||
if (stmt->executed) {
|
||||
SQLCancel(S->stmt);
|
||||
}
|
||||
|
||||
rc = SQLExecute(S->stmt);
|
||||
|
||||
switch (rc) {
|
||||
case SQL_SUCCESS:
|
||||
break;
|
||||
case SQL_NO_DATA_FOUND:
|
||||
case SQL_SUCCESS_WITH_INFO:
|
||||
pdo_odbc_stmt_error("SQLExecute");
|
||||
break;
|
||||
|
||||
default:
|
||||
pdo_odbc_stmt_error("SQLExecute");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!stmt->executed) {
|
||||
/* do first-time-only definition of bind/mapping stuff */
|
||||
SQLSMALLINT colcount;
|
||||
|
||||
/* how many columns do we have ? */
|
||||
SQLNumResultCols(S->stmt, &colcount);
|
||||
|
||||
stmt->column_count = (int)colcount;
|
||||
|
||||
S->cols = ecalloc(colcount, sizeof(pdo_odbc_column));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
|
||||
enum pdo_param_event event_type TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
|
||||
RETCODE rc;
|
||||
SWORD sqltype, ctype, scale, nullable;
|
||||
UDWORD precision;
|
||||
|
||||
/* we're only interested in parameters for prepared SQL right now */
|
||||
if (param->is_param) {
|
||||
|
||||
switch (event_type) {
|
||||
case PDO_PARAM_EVT_ALLOC:
|
||||
|
||||
/* figure out what we're doing */
|
||||
switch (param->param_type) {
|
||||
case PDO_PARAM_LOB:
|
||||
case PDO_PARAM_STMT:
|
||||
return 0;
|
||||
|
||||
case PDO_PARAM_STR:
|
||||
default:
|
||||
convert_to_string(param->parameter);
|
||||
}
|
||||
|
||||
SQLDescribeParam(S->stmt, param->paramno+1, &sqltype, &precision, &scale, &nullable);
|
||||
if (sqltype == SQL_BINARY || sqltype == SQL_VARBINARY || sqltype == SQL_LONGVARBINARY) {
|
||||
ctype = SQL_C_BINARY;
|
||||
} else {
|
||||
ctype = SQL_C_CHAR;
|
||||
}
|
||||
|
||||
rc = SQLBindParameter(S->stmt, param->paramno+1,
|
||||
SQL_PARAM_INPUT, ctype, sqltype, precision, scale,
|
||||
Z_STRVAL_P(param->parameter), 0,
|
||||
/* XXX: this has the wrong type for DB2 */
|
||||
&Z_STRLEN_P(param->parameter)
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int odbc_stmt_fetch(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
|
||||
RETCODE rc;
|
||||
|
||||
rc = SQLFetch(S->stmt);
|
||||
|
||||
if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (rc == SQL_NO_DATA) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pdo_odbc_stmt_error("SQLFetch");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int odbc_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
|
||||
struct pdo_column_data *col = &stmt->columns[colno];
|
||||
zend_bool dyn = FALSE;
|
||||
RETCODE rc;
|
||||
SWORD colnamelen;
|
||||
SDWORD colsize;
|
||||
|
||||
rc = SQLDescribeCol(S->stmt, colno+1, S->cols[colno].colname,
|
||||
sizeof(S->cols[colno].colname)-1, &colnamelen,
|
||||
&S->cols[colno].coltype, &colsize, NULL, NULL);
|
||||
|
||||
col->maxlen = S->cols[colno].datalen = colsize;
|
||||
col->namelen = colnamelen;
|
||||
col->name = S->cols[colno].colname;
|
||||
|
||||
S->cols[colno].data = emalloc(colsize+1);
|
||||
|
||||
/* returning data as a string */
|
||||
col->param_type = PDO_PARAM_STR;
|
||||
|
||||
/* tell ODBC to put it straight into our buffer */
|
||||
rc = SQLBindCol(S->stmt, colno+1, SQL_C_CHAR, S->cols[colno].data,
|
||||
S->cols[colno].datalen, &S->cols[colno].fetched_len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
|
||||
pdo_odbc_column *C = &S->cols[colno];
|
||||
|
||||
/* check the indicator to ensure that the data is intact */
|
||||
if (C->fetched_len == SQL_NULL_DATA) {
|
||||
/* A NULL value */
|
||||
*ptr = NULL;
|
||||
*len = 0;
|
||||
return 1;
|
||||
} else if (C->fetched_len >= 0) {
|
||||
/* it was stored perfectly */
|
||||
*ptr = C->data;
|
||||
*len = C->fetched_len;
|
||||
return 1;
|
||||
} else {
|
||||
/* no data? */
|
||||
*ptr = NULL;
|
||||
*len = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int odbc_stmt_set_param(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC)
|
||||
{
|
||||
SQLRETURN rc;
|
||||
pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
|
||||
|
||||
switch (attr) {
|
||||
case PDO_ATTR_CURSOR_NAME:
|
||||
convert_to_string(val);
|
||||
rc = SQLSetCursorName(S->stmt, Z_STRVAL_P(val), Z_STRLEN_P(val));
|
||||
|
||||
if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
|
||||
return 1;
|
||||
}
|
||||
pdo_odbc_stmt_error("SQLSetCursorName");
|
||||
return 0;
|
||||
|
||||
default:
|
||||
strcpy(S->einfo.last_err_msg, "Unknown Attribute");
|
||||
S->einfo.what = "setAttribute";
|
||||
stmt->error_code = PDO_ERR_NOT_IMPLEMENTED;
|
||||
S->einfo.last_state[0] = '\0';
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
struct pdo_stmt_methods odbc_stmt_methods = {
|
||||
odbc_stmt_dtor,
|
||||
odbc_stmt_execute,
|
||||
odbc_stmt_fetch,
|
||||
odbc_stmt_describe,
|
||||
odbc_stmt_get_col,
|
||||
odbc_stmt_param_hook,
|
||||
odbc_stmt_set_param,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* 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,53 +0,0 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE package SYSTEM "../pear/package.dtd">
|
||||
<package version="1.0">
|
||||
<name>PDO_ODBC</name>
|
||||
<summary>ODBC v3 Interface driver for PDO</summary>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>wez</user>
|
||||
<name>Wez Furlong</name>
|
||||
<email>wez@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
<configureoptions>
|
||||
<configureoption name="with-pdo-odbc" prompt="flavour,dir? (just leave blank for help)"/>
|
||||
</configureoptions>
|
||||
<description>
|
||||
This extension provides an ODBC v3 driver for PDO. It supports unixODBC
|
||||
and IBM DB2 libraries, and will support more in future releases.
|
||||
</description>
|
||||
<license>PHP</license>
|
||||
<release>
|
||||
<state>alpha</state>
|
||||
<version>0.1.1</version>
|
||||
<date>2004-05-22</date>
|
||||
|
||||
<notes>
|
||||
You need to install the PDO core module before you can make use of this one.
|
||||
You also require either IBM DB2 CLI libraries or unixODBC.
|
||||
|
||||
If you are running on windows, you can download the binary from here:
|
||||
http://snaps.php.net/win32/PECL_5_0/php_pdo_odbc.dll
|
||||
|
||||
This release features working error reporting(!) and ODBC connection pooling.
|
||||
</notes>
|
||||
|
||||
<filelist>
|
||||
<file role="src" name="config.m4"/>
|
||||
<file role="src" name="config.w32"/>
|
||||
<file role="src" name="pdo_odbc.c"/>
|
||||
<file role="src" name="odbc_driver.c"/>
|
||||
<file role="src" name="odbc_stmt.c"/>
|
||||
<file role="src" name="php_pdo_odbc.h"/>
|
||||
<file role="src" name="php_pdo_odbc_int.h"/>
|
||||
|
||||
<file role="doc" name="CREDITS"/>
|
||||
</filelist>
|
||||
<deps>
|
||||
<dep type="php" rel="ge" version="5.0.0RC3dev"/>
|
||||
<dep type="ext" rel="ge" name="pdo" version="0.1"/>
|
||||
</deps>
|
||||
</release>
|
||||
</package>
|
||||
@@ -1,155 +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: 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 "pdo/php_pdo.h"
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_odbc.h"
|
||||
#include "php_pdo_odbc_int.h"
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
# define PDO_ODBC_TYPE "Win32"
|
||||
#endif
|
||||
|
||||
#ifndef PDO_ODBC_TYPE
|
||||
# warning Please fix configure to give your ODBC libraries a name
|
||||
# define PDO_ODBC_TYPE "Unknown"
|
||||
#endif
|
||||
|
||||
/* {{{ pdo_odbc_functions[] */
|
||||
function_entry pdo_odbc_functions[] = {
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ pdo_odbc_module_entry */
|
||||
zend_module_entry pdo_odbc_module_entry = {
|
||||
STANDARD_MODULE_HEADER,
|
||||
"PDO_ODBC",
|
||||
pdo_odbc_functions,
|
||||
PHP_MINIT(pdo_odbc),
|
||||
PHP_MSHUTDOWN(pdo_odbc),
|
||||
NULL,
|
||||
NULL,
|
||||
PHP_MINFO(pdo_odbc),
|
||||
"0.1.1",
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_PDO_ODBC
|
||||
ZEND_GET_MODULE(pdo_odbc)
|
||||
#endif
|
||||
|
||||
#ifdef SQL_ATTR_CONNECTION_POOLING
|
||||
SQLUINTEGER pdo_odbc_pool_on = SQL_CP_OFF;
|
||||
SQLUINTEGER pdo_odbc_pool_mode = SQL_CP_ONE_PER_HENV;
|
||||
#endif
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION */
|
||||
PHP_MINIT_FUNCTION(pdo_odbc)
|
||||
{
|
||||
#ifdef SQL_ATTR_CONNECTION_POOLING
|
||||
char *pooling_val = NULL;
|
||||
#endif
|
||||
|
||||
if (FAILURE == php_pdo_register_driver(&pdo_odbc_driver)) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
pdo_odbc_init_error_table();
|
||||
|
||||
#ifdef SQL_ATTR_CONNECTION_POOLING
|
||||
/* ugh, we don't really .ini stuff in PDO, but since ODBC connection
|
||||
* pooling is process wide, we can't set it from within the scope of a
|
||||
* request without affecting others, which goes against our isolated request
|
||||
* policy. So, we use cfg_get_string here to check it this once.
|
||||
* */
|
||||
if (FAILURE == cfg_get_string("pdo_odbc.connection_pooling", &pooling_val) || pooling_val == NULL) {
|
||||
pooling_val = "strict";
|
||||
}
|
||||
if (strcasecmp(pooling_val, "strict") == 0 || strcmp(pooling_val, "1") == 0) {
|
||||
pdo_odbc_pool_on = SQL_CP_ONE_PER_HENV;
|
||||
pdo_odbc_pool_mode = SQL_CP_STRICT_MATCH;
|
||||
} else if (strcasecmp(pooling_val, "relaxed") == 0) {
|
||||
pdo_odbc_pool_on = SQL_CP_ONE_PER_HENV;
|
||||
pdo_odbc_pool_mode = SQL_CP_RELAXED_MATCH;
|
||||
} else if (*pooling_val == '\0' || strcasecmp(pooling_val, "off") == 0) {
|
||||
pdo_odbc_pool_on = SQL_CP_OFF;
|
||||
} else {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error in pdo_odbc.connection_pooling configuration. Value MUST be one of 'strict', 'relaxed' or 'off'");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (pdo_odbc_pool_on != SQL_CP_OFF) {
|
||||
SQLSetEnvAttr(SQL_NULL_HANDLE, SQL_ATTR_CONNECTION_POOLING, (void*)pdo_odbc_pool_on, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
REGISTER_LONG_CONSTANT("PDO_ODBC_ATTR_USE_CURSOR_LIBRARY", PDO_ODBC_ATTR_USE_CURSOR_LIBRARY, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ODBC_SQL_USE_IF_NEEDED", SQL_CUR_USE_IF_NEEDED, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ODBC_SQL_USE_DRIVER", SQL_CUR_USE_DRIVER, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PDO_ODBC_SQL_USE_ODBC", SQL_CUR_USE_ODBC, CONST_CS|CONST_PERSISTENT);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo_odbc)
|
||||
{
|
||||
php_pdo_unregister_driver(&pdo_odbc_driver);
|
||||
pdo_odbc_fini_error_table();
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
PHP_MINFO_FUNCTION(pdo_odbc)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "PDO Driver for ODBC (" PDO_ODBC_TYPE ")" , "enabled");
|
||||
#ifdef SQL_ATTR_CONNECTION_POOLING
|
||||
php_info_print_table_row(2, "ODBC Connection Pooling", pdo_odbc_pool_on == SQL_CP_OFF ?
|
||||
"Disabled" : (pdo_odbc_pool_mode == SQL_CP_STRICT_MATCH ? "Enabled, strict matching" : "Enabled, relaxed matching"));
|
||||
#else
|
||||
php_info_print_table_row(2, "ODBC Connection Pooling", "Not supported in this build");
|
||||
#endif
|
||||
php_info_print_table_end();
|
||||
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* 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,81 +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: |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef PHP_PDO_ODBC_H
|
||||
#define PHP_PDO_ODBC_H
|
||||
|
||||
extern zend_module_entry pdo_odbc_module_entry;
|
||||
#define phpext_pdo_odbc_ptr &pdo_odbc_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_PDO_ODBC_API __declspec(dllexport)
|
||||
#else
|
||||
#define PHP_PDO_ODBC_API
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
PHP_MINIT_FUNCTION(pdo_odbc);
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo_odbc);
|
||||
PHP_RINIT_FUNCTION(pdo_odbc);
|
||||
PHP_RSHUTDOWN_FUNCTION(pdo_odbc);
|
||||
PHP_MINFO_FUNCTION(pdo_odbc);
|
||||
|
||||
PHP_FUNCTION(confirm_pdo_odbc_compiled); /* For testing, remove later. */
|
||||
|
||||
/*
|
||||
Declare any global variables you may need between the BEGIN
|
||||
and END macros here:
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(pdo_odbc)
|
||||
long global_value;
|
||||
char *global_string;
|
||||
ZEND_END_MODULE_GLOBALS(pdo_odbc)
|
||||
*/
|
||||
|
||||
/* In every utility function you add that needs to use variables
|
||||
in php_pdo_odbc_globals, call TSRMLS_FETCH(); after declaring other
|
||||
variables used by that function, or better yet, pass in TSRMLS_CC
|
||||
after the last function argument and declare your utility function
|
||||
with TSRMLS_DC after the last declared argument. Always refer to
|
||||
the globals in your function as PDO_ODBC_G(variable). You are
|
||||
encouraged to rename these macros something shorter, see
|
||||
examples in any other php module directory.
|
||||
*/
|
||||
|
||||
#ifdef ZTS
|
||||
#define PDO_ODBC_G(v) TSRMG(pdo_odbc_globals_id, zend_pdo_odbc_globals *, v)
|
||||
#else
|
||||
#define PDO_ODBC_G(v) (pdo_odbc_globals.v)
|
||||
#endif
|
||||
|
||||
#endif /* PHP_PDO_ODBC_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,163 +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: Wez Furlong <wez@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/* {{{ Roll a dice, pick a header at random... */
|
||||
#if HAVE_SQLCLI1_H
|
||||
# include <sqlcli1.h>
|
||||
# if defined(DB268K) && HAVE_LIBRARYMANAGER_H
|
||||
# include <LibraryManager.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if HAVE_ODBC_H
|
||||
# include <odbc.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_IODBC_H
|
||||
# include <iodbc.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SQLUNIX_H && !defined(PHP_WIN32)
|
||||
# include <sqlunix.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SQLTYPES_H
|
||||
# include <sqltypes.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SQLUCODE_H
|
||||
# include <sqlucode.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SQL_H
|
||||
# include <sql.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_ISQL_H
|
||||
# include <isql.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SQLEXT_H
|
||||
# include <sqlext.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_ISQLEXT_H
|
||||
# include <isqlext.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_UDBCEXT_H
|
||||
# include <udbcext.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_CLI0CORE_H
|
||||
# include <cli0core.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_CLI0EXT1_H
|
||||
# include <cli0ext.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_CLI0CLI_H
|
||||
# include <cli0cli.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_CLI0DEFS_H
|
||||
# include <cli0defs.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_CLI0ENV_H
|
||||
# include <cli0env.h>
|
||||
#endif
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Figure out the type for handles */
|
||||
#if !defined(HENV) && !defined(SQLHENV) && defined(SQLHANDLE)
|
||||
# define PDO_ODBC_HENV SQLHANDLE
|
||||
# define PDO_ODBC_HDBC SQLHANDLE
|
||||
# define PDO_ODBC_HSTMT SQLHANDLE
|
||||
#elif !defined(HENV) && (defined(SQLHENV) || defined(DB2CLI_VER))
|
||||
# define PDO_ODBC_HENV SQLHENV
|
||||
# define PDO_ODBC_HDBC SQLHDBC
|
||||
# define PDO_ODBC_HSTMT SQLHSTMT
|
||||
#else
|
||||
# define PDO_ODBC_HENV HENV
|
||||
# define PDO_ODBC_HDBC HDBC
|
||||
# define PDO_ODBC_HSTMT HSTMT
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
typedef struct {
|
||||
char last_state[6];
|
||||
char last_err_msg[SQL_MAX_MESSAGE_LENGTH];
|
||||
SDWORD last_error;
|
||||
const char *file, *what;
|
||||
int line;
|
||||
} pdo_odbc_errinfo;
|
||||
|
||||
typedef struct {
|
||||
PDO_ODBC_HENV env;
|
||||
PDO_ODBC_HDBC dbc;
|
||||
pdo_odbc_errinfo einfo;
|
||||
} pdo_odbc_db_handle;
|
||||
|
||||
typedef struct {
|
||||
char *data;
|
||||
unsigned long datalen;
|
||||
long fetched_len;
|
||||
SWORD coltype;
|
||||
char colname[32];
|
||||
} pdo_odbc_column;
|
||||
|
||||
typedef struct {
|
||||
PDO_ODBC_HSTMT stmt;
|
||||
pdo_odbc_column *cols;
|
||||
pdo_odbc_db_handle *H;
|
||||
pdo_odbc_errinfo einfo;
|
||||
} pdo_odbc_stmt;
|
||||
|
||||
extern pdo_driver_t pdo_odbc_driver;
|
||||
extern struct pdo_stmt_methods odbc_stmt_methods;
|
||||
|
||||
void pdo_odbc_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, PDO_ODBC_HSTMT statement, char *what, const char *file, int line TSRMLS_DC);
|
||||
#define pdo_odbc_drv_error(what) pdo_odbc_error(dbh, NULL, SQL_NULL_HSTMT, what, __FILE__, __LINE__ TSRMLS_CC)
|
||||
#define pdo_odbc_stmt_error(what) pdo_odbc_error(stmt->dbh, stmt, SQL_NULL_HSTMT, what, __FILE__, __LINE__ TSRMLS_CC)
|
||||
#define pdo_odbc_doer_error(what) pdo_odbc_error(dbh, NULL, stmt, what, __FILE__, __LINE__ TSRMLS_CC)
|
||||
|
||||
void pdo_odbc_init_error_table(void);
|
||||
void pdo_odbc_fini_error_table(void);
|
||||
|
||||
#ifdef SQL_ATTR_CONNECTION_POOLING
|
||||
extern SQLUINTEGER pdo_odbc_pool_on;
|
||||
extern SQLUINTEGER pdo_odbc_pool_mode;
|
||||
#endif
|
||||
|
||||
enum {
|
||||
PDO_ODBC_ATTR_USE_CURSOR_LIBRARY = PDO_ATTR_DRIVER_SPECIFIC,
|
||||
};
|
||||
|
||||
/*
|
||||
* 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 @@
|
||||
PostgreSQL driver for PDO
|
||||
Edin Kadribasic, Ilia Alshanetsky
|
||||
@@ -1,101 +0,0 @@
|
||||
dnl
|
||||
dnl $Id$
|
||||
dnl
|
||||
|
||||
AC_DEFUN(PHP_PGSQL_CHECK_FUNCTIONS,[
|
||||
])
|
||||
|
||||
PHP_ARG_WITH(pdo-pgsql,for PostgreSQL support for PDO,
|
||||
[ --with-pdo-pgsql[=DIR] Include PDO PostgreSQL support. DIR
|
||||
is the PostgreSQL base install directory
|
||||
or the path to pg_config.])
|
||||
|
||||
if test "$PHP_PDO_PGSQL" != "no"; then
|
||||
PHP_EXPAND_PATH($PGSQL_INCLUDE, PGSQL_INCLUDE)
|
||||
|
||||
AC_MSG_CHECKING(for pg_config)
|
||||
for i in $PHP_PDO_PGSQL $PHP_PDO_PGSQL/bin /usr/local/pgsql/bin /usr/local/bin /usr/bin ""; do
|
||||
if test -x $i/pg_config; then
|
||||
PG_CONFIG="$i/pg_config"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
|
||||
if test -n "$PG_CONFIG"; then
|
||||
AC_MSG_RESULT([$PG_CONFIG])
|
||||
PGSQL_INCLUDE=`$PG_CONFIG --includedir`
|
||||
PGSQL_LIBDIR=`$PG_CONFIG --libdir`
|
||||
AC_DEFINE(HAVE_PG_CONFIG_H,1,[Whether to have pg_config.h])
|
||||
else
|
||||
AC_MSG_RESULT(not found)
|
||||
if test "$PHP_PDO_PGSQL" = "yes"; then
|
||||
PGSQL_SEARCH_PATHS="/usr /usr/local /usr/local/pgsql"
|
||||
else
|
||||
PGSQL_SEARCH_PATHS=$PHP_PDO_PGSQL
|
||||
fi
|
||||
|
||||
for i in $PGSQL_SEARCH_PATHS; do
|
||||
for j in include include/pgsql include/postgres include/postgresql ""; do
|
||||
if test -r "$i/$j/libpq-fe.h"; then
|
||||
PGSQL_INC_BASE=$i
|
||||
PGSQL_INCLUDE=$i/$j
|
||||
if test -r "$i/$j/pg_config.h"; then
|
||||
AC_DEFINE(HAVE_PG_CONFIG_H,1,[Whether to have pg_config.h])
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
for j in lib lib/pgsql lib/postgres lib/postgresql ""; do
|
||||
if test -f "$i/$j/libpq.so" || test -f "$i/$j/libpq.a"; then
|
||||
PGSQL_LIBDIR=$i/$j
|
||||
fi
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
if test -z "$PGSQL_INCLUDE"; then
|
||||
AC_MSG_ERROR(Cannot find libpq-fe.h. Please specify correct PostgreSQL installation path)
|
||||
fi
|
||||
|
||||
if test -z "$PGSQL_LIBDIR"; then
|
||||
AC_MSG_ERROR(Cannot find libpq.so. Please specify correct PostgreSQL installation path)
|
||||
fi
|
||||
|
||||
if test -z "$PGSQL_INCLUDE" -a -z "$PGSQL_LIBDIR" ; then
|
||||
AC_MSG_ERROR([Unable to find libpq anywhere under $withval])
|
||||
fi
|
||||
|
||||
AC_DEFINE(HAVE_PDO_PGSQL,1,[Whether to build PostgreSQL for PDO support or not])
|
||||
old_LIBS=$LIBS
|
||||
old_LDFLAGS=$LDFLAGS
|
||||
LDFLAGS="$LDFLAGS -L$PGSQL_LIBDIR"
|
||||
AC_CHECK_LIB(pq, PQescapeString,AC_DEFINE(HAVE_PQESCAPE,1,[PostgreSQL 7.2.0 or later]))
|
||||
AC_CHECK_LIB(pq, PQsetnonblocking,AC_DEFINE(HAVE_PQSETNONBLOCKING,1,[PostgreSQL 7.0.x or later]))
|
||||
AC_CHECK_LIB(pq, PQcmdTuples,AC_DEFINE(HAVE_PQCMDTUPLES,1,[Broken libpq under windows]))
|
||||
AC_CHECK_LIB(pq, PQoidValue,AC_DEFINE(HAVE_PQOIDVALUE,1,[Older PostgreSQL]))
|
||||
AC_CHECK_LIB(pq, PQclientEncoding,AC_DEFINE(HAVE_PQCLIENTENCODING,1,[PostgreSQL 7.0.x or later]))
|
||||
AC_CHECK_LIB(pq, PQparameterStatus,AC_DEFINE(HAVE_PQPARAMETERSTATUS,1,[PostgreSQL 7.4 or later]))
|
||||
AC_CHECK_LIB(pq, PQprotocolVersion,AC_DEFINE(HAVE_PQPROTOCOLVERSION,1,[PostgreSQL 7.4 or later]))
|
||||
AC_CHECK_LIB(pq, PQtransactionStatus,AC_DEFINE(HAVE_PGTRANSACTIONSTATUS,1,[PostgreSQL 7.4 or later]))
|
||||
AC_CHECK_LIB(pq, pg_encoding_to_char,AC_DEFINE(HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT,1,[Whether libpq is compiled with --enable-multibye]))
|
||||
LIBS=$old_LIBS
|
||||
LDFLAGS=$old_LDFLAGS
|
||||
|
||||
PHP_ADD_LIBRARY_WITH_PATH(pq, $PGSQL_LIBDIR, PDO_PGSQL_SHARED_LIBADD)
|
||||
PHP_SUBST(PDO_PGSQL_SHARED_LIBADD)
|
||||
|
||||
PHP_ADD_INCLUDE($PGSQL_INCLUDE)
|
||||
|
||||
dnl find PDO sources
|
||||
if test -f $prefix/include/php/ext/pdo/php_pdo_driver.h; then
|
||||
pdo_inc_path=$prefix/include/php/ext
|
||||
elif test -f $abs_srcdir/ext/pdo/php_pdo_driver.h; then
|
||||
pdo_inc_path=$abs_srcdir/ext
|
||||
elif test -f ext/pdo/php_pdo_driver.h; then
|
||||
pdo_inc_path=ext
|
||||
else
|
||||
AC_MSG_ERROR([Cannot find php_pdo_driver.h.])
|
||||
fi
|
||||
|
||||
PHP_NEW_EXTENSION(pdo_pgsql, pdo_pgsql.c pgsql_driver.c pgsql_statement.c, $ext_shared,,-I$pdo_inc_path)
|
||||
fi
|
||||
@@ -1,16 +0,0 @@
|
||||
// $Id$
|
||||
// vim:ft=javascript
|
||||
|
||||
ARG_WITH("pdo-pgsql", "PostgreSQL support for PDO", "no");
|
||||
|
||||
if (PHP_PDO_PGSQL != "no") {
|
||||
if (CHECK_LIB("libpq.lib", "pdo_pgsql", PHP_PDO_PGSQL) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("libpq-fe.h", "CFLAGS_PDO_PGSQL", PHP_PDO_PGSQL + ";" + PHP_PHP_BUILD + "\\include\\pgsql")) {
|
||||
EXTENSION("pdo_pgsql", "pdo_pgsql.c pgsql_driver.c pgsql_statement.c");
|
||||
ADD_FLAG('CFLAGS_PDO_PGSQL', "/I ..\\pecl");
|
||||
AC_DEFINE('HAVE_PDO_PGSQL', 1, 'Have PostgreSQL library');
|
||||
} else {
|
||||
WARNING("pdo_pgsql not enabled; libraries and headers not found");
|
||||
}
|
||||
ADD_EXTENSION_DEP('pdo_pgsql', 'pdo');
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE package SYSTEM "../pear/package.dtd">
|
||||
<package version="1.0">
|
||||
<name>PDO_PGSQL</name>
|
||||
<summary>PostgreSQL driver for PDO</summary>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>edink</user>
|
||||
<name>Edin Kadribasic</name>
|
||||
<email>edink@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<user>iliaa</user>
|
||||
<name>Ilia Alshanetsky</name>
|
||||
<email>iliaa@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
<description>
|
||||
This extension provides an PostgreSQL driver for PDO.
|
||||
</description>
|
||||
<license>PHP</license>
|
||||
<release>
|
||||
<state>alpha</state>
|
||||
<version>0.1</version>
|
||||
<date>2004-05-21</date>
|
||||
|
||||
<notes>
|
||||
You need to install the PDO core module before you can make use of this one.
|
||||
You also require PostgreSQL client libraries installed on the machine where you intend to build and/or use it.
|
||||
|
||||
If you are running on windows, you can download the binary from here:
|
||||
http://snaps.php.net/win32/PECL_5_0/php_pdo_pgsql.dll
|
||||
</notes>
|
||||
|
||||
<filelist>
|
||||
<file role="src" name="config.m4"/>
|
||||
<file role="src" name="config.w32"/>
|
||||
<file role="src" name="pdo_pgsql.c"/>
|
||||
<file role="src" name="pgsql_driver.c"/>
|
||||
<file role="src" name="pgsql_statement.c"/>
|
||||
<file role="src" name="php_pdo_pgsql.h"/>
|
||||
<file role="src" name="php_pdo_pgsql_int.h"/>
|
||||
|
||||
<file role="doc" name="CREDITS"/>
|
||||
</filelist>
|
||||
<deps>
|
||||
<dep type="php" rel="ge" version="5.0.0RC3dev"/>
|
||||
<dep type="ext" rel="ge" name="pdo" version="0.1"/>
|
||||
</deps>
|
||||
</release>
|
||||
</package>
|
||||
@@ -1,113 +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: Edin Kadribasic <edink@emini.dk> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "pdo/php_pdo.h"
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_pgsql.h"
|
||||
#include "php_pdo_pgsql_int.h"
|
||||
|
||||
/* {{{ pdo_pgsql_functions[] */
|
||||
function_entry pdo_pgsql_functions[] = {
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ pdo_pgsql_module_entry */
|
||||
zend_module_entry pdo_pgsql_module_entry = {
|
||||
STANDARD_MODULE_HEADER,
|
||||
"pdo_pgsql",
|
||||
pdo_pgsql_functions,
|
||||
PHP_MINIT(pdo_pgsql),
|
||||
PHP_MSHUTDOWN(pdo_pgsql),
|
||||
PHP_RINIT(pdo_pgsql),
|
||||
PHP_RSHUTDOWN(pdo_pgsql),
|
||||
PHP_MINFO(pdo_pgsql),
|
||||
"0.1",
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_PDO_PGSQL
|
||||
ZEND_GET_MODULE(pdo_pgsql)
|
||||
#endif
|
||||
|
||||
/* true global environment */
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION
|
||||
*/
|
||||
PHP_MINIT_FUNCTION(pdo_pgsql)
|
||||
{
|
||||
php_pdo_register_driver(&pdo_pgsql_driver);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo_pgsql)
|
||||
{
|
||||
php_pdo_unregister_driver(&pdo_pgsql_driver);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_RINIT_FUNCTION
|
||||
*/
|
||||
PHP_RINIT_FUNCTION(pdo_pgsql)
|
||||
{
|
||||
// php_pdo_register_driver(&pdo_pgsql_driver);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_RSHUTDOWN_FUNCTION(pdo_pgsql)
|
||||
{
|
||||
// php_pdo_unregister_driver(&pdo_pgsql_driver);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
PHP_MINFO_FUNCTION(pdo_pgsql)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "PDO Driver for PostgreSQL", "enabled");
|
||||
php_info_print_table_end();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* 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,345 +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: Edin Kadribasic <edink@emini.dk> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "pdo/php_pdo.h"
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
|
||||
#include "pg_config.h" /* needed for PG_VERSION */
|
||||
#include "php_pdo_pgsql.h"
|
||||
#include "php_pdo_pgsql_int.h"
|
||||
|
||||
int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *file, int line TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||
enum pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code;
|
||||
pdo_pgsql_error_info *einfo = &H->einfo;
|
||||
char *errmsg = PQerrorMessage(H->server);
|
||||
|
||||
einfo->errcode = errcode;
|
||||
einfo->file = file;
|
||||
einfo->line = line;
|
||||
|
||||
if (einfo->errmsg) {
|
||||
efree(einfo->errmsg);
|
||||
einfo->errmsg = NULL;
|
||||
}
|
||||
|
||||
switch (errcode) {
|
||||
case PGRES_EMPTY_QUERY:
|
||||
*pdo_err = PDO_ERR_SYNTAX;
|
||||
break;
|
||||
|
||||
default:
|
||||
*pdo_err = PDO_ERR_CANT_MAP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (errmsg) {
|
||||
einfo->errmsg = estrdup(errmsg);
|
||||
}
|
||||
|
||||
return errcode;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int pdo_pgsql_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||
pdo_pgsql_error_info *einfo = &H->einfo;
|
||||
|
||||
if (einfo->errcode) {
|
||||
add_next_index_long(info, einfo->errcode);
|
||||
add_next_index_string(info, einfo->errmsg, 1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int pgsql_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||
if (H) {
|
||||
if (H->server) {
|
||||
PQfinish(H->server);
|
||||
H->server = NULL;
|
||||
}
|
||||
if (H->einfo.errmsg) {
|
||||
efree(H->einfo.errmsg);
|
||||
H->einfo.errmsg = NULL;
|
||||
}
|
||||
pefree(H, dbh->is_persistent);
|
||||
H = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, long options, zval *driver_options TSRMLS_DC)
|
||||
{
|
||||
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||
pdo_pgsql_stmt *S = ecalloc(1, sizeof(pdo_pgsql_stmt));
|
||||
|
||||
S->H = H;
|
||||
stmt->driver_data = S;
|
||||
stmt->methods = &pgsql_stmt_methods;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static long pgsql_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
|
||||
{
|
||||
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||
PGresult *res;
|
||||
|
||||
if (!(res = PQexec(H->server, sql))) {
|
||||
/* fatal error */
|
||||
pdo_pgsql_error(dbh, PGRES_FATAL_ERROR);
|
||||
return 0;
|
||||
} else {
|
||||
ExecStatusType qs = PQresultStatus(res);
|
||||
if (qs != PGRES_COMMAND_OK && qs != PGRES_TUPLES_OK) {
|
||||
pdo_pgsql_error(dbh, qs);
|
||||
PQclear(res);
|
||||
return 0;
|
||||
}
|
||||
H->pgoid = PQoidValue(res);
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pgsql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen TSRMLS_DC)
|
||||
{
|
||||
unsigned char *escaped;
|
||||
|
||||
/* escapedlen returned by PQescapeBytea() accounts for trailing 0 */
|
||||
escaped = PQescapeBytea(unquoted, unquotedlen, quotedlen);
|
||||
*quotedlen += 1;
|
||||
*quoted = emalloc(*quotedlen + 1);
|
||||
memcpy((*quoted)+1, escaped, *quotedlen-2);
|
||||
(*quoted)[0] = '\'';
|
||||
(*quoted)[*quotedlen-1] = '\'';
|
||||
(*quoted)[*quotedlen] = '\0';
|
||||
free(escaped);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static long pdo_pgsql_last_insert_id(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||
|
||||
if (H->pgoid == InvalidOid) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (long) H->pgoid;
|
||||
}
|
||||
|
||||
static int pdo_pgsql_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC)
|
||||
{
|
||||
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||
|
||||
switch (attr) {
|
||||
case PDO_ATTR_CLIENT_VERSION:
|
||||
ZVAL_STRING(return_value, PG_VERSION, 1);
|
||||
break;
|
||||
|
||||
case PDO_ATTR_SERVER_VERSION:
|
||||
#ifdef HAVE_PQPROTOCOLVERSION
|
||||
if (PQprotocolVersion(H->server) >= 3) { /* PostgreSQL 7.4 or later */
|
||||
ZVAL_STRING(return_value, (char*)PQparameterStatus(H->server, "server_version"), 1);
|
||||
} else /* emulate above via a query */
|
||||
#endif
|
||||
{
|
||||
PGresult *res = PQexec(H->server, "SELECT VERSION()");
|
||||
if (res && PQresultStatus(res) == PGRES_TUPLES_OK) {
|
||||
ZVAL_STRING(return_value, (char *)PQgetvalue(res, 0, 0), 1);
|
||||
}
|
||||
|
||||
if (res) {
|
||||
PQclear(res);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PDO_ATTR_CONNECTION_STATUS:
|
||||
switch (PQstatus(H->server)) {
|
||||
case CONNECTION_STARTED:
|
||||
ZVAL_STRINGL(return_value, "Waiting for connection to be made.", sizeof("Waiting for connection to be made.")-1, 1);
|
||||
break;
|
||||
|
||||
case CONNECTION_MADE:
|
||||
case CONNECTION_OK:
|
||||
ZVAL_STRINGL(return_value, "Connection OK; waiting to send.", sizeof("Connection OK; waiting to send.")-1, 1);
|
||||
break;
|
||||
|
||||
case CONNECTION_AWAITING_RESPONSE:
|
||||
ZVAL_STRINGL(return_value, "Waiting for a response from the server.", sizeof("Waiting for a response from the server.")-1, 1);
|
||||
break;
|
||||
|
||||
case CONNECTION_AUTH_OK:
|
||||
ZVAL_STRINGL(return_value, "Received authentication; waiting for backend start-up to finish.", sizeof("Received authentication; waiting for backend start-up to finish.")-1, 1);
|
||||
break;
|
||||
#ifdef CONNECTION_SSL_STARTUP
|
||||
case CONNECTION_SSL_STARTUP:
|
||||
ZVAL_STRINGL(return_value, "Negotiating SSL encryption.", sizeof("Negotiating SSL encryption.")-1, 1);
|
||||
break;
|
||||
#endif
|
||||
case CONNECTION_SETENV:
|
||||
ZVAL_STRINGL(return_value, "Negotiating environment-driven parameter settings.", sizeof("Negotiating environment-driven parameter settings.")-1, 1);
|
||||
break;
|
||||
|
||||
case CONNECTION_BAD:
|
||||
default:
|
||||
ZVAL_STRINGL(return_value, "Bad connection.", sizeof("Bad connection.")-1, 1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PDO_ATTR_SERVER_INFO: {
|
||||
int spid = PQbackendPID(H->server);
|
||||
char *tmp;
|
||||
#ifdef HAVE_PQPROTOCOLVERSION
|
||||
spprintf(&tmp, 0,
|
||||
"PID: %d; Client Encoding: %s; Is Superuser: %s; Session Authorization: %s; Date Style: %s",
|
||||
spid,
|
||||
(char*)PQparameterStatus(H->server, "client_encoding"),
|
||||
(char*)PQparameterStatus(H->server, "is_superuser"),
|
||||
(char*)PQparameterStatus(H->server, "session_authorization"),
|
||||
(char*)PQparameterStatus(H->server, "DateStyle"));
|
||||
#else
|
||||
spprintf(&tmp, 0, "PID: %d", spid);
|
||||
#endif
|
||||
ZVAL_STRING(return_value, tmp, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pdo_pgsql_transaction_cmd(const char *cmd, pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||
PGresult *res;
|
||||
int ret = 1;
|
||||
|
||||
res = PQexec(H->server, cmd);
|
||||
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
PQclear(res);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pgsql_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
return pdo_pgsql_transaction_cmd("BEGIN", dbh TSRMLS_CC);
|
||||
}
|
||||
|
||||
static int pgsql_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
return pdo_pgsql_transaction_cmd("COMMIT", dbh TSRMLS_CC);
|
||||
}
|
||||
|
||||
static int pgsql_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
return pdo_pgsql_transaction_cmd("ROLLBACK", dbh TSRMLS_CC);
|
||||
}
|
||||
|
||||
static struct pdo_dbh_methods pgsql_methods = {
|
||||
pgsql_handle_closer,
|
||||
pgsql_handle_preparer,
|
||||
pgsql_handle_doer,
|
||||
pgsql_handle_quoter,
|
||||
pgsql_handle_begin,
|
||||
pgsql_handle_commit,
|
||||
pgsql_handle_rollback,
|
||||
NULL,
|
||||
pdo_pgsql_last_insert_id,
|
||||
pdo_pgsql_fetch_error_func,
|
||||
pdo_pgsql_get_attribute
|
||||
};
|
||||
|
||||
static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_pgsql_db_handle *H;
|
||||
int ret = 0;
|
||||
|
||||
H = pecalloc(1, sizeof(pdo_pgsql_db_handle), dbh->is_persistent);
|
||||
dbh->driver_data = H;
|
||||
|
||||
H->einfo.errcode = 0;
|
||||
H->einfo.errmsg = NULL;
|
||||
|
||||
H->server = PQconnectdb(dbh->data_source);
|
||||
|
||||
if (PQstatus(H->server) != CONNECTION_OK) {
|
||||
pdo_pgsql_error(dbh, PGRES_FATAL_ERROR);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
H->attached = 1;
|
||||
H->pgoid = -1;
|
||||
|
||||
dbh->methods = &pgsql_methods;
|
||||
dbh->alloc_own_columns = 1;
|
||||
dbh->supports_placeholders = PDO_PLACEHOLDER_NONE;
|
||||
dbh->max_escaped_char_length = 2;
|
||||
|
||||
ret = 1;
|
||||
|
||||
cleanup:
|
||||
if (!ret) {
|
||||
pgsql_handle_closer(dbh TSRMLS_CC);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
pdo_driver_t pdo_pgsql_driver = {
|
||||
PDO_DRIVER_HEADER(pgsql),
|
||||
pdo_pgsql_handle_factory
|
||||
};
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,157 +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: Edin Kadribasic <edink@emini.dk> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "pdo/php_pdo.h"
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_pgsql.h"
|
||||
#include "php_pdo_pgsql_int.h"
|
||||
|
||||
|
||||
static int pgsql_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
|
||||
int i;
|
||||
|
||||
if (S->result) {
|
||||
/* free the resource */
|
||||
PQclear(S->result);
|
||||
S->result = NULL;
|
||||
}
|
||||
if(S->cols) {
|
||||
efree(S->cols);
|
||||
S->cols = NULL;
|
||||
}
|
||||
efree(S);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pgsql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
pdo_dbh_t *dbh = stmt->dbh;
|
||||
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
|
||||
pdo_pgsql_db_handle *H = S->H;
|
||||
ExecStatusType status;
|
||||
|
||||
if (stmt->executed) {
|
||||
/* ensure that we free any previous unfetched results */
|
||||
if(S->result) {
|
||||
PQclear(S->result);
|
||||
S->result = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
S->result = PQexec(H->server, stmt->active_query_string);
|
||||
status = PQresultStatus(S->result);
|
||||
|
||||
if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
|
||||
pdo_pgsql_error_stmt(stmt, status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!stmt->executed) {
|
||||
stmt->column_count = (int) PQnfields(S->result);
|
||||
S->cols = ecalloc(stmt->column_count, sizeof(pdo_pgsql_column));
|
||||
}
|
||||
|
||||
|
||||
if (status == PGRES_COMMAND_OK) {
|
||||
stmt->row_count = (long)atoi(PQcmdTuples(S->result));
|
||||
} else {
|
||||
stmt->row_count = (long)PQntuples(S->result);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
|
||||
enum pdo_param_event event_type TSRMLS_DC)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pgsql_stmt_fetch(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
|
||||
|
||||
if (S->current_row < stmt->row_count) {
|
||||
S->current_row++;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int pgsql_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
|
||||
{
|
||||
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
|
||||
struct pdo_column_data *cols = stmt->columns;
|
||||
|
||||
if (!S->result) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cols[colno].name = estrdup(PQfname(S->result, colno));
|
||||
cols[colno].namelen = strlen(cols[colno].name);
|
||||
cols[colno].maxlen = PQfsize(S->result, colno);
|
||||
cols[colno].precision = PQfmod(S->result, colno);
|
||||
cols[colno].param_type = PDO_PARAM_STR;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len TSRMLS_DC)
|
||||
{
|
||||
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
|
||||
|
||||
if (!S->result) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We have already increased count by 1 in pgsql_stmt_fetch() */
|
||||
*ptr = PQgetvalue(S->result, S->current_row - 1, colno);
|
||||
*len = PQgetlength(S->result, S->current_row - 1, colno);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct pdo_stmt_methods pgsql_stmt_methods = {
|
||||
pgsql_stmt_dtor,
|
||||
pgsql_stmt_execute,
|
||||
pgsql_stmt_fetch,
|
||||
pgsql_stmt_describe,
|
||||
pgsql_stmt_get_col,
|
||||
pgsql_stmt_param_hook
|
||||
};
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
Loaded 100 of 144 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user