From ce79b44c278fcae832a5a8faddd14b13008b4daa Mon Sep 17 00:00:00 2001 From: Marc Boeren Date: Thu, 22 Mar 2001 11:07:04 +0000 Subject: 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) --- ext/dbx/CREDITS | 2 + ext/dbx/INSTALL | 25 ++ ext/dbx/LICENSE | 71 +++++ ext/dbx/Makefile.in | 6 + ext/dbx/config.m4 | 7 + ext/dbx/dbx.c | 832 ++++++++++++++++++++++++++++++++++++++++++++++++++++ ext/dbx/dbx.dsp | 141 +++++++++ ext/dbx/dbx.h | 45 +++ ext/dbx/dbx_mysql.c | 217 ++++++++++++++ ext/dbx/dbx_mysql.h | 54 ++++ ext/dbx/dbx_odbc.c | 239 +++++++++++++++ ext/dbx/dbx_odbc.h | 54 ++++ ext/dbx/php_dbx.h | 84 ++++++ 13 files changed, 1777 insertions(+) create mode 100644 ext/dbx/CREDITS create mode 100644 ext/dbx/INSTALL create mode 100644 ext/dbx/LICENSE create mode 100644 ext/dbx/Makefile.in create mode 100644 ext/dbx/config.m4 create mode 100644 ext/dbx/dbx.c create mode 100644 ext/dbx/dbx.dsp create mode 100644 ext/dbx/dbx.h create mode 100644 ext/dbx/dbx_mysql.c create mode 100644 ext/dbx/dbx_mysql.h create mode 100644 ext/dbx/dbx_odbc.c create mode 100644 ext/dbx/dbx_odbc.h create mode 100644 ext/dbx/php_dbx.h 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 . + +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 . 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 | + +----------------------------------------------------------------------+ + */ + +#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()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_indexvalue.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_indexvalue.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_countvalue.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_indexvalue.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 | + +----------------------------------------------------------------------+ + */ + +#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 | + +----------------------------------------------------------------------+ + */ + +#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 | + +----------------------------------------------------------------------+ + */ + +#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 | + +----------------------------------------------------------------------+ + */ + +#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_indexvalue.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 | + +----------------------------------------------------------------------+ + */ + +#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 | + +----------------------------------------------------------------------+ + */ + +#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: + */ -- cgit v1.2.1