summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Boeren <mboeren@php.net>2001-03-22 11:07:04 +0000
committerMarc Boeren <mboeren@php.net>2001-03-22 11:07:04 +0000
commitce79b44c278fcae832a5a8faddd14b13008b4daa (patch)
tree3b4c29d4da7825f8f3d841d544fa8cc363dc6a3a
parentdbc4d4b4572861258bcec7ab309065ba6acad087 (diff)
downloadphp-git-ce79b44c278fcae832a5a8faddd14b13008b4daa.tar.gz
Added dbx module (database abstraction) to the repositorty (/ext/dbx).
Compiles under Linux (--enable-dbx) and Windows. Supports MySQL and ODBC modules (more to be added later). @ Added dbx module (database abstraction) to the repository. (Marc)
-rw-r--r--ext/dbx/CREDITS2
-rw-r--r--ext/dbx/INSTALL25
-rw-r--r--ext/dbx/LICENSE71
-rw-r--r--ext/dbx/Makefile.in6
-rw-r--r--ext/dbx/config.m47
-rw-r--r--ext/dbx/dbx.c832
-rw-r--r--ext/dbx/dbx.dsp141
-rw-r--r--ext/dbx/dbx.h45
-rw-r--r--ext/dbx/dbx_mysql.c217
-rw-r--r--ext/dbx/dbx_mysql.h54
-rw-r--r--ext/dbx/dbx_odbc.c239
-rw-r--r--ext/dbx/dbx_odbc.h54
-rw-r--r--ext/dbx/php_dbx.h84
13 files changed, 1777 insertions, 0 deletions
diff --git a/ext/dbx/CREDITS b/ext/dbx/CREDITS
new file mode 100644
index 0000000000..57d1fa5651
--- /dev/null
+++ b/ext/dbx/CREDITS
@@ -0,0 +1,2 @@
+dbx
+Marc Boeren
diff --git a/ext/dbx/INSTALL b/ext/dbx/INSTALL
new file mode 100644
index 0000000000..99ba67cd6c
--- /dev/null
+++ b/ext/dbx/INSTALL
@@ -0,0 +1,25 @@
+
+If you downloaded this separately, you can place the dbx folder
+in the php-source-folders under the ext/folder. Be sure to
+use buildconf to rebuild the configure script.
+
+Linux:
+
+Compile php with the --enable-dbx switch
+
+Windows:
+
+This should set all includepaths to the right
+relative folders. Open the .dsp and compile. You could also
+add this project to the php_modules project.
+It generates a php_dbx.dll in your extensions folder, and you
+must enable it in your php.ini file.
+
+
+When you run phpinfo(), dbx-support should be visible in the
+resulting table.
+
+Good luck and enjoy!
+
+Marc Boeren
+march 16th, 2001
diff --git a/ext/dbx/LICENSE b/ext/dbx/LICENSE
new file mode 100644
index 0000000000..a784d4f184
--- /dev/null
+++ b/ext/dbx/LICENSE
@@ -0,0 +1,71 @@
+--------------------------------------------------------------------
+ The DBX License, version 0.01
+Copyright (c) 2001 Guidance bv. All rights reserved.
+--------------------------------------------------------------------
+
+Redistribution and use in source and binary forms, with or without
+modification, is permitted provided that the following conditions
+are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+ 3. The name "DBX" must not be used to endorse or promote products
+ derived from this software without prior permission from
+ Guidance bv. This does not apply to add-on libraries or tools
+ that work in conjunction with DBX. In such a case the DBX
+ name may be used to indicate that the product supports DBX.
+
+ 4. Guidance bv may publish revised and/or new versions of the
+ license from time to time. Each version will be given a
+ distinguishing version number.
+ Once covered code has been published under a particular version
+ of the license, you may always continue to use it under the
+ terms of that version. You may also choose to use such covered
+ code under the terms of any subsequent version of the license
+ published by Guidance bv. No one other than Guidance bv has
+ the right to modify the terms applicable to covered code created
+ under this License.
+
+ 5. Redistributions of any form whatsoever must retain the following
+ acknowledgment:
+ "This product includes DBX, freely available from
+ http://www.guidance.nl/dbx".
+
+ 6. The software is an add-on to PHP, which is freely available from
+ http://www.php.net. Be sure to read their license as well.
+
+
+THIS SOFTWARE IS PROVIDED BY GUIDANCE BV ``AS IS'' AND
+ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GUIDANCE BV
+ OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+--------------------------------------------------------------------
+
+Guidance bv can be contacted via Email at m.boeren@guidance.nl.
+
+For more information on Guidance bv and the DBX project,
+please see <http://www.guidance.nl>.
+
+The software is an add-on to the PHP project, whihc consists of
+voluntary contributions made by many individuals on behalf of the
+PHP Group.
+
+The PHP Group can be contacted via Email at group@php.net.
+
+For more information on the PHP Group and the PHP project,
+please see <http://www.php.net>.
diff --git a/ext/dbx/Makefile.in b/ext/dbx/Makefile.in
new file mode 100644
index 0000000000..8f40151240
--- /dev/null
+++ b/ext/dbx/Makefile.in
@@ -0,0 +1,6 @@
+
+LTLIBRARY_NAME = libdbx.la
+LTLIBRARY_SOURCES = dbx.c dbx_mysql.c dbx_odbc.c
+LTLIBRARY_SHARED_NAME = dbx.la
+
+include $(top_srcdir)/build/dynlib.mk
diff --git a/ext/dbx/config.m4 b/ext/dbx/config.m4
new file mode 100644
index 0000000000..5cf4885c7d
--- /dev/null
+++ b/ext/dbx/config.m4
@@ -0,0 +1,7 @@
+
+PHP_ARG_ENABLE(dbx,whether to enable dbx support,
+[ --enable-dbx Enable dbx])
+
+if test "$PHP_DBX" != "no"; then
+ PHP_EXTENSION(dbx, $ext_shared)
+fi
diff --git a/ext/dbx/dbx.c b/ext/dbx/dbx.c
new file mode 100644
index 0000000000..b99a9fc421
--- /dev/null
+++ b/ext/dbx/dbx.c
@@ -0,0 +1,832 @@
+/*
+ +----------------------------------------------------------------------+
+ | stentor module version 1.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 2001 Guidance Rotterdam BV |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 1.0 of the STENTOR license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at |
+ | http://www.guidance.nl/php/dbx/license/1_00.txt. |
+ | If you did not receive a copy of the STENTOR license and are unable |
+ | to obtain it through the world-wide-web, please send a note to |
+ | license@guidance.nl so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author : Marc Boeren <marc@guidance.nl> |
+ +----------------------------------------------------------------------+
+ */
+
+#include "php.h"
+#include "php_ini.h"
+#include "php_config.h"
+#include "php_dbx.h"
+#include "ext/standard/info.h"
+
+// defines for supported databases
+#define DBX_UNKNOWN 0
+#define DBX_MYSQL 1
+#define DBX_ODBC 2
+// includes for supported databases
+#include "dbx.h"
+#include "dbx_mysql.h"
+#include "dbx_odbc.h"
+
+// support routines
+int module_exists(char * module_name) {
+ zend_module_entry * zme;
+ int r;
+ r = zend_hash_find(&module_registry, module_name, strlen(module_name)+1, (void **) &zme);
+ return r==0?1:0;
+ }
+
+int get_module_identifier(char * module_name) {
+ if (!strcmp("mysql", module_name)) return DBX_MYSQL;
+ if (!strcmp("odbc", module_name)) return DBX_ODBC;
+ return DBX_UNKNOWN;
+ }
+
+int split_dbx_handle_object(zval ** dbx_object, zval *** pdbx_handle, zval *** pdbx_module) {
+ convert_to_object_ex(dbx_object);
+ if (zend_hash_find((*dbx_object)->value.obj.properties, "handle", 7, (void **) pdbx_handle)==FAILURE || zend_hash_find((*dbx_object)->value.obj.properties, "module", 7, (void **) pdbx_module)==FAILURE) {
+ return 0;
+ }
+ return 1;
+ }
+
+// from dbx.h, to be used in support-files (dbx_mysql.c etc...)
+void dbx_call_any_function(INTERNAL_FUNCTION_PARAMETERS, char * function_name, zval ** returnvalue, int number_of_arguments, zval *** params) {
+ zval * zval_function_name;
+ MAKE_STD_ZVAL(zval_function_name);
+ ZVAL_STRING(zval_function_name, function_name, 1);
+ if (call_user_function_ex(EG(function_table), NULL, zval_function_name, returnvalue, number_of_arguments, params, 0, NULL) == FAILURE) {
+ zend_error(E_ERROR, "function '%s' not found", zval_function_name->value.str.val);
+ }
+ zval_dtor(zval_function_name); // to free stringvalue memory
+ FREE_ZVAL(zval_function_name);
+ }
+
+// switch_dbx functions declarations
+// each must be supported in the x/dbx_module files as dbx_module_function,
+// e.g. switch_dbx_connect expects a dbx_mysql_connect in de x/dbx_mysql files
+// all params except the dbx_module param are passed on
+// each must return the expected zval * 's in the rv parameter, which are passed on unmodified
+// do NOT use the return_value parameter from INTERNAL_FUNCTION_PARAMETERS
+// you can additionally return 0 or 1 for failure or success which will also be returned by the switches
+
+int switch_dbx_connect(zval ** rv, zval ** host, zval ** db, zval ** username, zval ** password, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module);
+ // returns connection handle as resource on success or 0 as long on failure
+int switch_dbx_pconnect(zval ** rv, zval ** host, zval ** db, zval ** username, zval ** password, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module);
+ // returns persistent connection handle as resource on success or 0 as long on failure
+int switch_dbx_close(zval ** rv, zval ** dbx_handle, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module);
+ // returns 1 as long on success or 0 as long on failure
+int switch_dbx_query(zval ** rv, zval ** dbx_handle, zval ** sql_statement, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module);
+ // returns 1 as long or result identifier as resource on success or 0 as long on failure
+int switch_dbx_getcolumncount(zval ** rv, zval ** result_handle, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module);
+ // returns column-count as long on success or 0 as long on failure
+int switch_dbx_getcolumnname(zval ** rv, zval ** result_handle, long column_index, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module);
+ // returns column-name as string on success or 0 as long on failure
+int switch_dbx_getcolumntype(zval ** rv, zval ** result_handle, long column_index, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module);
+ // returns column-type as string on success or 0 as long on failure
+int switch_dbx_getrow(zval ** rv, zval ** result_handle, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module);
+ // returns array[0..columncount-1] as strings on success or 0 as long on failure
+int switch_dbx_error(zval ** rv, zval ** dbx_handle, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module);
+ // returns string
+
+/* If you declare any globals in php_dbx.h uncomment this: */
+//ZEND_DECLARE_MODULE_GLOBALS(dbx)
+/* True global resources - no need for thread safety here */
+static int le_dbx;
+
+/* Every user visible function must have an entry in dbx_functions[].
+*/
+function_entry dbx_functions[] = {
+ ZEND_FE(dbx_connect, NULL)
+ ZEND_FE(dbx_close, NULL)
+ ZEND_FE(dbx_query, NULL)
+ ZEND_FE(dbx_error, NULL)
+
+ ZEND_FE(dbx_sort, NULL)
+ ZEND_FE(dbx_cmp_asc, NULL)
+ ZEND_FE(dbx_cmp_desc, NULL)
+
+ ZEND_FE(dbx_test, NULL)
+
+ {NULL, NULL, NULL} /* Must be the last line in dbx_functions[] */
+ };
+
+zend_module_entry dbx_module_entry = {
+ "dbx",
+ dbx_functions,
+ ZEND_MINIT(dbx),
+ ZEND_MSHUTDOWN(dbx),
+ NULL, /*ZEND_RINIT(dbx), /* Replace with NULL if there's nothing to do at request start */
+ NULL, /*ZEND_RSHUTDOWN(dbx), /* Replace with NULL if there's nothing to do at request end */
+ ZEND_MINFO(dbx),
+ STANDARD_MODULE_PROPERTIES
+ };
+
+#ifdef COMPILE_DL_DBX
+ZEND_GET_MODULE(dbx)
+#endif
+
+//ZEND_INI_BEGIN()
+// ZEND_INI_ENTRY("dbx.defaulttype", "mysql", ZEND_INI_SYSTEM, NULL)
+//ZEND_INI_END()
+
+ZEND_MINIT_FUNCTION(dbx)
+{
+// zend_dbx_globals *dbx_globals;
+// ZEND_INIT_MODULE_GLOBALS(dbx, NULL, NULL);
+
+// REGISTER_INI_ENTRIES();
+
+ REGISTER_LONG_CONSTANT("DBX_PERSISTENT", DBX_PERSISTENT, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DBX_RESULT_INFO", DBX_RESULT_INFO, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DBX_RESULT_INDEX", DBX_RESULT_INDEX, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DBX_RESULT_ASSOC", DBX_RESULT_ASSOC, CONST_CS | CONST_PERSISTENT);
+
+// dbx_globals = ts_resource(dbx_globals_id);
+// global_dbx_ctor(&DBXG(dbx_global));
+
+ return SUCCESS;
+ }
+
+ZEND_MSHUTDOWN_FUNCTION(dbx)
+{
+// DBXLS_FETCH();
+// global_dbx_dtor(&DBXG(dbx_global));
+
+// UNREGISTER_INI_ENTRIES();
+ return SUCCESS;
+ }
+
+/* Remove if there's nothing to do at request start */
+/*ZEND_RINIT_FUNCTION(dbx)
+{ return SUCCESS;
+}*/
+
+/* Remove if there's nothing to do at request end */
+/*ZEND_RSHUTDOWN_FUNCTION(dbx)
+{ return SUCCESS;
+}*/
+
+ZEND_MINFO_FUNCTION(dbx)
+{
+ php_info_print_table_start();
+ php_info_print_table_row(2, "dbx support", "enabled");
+ php_info_print_table_row(2, "dbx support for MySQL", "enabled");
+ php_info_print_table_row(2, "dbx support for ODBC", "enabled");
+ php_info_print_table_end();
+// DISPLAY_INI_ENTRIES();
+}
+
+//
+// actual implementation of the dbx functions
+//
+//
+//
+//
+
+/* {{{ proto dbx_handle_object dbx_connect(string module_name, string host, string db, string username, string password [, bool persistent])
+ returns a dbx_handle_object on success
+ returns 0 on failure
+*/
+ZEND_FUNCTION(dbx_connect)
+{
+ int number_of_arguments=5;
+ zval ** arguments[6];
+
+ int result;
+ long module_identifier;
+ zval * dbx_module;
+ zval * rv_dbx_handle;
+ int persistent=0;
+
+ if ( !(ZEND_NUM_ARGS()==number_of_arguments+1 || ZEND_NUM_ARGS()==number_of_arguments) || zend_get_parameters_array_ex(ZEND_NUM_ARGS(), arguments) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ if (ZEND_NUM_ARGS()==number_of_arguments+1) {
+ convert_to_long_ex(arguments[5]);
+ if ((*arguments[5])->value.lval!=0) persistent=1;
+ }
+
+ convert_to_string_ex(arguments[0]);
+ if (!module_exists((*arguments[0])->value.str.val)) {
+ zend_error(E_WARNING, "dbx: module '%s' not loaded.\n", (*arguments[0])->value.str.val);
+ return;
+ }
+ module_identifier=get_module_identifier((*arguments[0])->value.str.val);
+ if (!module_identifier) {
+ zend_error(E_WARNING, "dbx: unsupported module '%s'.\n", (*arguments[0])->value.str.val);
+ return;
+ }
+
+ MAKE_STD_ZVAL(dbx_module);
+ ZVAL_LONG(dbx_module, module_identifier);
+ MAKE_STD_ZVAL(rv_dbx_handle);
+ ZVAL_LONG(rv_dbx_handle, 0);
+ convert_to_string_ex(arguments[1]);
+ convert_to_string_ex(arguments[2]);
+ convert_to_string_ex(arguments[3]);
+ convert_to_string_ex(arguments[4]);
+ if (persistent) {
+ result = switch_dbx_pconnect(&rv_dbx_handle, arguments[1], arguments[2], arguments[3], arguments[4], INTERNAL_FUNCTION_PARAM_PASSTHRU, &dbx_module);
+ }
+ else {
+ result = switch_dbx_connect(&rv_dbx_handle, arguments[1], arguments[2], arguments[3], arguments[4], INTERNAL_FUNCTION_PARAM_PASSTHRU, &dbx_module);
+ }
+ if (!result) {
+ FREE_ZVAL(dbx_module);
+ FREE_ZVAL(rv_dbx_handle);
+ RETURN_LONG(0);
+ }
+
+ if (object_init(return_value) != SUCCESS) {
+ zend_error(E_ERROR, "dbx: unable to create resulting object...");
+ FREE_ZVAL(dbx_module);
+ FREE_ZVAL(rv_dbx_handle);
+ RETURN_LONG(0);
+ }
+
+ zend_hash_update(return_value->value.obj.properties, "handle", 7, (void *)&(rv_dbx_handle), sizeof(zval *), NULL);
+ zend_hash_update(return_value->value.obj.properties, "module", 7, (void *)&(dbx_module), sizeof(zval *), NULL);
+}
+/* }}} */
+
+/* {{{ proto bool dbx_close(dbx_handle_object dbx_handle)
+ Returns success or failure */
+ZEND_FUNCTION(dbx_close)
+{
+ int number_of_arguments=1;
+ zval ** arguments[1];
+
+ int result;
+ zval ** dbx_handle;
+ zval ** dbx_module;
+ zval * rv_success;
+
+ if (ZEND_NUM_ARGS() !=number_of_arguments || zend_get_parameters_array_ex(number_of_arguments, arguments) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ if (!split_dbx_handle_object(arguments[0], &dbx_handle, &dbx_module)) {
+ zend_error(E_WARNING, "dbx_close: not a valid dbx_handle-object...");
+ RETURN_LONG(0);
+ }
+
+ MAKE_STD_ZVAL(rv_success);
+
+ result = switch_dbx_close(&rv_success, dbx_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU, dbx_module);
+
+ result = (result && rv_success->value.lval)?1:0;
+
+ FREE_ZVAL(rv_success);
+
+ RETURN_LONG(result?1:0);
+}
+/* }}} */
+
+/* {{{ proto data[rowinfo+rows][colinfo+cols] dbx_query(dbx_handle_object dbx_handle, string sql_statement [, long flags])
+ Returns results combined with query-information or false for failure or true for success on execution query
+ flags parameters is not implemented yet and if specified generates a WRONG_PARAM_COUNT
+ it will be used to indicate what column info should be returned, and if fieldnames should be used
+ as assoc column indicators in the result-set */
+ZEND_FUNCTION(dbx_query)
+{
+ int min_number_of_arguments=2;
+ int number_of_arguments=3;
+ zval ** arguments[3];
+
+ int result;
+ zval ** dbx_handle;
+ zval ** dbx_module;
+ zval * rv_result_handle;
+ zval * rv_column_count;
+ long col_index;
+ long row_count;
+ zval * info;
+ long info_flags;
+// long result_row_offset;
+// long result_row_count;
+ zval * data;
+
+ if (ZEND_NUM_ARGS()<min_number_of_arguments || ZEND_NUM_ARGS()>number_of_arguments || zend_get_parameters_array_ex(ZEND_NUM_ARGS(), arguments) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ if (!split_dbx_handle_object(arguments[0], &dbx_handle, &dbx_module)) {
+ zend_error(E_WARNING, "dbx_query: not a valid dbx_handle-object...");
+ RETURN_LONG(0);
+ }
+ // default values
+ info_flags = DBX_RESULT_INFO | DBX_RESULT_INDEX | DBX_RESULT_ASSOC;
+// result_row_offset = 0;
+// result_row_count = -1;
+ // parameter overrides
+ if (ZEND_NUM_ARGS()>2) {
+ convert_to_long_ex(arguments[2]);
+ info_flags = (*arguments[2])->value.lval;
+ // fieldnames are needed for association!
+ if (info_flags & DBX_RESULT_ASSOC) {
+ info_flags |= DBX_RESULT_INFO;
+ }
+ }
+// if (ZEND_NUM_ARGS()>3) {
+// convert_to_long_ex(arguments[3]);
+// result_row_offset = (*arguments[3])->value.lval;
+// }
+// if (ZEND_NUM_ARGS()>4) {
+// convert_to_long_ex(arguments[4]);
+// result_row_count = (*arguments[4])->value.lval;
+// }
+
+ MAKE_STD_ZVAL(rv_result_handle);
+ convert_to_string_ex(arguments[1]);
+ result = switch_dbx_query(&rv_result_handle, dbx_handle, arguments[1], INTERNAL_FUNCTION_PARAM_PASSTHRU, dbx_module);
+ // boolean return value means either failure for any query or success for queries that don't return anything
+ if (!result || (rv_result_handle && rv_result_handle->type==IS_BOOL)) {
+ result = (result && rv_result_handle->value.lval)?1:0;
+ FREE_ZVAL(rv_result_handle);
+ RETURN_LONG(result?1:0);
+ }
+ // if you get here, the query succeeded and returned results, so we'll return them
+ // rv_result_handle holds a resource
+ //
+ // init return_value as object (of rows)
+ if (object_init(return_value) != SUCCESS) {
+ zend_error(E_ERROR, "dbx_query: unable to create resulting object...");
+ FREE_ZVAL(rv_result_handle);
+ RETURN_LONG(0);
+ }
+ // add result_handle property to return_value
+ zend_hash_update(return_value->value.obj.properties, "handle", 7, (void *)&(rv_result_handle), sizeof(zval *), NULL);
+ // init info property as array and add to return_value as a property
+ if (info_flags & DBX_RESULT_INFO) {
+ MAKE_STD_ZVAL(info);
+ if (array_init(info) != SUCCESS) {
+ zend_error(E_ERROR, "dbx_query: unable to create info-array for results...");
+ FREE_ZVAL(info);
+ RETURN_LONG(0);
+ }
+ zend_hash_update(return_value->value.obj.properties, "info", 5, (void *)&(info), sizeof(zval *), NULL);
+ }
+ // init data property as array and add to return_value as a property
+ MAKE_STD_ZVAL(data);
+ if (array_init(data) != SUCCESS) {
+ zend_error(E_ERROR, "dbx_query: unable to create data-array for results...");
+ FREE_ZVAL(data);
+ RETURN_LONG(0);
+ }
+ zend_hash_update(return_value->value.obj.properties, "data", 5, (void *)&(data), sizeof(zval *), NULL);
+ // get columncount and add to returnvalue as property
+ MAKE_STD_ZVAL(rv_column_count);
+ result = switch_dbx_getcolumncount(&rv_column_count, &rv_result_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU, dbx_module);
+ if (!result) {
+ zend_error(E_ERROR, "dbx_query: get column_count failed...");
+ FREE_ZVAL(rv_column_count);
+ RETURN_LONG(0);
+ }
+ zend_hash_update(return_value->value.obj.properties, "cols", 5, (void *)&(rv_column_count), sizeof(zval *), NULL);
+ // fill the info array with columnnames (only indexed (maybe assoc))
+ if (info_flags & DBX_RESULT_INFO) {
+ zval * info_row;
+ MAKE_STD_ZVAL(info_row);
+ if (array_init(info_row) != SUCCESS) {
+ zend_error(E_ERROR, "dbx_query: unable to create info_row-array for results...");
+ FREE_ZVAL(info_row);
+ RETURN_LONG(0);
+ }
+ for (col_index=0; col_index<rv_column_count->value.lval; ++col_index) {
+ zval * rv_column_name;
+ MAKE_STD_ZVAL(rv_column_name);
+ result = switch_dbx_getcolumnname(&rv_column_name, &rv_result_handle, col_index, INTERNAL_FUNCTION_PARAM_PASSTHRU, dbx_module);
+ if (result) {
+ zend_hash_index_update(info_row->value.ht, col_index, (void *)&(rv_column_name), sizeof(zval *), NULL);
+ }
+ else {
+ FREE_ZVAL(rv_column_name);
+ }
+ }
+ zend_hash_update(info->value.ht, "name", 5, (void *) &info_row, sizeof(zval *), NULL);
+ }
+ // fill the info array with columntypes (indexed and assoc)
+ if (info_flags & DBX_RESULT_INFO) {
+ zval * info_row;
+ MAKE_STD_ZVAL(info_row);
+ if (array_init(info_row) != SUCCESS) {
+ zend_error(E_ERROR, "dbx_query: unable to create info_row-array for results...");
+ FREE_ZVAL(info_row);
+ RETURN_LONG(0);
+ }
+ for (col_index=0; col_index<rv_column_count->value.lval; ++col_index) {
+ zval * rv_column_type;
+ MAKE_STD_ZVAL(rv_column_type);
+ result = switch_dbx_getcolumntype(&rv_column_type, &rv_result_handle, col_index, INTERNAL_FUNCTION_PARAM_PASSTHRU, dbx_module);
+ if (result) {
+ zend_hash_index_update(info_row->value.ht, col_index, (void *)&(rv_column_type), sizeof(zval *), NULL);
+ }
+ else {
+ FREE_ZVAL(rv_column_type);
+ }
+ }
+ zend_hash_update(info->value.ht, "type", 5, (void *) &info_row, sizeof(zval *), NULL);
+ }
+ // fill each row array with fieldvalues (indexed and assoc)
+ row_count=0;
+ result=1;
+ while (result) {
+ zval * rv_row;
+ MAKE_STD_ZVAL(rv_row);
+ result = switch_dbx_getrow(&rv_row, &rv_result_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU, dbx_module);
+ if (result) {
+// if (row_count>=result_row_offset && (result_row_count==-1 || row_count<result_row_offset+result_row_count)) {
+ zval ** row_ptr;
+ zend_hash_index_update(data->value.ht, row_count, (void *)&(rv_row), sizeof(zval *), (void **) &row_ptr);
+ // associate results with fieldnames
+ if (info_flags & DBX_RESULT_ASSOC) {
+ zval **columnname_ptr, **actual_ptr, **reference_ptr;
+ zval *dummy, **inforow_ptr;
+ ALLOC_ZVAL(dummy);
+ INIT_ZVAL(*dummy);
+ zend_hash_find(info->value.ht, "name", 5, (void **) &inforow_ptr);
+ for (col_index=0; col_index<rv_column_count->value.lval; ++col_index) {
+ zend_hash_index_find((*inforow_ptr)->value.ht, col_index, (void **) &columnname_ptr);
+ zend_hash_index_find((*row_ptr)->value.ht, col_index, (void **) &actual_ptr);
+ zend_hash_update((*row_ptr)->value.ht, (*columnname_ptr)->value.str.val, (*columnname_ptr)->value.str.len + 1, &dummy, sizeof(zval *), (void **) &reference_ptr);
+ zend_assign_to_variable_reference(NULL, reference_ptr, actual_ptr, NULL ELS_CC);
+ }
+ }
+// }
+// else {
+// FREE_ZVAL(rv_row);
+// }
+ ++row_count;
+ }
+ else {
+ FREE_ZVAL(rv_row);
+ }
+ }
+ // add row_count property
+ add_property_long(return_value, "rows", row_count);
+ // thank you for watching.
+}
+/* }}} */
+
+/* {{{ proto void dbx_error()
+ Returns success or failure */
+ZEND_FUNCTION(dbx_error)
+{
+ int number_of_arguments=1;
+ zval ** arguments[1];
+
+ int result;
+ zval ** dbx_handle;
+ zval ** dbx_module;
+ zval * rv_errormsg;
+
+ if (ZEND_NUM_ARGS() !=number_of_arguments || zend_get_parameters_array_ex(number_of_arguments, arguments) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ if (!split_dbx_handle_object(arguments[0], &dbx_handle, &dbx_module)) {
+ zend_error(E_WARNING, "dbx_error: not a valid dbx_handle-object...");
+ RETURN_LONG(0);
+ }
+
+ MAKE_STD_ZVAL(rv_errormsg);
+ result = switch_dbx_error(&rv_errormsg, NULL, INTERNAL_FUNCTION_PARAM_PASSTHRU, dbx_module);
+ if (!result) {
+ FREE_ZVAL(rv_errormsg);
+ RETURN_STRING("", 1);
+ }
+ MOVE_RETURNED_TO_RV(&return_value, rv_errormsg);
+}
+/* }}} */
+
+/////////// dbx functions that are database independent... like sorting result_objects!
+
+/* {{{ proto long dbx_cmp_asc(array row_x, array row_y, string columnname)
+ returns row_x[columnname] - row_y[columnname], converted to -1, 0 or 1
+*/
+ZEND_FUNCTION(dbx_cmp_asc)
+{
+ int number_of_arguments=3;
+ double dtemp;
+ long ltemp;
+ zval ** arguments[3];
+ zval ** zv_a;
+ zval ** zv_b;
+ int result=0;
+ if (ZEND_NUM_ARGS() !=number_of_arguments || zend_get_parameters_array_ex(number_of_arguments, arguments) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ if ((*arguments[0])->type != IS_ARRAY
+ || (*arguments[1])->type != IS_ARRAY) {
+ zend_error(E_WARNING, "Wrong argument type for compare");
+ RETURN_LONG(0);
+ }
+ convert_to_string_ex(arguments[2]); // field name
+
+ if (zend_hash_find((*arguments[0])->value.ht, (*arguments[2])->value.str.val, (*arguments[2])->value.str.len+1, (void **) &zv_a)==FAILURE
+ || zend_hash_find((*arguments[1])->value.ht, (*arguments[2])->value.str.val, (*arguments[2])->value.str.len+1, (void **) &zv_b)==FAILURE) {
+ zend_error(E_WARNING, "Field '%s' not available in result-object", (*arguments[2])->value.str.val);
+ RETURN_LONG(0);
+ }
+
+ if ((*zv_a)->type != (*zv_b)->type) {
+ convert_to_string_ex(zv_a);
+ convert_to_string_ex(zv_b);
+ }
+ switch ((*zv_a)->type) {
+ case IS_LONG:
+ case IS_BOOL:
+ ltemp = (*zv_a)->value.lval - (*zv_b)->value.lval;
+ result = (ltemp==0?0: (ltemp>0?1:-1));
+ break;
+ case IS_DOUBLE:
+ dtemp = ((*zv_a)->value.dval - (*zv_b)->value.dval);
+ result = (dtemp==0?0: (dtemp>0?1:-1));
+ break;
+ case IS_STRING:
+ ltemp = strcmp((*zv_a)->value.str.val, (*zv_b)->value.str.val);
+ result = (ltemp==0?0: (ltemp>0?1:-1));
+ break;
+ default:
+ result=0;
+ break;
+ }
+
+ RETURN_LONG(result);
+}
+
+/* {{{ proto long dbx_cmp_desc(array row_x, array row_y, string columnname)
+ returns row_y[columnname] - row_x[columnname], converted to -1, 0 or 1
+*/
+ZEND_FUNCTION(dbx_cmp_desc)
+{
+ int number_of_arguments=3;
+ double dtemp;
+ long ltemp;
+ zval ** arguments[3];
+ zval ** zv_a;
+ zval ** zv_b;
+ int result=0;
+ if (ZEND_NUM_ARGS() !=number_of_arguments || zend_get_parameters_array_ex(number_of_arguments, arguments) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ if ((*arguments[0])->type != IS_ARRAY
+ || (*arguments[1])->type != IS_ARRAY) {
+ zend_error(E_WARNING, "Wrong argument type for compare");
+ RETURN_LONG(0);
+ }
+ convert_to_string_ex(arguments[2]); // field name
+
+ if (zend_hash_find((*arguments[0])->value.ht, (*arguments[2])->value.str.val, (*arguments[2])->value.str.len+1, (void **) &zv_a)==FAILURE
+ || zend_hash_find((*arguments[1])->value.ht, (*arguments[2])->value.str.val, (*arguments[2])->value.str.len+1, (void **) &zv_b)==FAILURE) {
+ zend_error(E_WARNING, "Field '%s' not available in result-object", (*arguments[2])->value.str.val);
+ RETURN_LONG(0);
+ }
+
+ if ((*zv_a)->type != (*zv_b)->type) {
+ convert_to_string_ex(zv_a);
+ convert_to_string_ex(zv_b);
+ }
+ switch ((*zv_a)->type) {
+ case IS_LONG:
+ case IS_BOOL:
+ ltemp = (*zv_b)->value.lval - (*zv_a)->value.lval;
+ result = (ltemp==0?0: (ltemp>0?1:-1));
+ break;
+ case IS_DOUBLE:
+ dtemp = ((*zv_b)->value.dval - (*zv_a)->value.dval);
+ result = (dtemp==0?0: (dtemp>0?1:-1));
+ break;
+ case IS_STRING:
+ ltemp = strcmp((*zv_b)->value.str.val, (*zv_a)->value.str.val);
+ result = (ltemp==0?0: (ltemp>0?1:-1));
+ break;
+ default:
+ result=0;
+ break;
+ }
+
+ RETURN_LONG(result);
+}
+
+/* {{{ proto long dbx_sort(dbx_result_object stn_search_keywords_result, string compare_function_name)
+ returns 0 on failure, 1 on success
+*/
+ZEND_FUNCTION(dbx_sort)
+{
+ int number_of_arguments=2;
+ zval ** arguments[2];
+ zval ** zval_data;
+ zval * returned_zval;
+ int result=0;
+ if (ZEND_NUM_ARGS() !=number_of_arguments || zend_get_parameters_array_ex(number_of_arguments, arguments) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ if ((*arguments[0])->type != IS_OBJECT
+ || (*arguments[1])->type != IS_STRING) {
+ zend_error(E_WARNING, "Wrong argument type for sort");
+ RETURN_LONG(0);
+ }
+
+ if (zend_hash_find((*arguments[0])->value.obj.properties, "data", 5, (void **) &zval_data)==FAILURE
+ || (*zval_data)->type != IS_ARRAY) {
+ zend_error(E_WARNING, "Wrong argument type for sort");
+ RETURN_LONG(0);
+ }
+
+ arguments[0] = zval_data;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "usort", &returned_zval, number_of_arguments, arguments);
+ zval_dtor(returned_zval);
+ FREE_ZVAL(returned_zval);
+
+ RETURN_LONG(1);
+}
+
+/////////////////
+
+/* {{{ proto long dbx_test(???)
+ */
+ZEND_FUNCTION(dbx_test)
+{
+ zval **args[2];
+ zval *rowheader[2];
+ zval *row[2];
+ int result;
+ zval * sz;
+// char psz[6];
+
+ array_init(return_value);
+
+ MAKE_STD_ZVAL(sz);
+// strcpy(psz, "blaaa");
+ ZVAL_STRING(sz, "blaaa", 0);
+
+ zend_hash_index_update(return_value->value.ht, 2, (void *) &sz, sizeof(zval *), NULL);
+ zend_hash_update(return_value->value.ht, "two", 4, (void *) &sz, sizeof(zval *), NULL);
+
+
+//add_index_string(return_value, 2, sz->value.str.val, 1);
+//add_assoc_string(return_value, "two", sz->value.str.val, 0);
+
+
+// zend_hash_update(return_value->value.ht, "x", 2, (void *)&sz, sizeof(zval *), NULL);
+// FREE_ZVAL(sz);
+ return;
+
+// DBXLS_FETCH();
+ for (result=0; result<2; ++result) {
+ args[result]=NULL;
+ }
+
+ if (ZEND_NUM_ARGS() !=2 || zend_get_parameters_array_ex(2, args) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long_ex(args[0]); // resource is also a long
+ convert_to_string_ex(args[1]);
+
+ if (array_init(return_value) != SUCCESS) {
+ zend_error(E_ERROR, "Unable to create array for results...");
+ RETURN_LONG(0);
+ }
+
+ for (result=0; result<2; ++result) {
+ MAKE_STD_ZVAL(rowheader[result]);
+ if (array_init(rowheader[result]) != SUCCESS) {
+ zend_error(E_ERROR, "Unable to create array for rowheader %d...", result);
+ }
+ }
+ for (result=0; result<2; ++result) {
+ MAKE_STD_ZVAL(row[result]);
+ if (array_init(row[result]) != SUCCESS) {
+ zend_error(E_ERROR, "Unable to create array for row %d...", result);
+ }
+ }
+
+ add_index_string(rowheader[0], 0, "header0", 1); add_assoc_string(rowheader[0], "header0", "header0", 0);
+ add_index_string(rowheader[0], 1, "header1", 1); add_assoc_string(rowheader[0], "header1", "header1", 0);
+ add_index_string(rowheader[1], 0, "string", 1); add_assoc_string(rowheader[1], "header0", "string", 0);
+ add_index_string(rowheader[1], 1, "string", 1); add_assoc_string(rowheader[1], "header1", "string", 0);
+ add_index_string(row[0], 0, "bla00", 0); add_assoc_string(row[0], "header0", "bla00", 1);
+ add_index_string(row[0], 1, "bla10", 0); add_assoc_string(row[0], "header1", "bla10", 1);
+ add_index_string(row[1], 0, "bla01", 0); add_assoc_string(row[1], "header0", "bla01", 1);
+ add_index_string(row[1], 1, "bla11", 1); add_assoc_string(row[1], "header1", "bla11", 1);
+
+ add_index_string(row[1], 2, "bla12", 1);
+
+ zend_hash_update(return_value->value.ht, "fieldname", 10, (void *)&(rowheader[0]), sizeof(zval *), NULL);
+ zend_hash_update(return_value->value.ht, "fieldtype", 10, (void *)&(rowheader[1]), sizeof(zval *), NULL);
+ zend_hash_index_update(return_value->value.ht, 0, (void *)&(row[0]), sizeof(zval *), NULL);
+ zend_hash_index_update(return_value->value.ht, 1, (void *)&(row[1]), sizeof(zval *), NULL);
+
+}
+/* }}} */
+
+
+
+
+
+
+//
+// switch_dbx functions
+//
+int switch_dbx_connect(zval ** rv, zval ** host, zval ** db, zval ** username, zval ** password, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module) {
+ // returns connection handle as resource on success or 0 as long on failure
+ switch ((*dbx_module)->value.lval) {
+ case DBX_MYSQL: return dbx_mysql_connect(rv, host, db, username, password, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ case DBX_ODBC: return dbx_odbc_connect(rv, host, db, username, password, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ }
+ zend_error(E_WARNING, "dbx_connect: not supported in this module");
+ return 0;
+ }
+
+int switch_dbx_pconnect(zval ** rv, zval ** host, zval ** db, zval ** username, zval ** password, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module) {
+ // returns persistent connection handle as resource on success or 0 as long on failure
+ switch ((*dbx_module)->value.lval) {
+ case DBX_MYSQL: return dbx_mysql_pconnect(rv, host, db, username, password, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ case DBX_ODBC: return dbx_odbc_pconnect(rv, host, db, username, password, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ }
+ zend_error(E_WARNING, "dbx_pconnect: not supported in this module");
+ return 0;
+ }
+
+int switch_dbx_close(zval ** rv, zval ** dbx_handle, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module) {
+ // returns 1 as long on success or 0 as long on failure
+ switch ((*dbx_module)->value.lval) {
+ case DBX_MYSQL: return dbx_mysql_close(rv, dbx_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ case DBX_ODBC: return dbx_odbc_close(rv, dbx_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ }
+ zend_error(E_WARNING, "dbx_close: not supported in this module");
+ return 0;
+ }
+
+int switch_dbx_query(zval ** rv, zval ** dbx_handle, zval ** sql_statement, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module) {
+ // returns 1 as long or result identifier as resource on success or 0 as long on failure
+ switch ((*dbx_module)->value.lval) {
+ case DBX_MYSQL: return dbx_mysql_query(rv, dbx_handle, sql_statement, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ case DBX_ODBC: return dbx_odbc_query(rv, dbx_handle, sql_statement, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ }
+ zend_error(E_WARNING, "dbx_query: not supported in this module");
+ return 0;
+ }
+
+int switch_dbx_getcolumncount(zval ** rv, zval ** result_handle, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module) {
+ // returns column-count as long on success or 0 as long on failure
+ switch ((*dbx_module)->value.lval) {
+ case DBX_MYSQL: return dbx_mysql_getcolumncount(rv, result_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ case DBX_ODBC: return dbx_odbc_getcolumncount(rv, result_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ }
+ zend_error(E_WARNING, "dbx_getcolumncount: not supported in this module");
+ return 0;
+ }
+
+int switch_dbx_getcolumnname(zval ** rv, zval ** result_handle, long column_index, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module) {
+ // returns column-name as string on success or 0 as long on failure
+ switch ((*dbx_module)->value.lval) {
+ case DBX_MYSQL: return dbx_mysql_getcolumnname(rv, result_handle, column_index, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ case DBX_ODBC: return dbx_odbc_getcolumnname(rv, result_handle, column_index, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ }
+ zend_error(E_WARNING, "dbx_getcolumnname: not supported in this module");
+ return 0;
+ }
+
+int switch_dbx_getcolumntype(zval ** rv, zval ** result_handle, long column_index, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module) {
+ // returns column-type as string on success or 0 as long on failure
+ switch ((*dbx_module)->value.lval) {
+ case DBX_MYSQL: return dbx_mysql_getcolumntype(rv, result_handle, column_index, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ case DBX_ODBC: return dbx_odbc_getcolumntype(rv, result_handle, column_index, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ }
+ zend_error(E_WARNING, "dbx_getcolumntype: not supported in this module");
+ return 0;
+ }
+
+int switch_dbx_getrow(zval ** rv, zval ** result_handle, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module) {
+ // returns array[0..columncount-1] as strings on success or 0 as long on failure
+ switch ((*dbx_module)->value.lval) {
+ case DBX_MYSQL: return dbx_mysql_getrow(rv, result_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ case DBX_ODBC: return dbx_odbc_getrow(rv, result_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ }
+ zend_error(E_WARNING, "dbx_getrow: not supported in this module");
+ return 0;
+ }
+
+int switch_dbx_error(zval ** rv, zval ** dbx_handle, INTERNAL_FUNCTION_PARAMETERS, zval ** dbx_module) {
+ // returns string
+ switch ((*dbx_module)->value.lval) {
+ case DBX_MYSQL: return dbx_mysql_error(rv, dbx_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ case DBX_ODBC: return dbx_odbc_error(rv, dbx_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ }
+ zend_error(E_WARNING, "dbx_error: not supported in this module");
+ return 0;
+ }
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/dbx/dbx.dsp b/ext/dbx/dbx.dsp
new file mode 100644
index 0000000000..4998d59a37
--- /dev/null
+++ b/ext/dbx/dbx.dsp
@@ -0,0 +1,141 @@
+# Microsoft Developer Studio Project File - Name="dbx" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=dbx - 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 "dbx.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 "dbx.mak" CFG="dbx - Win32 Release_TS"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "dbx - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "dbx - Win32 Debug_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)" == "dbx - Win32 Release_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release_TS"
+# PROP BASE Intermediate_Dir "Release_TS"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_TS"
+# PROP Intermediate_Dir "Release_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\..\TSRM" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_dbx" /D ZTS=1 /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "WIN32" /D "dbx_EXPORTS" /D "COMPILE_DL_dbx" /D ZTS=1 /D HAVE_LIBINTL=1 /D ZEND_DEBUG=0 /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZEND_WIN32" /D "PHP_WIN32" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x406 /d "NDEBUG"
+# ADD RSC /l 0x406 /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 php4ts.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_dbx.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline"
+# ADD LINK32 php4ts.lib 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 /machine:I386 /out:"..\..\Release_TS/php_dbx.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline"
+
+!ELSEIF "$(CFG)" == "dbx - Win32 Debug_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Debug_TS"
+# PROP BASE Intermediate_Dir "Debug_TS"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Debug_TS"
+# PROP Intermediate_Dir "Debug_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MSSQL_EXPORTS" /D "COMPILE_DL_dbx" /D ZTS=1 /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /GX /ZI /Od /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "dbx_EXPORTS" /D "COMPILE_DL_dbx" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_LIBINTL=1 /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x406 /d "NDEBUG"
+# ADD RSC /l 0x406 /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 php4ts.lib /nologo /dll /machine:I386 /out:"../../Debug_TS/php_dbx.dll" /libpath:"..\..\Debug_TS"
+# ADD LINK32 php4ts_debug.lib 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 /incremental:yes /debug /machine:I386 /out:"../../Debug_TS/php_dbx.dll" /libpath:"..\..\Debug_TS"
+
+!ENDIF
+
+# Begin Target
+
+# Name "dbx - Win32 Release_TS"
+# Name "dbx - Win32 Debug_TS"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\dbx.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dbx_mysql.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dbx_odbc.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\dbx.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\dbx_mysql.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\x\dbx_mysql.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\dbx_odbc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\x\dbx_odbc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\php_dbx.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
diff --git a/ext/dbx/dbx.h b/ext/dbx/dbx.h
new file mode 100644
index 0000000000..f98e1deb24
--- /dev/null
+++ b/ext/dbx/dbx.h
@@ -0,0 +1,45 @@
+/*
+ +----------------------------------------------------------------------+
+ | stentor module version 1.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 2001 Guidance Rotterdam BV |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 1.0 of the STENTOR license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at |
+ | http://www.guidance.nl/php/dbx/license/1_00.txt. |
+ | If you did not receive a copy of the STENTOR license and are unable |
+ | to obtain it through the world-wide-web, please send a note to |
+ | license@guidance.nl so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author : Marc Boeren <marc@guidance.nl> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef ZEND_DBX_H
+#define ZEND_DBX_H
+
+#ifndef INIT_FUNC_ARGS
+#include "zend_modules.h"
+#endif
+
+#include "php.h"
+
+#define DBX_PERSISTENT 1
+#define DBX_RESULT_INFO 1
+#define DBX_RESULT_INDEX 2
+#define DBX_RESULT_ASSOC 4
+
+#define MOVE_RETURNED_TO_RV(rv, returned_zval) { **rv = *returned_zval; zval_copy_ctor(*rv); zval_ptr_dtor(&returned_zval); }
+
+void dbx_call_any_function(INTERNAL_FUNCTION_PARAMETERS, char * function_name, zval ** returnvalue, int number_of_arguments, zval *** params);
+
+#endif /* ZEND_DBX_H */
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/dbx/dbx_mysql.c b/ext/dbx/dbx_mysql.c
new file mode 100644
index 0000000000..0b755e76c2
--- /dev/null
+++ b/ext/dbx/dbx_mysql.c
@@ -0,0 +1,217 @@
+/*
+ +----------------------------------------------------------------------+
+ | stentor module version 1.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 2001 Guidance Rotterdam BV |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 1.0 of the STENTOR license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at |
+ | http://www.guidance.nl/php/dbx/license/1_00.txt. |
+ | If you did not receive a copy of the STENTOR license and are unable |
+ | to obtain it through the world-wide-web, please send a note to |
+ | license@guidance.nl so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author : Marc Boeren <marc@guidance.nl> |
+ +----------------------------------------------------------------------+
+ */
+
+#include "dbx.h"
+#include "dbx_mysql.h"
+
+#define MYSQL_ASSOC 1<<0
+#define MYSQL_NUM 1<<1
+
+int dbx_mysql_connect(zval ** rv, zval ** host, zval ** db, zval ** username, zval ** password, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns connection handle as resource on success or 0 as long on failure
+ int number_of_arguments=3;
+ zval ** arguments[3];
+ zval * returned_zval=NULL;
+ zval * select_db_zval=NULL;
+
+ arguments[0]=host;
+ arguments[1]=username;
+ arguments[2]=password;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "mysql_connect", &returned_zval, number_of_arguments, arguments);
+ if (!returned_zval || returned_zval->type!=IS_RESOURCE) {
+ if (returned_zval) zval_ptr_dtor(&returned_zval);
+ return 0;
+ }
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+
+ number_of_arguments=2;
+ arguments[0]=db;
+ arguments[1]=rv;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "mysql_select_db", &select_db_zval, number_of_arguments, arguments);
+ zval_ptr_dtor(&select_db_zval);
+
+ return 1;
+ }
+
+int dbx_mysql_pconnect(zval ** rv, zval ** host, zval ** db, zval ** username, zval ** password, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns persistent connection handle as resource on success or 0 as long on failure
+ int number_of_arguments=3;
+ zval ** arguments[3];
+ zval * returned_zval=NULL;
+ zval * select_db_zval=NULL;
+
+ arguments[0]=host;
+ arguments[1]=username;
+ arguments[2]=password;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "mysql_pconnect", &returned_zval, number_of_arguments, arguments);
+ if (!returned_zval || returned_zval->type!=IS_RESOURCE) {
+ if (returned_zval) zval_ptr_dtor(&returned_zval);
+ return 0;
+ }
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+
+ number_of_arguments=2;
+ arguments[0]=db;
+ arguments[1]=rv;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "mysql_select_db", &select_db_zval, number_of_arguments, arguments);
+ zval_ptr_dtor(&select_db_zval);
+
+ return 1;
+ }
+
+int dbx_mysql_close(zval ** rv, zval ** dbx_handle, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns 1 as long on success or 0 as long on failure
+ int number_of_arguments=1;
+ zval ** arguments[1];
+ zval * returned_zval=NULL;
+
+ arguments[0]=dbx_handle;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "mysql_close", &returned_zval, number_of_arguments, arguments);
+ if (!returned_zval || returned_zval->type!=IS_BOOL) {
+ if (returned_zval) zval_ptr_dtor(&returned_zval);
+ return 0;
+ }
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+ return 1;
+ }
+
+int dbx_mysql_query(zval ** rv, zval ** dbx_handle, zval ** sql_statement, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns 1 as long or a result identifier as resource on success or 0 as long on failure
+ int number_of_arguments=2;
+ zval ** arguments[2];
+ zval * returned_zval=NULL;
+
+ arguments[0]=sql_statement;
+ arguments[1]=dbx_handle;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "mysql_query", &returned_zval, number_of_arguments, arguments);
+ // mysql_query returns a bool for success or failure, or a result_identifier for select statements
+ if (!returned_zval || (returned_zval->type!=IS_BOOL && returned_zval->type!=IS_RESOURCE)) {
+ if (returned_zval) zval_ptr_dtor(&returned_zval);
+ return 0;
+ }
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+ return 1;
+ }
+
+int dbx_mysql_getcolumncount(zval ** rv, zval ** result_handle, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns column-count as long on success or 0 as long on failure
+ int number_of_arguments=1;
+ zval ** arguments[1];
+ zval * returned_zval=NULL;
+
+ arguments[0]=result_handle;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "mysql_num_fields", &returned_zval, number_of_arguments, arguments);
+ if (!returned_zval || returned_zval->type!=IS_LONG) {
+ if (returned_zval) zval_ptr_dtor(&returned_zval);
+ return 0;
+ }
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+ return 1;
+ }
+
+int dbx_mysql_getcolumnname(zval ** rv, zval ** result_handle, long column_index, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns column-name as string on success or 0 as long on failure
+ int number_of_arguments=2;
+ zval ** arguments[2];
+ zval * zval_column_index;
+ zval * returned_zval=NULL;
+
+ MAKE_STD_ZVAL(zval_column_index);
+ ZVAL_LONG(zval_column_index, column_index);
+ arguments[0]=result_handle;
+ arguments[1]=&zval_column_index;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "mysql_field_name", &returned_zval, number_of_arguments, arguments);
+ // mysql_field_name returns a string
+ if (!returned_zval || returned_zval->type!=IS_STRING) {
+ if (returned_zval) zval_ptr_dtor(&returned_zval);
+ FREE_ZVAL(zval_column_index);
+ return 0;
+ }
+ FREE_ZVAL(zval_column_index);
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+ return 1;
+ }
+
+int dbx_mysql_getcolumntype(zval ** rv, zval ** result_handle, long column_index, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns column-type as string on success or 0 as long on failure
+ int number_of_arguments=2;
+ zval ** arguments[2];
+ zval * zval_column_index;
+ zval * returned_zval=NULL;
+
+ MAKE_STD_ZVAL(zval_column_index);
+ ZVAL_LONG(zval_column_index, column_index);
+ arguments[0]=result_handle;
+ arguments[1]=&zval_column_index;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "mysql_field_type", &returned_zval, number_of_arguments, arguments);
+ // mysql_field_name returns a string
+ if (!returned_zval || returned_zval->type!=IS_STRING) {
+ if (returned_zval) zval_ptr_dtor(&returned_zval);
+ FREE_ZVAL(zval_column_index);
+ return 0;
+ }
+ FREE_ZVAL(zval_column_index);
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+ return 1;
+ }
+
+int dbx_mysql_getrow(zval ** rv, zval ** result_handle, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns array[0..columncount-1] as strings on success or 0 as long on failure
+ int number_of_arguments=2;
+ zval ** arguments[2];
+ zval * zval_resulttype=NULL;
+ zval * returned_zval=NULL;
+
+ MAKE_STD_ZVAL(zval_resulttype);
+ ZVAL_LONG(zval_resulttype, MYSQL_NUM);
+ arguments[0]=result_handle;
+ arguments[1]=&zval_resulttype;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "mysql_fetch_array", &returned_zval, number_of_arguments, arguments);
+ if (!returned_zval || returned_zval->type!=IS_ARRAY) {
+ if (returned_zval) zval_ptr_dtor(&returned_zval);
+ FREE_ZVAL(zval_resulttype);
+ return 0;
+ }
+ FREE_ZVAL(zval_resulttype);
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+ return 1;
+ }
+
+int dbx_mysql_error(zval ** rv, zval ** dbx_handle, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns string
+ int number_of_arguments=1;
+ zval ** arguments[1];
+ zval * returned_zval=NULL;
+
+ arguments[0]=dbx_handle;
+ if (!dbx_handle) number_of_arguments=0;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "mysql_error", &returned_zval, number_of_arguments, arguments);
+ if (!returned_zval || returned_zval->type!=IS_STRING) {
+ if (returned_zval) zval_ptr_dtor(&returned_zval);
+ return 0;
+ }
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+ return 1;
+ }
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/dbx/dbx_mysql.h b/ext/dbx/dbx_mysql.h
new file mode 100644
index 0000000000..1867ba9ffb
--- /dev/null
+++ b/ext/dbx/dbx_mysql.h
@@ -0,0 +1,54 @@
+/*
+ +----------------------------------------------------------------------+
+ | stentor module version 1.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 2001 Guidance Rotterdam BV |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 1.0 of the STENTOR license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at |
+ | http://www.guidance.nl/php/dbx/license/1_00.txt. |
+ | If you did not receive a copy of the STENTOR license and are unable |
+ | to obtain it through the world-wide-web, please send a note to |
+ | license@guidance.nl so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author : Marc Boeren <marc@guidance.nl> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef ZEND_DBX_MYSQL_H
+#define ZEND_DBX_MYSQL_H
+
+#ifndef INIT_FUNC_ARGS
+#include "zend_modules.h"
+#endif
+
+#include "php.h"
+
+int dbx_mysql_connect(zval ** rv, zval ** host, zval ** db, zval ** username, zval ** password, INTERNAL_FUNCTION_PARAMETERS);
+ // returns connection handle as resource on success or 0 as long on failure
+int dbx_mysql_pconnect(zval ** rv, zval ** host, zval ** db, zval ** username, zval ** password, INTERNAL_FUNCTION_PARAMETERS);
+ // returns persistent connection handle as resource on success or 0 as long on failure
+int dbx_mysql_close(zval ** rv, zval ** dbx_handle, INTERNAL_FUNCTION_PARAMETERS);
+ // returns 1 as long on success or 0 as long on failure
+int dbx_mysql_query(zval ** rv, zval ** dbx_handle, zval ** sql_statement, INTERNAL_FUNCTION_PARAMETERS);
+ // returns 1 as long or a result identifier as resource on success or 0 as long on failure
+int dbx_mysql_getcolumncount(zval ** rv, zval ** result_handle, INTERNAL_FUNCTION_PARAMETERS);
+ // returns column-count as long on success or 0 as long on failure
+int dbx_mysql_getcolumnname(zval ** rv, zval ** result_handle, long column_index, INTERNAL_FUNCTION_PARAMETERS);
+ // returns column-name as string on success or 0 as long on failure
+int dbx_mysql_getcolumntype(zval ** rv, zval ** result_handle, long column_index, INTERNAL_FUNCTION_PARAMETERS);
+ // returns column-type as string on success or 0 as long on failure
+int dbx_mysql_getrow(zval ** rv, zval ** result_handle, INTERNAL_FUNCTION_PARAMETERS);
+ // returns array[0..columncount-1] as strings on success or 0 as long on failure
+int dbx_mysql_error(zval ** rv, zval ** dbx_handle, INTERNAL_FUNCTION_PARAMETERS);
+ // returns string
+
+#endif /* ZEND_DBX_MYSQL_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/dbx/dbx_odbc.c b/ext/dbx/dbx_odbc.c
new file mode 100644
index 0000000000..ac12d3b7f2
--- /dev/null
+++ b/ext/dbx/dbx_odbc.c
@@ -0,0 +1,239 @@
+/*
+ +----------------------------------------------------------------------+
+ | stentor module version 1.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 2001 Guidance Rotterdam BV |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 1.0 of the STENTOR license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at |
+ | http://www.guidance.nl/php/dbx/license/1_00.txt. |
+ | If you did not receive a copy of the STENTOR license and are unable |
+ | to obtain it through the world-wide-web, please send a note to |
+ | license@guidance.nl so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author : Marc Boeren <marc@guidance.nl> |
+ +----------------------------------------------------------------------+
+ */
+
+#include "dbx.h"
+#include "dbx_odbc.h"
+
+#define ODBC_ASSOC 1
+#define ODBC_NUM 2
+
+int dbx_odbc_connect(zval ** rv, zval ** host, zval ** db, zval ** username, zval ** password, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns connection handle as resource on success or 0 as long on failure
+ int number_of_arguments=3;
+ zval ** arguments[3];
+ zval * returned_zval=NULL;
+
+ arguments[0]=db;
+ arguments[1]=username;
+ arguments[2]=password;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "odbc_connect", &returned_zval, number_of_arguments, arguments);
+ if (!returned_zval || returned_zval->type!=IS_RESOURCE) {
+ if (returned_zval) zval_ptr_dtor(&returned_zval);
+ return 0;
+ }
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+ return 1;
+ }
+
+int dbx_odbc_pconnect(zval ** rv, zval ** host, zval ** db, zval ** username, zval ** password, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns connection handle as resource on success or 0 as long on failure
+ int number_of_arguments=3;
+ zval ** arguments[3];
+ zval * returned_zval=NULL;
+
+ arguments[0]=db;
+ arguments[1]=username;
+ arguments[2]=password;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "odbc_pconnect", &returned_zval, number_of_arguments, arguments);
+ if (!returned_zval || returned_zval->type!=IS_RESOURCE) {
+ if (returned_zval) zval_ptr_dtor(&returned_zval);
+ return 0;
+ }
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+ return 1;
+ }
+
+int dbx_odbc_close(zval ** rv, zval ** dbx_handle, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns 1 as long on success or 0 as long on failure
+ int number_of_arguments=1;
+ zval ** arguments[1];
+ zval * returned_zval=NULL;
+
+ arguments[0]=dbx_handle;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "odbc_close", &returned_zval, number_of_arguments, arguments);
+ if (!returned_zval || returned_zval->type!=IS_BOOL) {
+ if (returned_zval) zval_ptr_dtor(&returned_zval);
+ return 0;
+ }
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+ return 1;
+ }
+
+int dbx_odbc_query(zval ** rv, zval ** dbx_handle, zval ** sql_statement, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns 1 as long or a result identifier as resource on success or 0 as long on failure
+ int number_of_arguments=2;
+ zval ** arguments[2];
+ zval * queryresult_zval=NULL;
+ zval * num_fields_zval=NULL;
+
+ arguments[0]=dbx_handle;
+ arguments[1]=sql_statement;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "odbc_exec", &queryresult_zval, number_of_arguments, arguments);
+ // odbc_query returns a bool for failure, or a result_identifier for success
+ if (!queryresult_zval || queryresult_zval->type!=IS_RESOURCE) {
+ if (queryresult_zval) zval_ptr_dtor(&queryresult_zval);
+ return 0;
+ }
+ MAKE_STD_ZVAL(num_fields_zval);
+ if (!dbx_odbc_getcolumncount(&num_fields_zval, &queryresult_zval, INTERNAL_FUNCTION_PARAM_PASSTHRU)) {
+ FREE_ZVAL(num_fields_zval);
+ if (queryresult_zval) zval_ptr_dtor(&queryresult_zval);
+ return 0;
+ }
+ if (num_fields_zval->value.lval==0) {
+ (*rv)->type=IS_BOOL;
+ (*rv)->value.lval=1; // success, but no data
+ FREE_ZVAL(num_fields_zval);
+ if (queryresult_zval) zval_ptr_dtor(&queryresult_zval);
+ return 1;
+ }
+ FREE_ZVAL(num_fields_zval);
+ MOVE_RETURNED_TO_RV(rv, queryresult_zval);
+ return 1;
+ }
+
+int dbx_odbc_getcolumncount(zval ** rv, zval ** result_handle, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns column-count as long on success or 0 as long on failure
+ int number_of_arguments=1;
+ zval ** arguments[1];
+ zval * returned_zval=NULL;
+
+ arguments[0]=result_handle;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "odbc_num_fields", &returned_zval, number_of_arguments, arguments);
+ if (!returned_zval || returned_zval->type!=IS_LONG || returned_zval->value.lval<0) {
+ if (returned_zval) zval_ptr_dtor(&returned_zval);
+ return 0;
+ }
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+ return 1;
+ }
+
+int dbx_odbc_getcolumnname(zval ** rv, zval ** result_handle, long column_index, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns column-name as string on success or 0 as long on failure
+ int number_of_arguments=2;
+ zval ** arguments[2];
+ zval * zval_column_index;
+ zval * returned_zval=NULL;
+
+ MAKE_STD_ZVAL(zval_column_index);
+ ZVAL_LONG(zval_column_index, column_index+1);
+ arguments[0]=result_handle;
+ arguments[1]=&zval_column_index;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "odbc_field_name", &returned_zval, number_of_arguments, arguments);
+ // odbc_field_name returns a string
+ if (!returned_zval || returned_zval->type!=IS_STRING) {
+ if (returned_zval) zval_ptr_dtor(&returned_zval);
+ FREE_ZVAL(zval_column_index);
+ return 0;
+ }
+ FREE_ZVAL(zval_column_index);
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+ return 1;
+ }
+
+int dbx_odbc_getcolumntype(zval ** rv, zval ** result_handle, long column_index, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns column-type as string on success or 0 as long on failure
+ int number_of_arguments=2;
+ zval ** arguments[2];
+ zval * zval_column_index;
+ zval * returned_zval=NULL;
+
+ MAKE_STD_ZVAL(zval_column_index);
+ ZVAL_LONG(zval_column_index, column_index+1);
+ arguments[0]=result_handle;
+ arguments[1]=&zval_column_index;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "odbc_field_type", &returned_zval, number_of_arguments, arguments);
+ // odbc_field_name returns a string
+ if (!returned_zval || returned_zval->type!=IS_STRING) {
+ if (returned_zval) zval_ptr_dtor(&returned_zval);
+ FREE_ZVAL(zval_column_index);
+ return 0;
+ }
+ FREE_ZVAL(zval_column_index);
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+ return 1;
+ }
+
+int dbx_odbc_getrow(zval ** rv, zval ** result_handle, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns array[0..columncount-1] as strings on success or 0 as long on failure
+ int number_of_arguments;
+ zval ** arguments[2];
+ zval * num_fields_zval=NULL;
+ zval * fetch_row_result_zval=NULL;
+ zval * field_result_zval=NULL;
+ zval * field_index_zval;
+ zval * returned_zval=NULL;
+ long field_index;
+ long field_count=-1;
+
+ // get # fields
+ MAKE_STD_ZVAL(num_fields_zval);
+ if (!dbx_odbc_getcolumncount(&num_fields_zval, result_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU)) {
+ return 0;
+ }
+ field_count=num_fields_zval->value.lval;
+ FREE_ZVAL(num_fields_zval);
+ // fetch row
+ number_of_arguments=1;
+ arguments[0]=result_handle;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "odbc_fetch_row", &fetch_row_result_zval, number_of_arguments, arguments);
+ if (!fetch_row_result_zval || fetch_row_result_zval->type!=IS_BOOL) {
+ if (fetch_row_result_zval) zval_ptr_dtor(&fetch_row_result_zval);
+ return 0;
+ }
+ if (fetch_row_result_zval->value.lval==0) {
+ (*rv)->type=IS_LONG;
+ (*rv)->value.lval=0; // ok, no more rows
+ zval_ptr_dtor(&fetch_row_result_zval);
+ return 0;
+ }
+ zval_ptr_dtor(&fetch_row_result_zval);
+ // fill array with field results...
+ MAKE_STD_ZVAL(returned_zval);
+ if (array_init(returned_zval) != SUCCESS) {
+ zend_error(E_ERROR, "dbx_odbc_getrow: unable to create result-array...");
+ FREE_ZVAL(returned_zval);
+ return 0;
+ }
+ MAKE_STD_ZVAL(field_index_zval);
+ number_of_arguments=2;
+ for (field_index=0; field_index<field_count; ++field_index) {
+ ZVAL_LONG(field_index_zval, field_index+1);
+ arguments[0]=result_handle;
+ arguments[1]=&field_index_zval;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "odbc_result", &field_result_zval, number_of_arguments, arguments);
+ zend_hash_index_update(returned_zval->value.ht, field_index, (void *)&(field_result_zval), sizeof(zval *), NULL);
+ }
+ FREE_ZVAL(field_index_zval);
+
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+ return 1;
+ }
+
+int dbx_odbc_error(zval ** rv, zval ** dbx_handle, INTERNAL_FUNCTION_PARAMETERS) {
+ // returns empty string // no equivalent in odbc module (yet???)
+ ZVAL_EMPTY_STRING((*rv));
+ return 1;
+ }
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/dbx/dbx_odbc.h b/ext/dbx/dbx_odbc.h
new file mode 100644
index 0000000000..003505ed50
--- /dev/null
+++ b/ext/dbx/dbx_odbc.h
@@ -0,0 +1,54 @@
+/*
+ +----------------------------------------------------------------------+
+ | stentor module version 1.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 2001 Guidance Rotterdam BV |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 1.0 of the STENTOR license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at |
+ | http://www.guidance.nl/php/dbx/license/1_00.txt. |
+ | If you did not receive a copy of the STENTOR license and are unable |
+ | to obtain it through the world-wide-web, please send a note to |
+ | license@guidance.nl so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author : Marc Boeren <marc@guidance.nl> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef ZEND_DBX_ODBC_H
+#define ZEND_DBX_ODBC_H
+
+#ifndef INIT_FUNC_ARGS
+#include "zend_modules.h"
+#endif
+
+#include "php.h"
+
+int dbx_odbc_connect(zval ** rv, zval ** host, zval ** db, zval ** username, zval ** password, INTERNAL_FUNCTION_PARAMETERS);
+ // returns connection handle as resource on success or 0 as long on failure
+int dbx_odbc_pconnect(zval ** rv, zval ** host, zval ** db, zval ** username, zval ** password, INTERNAL_FUNCTION_PARAMETERS);
+ // returns persisten connection handle as resource on success or 0 as long on failure
+int dbx_odbc_close(zval ** rv, zval ** dbx_handle, INTERNAL_FUNCTION_PARAMETERS);
+ // returns 1 as long on success or 0 as long on failure
+int dbx_odbc_query(zval ** rv, zval ** dbx_handle, zval ** sql_statement, INTERNAL_FUNCTION_PARAMETERS);
+ // returns 1 as long or a result identifier as resource on success or 0 as long on failure
+int dbx_odbc_getcolumncount(zval ** rv, zval ** result_handle, INTERNAL_FUNCTION_PARAMETERS);
+ // returns column-count as long on success or 0 as long on failure
+int dbx_odbc_getcolumnname(zval ** rv, zval ** result_handle, long column_index, INTERNAL_FUNCTION_PARAMETERS);
+ // returns column-name as string on success or 0 as long on failure
+int dbx_odbc_getcolumntype(zval ** rv, zval ** result_handle, long column_index, INTERNAL_FUNCTION_PARAMETERS);
+ // returns column-type as string on success or 0 as long on failure
+int dbx_odbc_getrow(zval ** rv, zval ** result_handle, INTERNAL_FUNCTION_PARAMETERS);
+ // returns array[0..columncount-1] as strings on success or 0 as long on failure
+int dbx_odbc_error(zval ** rv, zval ** dbx_handle, INTERNAL_FUNCTION_PARAMETERS);
+ // returns string
+
+#endif /* ZEND_DBX_ODBC_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/dbx/php_dbx.h b/ext/dbx/php_dbx.h
new file mode 100644
index 0000000000..4e7f7ae2ac
--- /dev/null
+++ b/ext/dbx/php_dbx.h
@@ -0,0 +1,84 @@
+/*
+ +----------------------------------------------------------------------+
+ | stentor module version 1.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 2001 Guidance Rotterdam BV |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 1.0 of the STENTOR license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at |
+ | http://www.guidance.nl/php/dbx/license/1_00.txt. |
+ | If you did not receive a copy of the STENTOR license and are unable |
+ | to obtain it through the world-wide-web, please send a note to |
+ | license@guidance.nl so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author : Marc Boeren <marc@guidance.nl> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef ZEND_PHP_DBX_H
+#define ZEND_PHP_DBX_H
+
+#ifndef INIT_FUNC_ARGS
+#include "zend_modules.h"
+#endif
+
+extern zend_module_entry dbx_module_entry;
+#define phpext_dbx_ptr &dbx_module_entry
+
+#ifdef ZEND_WIN32
+#define ZEND_DBX_API __declspec(dllexport)
+#else
+#define ZEND_DBX_API
+#endif
+
+ZEND_MINIT_FUNCTION(dbx);
+ZEND_MSHUTDOWN_FUNCTION(dbx);
+//ZEND_RINIT_FUNCTION(dbx);
+//ZEND_RSHUTDOWN_FUNCTION(dbx);
+ZEND_MINFO_FUNCTION(dbx);
+
+ZEND_FUNCTION(dbx_connect);
+ZEND_FUNCTION(dbx_close);
+ZEND_FUNCTION(dbx_query);
+ZEND_FUNCTION(dbx_error);
+
+ZEND_FUNCTION(dbx_sort);
+ZEND_FUNCTION(dbx_cmp_asc);
+ZEND_FUNCTION(dbx_cmp_desc);
+
+ZEND_FUNCTION(dbx_test);
+
+/*
+ Declare any global variables you may need between the BEGIN
+ and END macros here:
+*/
+//ZEND_BEGIN_MODULE_GLOBALS(dbx)
+// void * dbx_global;
+//ZEND_END_MODULE_GLOBALS(dbx)
+
+
+/* In every function that needs to use variables in php_dbx_globals,
+ do call dbxLS_FETCH(); after declaring other variables used by
+ that function, and always refer to them as dbxG(variable).
+ You are encouraged to rename these macros something shorter, see
+ examples in any other php module directory.
+*/
+
+#ifdef ZTS
+#define DBXG(v) (dbx_globals->v)
+#define DBXLS_FETCH() zend_dbx_globals *dbx_globals = ts_resource(dbx_globals_id)
+#else
+#define DBXG(v) (dbx_globals.v)
+#define DBXLS_FETCH()
+#endif
+
+#endif /* ZEND_PHP_DBX_H */
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */