mboeren         Thu Mar 22 03:07:04 2001 EDT

  Added files:                 
    /php4/ext/dbx       CREDITS INSTALL LICENSE Makefile.in config.m4 dbx.c 
                        dbx.dsp dbx.h dbx_mysql.c dbx_mysql.h dbx_odbc.c 
                        dbx_odbc.h php_dbx.h 
  Log:
  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)
  
  

Index: php4/ext/dbx/Makefile.in
+++ php4/ext/dbx/Makefile.in

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

Index: php4/ext/dbx/config.m4
+++ php4/ext/dbx/config.m4

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

Index: php4/ext/dbx/dbx.c
+++ php4/ext/dbx/dbx.c
/*
   +----------------------------------------------------------------------+
   | 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       |
   | [EMAIL PROTECTED] so we can mail you a copy immediately.           |
   +----------------------------------------------------------------------+
   | Author : Marc Boeren         <[EMAIL PROTECTED]>                      |
   +----------------------------------------------------------------------+
 */

#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:
 */

Index: php4/ext/dbx/dbx.dsp
+++ php4/ext/dbx/dbx.dsp
# 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

Index: php4/ext/dbx/dbx.h
+++ php4/ext/dbx/dbx.h
/*
   +----------------------------------------------------------------------+
   | 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       |
   | [EMAIL PROTECTED] so we can mail you a copy immediately.           |
   +----------------------------------------------------------------------+
   | Author : Marc Boeren         <[EMAIL PROTECTED]>                      |
   +----------------------------------------------------------------------+
 */

#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:
 */

Index: php4/ext/dbx/dbx_mysql.c
+++ php4/ext/dbx/dbx_mysql.c
/*
   +----------------------------------------------------------------------+
   | 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       |
   | [EMAIL PROTECTED] so we can mail you a copy immediately.           |
   +----------------------------------------------------------------------+
   | Author : Marc Boeren         <[EMAIL PROTECTED]>                      |
   +----------------------------------------------------------------------+
 */

#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:
 */

Index: php4/ext/dbx/dbx_mysql.h
+++ php4/ext/dbx/dbx_mysql.h
/*
   +----------------------------------------------------------------------+
   | 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       |
   | [EMAIL PROTECTED] so we can mail you a copy immediately.           |
   +----------------------------------------------------------------------+
   | Author : Marc Boeren         <[EMAIL PROTECTED]>                      |
   +----------------------------------------------------------------------+
 */

#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:
 */

Index: php4/ext/dbx/dbx_odbc.c
+++ php4/ext/dbx/dbx_odbc.c
/*
   +----------------------------------------------------------------------+
   | 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       |
   | [EMAIL PROTECTED] so we can mail you a copy immediately.           |
   +----------------------------------------------------------------------+
   | Author : Marc Boeren         <[EMAIL PROTECTED]>                      |
   +----------------------------------------------------------------------+
 */

#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:
 */

Index: php4/ext/dbx/dbx_odbc.h
+++ php4/ext/dbx/dbx_odbc.h
/*
   +----------------------------------------------------------------------+
   | 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       |
   | [EMAIL PROTECTED] so we can mail you a copy immediately.           |
   +----------------------------------------------------------------------+
   | Author : Marc Boeren         <[EMAIL PROTECTED]>                      |
   +----------------------------------------------------------------------+
 */

#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:
 */

Index: php4/ext/dbx/php_dbx.h
+++ php4/ext/dbx/php_dbx.h
/*
   +----------------------------------------------------------------------+
   | 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       |
   | [EMAIL PROTECTED] so we can mail you a copy immediately.           |
   +----------------------------------------------------------------------+
   | Author : Marc Boeren         <[EMAIL PROTECTED]>                      |
   +----------------------------------------------------------------------+
 */

#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:
 */

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to