mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-11 11:10:49 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3fa7d9636a |
No files matched your search
@@ -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,721 +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();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#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 tag)
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
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 long enchant_dict_check(resource broker)
|
||||
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 broker, 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 broker)
|
||||
A list of UTF-8 encoded suggestions, or false */
|
||||
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 broker, 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 broker)
|
||||
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 broker, 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
|
||||
*/
|
||||
-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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
-314
@@ -1,314 +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_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,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: 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_dtor(info);
|
||||
FREE_ZVAL(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;
|
||||
long data_source_len;
|
||||
char *colon;
|
||||
char *username=NULL, *password=NULL;
|
||||
long 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 = pemalloc(sizeof(*dbh), is_persistent);
|
||||
|
||||
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!?");
|
||||
}
|
||||
|
||||
memset(dbh, 0, sizeof(*dbh));
|
||||
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. */
|
||||
;
|
||||
}
|
||||
|
||||
zend_object_store_set_object(object, dbh TSRMLS_CC);
|
||||
return;
|
||||
}
|
||||
|
||||
/* the connection failed; tidy things up */
|
||||
pefree((char*)dbh->data_source, is_persistent);
|
||||
pefree(dbh, is_persistent);
|
||||
|
||||
/* 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;
|
||||
long 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;
|
||||
long 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(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 = do_alloca(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) {
|
||||
free_alloca(lc_method_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free_alloca(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)
|
||||
{
|
||||
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;
|
||||
|
||||
retval.handle = zend_objects_store_put(NULL, 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
|
||||
*/
|
||||
-1106
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,411 +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;
|
||||
#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 @@
|
||||
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,165 +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) {
|
||||
pdo_mysql_error_stmt(stmt);
|
||||
return 0;
|
||||
}
|
||||
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 $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="$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)
|
||||
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, 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,472 +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,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
|
||||
*/
|
||||
@@ -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: Edin Kadribasic <edink@emini.dk> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef PHP_PDO_PGSQL_H
|
||||
#define PHP_PDO_PGSQL_H
|
||||
|
||||
#if HAVE_PDO_PGSQL
|
||||
|
||||
#include <libpq-fe.h>
|
||||
|
||||
extern zend_module_entry pdo_pgsql_module_entry;
|
||||
#define phpext_pdo_pgsql_ptr &pdo_pgsql_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_PDO_PGSQL_API __declspec(dllexport)
|
||||
#else
|
||||
#define PHP_PDO_PGSQL_API
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
PHP_MINIT_FUNCTION(pdo_pgsql);
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo_pgsql);
|
||||
PHP_RINIT_FUNCTION(pdo_pgsql);
|
||||
PHP_RSHUTDOWN_FUNCTION(pdo_pgsql);
|
||||
PHP_MINFO_FUNCTION(pdo_pgsql);
|
||||
|
||||
#endif /* HAVE_PDO_PGSQL */
|
||||
#endif /* PHP_PDO_PGSQL_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,80 +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$ */
|
||||
|
||||
#ifndef PHP_PDO_PGSQL_INT_H
|
||||
#define PHP_PDO_PGSQL_INT_H
|
||||
|
||||
#if HAVE_PDO_PGSQL
|
||||
|
||||
#include <libpq-fe.h>
|
||||
|
||||
typedef struct {
|
||||
const char *file;
|
||||
int line;
|
||||
unsigned int errcode;
|
||||
char *errmsg;
|
||||
} pdo_pgsql_error_info;
|
||||
|
||||
/* stuff we use in a pgsql database handle */
|
||||
typedef struct {
|
||||
PGconn *server;
|
||||
unsigned attached:1;
|
||||
unsigned _reserved:31;
|
||||
pdo_pgsql_error_info einfo;
|
||||
Oid pgoid;
|
||||
} pdo_pgsql_db_handle;
|
||||
|
||||
typedef struct {
|
||||
char *def;
|
||||
} pdo_pgsql_column;
|
||||
|
||||
typedef struct {
|
||||
pdo_pgsql_db_handle *H;
|
||||
PGresult *result;
|
||||
int current_row;
|
||||
pdo_pgsql_column *cols;
|
||||
} pdo_pgsql_stmt;
|
||||
|
||||
typedef struct {
|
||||
char *repr;
|
||||
long repr_len;
|
||||
int pgsql_type;
|
||||
void *thing; /* for LOBS, REFCURSORS etc. */
|
||||
} pdo_pgsql_bound_param;
|
||||
|
||||
extern pdo_driver_t pdo_pgsql_driver;
|
||||
|
||||
extern int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *file, int line TSRMLS_DC);
|
||||
#define pdo_pgsql_error(d,e) _pdo_pgsql_error(d, NULL, e, __FILE__, __LINE__ TSRMLS_CC)
|
||||
#define pdo_pgsql_error_stmt(s,e) _pdo_pgsql_error(s->dbh, s, e, __FILE__, __LINE__ TSRMLS_CC)
|
||||
|
||||
extern struct pdo_stmt_methods pgsql_stmt_methods;
|
||||
|
||||
#endif /* HAVE_PDO_PGSQL */
|
||||
#endif /* PHP_PDO_PGSQL_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,2 +0,0 @@
|
||||
XMLReader
|
||||
Rob Richards
|
||||
@@ -1,4 +0,0 @@
|
||||
this module is experimental,
|
||||
its functions may change their names
|
||||
so do not rely to much on them
|
||||
you have been warned!
|
||||
@@ -1,5 +0,0 @@
|
||||
XMLReader represents a reader that provides non-cached,
|
||||
forward-only access to XML data. It is based upon the
|
||||
xmlTextReader api from libxml
|
||||
|
||||
This extension is designed to only work under PHP 5.
|
||||
@@ -1,6 +0,0 @@
|
||||
- Refactor internals once libxml 2.6.x is minimum requirement for PHP 5
|
||||
use new api for creating the xmlTextReaderPtr
|
||||
|
||||
- Add Custom Error Handling
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
dnl
|
||||
dnl $Id$
|
||||
dnl
|
||||
|
||||
PHP_ARG_WITH(xmlreader, for XMLReader support,
|
||||
[ --with-xmlreader Include XMLReader support.])
|
||||
|
||||
if test -z "$PHP_LIBXML_DIR"; then
|
||||
PHP_ARG_WITH(libxml-dir, libxml2 install dir,
|
||||
[ --with-libxml-dir=DIR XMLReader: libxml2 install prefix], no, no)
|
||||
fi
|
||||
|
||||
if test "$PHP_XMLREADER" != "no" && test "$PHP_LIBXML" != "no"; then
|
||||
|
||||
PHP_SETUP_LIBXML(XMLREADER_SHARED_LIBADD, [
|
||||
AC_DEFINE(HAVE_XMLREADER,1,[ ])
|
||||
PHP_NEW_EXTENSION(xmlreader, php_xmlreader.c, $ext_shared)
|
||||
PHP_SUBST(XMLREADER_SHARED_LIBADD)
|
||||
], [
|
||||
AC_MSG_ERROR([xml2-config not found. Please check your libxml2 installation.])
|
||||
])
|
||||
fi
|
||||
@@ -1,14 +0,0 @@
|
||||
// $Id$
|
||||
// vim:ft=javascript
|
||||
|
||||
ARG_WITH("xmlreader", "XMLReader support", "yes");
|
||||
|
||||
if (PHP_XMLREADER == "yes" && PHP_LIBXML == "yes") {
|
||||
EXTENSION("xmlreader", "php_xmlreader.c");
|
||||
AC_DEFINE("HAVE_XMLREADER", 1, "XMLReader support");
|
||||
if (!PHP_XMLREADER_SHARED) {
|
||||
ADD_FLAG("CFLAGS_XMLREADER", "/D LIBXML_STATIC");
|
||||
}
|
||||
ADD_EXTENSION_DEP('xmlreader', 'libxml');
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!ELEMENT LIST (MOVIE+)>
|
||||
<!ELEMENT MOVIE (TITLE, ORGTITLE, LOC, INFO)>
|
||||
<!ATTLIST MOVIE ID ID #REQUIRED>
|
||||
<!ELEMENT TITLE (#PCDATA)>
|
||||
<!ELEMENT ORGTITLE (#PCDATA)>
|
||||
<!ELEMENT LOC (#PCDATA)>
|
||||
<!ELEMENT INFO (#PCDATA)>
|
||||
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE LIST SYSTEM "dtdexample.dtd">
|
||||
<LIST>
|
||||
<MOVIE ID="x200338360">
|
||||
<TITLE>Move Title 1</TITLE>
|
||||
<ORGTITLE/><LOC>Location 1</LOC>
|
||||
<INFO/>
|
||||
</MOVIE>
|
||||
<MOVIE ID="m200338361">
|
||||
<TITLE>Move Title 2</TITLE>
|
||||
<ORGTITLE/>
|
||||
<LOC>Location 2</LOC>
|
||||
<INFO/>
|
||||
</MOVIE>
|
||||
</LIST>
|
||||
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
|
||||
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
||||
|
||||
<include href="relaxNG2.rng">
|
||||
<define name="TEI.prose"><ref name="INCLUDE"/></define>
|
||||
</include>
|
||||
</grammar>
|
||||
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<TEI.2>hello</TEI.2>
|
||||
@@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<grammar xmlns="http://relaxng.org/ns/structure/1.0" xmlns:t="http://www.thaiopensource.com/ns/annotations" xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
||||
|
||||
<start>
|
||||
<ref name="TEI.2"/>
|
||||
</start>
|
||||
<define name="IGNORE">
|
||||
<notAllowed/>
|
||||
</define>
|
||||
<define name="INCLUDE">
|
||||
<empty/>
|
||||
</define>
|
||||
|
||||
|
||||
<include href="relaxNG3.rng"/>
|
||||
|
||||
<define name="TEI.2">
|
||||
<element name="TEI.2">
|
||||
<text/>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
</grammar>
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<grammar xmlns="http://relaxng.org/ns/structure/1.0" xmlns:t="http://www.thaiopensource.com/ns/annotations" xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
||||
|
||||
<define name="TEI.prose" combine="interleave">
|
||||
<ref name="IGNORE"/>
|
||||
</define>
|
||||
|
||||
</grammar>
|
||||
@@ -1,10 +0,0 @@
|
||||
<books>
|
||||
<book num="1">
|
||||
<title>The Grapes of Wrath</title>
|
||||
<author>John Steinbeck</author>
|
||||
</book>
|
||||
<book num="2">
|
||||
<title>The Pearl</title>
|
||||
<author>John Steinbeck</author>
|
||||
</book>
|
||||
</books>
|
||||
@@ -1,20 +0,0 @@
|
||||
<?php
|
||||
$reader = new XMLReader();
|
||||
$reader->open('xmlreader.xml');
|
||||
while ($reader->read()) {
|
||||
if ($reader->nodeType != XMLREADER_END_ELEMENT) {
|
||||
print "Node Name: ".$reader->name."\n";
|
||||
print "Node Value: ".$reader->value."\n";
|
||||
print "Node Depth: ".$reader->depth."\n";
|
||||
if ($reader->nodeType==XMLREADER_ELEMENT && $reader->hasAttributes) {
|
||||
$attr = $reader->moveToFirstAttribute();
|
||||
while ($attr) {
|
||||
print " Attribute Name: ".$reader->name."\n";
|
||||
print " Attribute Value: ".$reader->value."\n";
|
||||
$attr = $reader->moveToNextAttribute();
|
||||
}
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
$indent = 5; /* Number of spaces to indent per level */
|
||||
|
||||
$reader = new XMLReader();
|
||||
$reader->open('relaxNG.xml');
|
||||
/*
|
||||
Example setting relaxNG using string:
|
||||
$reader->setRelaxNGSchemaSource(file_get_contents('relaxNG.rng'));
|
||||
*/
|
||||
if ($reader->setRelaxNGSchema('relaxNG.rng')) {
|
||||
while ($reader->read()) {
|
||||
/* Print node name indenting it based on depth and $indent var */
|
||||
print str_repeat(" ", $reader->depth * $indent).$reader->name."\n";
|
||||
}
|
||||
}
|
||||
|
||||
print "\n";
|
||||
|
||||
if (! $reader->isValid()) {
|
||||
print "Document is not valid\n";
|
||||
} else {
|
||||
print "Document is valid\n";
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
$xmlstring = '<books>
|
||||
<book num="1">
|
||||
<title>The Grapes of Wrath</title>
|
||||
<author>John Steinbeck</author>
|
||||
</book>
|
||||
<book num="2">
|
||||
<title>The Pearl</title>
|
||||
<author>John Steinbeck</author>
|
||||
</book>
|
||||
</books>';
|
||||
|
||||
$reader = new XMLReader();
|
||||
$reader->XML($xmlstring);
|
||||
while ($reader->read()) {
|
||||
if ($reader->nodeType != XMLREADER_END_ELEMENT) {
|
||||
print "Node Name: ".$reader->name."\n";
|
||||
print "Node Value: ".$reader->value."\n";
|
||||
print "Node Depth: ".$reader->depth."\n";
|
||||
if ($reader->nodeType==XMLREADER_ELEMENT && $reader->hasAttributes) {
|
||||
$attr = $reader->moveToFirstAttribute();
|
||||
while ($attr) {
|
||||
print " Attribute Name: ".$reader->name."\n";
|
||||
print " Attribute Value: ".$reader->value."\n";
|
||||
$attr = $reader->moveToNextAttribute();
|
||||
}
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
$indent = 5; /* Number of spaces to indent per level */
|
||||
|
||||
$xml = new XMLReader();
|
||||
$xml->open("dtdexample.xml");
|
||||
$xml->setParserProperty(XMLREADER_LOADDTD, TRUE);
|
||||
$xml->setParserProperty(XMLREADER_VALIDATE, TRUE);
|
||||
while($xml->read()) {
|
||||
/* Print node name indenting it based on depth and $indent var */
|
||||
print str_repeat(" ", $xml->depth * $indent).$xml->name."\n";
|
||||
if ($xml->hasAttributes) {
|
||||
$attCount = $xml->attributeCount;
|
||||
print str_repeat(" ", $xml->depth * $indent)." Number of Attributes: ".$xml->attributeCount."\n";
|
||||
}
|
||||
}
|
||||
print "\n\nValid:\n";
|
||||
var_dump($xml->isValid());
|
||||
?>
|
||||
@@ -1,65 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!DOCTYPE package SYSTEM "../package.dtd">
|
||||
<package>
|
||||
<name>xmlreader</name>
|
||||
<summary>Provides fast, non-cached, forward-only access to XML data.</summary>
|
||||
<description>
|
||||
This extension wraps the libxml xmlReader API. The reader acts as a cursor
|
||||
going forward on the document stream and stopping at each node in the way.
|
||||
xmlReader is similar to SAX though uses a much simpler API.
|
||||
</description>
|
||||
<license>PHP License</license>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>rrichards</user>
|
||||
<name>Rob Richards</name>
|
||||
<email>rrichards@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<user>chregu</user>
|
||||
<role>lead</role>
|
||||
<name>Christian Stocker</name>
|
||||
<email>chregu@php.net</email>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
<release>
|
||||
<version>0.2</version>
|
||||
<date>2004-05-10</date>
|
||||
<state>beta</state>
|
||||
<notes>
|
||||
Allow open and XML methods to be called statically.
|
||||
Add expand() support to export copies of nodes as DOM objects. (chregu)
|
||||
Add next() support to skip to next sibling node. (chregu)
|
||||
</notes>
|
||||
<configureoptions>
|
||||
<configureoption name="with-xmlreader" default="autodetect" prompt="Include XMLReader support?"/>
|
||||
</configureoptions>
|
||||
<filelist>
|
||||
<file role="src" name="config.m4"/>
|
||||
<file role="src" name="config.w32"/>
|
||||
<file role="src" name="php_xmlreader.c"/>
|
||||
<file role="src" name="php_xmlreader.h"/>
|
||||
|
||||
<file role="doc" name="CREDITS"/>
|
||||
<file role="doc" name="TODO"/>
|
||||
<file role="doc" name="README"/>
|
||||
<file role="doc" name="EXPERIMENTAL"/>
|
||||
<file role="doc" name="examples/xmlreader_file.php"/>
|
||||
<file role="doc" name="examples/xmlreader_string.php"/>
|
||||
<file role="doc" name="examples/xmlreader.xml"/>
|
||||
<file role="doc" name="examples/xmlreader_validatedtd.php"/>
|
||||
<file role="doc" name="examples/dtdexample.xml"/>
|
||||
<file role="doc" name="examples/dtdexample.dtd"/>
|
||||
<file role="doc" name="examples/xmlreader_relaxNG.php"/>
|
||||
<file role="doc" name="examples/relaxNG.xml"/>
|
||||
<file role="doc" name="examples/relaxNG.rng"/>
|
||||
<file role="doc" name="examples/relaxNG2.rng"/>
|
||||
<file role="doc" name="examples/relaxNG3.rng"/>
|
||||
</filelist>
|
||||
<deps>
|
||||
<dep type="php" rel="ge" version="5" />
|
||||
<dep type="ext" rel="has">libxml</dep>
|
||||
</deps>
|
||||
</release>
|
||||
</package>
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,72 +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: Rob Richards <rrichards@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef PHP_XMLREADER_H
|
||||
#define PHP_XMLREADER_H
|
||||
|
||||
extern zend_module_entry xmlreader_module_entry;
|
||||
#define phpext_xmlreader_ptr &xmlreader_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_XMLREADER_API __declspec(dllexport)
|
||||
#else
|
||||
#define PHP_XMLREADER_API
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
#include "ext/libxml/php_libxml.h"
|
||||
#include <libxml/xmlreader.h>
|
||||
|
||||
typedef struct _xmlreader_object {
|
||||
zend_object std;
|
||||
xmlTextReaderPtr ptr;
|
||||
/* input is used to allow strings to be loaded under libxml 2.5.x
|
||||
must manually allocate and de-allocate these - can be refactored when
|
||||
libxml 2.6.x becomes minimum version */
|
||||
xmlParserInputBufferPtr input;
|
||||
void *schema;
|
||||
HashTable *prop_handler;
|
||||
zend_object_handle handle;
|
||||
} xmlreader_object;
|
||||
|
||||
PHP_MINIT_FUNCTION(xmlreader);
|
||||
PHP_MSHUTDOWN_FUNCTION(xmlreader);
|
||||
PHP_MINFO_FUNCTION(xmlreader);
|
||||
|
||||
|
||||
#ifdef ZTS
|
||||
#define XMLREADER_G(v) TSRMG(xmlreader_globals_id, zend_xmlreader_globals *, v)
|
||||
#else
|
||||
#define XMLREADER_G(v) (xmlreader_globals.v)
|
||||
#endif
|
||||
|
||||
#endif /* PHP_XMLREADER_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,114 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="xmlreader" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=xmlreader - Win32 Release_TS
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "xmlreader.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "xmlreader.mak" CFG="xmlreader - Win32 Release_TS"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "xmlreader - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "xmlreader - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "xmlreader - Win32 Debug_TS"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "xmlreader___Win32_Debug_TS"
|
||||
# PROP BASE Intermediate_Dir "xmlreader___Win32_Debug_TS"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug_TS"
|
||||
# PROP Intermediate_Dir "Debug_TS"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XMLREADER_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /GX /ZI /Od /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XMLREADER_EXPORTS" /D "COMPILE_DL_XMLREADER" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D "LIBXML_THREAD_ENABLED" /FR /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 php5ts_debug.lib resolv.lib kernel32.lib user32.lib gdi32.lib winspool.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"msvcrt" /out:"..\..\Debug_TS/php_xmlreader.dll" /libpath:"..\..\Debug_TS" /libpath:"..\..\..\bindlib_w32\Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "xmlreader - Win32 Release_TS"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "xmlreader___Win32_Release_TS0"
|
||||
# PROP BASE Intermediate_Dir "xmlreader___Win32_Release_TS0"
|
||||
# PROP BASE Ignore_Export_Lib 0
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Release_TS"
|
||||
# PROP Intermediate_Dir "Release_TS"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MDd /W3 /GX /ZI /Od /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XMLREADER_EXPORTS" /D "COMPILE_DL_XSL" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D "LIBXML_THREAD_ENABLED" /FR /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /D ZEND_DEBUG=0 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XMLREADER_EXPORTS" /D "COMPILE_DL_XSL" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D "LIBXML_THREAD_ENABLED" /YX /FD /GZ /c
|
||||
# SUBTRACT CPP /Fr
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 php5ts_debug.lib resolv.lib kernel32.lib user32.lib gdi32.lib winspool.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"msvcrt" /out:"..\..\Debug_TS/php_xmlreader.dll" /libpath:"..\..\Debug_TS" /libpath:"..\..\..\bindlib_w32\Release"
|
||||
# ADD LINK32 php5ts.lib resolv.lib kernel32.lib user32.lib gdi32.lib winspool.lib /nologo /dll /incremental:no /machine:I386 /out:"..\..\Release_TS/php_xmlreader.dll" /libpath:"..\..\Debug_TS" /libpath:"..\..\..\bindlib_w32\Release"
|
||||
# SUBTRACT LINK32 /debug
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "xmlreader - Win32 Debug_TS"
|
||||
# Name "xmlreader - Win32 Release_TS"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\php_xmlreader.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\php_xmlreader.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -1,285 +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: Sander Steffann (sander@steffann.nl) |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include "php.h"
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef MAXSYMLINKS
|
||||
#define MAXSYMLINKS 32
|
||||
#endif
|
||||
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
char *php_realpath(char *path, char resolved_path[]);
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define IS_SLASH(p) ((p) == '/' || (p) == '\\')
|
||||
#else
|
||||
#define IS_SLASH(p) ((p) == '/')
|
||||
#endif
|
||||
|
||||
char *php_realpath(char *path, char resolved_path []) {
|
||||
char path_construction[MAXPATHLEN]; /* We build the result in here */
|
||||
char *writepos; /* Position to write next char */
|
||||
|
||||
char path_copy[MAXPATHLEN]; /* A work-copy of the path */
|
||||
char *workpos; /* working position in *path */
|
||||
|
||||
#if !defined(PHP_WIN32)
|
||||
char buf[MAXPATHLEN]; /* Buffer for readlink */
|
||||
int linklength; /* The result from readlink */
|
||||
#endif
|
||||
int linkcount = 0; /* Count symlinks to avoid loops */
|
||||
|
||||
struct stat filestat; /* result from stat */
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
char *temppos; /* position while counting '.' */
|
||||
int dotcount; /* number of '.' */
|
||||
int t; /* counter */
|
||||
#endif
|
||||
|
||||
/* Set the work-position to the beginning of the given path */
|
||||
strcpy(path_copy, path);
|
||||
workpos = path_copy;
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
/* Find out where we start - Windows version */
|
||||
if (IS_SLASH(*workpos)) {
|
||||
/* We start at the root of the current drive */
|
||||
/* Get the current directory */
|
||||
if (V_GETCWD(path_construction, MAXPATHLEN-1) == NULL) {
|
||||
/* Unable to get cwd */
|
||||
resolved_path[0] = 0;
|
||||
return NULL;
|
||||
}
|
||||
/* We only need the first three chars (for example "C:\") */
|
||||
path_construction[3] = 0;
|
||||
workpos++;
|
||||
} else if (workpos[1] == ':') {
|
||||
/* A drive-letter is specified, copy it */
|
||||
strncpy(path_construction, path, 2);
|
||||
strcat(path_construction, "\\");
|
||||
workpos++;
|
||||
workpos++;
|
||||
} else {
|
||||
/* Use the current directory */
|
||||
if (V_GETCWD(path_construction, MAXPATHLEN-1) == NULL) {
|
||||
/* Unable to get cwd */
|
||||
resolved_path[0] = 0;
|
||||
return NULL;
|
||||
}
|
||||
strcat(path_construction, "\\");
|
||||
}
|
||||
#else
|
||||
/* Find out where we start - Unix version */
|
||||
if (*workpos == '/') {
|
||||
/* We start at the root */
|
||||
strcpy(path_construction, "/");
|
||||
workpos++;
|
||||
} else {
|
||||
/* Use the current directory */
|
||||
if (V_GETCWD(path_construction, MAXPATHLEN-1) == NULL) {
|
||||
/* Unable to get cwd */
|
||||
resolved_path[0] = 0;
|
||||
return NULL;
|
||||
}
|
||||
strcat(path_construction, "/");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set the next-char-position */
|
||||
writepos = &path_construction[strlen(path_construction)];
|
||||
|
||||
/* Go to the end, then stop */
|
||||
while(*workpos != 0) {
|
||||
/* Strip (back)slashes */
|
||||
while(IS_SLASH(*workpos)) workpos++;
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
/* reset dotcount */
|
||||
dotcount = 0;
|
||||
|
||||
/* Look for .. */
|
||||
if ((workpos[0] == '.') && (workpos[1] != 0)) {
|
||||
/* Windows accepts \...\ as \..\..\, \....\ as \..\..\..\, etc */
|
||||
/* At least Win98 does */
|
||||
|
||||
temppos = workpos;
|
||||
while(*temppos++ == '.') {
|
||||
dotcount++;
|
||||
if (!IS_SLASH(*temppos) && (*temppos != 0) && (*temppos != '.')) {
|
||||
/* This is not a /../ component, but a filename that starts with '.' */
|
||||
dotcount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Go back dotcount-1 times */
|
||||
for (t=0 ; t<(dotcount-1) ; t++) {
|
||||
workpos++; /* move to next '.' */
|
||||
|
||||
/* Can we still go back? */
|
||||
if ((writepos-3) <= path_construction) return NULL;
|
||||
|
||||
/* Go back */
|
||||
writepos--; /* move to '\' */
|
||||
writepos--;
|
||||
while(!IS_SLASH(*writepos)) writepos--; /* skip until previous '\\' */
|
||||
}
|
||||
workpos++;
|
||||
}
|
||||
|
||||
/* No special case */
|
||||
if (dotcount == 0) {
|
||||
/* Append */
|
||||
while(!IS_SLASH(*workpos) && (*workpos != 0)) {
|
||||
*writepos++ = *workpos++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Just one '.', go to next element */
|
||||
if (dotcount == 1) {
|
||||
while(!IS_SLASH(*workpos) && (*workpos != 0)) {
|
||||
*workpos++;
|
||||
}
|
||||
|
||||
/* Avoid double \ in the result */
|
||||
writepos--;
|
||||
}
|
||||
|
||||
/* If it was a directory, append a slash */
|
||||
if (IS_SLASH(*workpos)) {
|
||||
*writepos++ = *workpos++;
|
||||
}
|
||||
*writepos = 0;
|
||||
#else /* defined(PHP_WIN32) */
|
||||
/* Look for .. */
|
||||
if ((workpos[0] == '.') && (workpos[1] != 0)) {
|
||||
if ((workpos[1] == '.') && ((workpos[2] == '/') || (workpos[2] == 0))) {
|
||||
/* One directory back */
|
||||
/* Set pointers to right position */
|
||||
workpos++; /* move to second '.' */
|
||||
workpos++; /* move to '/' */
|
||||
|
||||
/* Only apply .. if not in root */
|
||||
if ((writepos-1) > path_construction) {
|
||||
writepos--; /* move to '/' */
|
||||
while(*--writepos != '/') ; /* skip until previous '/' */
|
||||
}
|
||||
} else {
|
||||
if (workpos[1] == '/') {
|
||||
/* Found a /./ skip it */
|
||||
workpos++; /* move to '/' */
|
||||
|
||||
/* Avoid double / in the result */
|
||||
writepos--;
|
||||
} else {
|
||||
/* No special case, the name just started with a . */
|
||||
/* Append */
|
||||
while((*workpos != '/') && (*workpos != 0)) {
|
||||
*writepos++ = *workpos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* No special case */
|
||||
/* Append */
|
||||
while((*workpos != '/') && (*workpos != 0)) {
|
||||
*writepos++ = *workpos++;
|
||||
}
|
||||
}
|
||||
|
||||
#if HAVE_SYMLINK
|
||||
/* We are going to use path_construction, so close it */
|
||||
*writepos = 0;
|
||||
|
||||
/* Check the current location to see if it is a symlink */
|
||||
if((linklength = readlink(path_construction, buf, MAXPATHLEN)) != -1) {
|
||||
/* Check linkcount */
|
||||
if (linkcount > MAXSYMLINKS) return NULL;
|
||||
|
||||
/* Count this symlink */
|
||||
linkcount++;
|
||||
|
||||
/* Set end of buf */
|
||||
buf[linklength] = 0;
|
||||
|
||||
/* Check for overflow */
|
||||
if ((strlen(workpos) + strlen(buf) + 1) >= MAXPATHLEN) return NULL;
|
||||
|
||||
/* Remove the symlink-component wrom path_construction */
|
||||
writepos--; /* move to '/' */
|
||||
while(*--writepos != '/') ; /* skip until previous '/' */
|
||||
*++writepos = 0; /* end of string after '/' */
|
||||
|
||||
/* If the symlink starts with a '/', empty path_construction */
|
||||
if (*buf == '/') {
|
||||
*path_construction = 0;
|
||||
writepos = path_construction;
|
||||
}
|
||||
|
||||
/* Insert symlink into path_copy */
|
||||
strcat(buf, workpos);
|
||||
strcpy(path_copy, buf);
|
||||
workpos = path_copy;
|
||||
}
|
||||
#endif /* HAVE_SYMLINK */
|
||||
|
||||
/* If it was a directory, append a slash */
|
||||
if (*workpos == '/') {
|
||||
*writepos++ = *workpos++;
|
||||
}
|
||||
*writepos = 0;
|
||||
#endif /* defined(PHP_WIN32) */
|
||||
}
|
||||
|
||||
/* Check if the resolved path is a directory */
|
||||
if (V_STAT(path_construction, &filestat) != 0) {
|
||||
if (errno != ENOENT) return NULL;
|
||||
} else {
|
||||
if (S_ISDIR(filestat.st_mode)) {
|
||||
/* It's a directory, append a / if needed */
|
||||
if (*(writepos-1) != '/') {
|
||||
/* Check for overflow */
|
||||
if ((strlen(workpos) + 2) >= MAXPATHLEN) {
|
||||
return NULL;
|
||||
}
|
||||
*writepos++ = '/';
|
||||
*writepos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(resolved_path, path_construction);
|
||||
return resolved_path;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
Reference in new issue
Block a user