Logo Search packages:      
Sourcecode: maxdb-7.5.00 version File versions

php_maxdb.c

Go to the documentation of this file.
/*
-------------------------------------------------------------------- 
                  The PHP License, version 3.0
Copyright (c) 1999 - 2005 The PHP Group. 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 "PHP" must not be used to endorse or promote products
     derived from this software without prior written permission. For
     written permission, please contact group@php.net.
  
  4. Products derived from this software may not be called "PHP", nor
     may "PHP" appear in their name, without prior written permission
     from group@php.net.  You may indicate that your software works in
     conjunction with PHP by saying "Foo for PHP" instead of calling
     it "PHP Foo" or "phpfoo"
 
  5. The PHP Group 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 the PHP Group. No one other than the PHP Group has
     the right to modify the terms applicable to covered code created
     under this License.

  6. Redistributions of any form whatsoever must retain the following
     acknowledgment:
     "This product includes PHP, freely available from
     <http://www.php.net/>".

THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``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 THE PHP
DEVELOPMENT TEAM 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.

-------------------------------------------------------------------- 

This software consists of voluntary contributions made by many
individuals on behalf of the PHP Group.

The PHP Group can be contacted via Email at group@php.net.

For more information on the PHP Group and the PHP project, 
please see <http://www.php.net>.

This product includes the Zend Engine, freely available at
<http://www.zend.com>.
*/


/*!
@file           php_maxdb.c
@author         Thomas Simenec (thomas.simenec@sap.com)
@ingroup        PHP MaxDB
@brief          PHP MaxDB - PHP driver for the MaxDB database
@see            
*/

#if WIN32
#include <process.h>
#else
#include <unistd.h>
#endif
#include <string.h>

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_maxdb.h"
#ifdef MAXDB_OO
#include "zend_exceptions.h"
#endif

#define MAXDB_COMPNAME            0
#define MAXDB_APPLICATION         1
#define MAXDB_APPVERSION          2
#define MAXDB_SQLMODE             3
#define MAXDB_UNICODE             4
#define MAXDB_TIMEOUT             5
#define MAXDB_ISOLATIONLEVEL      6
#define MAXDB_PACKETCOUNT         7
#define MAXDB_STATEMENTCACHESIZE  8
#define MAXDB_CURSORPREFIX        9

#define MAXDB_COLUMN_NAME_LENGTH 4096

enum Command {
        C_NONE                   = 0,

        C_TRACE_SHORT,
        C_TRACE_LONG,
        C_TRACE_PACKET,
        C_TRACE_SQL,
        C_TRACE_TIMESTAMP,
        C_TRACE_SIZE,
};

static char *maxdb_optionlist[] = { "COMPNAME",
                                    "APPLICATION",
                                    "APPVERSION",
                                    "SQLMODE",
                                    "UNICODE",
                                    "TIMEOUT",
                                    "ISOLATIONLEVEL",
                                    "PACKETCOUNT",
                                    "STATEMENTCACHESIZE",
                                    "CURSORPREFIX" };


#define MAXDB_STORE_RESULT 0
#define MAXDB_USE_RESULT   1

#define MAXDB_ASSOC           1<<0
#define MAXDB_ASSOC_UPPER 1<<2
#define MAXDB_ASSOC_LOWER 1<<3
#define MAXDB_NUM         1<<1
#define MAXDB_BOTH        (MAXDB_ASSOC|MAXDB_NUM)

#define MAXDB_PROTOCOL_VERSION 10

#define LONG_READLEN "200"

#define MAXDB_MAX(a,b) ((a) > (b) ? (a) : (b))
#define MAXDB_MIN(a,b) ((a) < (b) ? (a) : (b))

#define CHECK_MAXDB_CONNECTION(conn) { if (conn == -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "A connection to the server could not be established"); RETURN_FALSE; } }

#ifdef MAXDB_OO
#define MAXDB_MAP_PROPERTY_FUNC_LONG( __func, __int_func, __get_type, __ret_type)\
int __func(maxdb_object *obj, zval **retval TSRMLS_DC) \
{\
      __ret_type l;\
      __get_type;\
      ALLOC_ZVAL(*retval);\
      if (!p) {\
            ZVAL_NULL(*retval);\
      } else {\
            l = (__ret_type)__int_func(p TSRMLS_CC); \
            if (l < LONG_MAX) {\
                  ZVAL_LONG(*retval, l);\
            } else { \
                  char ret[40]; \
                  sprintf(ret, "%d", (int)l); \
                  ZVAL_STRING(*retval, ret, 1); \
            } \
      }\
      return SUCCESS;\
}

#define MAXDB_MAP_PROPERTY_FUNC_STRING(__func, __int_func, __get_type)\
int __func(maxdb_object *obj, zval **retval TSRMLS_DC) \
{\
      char *c;\
      __get_type;\
      ALLOC_ZVAL(*retval);\
      if (!p) {\
            ZVAL_NULL(*retval);\
      } else {\
            c = (char *)__int_func(p TSRMLS_CC);\
            if (!c) {\
                  ZVAL_NULL(*retval);\
            } else {\
                  ZVAL_STRING(*retval, c, 1);\
            }\
      }\
      return SUCCESS;\
}

#define MAXDB_GET_MAXDB() \
maxdb_connection *p = (maxdb_connection *)((MAXDB_RESOURCE *)(obj->ptr))->ptr

#define MAXDB_GET_RESULT() \
maxdb_result *p = (maxdb_result *)((MAXDB_RESOURCE *)(obj->ptr))->ptr

#define MAXDB_GET_STMT() \
maxdb_prepstmt *p = (maxdb_prepstmt *)((MAXDB_RESOURCE *)(obj->ptr))->ptr

typedef struct _maxdb_property_entry {
      char *pname;
      int (*r_func)(maxdb_object *obj, zval **retval TSRMLS_DC);
      int (*w_func)(maxdb_object *obj, zval **retval TSRMLS_DC);
} maxdb_property_entry;

typedef int (*maxdb_read_t)(maxdb_object *obj, zval **retval TSRMLS_DC);
typedef int (*maxdb_write_t)(maxdb_object *obj, zval *newval TSRMLS_DC);

typedef struct _maxdb_prop_handler {
      maxdb_read_t read_func;
      maxdb_write_t write_func;
} maxdb_prop_handler;

static int   maxdb_prop_affected_rows(maxdb_connection *conn TSRMLS_DC);
static char *maxdb_prop_get_client_info (maxdb_connection *conn TSRMLS_DC);
static int   maxdb_prop_get_client_version (maxdb_connection *conn TSRMLS_DC);
static int   maxdb_prop_connect_errno (maxdb_connection *conn TSRMLS_DC);
static char *maxdb_prop_connect_error (maxdb_connection *conn TSRMLS_DC);
static int   maxdb_prop_errno (maxdb_connection *conn TSRMLS_DC);
static char *maxdb_prop_error (maxdb_connection *conn TSRMLS_DC);
static int   maxdb_prop_field_count (maxdb_connection *conn TSRMLS_DC);
static char *maxdb_prop_get_host_info(maxdb_connection *conn TSRMLS_DC);
static char *maxdb_prop_info (maxdb_connection *conn TSRMLS_DC);
static int   maxdb_prop_insert_id (maxdb_connection *conn TSRMLS_DC);
static int   maxdb_prop_get_proto_info (maxdb_connection *conn TSRMLS_DC);
static char *maxdb_prop_get_server_info (maxdb_connection *conn TSRMLS_DC);
static int   maxdb_prop_get_server_version (maxdb_connection *conn TSRMLS_DC);
static char *maxdb_prop_sqlstate (maxdb_connection *conn TSRMLS_DC);
static int   maxdb_prop_thread_id (maxdb_connection *conn TSRMLS_DC);
static int   maxdb_prop_warning_count (maxdb_connection *conn TSRMLS_DC);

static int   maxdb_result_lengths_read(maxdb_object *obj, zval **retval TSRMLS_DC);
static int   maxdb_prop_type_read (maxdb_result *result TSRMLS_DC);
static int   maxdb_prop_field_tell (maxdb_result *result TSRMLS_DC);
static int   maxdb_result_field_count_read (maxdb_object *obj, zval **retval TSRMLS_DC);
static int   maxdb_prop_num_rows (maxdb_result *result TSRMLS_DC);

static int   maxdb_prop_stmt_affected_rows(maxdb_prepstmt *stmt TSRMLS_DC);
static int   maxdb_prop_stmt_insert_id(maxdb_prepstmt *stmt TSRMLS_DC);
static int   maxdb_prop_stmt_num_rows(maxdb_prepstmt *stmt TSRMLS_DC);
static int   maxdb_prop_stmt_param_count(maxdb_prepstmt *stmt TSRMLS_DC);
static int   maxdb_prop_stmt_field_count(maxdb_prepstmt *stmt TSRMLS_DC);
static int   maxdb_prop_stmt_errno(maxdb_prepstmt *stmt TSRMLS_DC);
static char *maxdb_prop_stmt_error(maxdb_prepstmt *stmt TSRMLS_DC);
static char *maxdb_prop_stmt_sqlstate(maxdb_prepstmt *stmt TSRMLS_DC);

/* link properties */
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_link_affected_rows_read, maxdb_prop_affected_rows, MAXDB_GET_MAXDB(), int);
MAXDB_MAP_PROPERTY_FUNC_STRING(maxdb_link_client_info_read, maxdb_prop_get_client_info, MAXDB_GET_MAXDB());
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_link_client_version_read, maxdb_prop_get_client_version, MAXDB_GET_MAXDB(), int);
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_link_connect_errno_read, maxdb_prop_connect_errno, MAXDB_GET_MAXDB(), int);
MAXDB_MAP_PROPERTY_FUNC_STRING(maxdb_link_connect_error_read, maxdb_prop_connect_error, MAXDB_GET_MAXDB());
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_link_errno_read, maxdb_prop_errno, MAXDB_GET_MAXDB(), int);
MAXDB_MAP_PROPERTY_FUNC_STRING(maxdb_link_error_read, maxdb_prop_error, MAXDB_GET_MAXDB());
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_link_field_count_read, maxdb_prop_field_count, MAXDB_GET_MAXDB(), int);
MAXDB_MAP_PROPERTY_FUNC_STRING(maxdb_link_host_info_read, maxdb_prop_get_host_info, MAXDB_GET_MAXDB());
MAXDB_MAP_PROPERTY_FUNC_STRING(maxdb_link_info_read, maxdb_prop_info, MAXDB_GET_MAXDB());
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_link_insert_id_read, maxdb_prop_insert_id, MAXDB_GET_MAXDB(), int);
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_link_protocol_version_read, maxdb_prop_get_proto_info, MAXDB_GET_MAXDB(), int);
MAXDB_MAP_PROPERTY_FUNC_STRING(maxdb_link_server_info_read, maxdb_prop_get_server_info, MAXDB_GET_MAXDB());
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_link_server_version_read, maxdb_prop_get_server_version, MAXDB_GET_MAXDB(), int);
MAXDB_MAP_PROPERTY_FUNC_STRING(maxdb_link_sqlstate_read, maxdb_prop_sqlstate, MAXDB_GET_MAXDB());
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_link_thread_id_read, maxdb_prop_thread_id, MAXDB_GET_MAXDB(), int);
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_link_warning_count_read, maxdb_prop_warning_count, MAXDB_GET_MAXDB(), int);

MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_result_type_read, maxdb_prop_type_read, MAXDB_GET_RESULT(), int);
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_result_current_field_read, maxdb_prop_field_tell, MAXDB_GET_RESULT(), int);
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_result_num_rows_read, maxdb_prop_num_rows, MAXDB_GET_RESULT(), int);

/* statement properties */
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_stmt_affected_rows_read, maxdb_prop_stmt_affected_rows, MAXDB_GET_STMT(), int);
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_stmt_insert_id_read, maxdb_prop_stmt_insert_id, MAXDB_GET_STMT(), int);
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_stmt_num_rows_read, maxdb_prop_stmt_num_rows, MAXDB_GET_STMT(), int);
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_stmt_param_count_read, maxdb_prop_stmt_param_count, MAXDB_GET_STMT(), int);
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_stmt_field_count_read, maxdb_prop_stmt_field_count, MAXDB_GET_STMT(), int);
MAXDB_MAP_PROPERTY_FUNC_LONG(maxdb_stmt_errno_read, maxdb_prop_stmt_errno, MAXDB_GET_STMT(), int);
MAXDB_MAP_PROPERTY_FUNC_STRING(maxdb_stmt_error_read, maxdb_prop_stmt_error, MAXDB_GET_STMT());
MAXDB_MAP_PROPERTY_FUNC_STRING(maxdb_stmt_sqlstate_read, maxdb_prop_stmt_sqlstate, MAXDB_GET_STMT());

maxdb_property_entry maxdb_link_property_entries[] = {
      {"affected_rows", maxdb_link_affected_rows_read, NULL},
      {"client_info", maxdb_link_client_info_read, NULL},
      {"client_version", maxdb_link_client_version_read, NULL},
      {"connect_errno", maxdb_link_connect_errno_read, NULL},
      {"connect_error", maxdb_link_connect_error_read, NULL},
      {"errno", maxdb_link_errno_read, NULL},
      {"error", maxdb_link_error_read, NULL},
    {"field_count", maxdb_link_field_count_read, NULL},
      {"host_info", maxdb_link_host_info_read, NULL},
      {"info", maxdb_link_info_read, NULL},
      {"insert_id", maxdb_link_insert_id_read, NULL},
      {"server_info", maxdb_link_server_info_read, NULL},
      {"server_version", maxdb_link_server_version_read, NULL},
      {"sqlstate", maxdb_link_sqlstate_read, NULL},
      {"protocol_version", maxdb_link_protocol_version_read, NULL},
      {"thread_id", maxdb_link_thread_id_read, NULL},
      {"warning_count", maxdb_link_warning_count_read, NULL},
      {NULL, NULL, NULL}
};

maxdb_property_entry maxdb_result_property_entries[] = {
      {"current_field", maxdb_result_current_field_read, NULL},
      {"field_count", maxdb_result_field_count_read, NULL},
      {"lengths", maxdb_result_lengths_read, NULL},
      {"num_rows", maxdb_result_num_rows_read, NULL},
      {"type", maxdb_result_type_read, NULL},
      {NULL, NULL, NULL}
};

maxdb_property_entry maxdb_stmt_property_entries[] = {
      {"affected_rows", maxdb_stmt_affected_rows_read, NULL},
      {"insert_id", maxdb_stmt_insert_id_read, NULL},
      {"num_rows", maxdb_stmt_num_rows_read, NULL},
      {"param_count", maxdb_stmt_param_count_read, NULL},
      {"field_count", maxdb_stmt_field_count_read, NULL}, 
      {"errno", maxdb_stmt_errno_read, NULL},
      {"error", maxdb_stmt_error_read, NULL},
      {"sqlstate", maxdb_stmt_sqlstate_read, NULL},
      {NULL, NULL, NULL}
};

/* {{{ maxdb_link_methods[]
 *
 * Every user visible function must have an entry in maxdb_functions[].
 */
function_entry maxdb_link_methods[] = {
      PHP_FALIAS(autocommit,maxdb_autocommit,NULL)
      PHP_FALIAS(change_user,maxdb_change_user,NULL)
      PHP_FALIAS(character_set_name,maxdb_character_set_name,NULL)
      PHP_FALIAS(client_encoding, maxdb_character_set_name,NULL)
      PHP_FALIAS(close,maxdb_close,NULL)
      PHP_FALIAS(commit,maxdb_commit,NULL)
      PHP_FALIAS(connect,maxdb_connect,NULL)
      PHP_FALIAS(debug,maxdb_debug,NULL)
      PHP_FALIAS(disable_reads_from_master,maxdb_disable_reads_from_master,NULL)
      PHP_FALIAS(disable_rpl_parse,maxdb_disable_rpl_parse,NULL)
      PHP_FALIAS(dump_debug_info,maxdb_dump_debug_info,NULL)
      PHP_FALIAS(enable_reads_from_master,maxdb_enable_reads_from_master,NULL)
      PHP_FALIAS(enable_rpl_parse,maxdb_enable_rpl_parse,NULL)
    PHP_FALIAS(field_count,maxdb_field_count,NULL)
      PHP_FALIAS(get_client_info,maxdb_get_client_info,NULL)
      PHP_FALIAS(get_server_info,maxdb_get_server_info,NULL)
      PHP_FALIAS(init,maxdb_init,NULL)
      PHP_FALIAS(kill,maxdb_kill,NULL)
      PHP_FALIAS(master_query,maxdb_master_query,NULL)
      PHP_FALIAS(multi_query,maxdb_multi_query,NULL)
      PHP_FALIAS(more_results,maxdb_more_results, NULL)
      PHP_FALIAS(maxdb, maxdb_connect, NULL)
      PHP_FALIAS(next_result, maxdb_next_result, NULL)
      PHP_FALIAS(options,maxdb_options,NULL)
      PHP_FALIAS(ping,maxdb_ping,NULL)
      PHP_FALIAS(prepare,maxdb_prepare,NULL)
      PHP_FALIAS(query,maxdb_query,NULL)
      PHP_FALIAS(real_connect,maxdb_real_connect,NULL)
      PHP_FALIAS(real_escape_string,maxdb_real_escape_string,NULL)
      PHP_FALIAS(escape_string, maxdb_real_escape_string,NULL)
      PHP_FALIAS(real_query,maxdb_real_query,NULL)
      PHP_FALIAS(rollback,maxdb_rollback,NULL)
      PHP_FALIAS(rpl_parse_enabled,maxdb_rpl_parse_enabled,NULL)
      PHP_FALIAS(rpl_probe,maxdb_rpl_probe,NULL)
      PHP_FALIAS(rpl_query_type,maxdb_rpl_query_type,NULL)
      PHP_FALIAS(select_db,maxdb_select_db,NULL)
      PHP_FALIAS(set_opt, maxdb_options,NULL)
      PHP_FALIAS(ssl_set,maxdb_ssl_set,NULL)
      PHP_FALIAS(stat,maxdb_stat,NULL)
      PHP_FALIAS(stmt_init,maxdb_stmt_init, NULL)
      PHP_FALIAS(store_result,maxdb_store_result,NULL)
      PHP_FALIAS(use_result,maxdb_use_result,NULL)
      {NULL, NULL, NULL}
};
/* }}} */

/* {{{ maxdb_result_methods[]
 *
 * Every user visible function must have an entry in maxdb_result_functions[].
 */
function_entry maxdb_result_methods[] = {
      PHP_FALIAS(close,maxdb_free_result,NULL)
      PHP_FALIAS(free,maxdb_free_result,NULL)
      PHP_FALIAS(data_seek,maxdb_data_seek,NULL)
      PHP_FALIAS(fetch_field,maxdb_fetch_field,NULL)
      PHP_FALIAS(fetch_fields,maxdb_fetch_fields,NULL)
      PHP_FALIAS(fetch_field_direct,maxdb_fetch_field_direct,NULL)
      PHP_FALIAS(fetch_array,maxdb_fetch_array,NULL)
      PHP_FALIAS(fetch_assoc,maxdb_fetch_assoc,NULL) 
      PHP_FALIAS(fetch_object,maxdb_fetch_object,NULL) 
      PHP_FALIAS(fetch_row,maxdb_fetch_row,NULL)
      PHP_FALIAS(field_count,maxdb_field_count,NULL)
      PHP_FALIAS(field_seek,maxdb_field_seek,NULL)
      PHP_FALIAS(free_result,maxdb_free_result,NULL)
      {NULL, NULL, NULL}
};
/* }}} */

/* {{{ maxdb_stmt_methods[]
 *
 * Every user visible function must have an entry in maxdb_stmt_functions[].
 */
function_entry maxdb_stmt_methods[] = {
      /* PHP_FALIAS(attr_get,maxdb_stmt_attr_get,NULL)
       PHP_FALIAS(attr_set,maxdb_stmt_attr_set,NULL) */
      PHP_FALIAS(bind_param,maxdb_stmt_bind_param,second_arg_force_by_ref_rest)
      PHP_FALIAS(bind_result,maxdb_stmt_bind_result,all_args_force_by_ref)
      PHP_FALIAS(close,maxdb_stmt_close,NULL)
      PHP_FALIAS(data_seek,maxdb_stmt_data_seek,NULL)
      PHP_FALIAS(execute,maxdb_stmt_execute,NULL)
      PHP_FALIAS(fetch,maxdb_stmt_fetch,NULL)
      PHP_FALIAS(result_metadata, maxdb_stmt_result_metadata,NULL)
      PHP_FALIAS(num_rows, maxdb_stmt_num_rows,NULL)
      PHP_FALIAS(send_long_data,maxdb_stmt_send_long_data,NULL)
      PHP_FALIAS(stmt,maxdb_prepare,NULL)
      PHP_FALIAS(free_result,maxdb_stmt_free_result,NULL)
      PHP_FALIAS(reset,maxdb_stmt_reset,NULL)
      PHP_FALIAS(prepare,maxdb_stmt_prepare, NULL)
      PHP_FALIAS(store_result,maxdb_stmt_store_result,NULL)
      {NULL, NULL, NULL}
};
/* }}} */

#endif

00426 typedef enum
{
00428     PHP_ERR_UNKNOWN,                  //!< Unknown error.   
    PHP_ERR_INITIALIZATION_FAILED_S,
    PHP_ERR_SESSION_NOT_CONNECTED,
    PHP_ERR_CANNOT_GET_COLUMNNAME_D,
    PHP_ERR_NO_RESULTSET,
    PHP_ERR_STATEMENT_NOT_PREPARED,
    PHP_ERR_INVALID_PARAMETER_INDEX_D,
    PHP_ERR_LONG_COLUMN_TRUNCATED_D,
    PHP_ERR_PARAMETER_NOT_SET_D,
    PHP_ERR_PARAMETER_CNT_MISMATCH,
    PHP_ERR_CMD_OUT_OF_SYNC,
    PHP_ERR_SYNTAX_ERROR_S
} php_maxdb_errorcode;

typedef struct php_maxdb_errordata
{
    php_maxdb_errorcode applcode;
    SQLDBC_Int4         errorcode;
    const char*         sqlstate;
    const char*         msgformat;
} php_maxdb_errordata;

static php_maxdb_errordata errordata[] = 
{
    { PHP_ERR_UNKNOWN,                   -11100 ,  "",     "Unknown error"    },
    { PHP_ERR_INITIALIZATION_FAILED_S  , -11101 ,  "",     "Initialization failed [%s]." },
    { PHP_ERR_SESSION_NOT_CONNECTED    , -11104 ,  "",     "Session not connected."},
    { PHP_ERR_CANNOT_GET_COLUMNNAME_D  , -11105 ,  "",     "Cannot get column name for column %d."},
    { PHP_ERR_NO_RESULTSET             , -11106 ,  "",     "No resultset found."},
    { PHP_ERR_STATEMENT_NOT_PREPARED   , -11107 ,  "",     "Statement not prepared."},
    { PHP_ERR_INVALID_PARAMETER_INDEX_D, -11108 ,  "",     "Invalid parameter index %d."},
    { PHP_ERR_LONG_COLUMN_TRUNCATED_D,   -11109 ,  "",     "Column/Parameter %d truncated. Maybe maxdb.long_readlen is too small"},
    { PHP_ERR_PARAMETER_NOT_SET_D,       -11111 ,  "07002","Parameter/Column (%d) not bound."},
      { PHP_ERR_PARAMETER_CNT_MISMATCH,    -11113 ,  "",     "Number of parameters doesn't match number of result columns."},
    { PHP_ERR_CMD_OUT_OF_SYNC,           -11114 ,  "",     "Commands out of sync. You can't use this command now."},
    { PHP_ERR_SYNTAX_ERROR_S,            -11115 ,  "",     "Syntax error. Expected: %s."}
};

/* If you declare any globals in php_maxdb.h uncomment this: */
ZEND_DECLARE_MODULE_GLOBALS(maxdb)


#ifndef MAXDB_OO
/* True global resources - no need for thread safety here */
static int le_conn, le_result, le_prepstmt;
#endif
       
/* {{{ maxdb_functions[]
 *
 * Every user visible function must have an entry in maxdb_functions[].
 */
function_entry maxdb_functions[] = {
    PHP_FE(maxdb_debug, NULL)
      PHP_FE(maxdb_enable_reads_from_master, NULL)
      PHP_FE(maxdb_disable_reads_from_master, NULL)
      PHP_FE(maxdb_enable_rpl_parse, NULL)
      PHP_FE(maxdb_disable_rpl_parse, NULL)
      PHP_FE(maxdb_rpl_parse_enabled, NULL)
      PHP_FE(maxdb_rpl_probe, NULL)
      PHP_FE(maxdb_rpl_query_type, NULL)
      PHP_FE(maxdb_dump_debug_info, NULL)
      PHP_FE(maxdb_embedded_connect, NULL)
      PHP_FE(maxdb_select_db, NULL)
      PHP_FE(maxdb_stat, NULL)
      PHP_FE(maxdb_thread_id, NULL)
      PHP_FE(maxdb_get_proto_info, NULL)
      PHP_FE(maxdb_get_server_info, NULL)
      PHP_FE(maxdb_server_init, NULL)
      PHP_FE(maxdb_server_end, NULL)
      PHP_FE(maxdb_get_server_version, NULL)
      PHP_FE(maxdb_get_client_info, NULL)
      PHP_FE(maxdb_get_client_version, NULL)
      PHP_FE(maxdb_get_host_info, NULL)
      PHP_FE(maxdb_autocommit, NULL)
      PHP_FE(maxdb_report, NULL)
      PHP_FE(maxdb_options, NULL)
      PHP_FE(maxdb_init, NULL)
      PHP_FE(maxdb_real_connect, NULL)
      PHP_FE(maxdb_ssl_set, NULL)
    PHP_FE(maxdb_connect, NULL)
      PHP_FE(maxdb_connect_errno, NULL)
      PHP_FE(maxdb_connect_error, NULL)
      PHP_FE(maxdb_rollback, NULL)
      PHP_FE(maxdb_kill, NULL)
      PHP_FE(maxdb_change_user, NULL)
      PHP_FE(maxdb_insert_id, NULL)
      PHP_FE(maxdb_real_escape_string, NULL)
      PHP_FE(maxdb_query, NULL)
      PHP_FE(maxdb_send_query, NULL)
      PHP_FE(maxdb_real_query, NULL)
      PHP_FE(maxdb_master_query, NULL)
      PHP_FE(maxdb_multi_query, NULL)
      PHP_FE(maxdb_store_result, NULL)
      PHP_FE(maxdb_use_result, NULL)
      PHP_FE(maxdb_next_result, NULL)
      PHP_FE(maxdb_more_results, NULL)
      PHP_FE(maxdb_sqlstate, NULL)
    PHP_FE(maxdb_prepare, NULL)
      PHP_FE(maxdb_stmt_init, NULL)
      PHP_FE(maxdb_stmt_prepare, NULL)
      PHP_FE(maxdb_stmt_execute, NULL)
      PHP_FE(maxdb_stmt_errno, NULL)
      PHP_FE(maxdb_stmt_error, NULL)
      PHP_FE(maxdb_stmt_affected_rows, NULL)
      PHP_FE(maxdb_stmt_sqlstate, NULL)
      PHP_FE(maxdb_stmt_param_count, NULL)
      PHP_FE(maxdb_stmt_num_rows, NULL)
    PHP_FE(maxdb_stmt_bind_param, third_arg_force_by_ref_rest)
      PHP_FE(maxdb_stmt_bind_result, second_arg_force_by_ref_rest)
      PHP_FE(maxdb_stmt_fetch, NULL)
      PHP_FE(maxdb_stmt_data_seek, NULL)
      PHP_FE(maxdb_stmt_send_long_data, NULL)
      PHP_FE(maxdb_stmt_close_long_data, NULL)
      PHP_FE(maxdb_stmt_store_result, NULL)
      PHP_FE(maxdb_stmt_free_result, NULL)
      PHP_FE(maxdb_stmt_reset, NULL)
      PHP_FE(maxdb_stmt_close, NULL)
      PHP_FE(maxdb_stmt_result_metadata, NULL)
      PHP_FE(maxdb_free_result, NULL)
      PHP_FE(maxdb_data_seek, NULL)
    PHP_FE(maxdb_fetch_row, NULL)
    PHP_FE(maxdb_fetch_assoc, NULL)
    PHP_FE(maxdb_fetch_array, NULL)
    PHP_FE(maxdb_fetch_object, NULL)
    PHP_FE(maxdb_num_fields, NULL)
      PHP_FE(maxdb_num_rows, NULL)
    PHP_FE(maxdb_fetch_field, NULL)
    PHP_FE(maxdb_fetch_fields, NULL)
      PHP_FE(maxdb_fetch_field_direct, NULL)
      PHP_FE(maxdb_fetch_lengths, NULL)
      PHP_FE(maxdb_field_count, NULL)
      PHP_FE(maxdb_field_seek, NULL)
      PHP_FE(maxdb_field_tell, NULL)
      PHP_FE(maxdb_affected_rows, NULL)
      PHP_FE(maxdb_info, NULL)
      PHP_FE(maxdb_character_set_name, NULL)
      PHP_FE(maxdb_ping, NULL)
      PHP_FE(maxdb_error, NULL)
    PHP_FE(maxdb_errno, NULL)
      PHP_FE(maxdb_warning_count, NULL)
      PHP_FE(maxdb_close, NULL)
      PHP_FE(maxdb_commit, NULL)

      /* Aliases */
      PHP_FALIAS(maxdb_bind_param, maxdb_stmt_bind_param,   third_arg_force_by_ref_rest)
      PHP_FALIAS(maxdb_execute, maxdb_stmt_execute, NULL)
      PHP_FALIAS(maxdb_bind_result, maxdb_stmt_bind_result, second_arg_force_by_ref_rest)
      PHP_FALIAS(maxdb_fetch, maxdb_stmt_fetch, NULL)
      PHP_FALIAS(maxdb_send_long_data, maxdb_stmt_send_long_data, NULL)
      PHP_FALIAS(maxdb_close_long_data, maxdb_stmt_close_long_data, NULL)
      PHP_FALIAS(maxdb_client_encoding, maxdb_character_set_name, NULL)
      PHP_FALIAS(maxdb_get_metadata, maxdb_stmt_result_metadata, NULL)
      PHP_FALIAS(maxdb_set_opt, maxdb_options, NULL)
      PHP_FALIAS(maxdb_param_count, maxdb_stmt_param_count, NULL)
      PHP_FALIAS(maxdb_escape_string, maxdb_real_escape_string, NULL)
      {NULL, NULL, NULL}      /* Must be the last line in maxdb_functions[] */
};
/* }}} */


/* {{{ maxdb_module_entry
*/
zend_module_entry maxdb_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
      STANDARD_MODULE_HEADER,
#endif
      "maxdb",
      maxdb_functions,
      PHP_MINIT(maxdb),
      PHP_MSHUTDOWN(maxdb),
      PHP_RINIT(maxdb),       /* Replace with NULL if there's nothing to do at request start */
      PHP_RSHUTDOWN(maxdb),   /* Replace with NULL if there's nothing to do at request end */
      PHP_MINFO(maxdb),
#if ZEND_MODULE_API_NO >= 20010901
      "<FORMATED_BUILD_VERSION>", /* Replace with version number for your extension */
#endif
      STANDARD_MODULE_PROPERTIES
};
/* }}} */


#ifdef COMPILE_DL_MAXDB
ZEND_GET_MODULE(maxdb)
#endif


/* {{{ PHP_INI */
PHP_INI_BEGIN()
      STD_PHP_INI_ENTRY("maxdb.default_host",   NULL, PHP_INI_ALL, OnUpdateString, default_host, zend_maxdb_globals,    maxdb_globals)
      STD_PHP_INI_ENTRY("maxdb.default_db", NULL,     PHP_INI_ALL, OnUpdateString, default_db, zend_maxdb_globals, maxdb_globals)
      STD_PHP_INI_ENTRY("maxdb.default_user",   NULL, PHP_INI_ALL, OnUpdateString, default_user, zend_maxdb_globals,    maxdb_globals)
      STD_PHP_INI_ENTRY("maxdb.default_pw",     NULL, PHP_INI_ALL, OnUpdateString, default_pw, zend_maxdb_globals,      maxdb_globals)
#if ZEND_MODULE_API_NO >= 20040412
       STD_PHP_INI_ENTRY("maxdb.long_readlen", LONG_READLEN, PHP_INI_ALL, OnUpdateLong, long_readlen, zend_maxdb_globals,     maxdb_globals)
#else
       STD_PHP_INI_ENTRY("maxdb.long_readlen", LONG_READLEN, PHP_INI_ALL, OnUpdateInt, long_readlen, zend_maxdb_globals,      maxdb_globals)
#endif
PHP_INI_END()
/* }}} */


static void maxdb_upper (char *src, char *dest, int len) {
    int i = 0;
    while (*src && (i < len)) {
        dest[i++] = toupper(*src++);
    }
    if (i < len) {
        dest[i] = '\0';
    }
}

static void maxdb_lower (char *src, char *dest, int len) {
    int i = 0;
    while (*src && (i < len)) {
        dest[i++] = tolower(*src++);
    }
    if (i < len) {
        dest[i] = '\0';
    }
}

/* {{{ php_maxdb_init_globals
 */
static void php_maxdb_init_globals(zend_maxdb_globals *maxdb_globals)
{
      maxdb_globals->default_host = NULL;
      maxdb_globals->default_db = NULL;
      maxdb_globals->default_user = NULL;
      maxdb_globals->default_pw = NULL;
      maxdb_globals->db = NULL;
      maxdb_globals->user = NULL;
      maxdb_globals->password = NULL;
      maxdb_globals->m_maxDBEnv = NULL;
      maxdb_globals->report_mode = MAXDB_REPORT_ERROR;
      maxdb_globals->long_readlen = 0;
      maxdb_globals->error_no = 0;
      maxdb_globals->error_msg = NULL;
      maxdb_globals->conn_prop = NULL;
    maxdb_globals->trace_prop = NULL;
      maxdb_globals->ssl_error = 0;
      maxdb_globals->thread_id = 0;
}


static void php_maxdb_free_stmt_bind_buffer (maxdb_prepstmt *prepstmt)
{
      int i;

      if (!prepstmt->m_parcnt) {
            return;
      }

      if (prepstmt->m_bindparams) {
            for (i = 0; i < prepstmt->m_parcnt; i++) {
                  if ((prepstmt->m_bindparams[i].hostType == SQLDBC_HOSTTYPE_ASCII_CLOB) &&
                        prepstmt->m_bindparams[i].buf) {
                        SQLDBC_LOB_delete_SQLDBC_LOB ((SQLDBC_LOB *) prepstmt->m_bindparams[i].buf);
                  }
                  if (prepstmt->m_bindparams[i].var) {
                        zval_ptr_dtor(&prepstmt->m_bindparams[i].var);
                  }
            }
                  efree(prepstmt->m_bindparams);
      }
}

static void php_maxdb_free_result (maxdb_result *res)
{
      SQLDBC_UInt4 i;

      if (res) {
            if (res->m_resultset && (res->m_noclose == SQLDBC_FALSE)) {
                  SQLDBC_ResultSet_close (res->m_resultset);
                  res->m_resultset = NULL;
            }
            if (res->m_cols) {
                  for(i = 0; i < res->m_numcols; i++) {
                        if (res->m_cols[i].buf)
                              efree(res->m_cols[i].buf);
                  }
                  efree (res->m_cols);
                  res->m_cols = NULL;
            }
            if (res->m_vars) {
                  for (i = 0; i < res->m_varscnt; i++) {
                        efree (res->m_vars[i]);
                        res->m_vars[i] = NULL;
                  }
                  res->m_vars = NULL;
            }
      }
}

static void z_close_maxdb_conn (maxdb_connection *conn, SQLDBC_Environment *env)
{
    if (SQLDBC_Connection_isConnected (conn->m_connection) == SQLDBC_TRUE) {
            SQLDBC_Connection_close (conn->m_connection);
      }
      SQLDBC_Environment_releaseConnection (env, conn->m_connection);
      if (conn->m_host) {
            efree(conn->m_host);
      }
      if (conn->m_db) {
            efree(conn->m_db);
      }
    if (conn->m_user) {
        efree (conn->m_user);
        conn->m_user = NULL;
    }
    if (conn->m_passwd) {
        efree (conn->m_passwd);
        conn->m_passwd = NULL;
    }
    if (conn->m_result) {
        php_maxdb_free_result(conn->m_result);
    }
      efree (conn);
}

#ifndef MAXDB_OO
static void _close_maxdb_conn(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
      maxdb_connection *conn = (maxdb_connection *) rsrc->ptr;

    z_close_maxdb_conn(conn, MAXDB_G(m_maxDBEnv));
}


static void _free_maxdb_result(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
      maxdb_result *res = (maxdb_result *)rsrc->ptr;

      php_maxdb_free_result (res);

      efree (res);
}
#endif

static void z_free_maxdb_prepstmt (maxdb_prepstmt *prepstmt)
{
      unsigned int i;

      if (prepstmt) {
            php_maxdb_free_stmt_bind_buffer (prepstmt);
            if (prepstmt->m_result) {
                  if (prepstmt->m_result->m_vars) {
                        for (i = 0; i < prepstmt->m_result->m_varscnt; i++) {
                              if ((prepstmt->m_result->m_vars[i]->type == IS_STRING) &&
                                    (prepstmt->m_result->m_vars[i]->value.str.len)) {
                                    efree(prepstmt->m_result->m_vars[i]->value.str.val);
                              }
                              efree (prepstmt->m_result->m_vars[i]);
                        }
                        efree (prepstmt->m_result->m_vars);
                  }
                  if (prepstmt->m_result->m_cols) {
                        for(i = 0; i < prepstmt->m_result->m_numcols; i++) {
                              if (prepstmt->m_result->m_cols[i].buf)
                                    efree(prepstmt->m_result->m_cols[i].buf);
                        }
                        efree (prepstmt->m_result->m_cols);
                        prepstmt->m_result->m_cols = NULL;
                  }
                  efree(prepstmt->m_result);
            }
            efree(prepstmt);
      }
}

#ifndef MAXDB_OO
static void _free_maxdb_prepstmt(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
      maxdb_prepstmt *prepstmt = (maxdb_prepstmt  *) rsrc->ptr;
    z_free_maxdb_prepstmt (prepstmt);
}
#endif

static void php_maxdb_internal_error(INTERNAL_FUNCTION_PARAMETERS, php_maxdb_errorcode errcode, ...) {
      char *message;
      int buflen;
    va_list ap;
    php_maxdb_errordata err = errordata[errcode];
       
      if (!(MAXDB_G(report_mode) & MAXDB_REPORT_ERROR))
            return;

    va_start (ap, errcode);
      buflen = (int) strlen (err.msgformat);
      if (buflen < 512)
            buflen = 512;
      message = emalloc (buflen);
    memset (message, 0, buflen);
    vsnprintf (message, buflen, err.msgformat, ap);
      php_error_docref (NULL TSRMLS_CC, E_WARNING, message);
      efree (message);
    va_end (ap); 
}


static maxdb_result_value *php_maxdb_copy_result_value (maxdb_result *result)
{
      unsigned int i;
      maxdb_result_value *res;

      res = (maxdb_result_value *) emalloc (sizeof(maxdb_result_value)*result->m_numcols);
      if (!res) {
            return (maxdb_result_value *) NULL;
      }

      for (i = 0; i < result->m_numcols; i++) {
          res[i].buf = (char *) emalloc (result->m_cols[i].bufLen);
            if (!res[i].buf) {
                  return (maxdb_result_value *) NULL;
            }

            memcpy (res[i].buf, result->m_cols[i].buf, result->m_cols[i].bufLen);
            memcpy (res[i].bufName, result->m_cols[i].bufName, sizeof(result->m_cols[i].bufName));
            res[i].bufLen = result->m_cols[i].bufLen;
            res[i].hostType = result->m_cols[i].hostType;
            res[i].indicator = result->m_cols[i].indicator;
            res[i].chopBlanks = result->m_cols[i].chopBlanks;
            res[i].isint = result->m_cols[i].isint;
      }

      return res;
}


static zval **php_maxdb_copy_mvars(maxdb_result *result)
{
      zval **res;
      unsigned int i;

      if (result->m_varscnt == 0) {
            return (zval **) NULL;
      }
      res = (zval **) safe_emalloc ((result->m_varscnt), sizeof(zval), 0);
      if (!res) {
            return (zval **) NULL;
      }
      for (i = 0; i < result->m_varscnt; i++) {
            res[i] = result->m_vars[i];
      }
      return res;
}


static maxdb_result *php_maxdb_copy_result (maxdb_result *result)
{
      maxdb_result *res;

      res = (maxdb_result *) emalloc (sizeof(maxdb_result));
      if (!res) {
            return (maxdb_result *) NULL;
      }

      res->m_id = 0;
      res->m_resultset = result->m_resultset;
      res->m_rsmd = result->m_rsmd; 
      res->m_cols = php_maxdb_copy_result_value(result);;
      res->m_numcols = result->m_numcols;
      res->m_rowNotFound = result->m_rowNotFound;
      res->m_rowsaffected = result->m_rowsaffected;
      res->m_rowSetSize = result->m_rowSetSize;
      res->m_lastindex = result->m_lastindex;
      res->m_vars = php_maxdb_copy_mvars(result);
      res->m_varscnt = result->m_varscnt;
      res->m_noclose = result->m_noclose;
    res->m_connid = result->m_connid;
    res->m_conn = result->m_conn;

      return res;
}


static void php_maxdb_error (INTERNAL_FUNCTION_PARAMETERS, SQLDBC_Int4 errnum, char* errmsg, char* sqlstate) {
      php_error_docref (NULL TSRMLS_CC, E_WARNING, "%d %s [%s]\n", errnum, errmsg, sqlstate);
}


static void php_maxdb_sqldbc_error (INTERNAL_FUNCTION_PARAMETERS, SQLDBC_ErrorHndl *errhdl) {
      SQLDBC_Int4  errnum = SQLDBC_ErrorHndl_getErrorCode(errhdl);
    char* errmsg = SQLDBC_ErrorHndl_getErrorText(errhdl);
    char* sqlstate = SQLDBC_ErrorHndl_getSQLState(errhdl);

      if (!(MAXDB_G(report_mode) & MAXDB_REPORT_ERROR))
            return;

      MAXDB_G(error_no) = errnum;
      if (MAXDB_G(error_msg)) {
            efree (MAXDB_G(error_msg));
            MAXDB_G(error_msg) = NULL;
      }
      if (errmsg) {
            MAXDB_G(error_msg) = estrdup(errmsg);
      }

    php_maxdb_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, errnum, errmsg, sqlstate);
}


static void php_maxdb_handle_connect_error (INTERNAL_FUNCTION_PARAMETERS, maxdb_connection *c)
{
      SQLDBC_ErrorHndl *errhndl;
      char *str;

      errhndl = SQLDBC_Connection_getError(c->m_connection);
      MAXDB_G(error_no) = SQLDBC_ErrorHndl_getErrorCode (errhndl);
      if (MAXDB_G(error_msg)) {
            efree (MAXDB_G(error_msg));
            MAXDB_G(error_msg) = NULL;
      }
      if ((str = SQLDBC_ErrorHndl_getErrorText (errhndl))) {
            MAXDB_G(error_msg) = estrdup (str);
      }
      php_maxdb_sqldbc_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                       errhndl);
}

static bool php_maxdb_init_environment (INTERNAL_FUNCTION_PARAMETERS)
{
    SQLDBC_IRuntime *runtime = 0;
      char errorText[128];

    if (!MAXDB_G(m_maxDBEnv)) {
        runtime = ClientRuntime_GetClientRuntime(errorText, sizeof(errorText));
        if (!(MAXDB_G(m_maxDBEnv) = SQLDBC_Environment_new_SQLDBC_Environment (runtime))) {
            return 0;
        }
        if (!MAXDB_G(conn_prop)) {
            MAXDB_G(conn_prop) = SQLDBC_ConnectProperties_new_SQLDBC_ConnectProperties();
        }
        if (!MAXDB_G(trace_prop)) {
            MAXDB_G(trace_prop) = SQLDBC_ConnectProperties_new_SQLDBC_ConnectProperties();
        }
    }

    return 1;
}

static void php_maxdb_init_connection (maxdb_connection *c)
{
      c->m_host = NULL;
      c->m_db = NULL;
    c->m_user = NULL;
    c->m_passwd = NULL;
      c->m_connprop = NULL;
      c->m_connection = NULL;
      c->m_errhndl = NULL;
      c->m_stmt = NULL;
      c->m_prepstmt = NULL;
      c->m_isprepared = 0;
      c->m_rowsaffected = -1;
      c->m_numcols = 0;
      c->m_id = 0;
      c->m_resultid = 0;
    c->m_result = NULL;
}


static void php_init_prepared_statement (maxdb_prepstmt *prepstmt)
{
      prepstmt->m_id = -1;
      prepstmt->m_prepstmt = NULL;
      prepstmt->m_bindparams = NULL;
      prepstmt->m_parcnt = 0;
      prepstmt->m_parammetadata = NULL;
      prepstmt->m_rownotfound = SQLDBC_FALSE;
      prepstmt->m_result = NULL;
      prepstmt->m_isexecuted = SQLDBC_FALSE;
      prepstmt->m_clink = NULL;
}

static void php_maxdb_init_bindparams (maxdb_bind_param *param, int num)
{
      int i;
      
      for (i = 0; i < num; i++) {
            param[i].buf = NULL;
            param[i].lob = NULL;
            param[i].paramlen = 0;
            param[i].sqltype = SQLDBC_SQLTYPE_UNKNOWN;
            param[i].hostType = SQLDBC_HOSTTYPE_PARAMETER_NOTSET;
            param[i].indicator = 0;
            param[i].var = NULL;
        param[i].isint = SQLDBC_FALSE;
      }
}

static void php_init_result (maxdb_result *result)
{
      result->m_id = 0;
      result->m_resultset = NULL;
      result->m_rsmd = NULL;
      result->m_cols = NULL;
      result->m_numcols = 0;
      result->m_rowNotFound = SQLDBC_FALSE;
      result->m_rowsaffected = 0;
      result->m_rowSetSize = 1;
      result->m_lastindex = 0;
      result->m_vars = NULL;
      result->m_varscnt = 0;
      result->m_noclose = SQLDBC_FALSE;
    result->m_connid = 0;
    result->m_conn = NULL;
}


static void php_maxdb_init_result_values (maxdb_result_value *vals, int nr)
{
      int i;
      
      if (!vals)
            return;

      for (i = 0; i < nr; i++) {
            vals[i].buf = NULL;
            memset (vals[i].bufName, ' ', sizeof(vals[i].bufName));
            vals[i].bufLen = 0;
            vals[i].hostType = SQLDBC_HOSTTYPE_PARAMETER_NOTSET;
            vals[i].indicator = 0;
            vals[i].chopBlanks = SQLDBC_TRUE;
            vals[i].isint = SQLDBC_FALSE;
      }
}


static char *php_maxdb_get_server_info (maxdb_connection *conn, char *ver, int verlen)
{
      SQLDBC_PreparedStatement *stmt;
      SQLDBC_Length ind;

      stmt = SQLDBC_Connection_createPreparedStatement(conn->m_connection);
      if (!stmt) {
            return "";
      }
      if (SQLDBC_PreparedStatement_prepareASCII(stmt, "SELECT KERNEL INTO ? FROM DOMAIN.VERSIONS") != SQLDBC_OK) {
            SQLDBC_Connection_releasePreparedStatement (conn->m_connection, stmt);
            return "";;
      }
      if (SQLDBC_PreparedStatement_bindParameter (stmt,
                                                                        1,
                                                                        SQLDBC_HOSTTYPE_ASCII,
                                                                        ver,
                                                                        &ind,
                                                                        verlen,
                                                                        SQLDBC_TRUE) != SQLDBC_OK) {
            SQLDBC_Connection_releasePreparedStatement (conn->m_connection, stmt);
            return "";;
      }

      if (SQLDBC_PreparedStatement_executeASCII (stmt) != SQLDBC_OK) {
            SQLDBC_Connection_releasePreparedStatement (conn->m_connection, stmt);
          return "";
      }

      return ver;
}


static int php_maxdb_get_version_number (char *ver) {
      unsigned int i, j;
      char major[24];
      char minor[24];
      char cl[24];

      memset (major, 0, sizeof(major));
      memset (minor, 0, sizeof(minor));
      memset (cl, 0, sizeof(cl));

      i = 0;
      while ((i < strlen(ver)) && ((ver[i] < '0') || (ver[i] > '9')))
            i++;

      j = 0;
      while ((i < strlen(ver)) && (ver[i] != '.')) {
            major[j] = ver[i];
            i++; j++;
      }

      i++;
      j = 0;
      while ((i < strlen(ver)) && (ver[i] != '.')) {
            minor[j] = ver[i];
            i++; j++;
      }
      i++;
      j = 0;
      while ((i < strlen(ver)) && (ver[i] != ' ')) {
            cl[j] = ver[i];
            i++; j++;
      }
      
      return (atoi(major) * 10000 + atoi(minor) * 100 + atoi(cl));
}


static void php_maxdb_get_field_info (INTERNAL_FUNCTION_PARAMETERS,
                                                        maxdb_result *result,
                                                        int index,
                                                        char *colname,
                                                        SQLDBC_Int4 *collen,
                                                        SQLDBC_Int4 cbLen,
                                                        SQLDBC_SQLType *coltype,
                                                        SQLDBC_Int4 *colprec) {
      SQLDBC_Length ind;

      if (SQLDBC_ResultSetMetaData_getColumnName (result->m_rsmd,
                                                                        index,
                                                                        colname,
                                                                        SQLDBC_StringEncodingType_Encoding_Ascii,
                                                                        cbLen,
                                                                        &ind) == SQLDBC_NOT_OK) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_CANNOT_GET_COLUMNNAME_D, 
                                                 index);
            RETURN_FALSE;
      }
      
      *collen = SQLDBC_ResultSetMetaData_getColumnLength (result->m_rsmd, index);

      *coltype = SQLDBC_ResultSetMetaData_getColumnType (result->m_rsmd, index);

      *colprec = SQLDBC_ResultSetMetaData_getPrecision (result->m_rsmd, index);
}


static bool php_maxdb_check_long_param (INTERNAL_FUNCTION_PARAMETERS, maxdb_prepstmt *prepstmt, long param_nr)
{
      if (!prepstmt->m_bindparams) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "No parameters bound");
            return 0;
      }

      if ((param_nr < 0) || (param_nr > prepstmt->m_parcnt-1)) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INVALID_PARAMETER_INDEX_D, 
                                                 param_nr);
            return 0;
      }

      if (prepstmt->m_bindparams[param_nr].hostType != SQLDBC_HOSTTYPE_ASCII_CLOB) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "Parameter %d is not a lob", param_nr);
            return 0;
      }

      if (!prepstmt->m_bindparams[param_nr].buf && (prepstmt->m_isexecuted == SQLDBC_TRUE)) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "No lob bound");
          return 0;
      }
      return 1;
}

static void php_maxdb_map_column_info (SQLDBC_SQLType ColumnType,
                                       SQLDBC_HostType *hT,
                                       SQLDBC_Int4 *CL,
                                       SQLDBC_Bool *ii,
                                       SQLDBC_Bool *cB,
                                       SQLDBC_ParameterMetaData *pmd,
                                       SQLDBC_ResultSetMetaData *rmd,
                                       SQLDBC_Int4 ind TSRMLS_DC)
{
    switch (ColumnType) {
    case SQLDBC_SQLTYPE_NUMBER        :
    case SQLDBC_SQLTYPE_SMALLINT      :
    case SQLDBC_SQLTYPE_INTEGER       : {
        if (hT) *hT = SQLDBC_HOSTTYPE_INT4;
        if (CL) *CL = sizeof(SQLDBC_Int4);
        break;
    }
    case SQLDBC_SQLTYPE_FIXED         : {
        if (hT) *hT = SQLDBC_HOSTTYPE_ASCII;
        if (ii) *ii = SQLDBC_TRUE;
        if (rmd) {
            if (SQLDBC_ResultSetMetaData_getScale (rmd, ind) > 0) {
                if (hT) *hT = SQLDBC_HOSTTYPE_DOUBLE;
                if (ii) *ii = SQLDBC_FALSE;
                if (CL) *CL = sizeof(double);
            } else {
                if (CL) *CL = SQLDBC_ResultSetMetaData_getPrecision (rmd, ind) + 1;
            }
        }
        if (pmd) {
            if (SQLDBC_ParameterMetaData_getScale (pmd, ind) > 0) {
                if (hT) *hT = SQLDBC_HOSTTYPE_DOUBLE;
                if (ii) *ii = SQLDBC_FALSE;
                if (CL) *CL = sizeof(double);
            } else {
                if (CL) *CL = SQLDBC_ParameterMetaData_getPrecision (pmd, ind) + 1;
            }
        }
        break;
    }
    case SQLDBC_SQLTYPE_FLOAT         :
    case SQLDBC_SQLTYPE_VFLOAT        : {
        if (hT) *hT = SQLDBC_HOSTTYPE_DOUBLE;
        if (CL) *CL = sizeof(double); 
        break;
    }
    case SQLDBC_SQLTYPE_CHB           :
    case SQLDBC_SQLTYPE_ROWID         :
    case SQLDBC_SQLTYPE_VARCHARB      : {
        if (hT) *hT = SQLDBC_HOSTTYPE_BINARY;
        break;
    }
    case SQLDBC_SQLTYPE_CHA           :               
    case SQLDBC_SQLTYPE_CHE           :{
        if (cB) *cB = SQLDBC_TRUE;
        break; 
    }
        
    case SQLDBC_SQLTYPE_VARCHARA      :
    case SQLDBC_SQLTYPE_VARCHARE      :
    case SQLDBC_SQLTYPE_DATE          :
    case SQLDBC_SQLTYPE_TIME          :
    case SQLDBC_SQLTYPE_TIMESTAMP     : {
        break;
    }
    case SQLDBC_SQLTYPE_UNICODE       :
    case SQLDBC_SQLTYPE_VARCHARUNI    : {
        if (cB) *cB = SQLDBC_TRUE;
        break;
    }
    case SQLDBC_SQLTYPE_BOOLEAN       : {
        if (hT) *hT = SQLDBC_HOSTTYPE_INT1;
        if (CL) *CL = 1;
        break;
    }
    case SQLDBC_SQLTYPE_ABAPTABHANDLE : {
        break;
    }
    case SQLDBC_SQLTYPE_STRB          :
    case SQLDBC_SQLTYPE_LONGB         : {
        if (hT) *hT = SQLDBC_HOSTTYPE_BINARY;
        if (CL) *CL = MAXDB_G(long_readlen);
        break;
    }
    case SQLDBC_SQLTYPE_STRA          :
    case SQLDBC_SQLTYPE_STRE          :
    case SQLDBC_SQLTYPE_LONGA         :
    case SQLDBC_SQLTYPE_LONGE         : 
    case SQLDBC_SQLTYPE_STRUNI        :
    case SQLDBC_SQLTYPE_LONGUNI       : {
        if (hT) *hT = SQLDBC_HOSTTYPE_ASCII;
        if (CL) *CL = MAXDB_G(long_readlen);
        break;
    }
    default: {
        break;
    }
    }
}

static bool php_maxdb_bind_parameters (INTERNAL_FUNCTION_PARAMETERS, maxdb_prepstmt *prepstmt)
{
      int i;

      for (i = 0; i < prepstmt->m_parcnt; i++) {
        ParameterMode pMode = SQLDBC_ParameterMetaData_getParameterMode  (prepstmt->m_parammetadata, i+1);
        SQLDBC_SQLType ColumnType = SQLDBC_ParameterMetaData_getParameterType (prepstmt->m_parammetadata, i+1);
            zval *var = prepstmt->m_bindparams[i].var;
            if (var == NULL) {
                  php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                       PHP_ERR_PARAMETER_NOT_SET_D, i+1);
                  return 0;
            }
        if (pMode == parameterModeInOut || pMode == parameterModeOut) {            
            prepstmt->m_bindparams[i].paramlen = 
               SQLDBC_ParameterMetaData_getParameterLength(prepstmt->m_parammetadata, i+1) + 1;

            php_maxdb_map_column_info (ColumnType, &prepstmt->m_bindparams[i].hostType, 
                                       &prepstmt->m_bindparams[i].paramlen, &prepstmt->m_bindparams[i].isint, 0,
                                       prepstmt->m_parammetadata, 0, i+1 TSRMLS_CC);

            if (pMode == parameterModeInOut) {
                if (Z_TYPE_P(prepstmt->m_bindparams[i].var) != IS_NULL) {
                    if (prepstmt->m_bindparams[i].var->type == IS_STRING) {
                        prepstmt->m_bindparams[i].paramlen = prepstmt->m_bindparams[i].var->value.str.len;
                        prepstmt->m_bindparams[i].buf = 
                            (char *) emalloc (MAXDB_MAX(prepstmt->m_bindparams[i].paramlen,
                                                        prepstmt->m_bindparams[i].var->value.str.len)+1);
                        memcpy (prepstmt->m_bindparams[i].buf, prepstmt->m_bindparams[i].var->value.str.val,
                                prepstmt->m_bindparams[i].var->value.str.len);
                        prepstmt->m_bindparams[i].buf[prepstmt->m_bindparams[i].paramlen] = '\0';
                        prepstmt->m_bindparams[i].indicator = SQLDBC_NTS;
                    }
                } else {
                    prepstmt->m_bindparams[i].buf = (char *) emalloc (prepstmt->m_bindparams[i].paramlen);
                }
            } else {
                prepstmt->m_bindparams[i].buf = (char *) emalloc (prepstmt->m_bindparams[i].paramlen);
                memset (prepstmt->m_bindparams[i].buf, ' ', prepstmt->m_bindparams[i].paramlen);
            }
            if (Z_TYPE_P(prepstmt->m_bindparams[i].var) != IS_NULL) {
                if ((prepstmt->m_bindparams[i].var->type == IS_STRING) &&
                    (prepstmt->m_bindparams[i].var->value.str.len > 0)) {
                    efree (prepstmt->m_bindparams[i].var->value.str.val);
                    prepstmt->m_bindparams[i].var->type = IS_NULL;
                }
            }
        } else {
            if ((Z_TYPE_P(prepstmt->m_bindparams[i].var) == IS_NULL) &&
                (prepstmt->m_bindparams[i].hostType != SQLDBC_HOSTTYPE_ASCII_CLOB)) {
                prepstmt->m_bindparams[i].indicator = SQLDBC_NULL_DATA;
                prepstmt->m_bindparams[i].buf = 0;
            } else {
                if (prepstmt->m_bindparams[i].hostType == SQLDBC_HOSTTYPE_ASCII) {
                    prepstmt->m_bindparams[i].buf = (char *) Z_STRVAL_P(var);
                    prepstmt->m_bindparams[i].paramlen = Z_STRLEN_P(var);
                    prepstmt->m_bindparams[i].indicator = SQLDBC_NTS;
                } else if (prepstmt->m_bindparams[i].hostType == SQLDBC_HOSTTYPE_ASCII_CLOB) {
                    if (prepstmt->m_isexecuted == SQLDBC_TRUE) {
                        prepstmt->m_bindparams[i].lob = 0;
                        prepstmt->m_bindparams[i].paramlen = 0;
                        prepstmt->m_bindparams[i].indicator = 0;
                    }
                    prepstmt->m_bindparams[i].buf = (char *) SQLDBC_LOB_new_SQLDBC_LOB();
                }
            }
        }
            if (SQLDBC_PreparedStatement_bindParameter (prepstmt->m_prepstmt,
                                                                              i+1,
                                                                              prepstmt->m_bindparams[i].hostType,
                                                                              prepstmt->m_bindparams[i].buf,
                                                                              &prepstmt->m_bindparams[i].indicator,
                                                                              prepstmt->m_bindparams[i].paramlen,
                                                                              SQLDBC_TRUE) != SQLDBC_OK) {
                  php_maxdb_sqldbc_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                   SQLDBC_PreparedStatement_getError(prepstmt->m_prepstmt));
                  return 0;
            }
      }
      return 1;
}

static bool php_maxdb_register_resultset(INTERNAL_FUNCTION_PARAMETERS, maxdb_result *result)
{
      SQLDBC_Int4 column;
      SQLDBC_UInt2 colcnt = result->m_numcols;

      if (!result->m_rsmd) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, "Missing resultset meta data");
            return 0;
      }

      result->m_cols = (maxdb_result_value *) emalloc(sizeof(maxdb_result_value)*result->m_numcols);
      if (!result->m_cols) {
            return 0;
      }
    php_maxdb_init_result_values (result->m_cols, result->m_numcols);

      for (column = 1; column <= colcnt; column++) {
            SQLDBC_Length ind;
            maxdb_result_value *m_col = &result->m_cols[column-1];
            SQLDBC_Int4 ColumnLength = SQLDBC_ResultSetMetaData_getColumnLength (result->m_rsmd, column);
            SQLDBC_SQLType ColumnType = SQLDBC_ResultSetMetaData_getColumnType (result->m_rsmd, column);
            if (SQLDBC_ResultSetMetaData_getColumnName (result->m_rsmd, 
                                                                              column, 
                                                                              m_col->bufName, 
                                                                              SQLDBC_StringEncodingType_Encoding_Ascii, 
                                                                              sizeof(m_col->bufName), 
                                                                              &ind) != SQLDBC_OK) {
                  php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                       PHP_ERR_CANNOT_GET_COLUMNNAME_D, 
                                                       column);
            }
            m_col->hostType = SQLDBC_HOSTTYPE_ASCII;
            m_col->chopBlanks = SQLDBC_FALSE;
            
        php_maxdb_map_column_info (ColumnType, &m_col->hostType, &ColumnLength, &m_col->isint, &m_col->chopBlanks, 
                                   0, result->m_rsmd, column TSRMLS_CC);

            m_col->buf = (char *) emalloc (ColumnLength+1);
            if (!m_col->buf) {
                  return 0;
            }
            memset (m_col->buf, ' ', ColumnLength+1);
            m_col->bufLen = ColumnLength + 1;
            if (SQLDBC_ResultSet_bindColumn (result->m_resultset,
                                                             column,
                                                             m_col->hostType,
                                                             m_col->buf,
                                                             &m_col->indicator,
                                                             m_col->bufLen,
                                                             SQLDBC_TRUE) != SQLDBC_OK) {
                  php_maxdb_sqldbc_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                   SQLDBC_ResultSet_getError(result->m_resultset));
                  return 0;;
            }
      }
      return 1;;
}


static void php_maxdb_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type, int expected_args, int into_object)
{
      SQLDBC_UInt4 i;
      zval *pv_result = 0;
    int fetchtype = 0;
      maxdb_result *result;
      SQLDBC_Retcode rc;
      SQLDBC_RowSet *rowset = NULL;
#ifdef MAXDB_OO
      zval            *ctor_params = NULL;
      zend_class_entry *ce = NULL;
#endif

#ifdef MAXDB_OO
      if (into_object) {
            char *class_name;
            int class_name_len;

            if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sz", &pv_result, maxdb_result_class_entry, 
                                         &class_name, &class_name_len, &ctor_params) == FAILURE) {
                  return;
            }
            if (ZEND_NUM_ARGS() < (getThis() ? 1 : 2)) {
                  ce = zend_standard_class_def;
            } else {
                  ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
            }
            if (!ce) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                     PHP_ERR_INITIALIZATION_FAILED_S, 
                                     "Could not find class '%s'", class_name);
                  return;
            }
            fetchtype = MAXDB_ASSOC;
      } else {
        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &pv_result, maxdb_result_class_entry, 
                                         &fetchtype) == FAILURE) {
            return;
        }
      }
#else
    if (ZEND_NUM_ARGS() > expected_args) {
        WRONG_PARAM_COUNT;
    }
    
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &pv_result, &fetchtype) == FAILURE) {
        return;
    }
#endif
    
    if (fetchtype) {
        result_type = fetchtype;
    }
    
    if (!result_type) {
        result_type = MAXDB_BOTH;
    }
    
      if ((result_type & (MAXDB_BOTH|MAXDB_ASSOC_UPPER|MAXDB_ASSOC_LOWER)) == 0) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "The result type should be either MAXDB_NUM, MAXDB_ASSOC, MAXDB_ASSOC_UPPER, MAXDB_ASSOC_LOWER, or MAXDB_BOTH.");
      }
      
#ifdef MAXDB_OO
      MAXDB_FETCH_RESOURCE(result, maxdb_result *, &pv_result, "maxdb_result");
#else
      ZEND_FETCH_RESOURCE(result, maxdb_result *, &pv_result, -1, "maxdb result", le_result);
#endif

      if ((rc = SQLDBC_ResultSet_next (result->m_resultset)) == SQLDBC_NO_DATA_FOUND) {
            RETURN_NULL();
      } else if (rc == SQLDBC_NOT_OK) {
            php_maxdb_sqldbc_error (INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                                SQLDBC_ResultSet_getError(result->m_resultset));
            RETURN_NULL();
      }
      rowset = SQLDBC_ResultSet_getRowSet (result->m_resultset);

      if (SQLDBC_RowSet_fetch (rowset) == SQLDBC_NOT_OK) {
            php_maxdb_sqldbc_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                             SQLDBC_RowSet_getError(rowset));
            return;
      }
      array_init (return_value);

      for (i = 0; i < result->m_numcols; i++) {
            if (result->m_cols[i].indicator >= result->m_cols[i].bufLen) {
                  php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                       PHP_ERR_LONG_COLUMN_TRUNCATED_D, 
                                                       i+1);
                  result->m_cols[i].indicator = result->m_cols[i].bufLen;
            }

            if ((result->m_cols[i].indicator > 0) &&
                  (result->m_cols[i].hostType == SQLDBC_HOSTTYPE_ASCII)) {
                  char *buf = result->m_cols[i].buf;
                  while (result->m_cols[i].indicator && buf[result->m_cols[i].indicator-1]==' ')
                        --result->m_cols[i].indicator;
                  result->m_cols[i].buf[result->m_cols[i].indicator] = '\0';
            }

            if (result->m_cols[i].indicator == SQLDBC_NULL_DATA) {
                  if (result_type & MAXDB_NUM) {
                        add_index_null (return_value, i);
                  }
                  if (result_type & MAXDB_ASSOC) {
                        add_assoc_null (return_value, result->m_cols[i].bufName);
                  }
                  continue;
            }

            if (result_type & MAXDB_NUM) {
                  switch (result->m_cols[i].hostType) {
                  case SQLDBC_HOSTTYPE_INT1 : {
                        SQLDBC_Int1 tmp;
                        memcpy (&tmp, result->m_cols[i].buf, sizeof(SQLDBC_Int1));
                        add_index_bool (return_value, i, tmp);
                        break;
                  }
                  case SQLDBC_HOSTTYPE_INT4: {
                        SQLDBC_Int4 tmp;
                        memcpy (&tmp, result->m_cols[i].buf, sizeof(SQLDBC_Int4));
                        add_index_long (return_value, i, tmp);
                        break;
                  }
                  case SQLDBC_HOSTTYPE_DOUBLE: {
                        double tmp;
                        memcpy (&tmp, result->m_cols[i].buf, sizeof(double));
                        add_index_double (return_value, i, tmp);
                        break;
                  }
                  default: {
                        add_index_stringl (return_value, i, result->m_cols[i].buf, 
                                                   result->m_cols[i].indicator, 1);
                        break;
                  }
                  }
            }
            if (result_type & (MAXDB_ASSOC|MAXDB_ASSOC_UPPER|MAXDB_ASSOC_LOWER)) {
                  switch (result->m_cols[i].hostType) {
                  case SQLDBC_HOSTTYPE_INT1 : {
                        SQLDBC_Int1 tmp;
                        memcpy (&tmp, result->m_cols[i].buf, sizeof(SQLDBC_Int1));
                        add_assoc_bool (return_value, result->m_cols[i].bufName, tmp);
                        break;
                  }
                  case SQLDBC_HOSTTYPE_INT4: {
                        SQLDBC_Int4 tmp;
                        memcpy (&tmp, result->m_cols[i].buf, sizeof(SQLDBC_Int4));
                        add_assoc_long (return_value, result->m_cols[i].bufName, tmp);
                        break;
                  }
                  case SQLDBC_HOSTTYPE_DOUBLE: {
                        double tmp;
                        memcpy (&tmp, result->m_cols[i].buf, sizeof(double));
                        add_assoc_double (return_value, result->m_cols[i].bufName, tmp);
                        break;
                  }
                  default: {
                char myname[MAXDB_COLUMN_NAME_LENGTH];

                if (result_type & MAXDB_ASSOC) {
                    add_assoc_stringl (return_value, result->m_cols[i].bufName, 
                                       result->m_cols[i].buf, result->m_cols[i].indicator, 1);
                } else if (result_type & MAXDB_ASSOC_UPPER) {
                    maxdb_upper(result->m_cols[i].bufName, myname, MAXDB_COLUMN_NAME_LENGTH);
                    add_assoc_stringl (return_value, myname, 
                                       result->m_cols[i].buf, result->m_cols[i].indicator, 1);
                } else if (result_type & MAXDB_ASSOC_LOWER) {
                    maxdb_lower(result->m_cols[i].bufName, myname, MAXDB_COLUMN_NAME_LENGTH);
                    add_assoc_stringl (return_value, myname, 
                                   result->m_cols[i].buf, result->m_cols[i].indicator, 1);
                }
                        break;
                  }
                  }
            }
      }

#ifdef MAXDB_OO
      if (into_object) {
            zval dataset = *return_value;
            zend_fcall_info fci;
            zend_fcall_info_cache fcc;
            zval *retval_ptr; 
      
            object_and_properties_init(return_value, ce, NULL);
            zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC);
      
            if (ce->constructor) {
                  fci.size = sizeof(fci);
                  fci.function_table = &ce->function_table;
                  fci.function_name = NULL;
                  fci.symbol_table = NULL;
                  fci.object_pp = &return_value;
                  fci.retval_ptr_ptr = &retval_ptr;
                  if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
                        if (Z_TYPE_P(ctor_params) == IS_ARRAY) {
                              HashTable *ht = Z_ARRVAL_P(ctor_params);
                              Bucket *p;
      
                              fci.param_count = 0;
                              fci.params = safe_emalloc(sizeof(zval*), ht->nNumOfElements, 0);
                              p = ht->pListHead;
                              while (p != NULL) {
                                    fci.params[fci.param_count++] = (zval**)p->pData;
                                    p = p->pListNext;
                              }
                        } else {
                              /* Two problems why we throw exceptions here: PHP is typeless
                               * and hence passing one argument that's not an array could be
                               * by mistake and the other way round is possible, too. The 
                               * single value is an array. Also we'd have to make that one
                               * argument passed by reference.
                               */
                              zend_throw_exception(zend_exception_get_default(), "Parameter ctor_params must be an array", 0 TSRMLS_CC);
                              return;
                        }
                  } else {
                        fci.param_count = 0;
                        fci.params = NULL;
                  }
                  fci.no_separation = 1;

                  fcc.initialized = 1;
                  fcc.function_handler = ce->constructor;
                  fcc.calling_scope = EG(scope);
                  fcc.object_pp = &return_value;
            
                  if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
                        zend_throw_exception_ex(zend_exception_get_default(), 0 TSRMLS_CC, 
                                        "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name);
                  } else {
                        if (retval_ptr) {
                              zval_ptr_dtor(&retval_ptr);
                        }
                  }
                  if (fci.params) {
                        efree(fci.params);
                  }
            } else if (ctor_params) {
                  zend_throw_exception_ex(zend_exception_get_default(), 0 TSRMLS_CC, 
                                    "Class %s does not have a constructor hence you cannot use ctor_params", ce->name);
            }
      }
#endif
}


static void php_maxdb_do_query_general (INTERNAL_FUNCTION_PARAMETERS, char *query, maxdb_connection *conn,
                                        maxdb_result **ret_result, bool *err)
{
    maxdb_result *result = NULL;
      SQLDBC_Retcode exec_rc;

    *err = 0;
      if (conn->m_stmt == NULL) {
            conn->m_stmt = SQLDBC_Connection_createStatement (conn->m_connection);
      }
      if (!conn->m_stmt) {
            php_maxdb_sqldbc_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                             SQLDBC_Connection_getError(conn->m_connection));
        *err = 1;
            return;
      }

      conn->m_isprepared = 0;

      exec_rc = SQLDBC_Statement_executeASCII (conn->m_stmt, query); 
      if ((exec_rc != SQLDBC_OK) && (exec_rc != SQLDBC_NO_DATA_FOUND)) {
        conn->m_errhndl = SQLDBC_Statement_getError(conn->m_stmt);
            php_maxdb_sqldbc_error (INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                                conn->m_errhndl);
            *err = 1;
        return;
      }

      conn->m_rowsaffected = SQLDBC_Statement_getRowsAffected(conn->m_stmt);
      if (SQLDBC_Statement_isQuery (conn->m_stmt)) {
            result = (maxdb_result *) emalloc (sizeof(maxdb_result));
            if (!result) {
            *err = 1;
                  return;
            }
            php_init_result (result);

            result->m_resultset = SQLDBC_Statement_getResultSet (conn->m_stmt);
            result->m_rsmd = SQLDBC_ResultSet_getResultSetMetaData (result->m_resultset);
            result->m_numcols = SQLDBC_ResultSetMetaData_getColumnCount (result->m_rsmd);

            conn->m_numcols = result->m_numcols;

            if (exec_rc == SQLDBC_NO_DATA_FOUND) {
                  result->m_rowNotFound = SQLDBC_TRUE;
            } else {
                  result->m_rowNotFound = SQLDBC_FALSE;
            }

#ifndef MAXDB_OO
            zend_list_addref(conn->m_id);
#endif

            if (!php_maxdb_register_resultset(INTERNAL_FUNCTION_PARAM_PASSTHRU, result)) {
            *err = 1;
                  return;
            }
            
#ifndef MAXDB_OO
            result->m_id = ZEND_REGISTER_RESOURCE(return_value, result, le_result);

        result->m_connid = conn->m_id;

            conn->m_resultid = Z_LVAL_P(return_value);
#endif

            SQLDBC_ResultSet_setRowSetSize (result->m_resultset, result->m_rowSetSize);
      } else {
        *err = 0;
            return;
      }
    *err = 0;
    *ret_result = result;

    return;
}

#ifdef MAXDB_OO
/* {{{ maxdb_read_na */
static int maxdb_read_na(maxdb_object *obj, zval **retval TSRMLS_DC)
{
      *retval = NULL;
      php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot read property");
      return FAILURE;
}
/* }}} */

/* {{{ maxdb_write_na */
static int maxdb_write_na(maxdb_object *obj, zval *newval TSRMLS_DC)
{
      php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot write property");
      return FAILURE;
}
/* }}} */

/* {{{ maxdb_read_property */
zval *maxdb_read_property(zval *object, zval *member, int type TSRMLS_DC)
{
      zval tmp_member;
      zval *retval;
      maxdb_object *obj;
      maxdb_prop_handler *hnd;
      zend_object_handlers *std_hnd;
      int ret;

      ret = FAILURE;
      obj = (maxdb_object *)zend_objects_get_address(object TSRMLS_CC);

      if (!obj->valid) {
            retval = EG(uninitialized_zval_ptr);
            return(retval);
      }

      if (member->type != IS_STRING) {
            tmp_member = *member;
            zval_copy_ctor(&tmp_member);
            convert_to_string(&tmp_member);
            member = &tmp_member;
      }

      if (obj->prop_handler != NULL) {
            ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
      }
      if (ret == SUCCESS) {

            /* check if maxdb object is still valid */
            if (!strcmp(obj->zo.ce->name, "maxdb")) {
                  if (!obj->ptr ||
                  !((maxdb_connection *)((MAXDB_RESOURCE *)(obj->ptr))->ptr)) {
                        retval = EG(uninitialized_zval_ptr);
                        return(retval);
            }
            } else
            /* check if stmt object is still valid */
            if (!strcmp(obj->zo.ce->name, "maxdb_stmt")) {
                  if (!obj->ptr ||
                  !((maxdb_prepstmt *)((MAXDB_RESOURCE *)(obj->ptr))->ptr)) {
                        retval = EG(uninitialized_zval_ptr);
                        return(retval);
            }
            }

            ret = hnd->read_func(obj, &retval TSRMLS_CC);
            if (ret == SUCCESS) {
                  /* ensure we're creating a temporary variable */
                  retval->refcount = 0;
            } else {
                  retval = EG(uninitialized_zval_ptr);
            }
      } else {
            std_hnd = zend_get_std_object_handlers();
            retval = std_hnd->read_property(object, member, type TSRMLS_CC);
      }

      if (member == &tmp_member) {
            zval_dtor(member);
      }
      return(retval);
}
/* }}} */

/* {{{ maxdb_write_property */
void maxdb_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
{
      zval tmp_member;
      maxdb_object *obj;
      maxdb_prop_handler *hnd;
      zend_object_handlers *std_hnd;
      int ret;

      if (member->type != IS_STRING) {
            tmp_member = *member;
            zval_copy_ctor(&tmp_member);
            convert_to_string(&tmp_member);
            member = &tmp_member;
      }

      ret = FAILURE;
      obj = (maxdb_object *)zend_objects_get_address(object TSRMLS_CC);

      if (obj->prop_handler != NULL) {
            ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
      }
      if (ret == SUCCESS) {
            hnd->write_func(obj, value TSRMLS_CC);
            if (! PZVAL_IS_REF(value) && value->refcount == 0) {
                  value->refcount++;
                  zval_ptr_dtor(&value);
            }
      } else {
            std_hnd = zend_get_std_object_handlers();
            std_hnd->write_property(object, member, value TSRMLS_CC);
      }

      if (member == &tmp_member) {
            zval_dtor(member);
      }
}
/* }}} */

/* {{{ void maxdb_add_property(HashTable *h, char *pname, maxdb_read_t r_func, maxdb_write_t w_func TSRMLS_DC) */
void maxdb_add_property(HashTable *h, char *pname, maxdb_read_t r_func, maxdb_write_t w_func TSRMLS_DC) {
      maxdb_prop_handler            p;

      p.read_func = (r_func) ? r_func : maxdb_read_na; 
      p.write_func = (w_func) ? w_func : maxdb_write_na;

      zend_hash_add(h, pname, strlen(pname) + 1, &p, sizeof(maxdb_prop_handler), NULL);
}
/* }}} */

static union _zend_function *php_maxdb_constructor_get(zval *object TSRMLS_DC)
{
      maxdb_object *obj = (maxdb_object *)zend_objects_get_address(object TSRMLS_CC);

      if (obj->zo.ce != maxdb_link_class_entry) {
            return obj->zo.ce->constructor;
      } else {
            static zend_internal_function f;

            f.function_name = maxdb_link_class_entry->name;
            f.scope = maxdb_link_class_entry;
            f.arg_info = NULL;
            f.num_args = 0;
            f.fn_flags = 0;

            f.type = ZEND_INTERNAL_FUNCTION;
            f.handler = ZEND_FN(maxdb_connect);
      
            return (union _zend_function*)&f;
      }
}

/* {{{ maxdb_objects_free_storage
 */
static void maxdb_objects_free_storage(zend_object *object TSRMLS_DC)
{
      maxdb_object      *intern = (maxdb_object *)object;
      MAXDB_RESOURCE    *my_res = (MAXDB_RESOURCE *)intern->ptr;

      zend_hash_destroy(intern->zo.properties);
      FREE_HASHTABLE(intern->zo.properties);

      /* link object */
      if (instanceof_function(intern->zo.ce, maxdb_link_class_entry TSRMLS_CC)) {
            if (my_res && my_res->ptr) {
            maxdb_connection *conn = (maxdb_connection *) my_res->ptr;
            z_close_maxdb_conn(conn, MAXDB_G(m_maxDBEnv));
            }
      } else if (intern->zo.ce == maxdb_stmt_class_entry) { /* stmt object */
            if (my_res && my_res->ptr) {
            maxdb_prepstmt *prepstmt = (maxdb_prepstmt *) my_res->ptr;
            z_free_maxdb_prepstmt (prepstmt);
            }
      } else if (intern->zo.ce == maxdb_result_class_entry) { /* result object */
            if (my_res && my_res->ptr) {
            maxdb_result *res = (maxdb_result *) my_res->ptr;
            php_maxdb_free_result(res);
            efree(res);
            }
      }
      if (my_res) {
        efree(my_res);
    }
      efree(object);
}
/* }}} */

/* {{{ maxdb_objects_new
 */
PHP_MAXDB_EXPORT(zend_object_value) maxdb_objects_new(zend_class_entry *class_type TSRMLS_DC)
{
      zend_object_value retval;
      maxdb_object *intern;
      zval *tmp;
      zend_class_entry *parent;

      intern = emalloc(sizeof(maxdb_object));
      memset(intern, 0, sizeof(maxdb_object));
      intern->zo.ce = class_type;
      intern->zo.in_get = 0;
      intern->zo.in_set = 0;
      intern->ptr = NULL;
      intern->valid = 0;
      intern->prop_handler = NULL;
      if ((parent = class_type->parent))
      {
            zend_hash_find(&classes, parent->name, parent->name_length + 1, (void **) &intern->prop_handler);
      }
      zend_hash_find(&classes, class_type->name, class_type->name_length + 1, (void **) &intern->prop_handler);

      ALLOC_HASHTABLE(intern->zo.properties);
      zend_hash_init(intern->zo.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
      zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref,
                              (void *) &tmp, sizeof(zval *));

      retval.handle = zend_objects_store_put(intern, NULL, maxdb_objects_free_storage, NULL TSRMLS_CC);
      retval.handlers = &maxdb_object_handlers;

      return retval;
}
/* }}} */
#endif

/* {{{ PHP_MINIT_FUNCTION

 */
PHP_MINIT_FUNCTION(maxdb)
{
#ifdef MAXDB_OO
    zend_class_entry *ce;
#endif
      SQLDBC_IRuntime *runtime = 0;
      char errorText[128];

      /* If you have INI entries, uncomment these lines */
      ZEND_INIT_MODULE_GLOBALS(maxdb, php_maxdb_init_globals, NULL);
      REGISTER_INI_ENTRIES();

      runtime = ClientRuntime_GetClientRuntime(errorText, sizeof(errorText));

      MAXDB_G(m_maxDBEnv) = SQLDBC_Environment_new_SQLDBC_Environment (runtime);
      MAXDB_G(conn_prop) = SQLDBC_ConnectProperties_new_SQLDBC_ConnectProperties();
      MAXDB_G(trace_prop) = SQLDBC_ConnectProperties_new_SQLDBC_ConnectProperties();

#ifndef MAXDB_OO
      le_conn = zend_register_list_destructors_ex(_close_maxdb_conn, NULL, "maxdb conn", module_number);
      le_result = zend_register_list_destructors_ex(_free_maxdb_result, NULL, "maxdb result", module_number);
      le_prepstmt = zend_register_list_destructors_ex(_free_maxdb_prepstmt, NULL, "maxdb prepstmt", module_number);
#endif

#ifdef MAXDB_OO
      memcpy(&maxdb_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
      maxdb_object_handlers.clone_obj = NULL;
      maxdb_object_handlers.read_property = maxdb_read_property;
      maxdb_object_handlers.write_property = maxdb_write_property;
      maxdb_object_handlers.get_property_ptr_ptr = NULL;
      maxdb_object_handlers.get_constructor = php_maxdb_constructor_get;

      zend_hash_init(&classes, 0, NULL, NULL, 1);
      REGISTER_MAXDB_CLASS_ENTRY("maxdb", maxdb_link_class_entry, maxdb_link_methods);

      ce = maxdb_link_class_entry;
      zend_hash_init(&maxdb_link_properties, 0, NULL, NULL, 1);
      MAXDB_ADD_PROPERTIES(&maxdb_link_properties, maxdb_link_property_entries);
      zend_hash_add(&classes, ce->name, ce->name_length+1, &maxdb_link_properties, sizeof(maxdb_link_properties), NULL);

      REGISTER_MAXDB_CLASS_ENTRY("maxdb_result", maxdb_result_class_entry, maxdb_result_methods);
      ce = maxdb_result_class_entry;
      zend_hash_init(&maxdb_result_properties, 0, NULL, NULL, 1);
      MAXDB_ADD_PROPERTIES(&maxdb_result_properties, maxdb_result_property_entries);
      zend_hash_add(&classes, ce->name, ce->name_length+1, &maxdb_result_properties, sizeof(maxdb_result_properties), NULL);

      REGISTER_MAXDB_CLASS_ENTRY("maxdb_stmt", maxdb_stmt_class_entry, maxdb_stmt_methods);
      ce = maxdb_stmt_class_entry;
      zend_hash_init(&maxdb_stmt_properties, 0, NULL, NULL, 1);
      MAXDB_ADD_PROPERTIES(&maxdb_stmt_properties, maxdb_stmt_property_entries);
      zend_hash_add(&classes, ce->name, ce->name_length+1, &maxdb_stmt_properties, sizeof(maxdb_stmt_properties), NULL);
#endif

      REGISTER_LONG_CONSTANT("MAXDB_COMPNAME", MAXDB_COMPNAME, CONST_CS | CONST_PERSISTENT);
      REGISTER_LONG_CONSTANT("MAXDB_APPLICATION", MAXDB_APPLICATION, CONST_CS | CONST_PERSISTENT);
      REGISTER_LONG_CONSTANT("MAXDB_APPVERSIION", MAXDB_APPVERSION, CONST_CS | CONST_PERSISTENT);
      REGISTER_LONG_CONSTANT("MAXDB_SQLMODE", MAXDB_SQLMODE, CONST_CS | CONST_PERSISTENT);
      REGISTER_LONG_CONSTANT("MAXDB_UNICODE", MAXDB_UNICODE, CONST_CS | CONST_PERSISTENT);
      REGISTER_LONG_CONSTANT("MAXDB_TIMEOUT", MAXDB_TIMEOUT, CONST_CS | CONST_PERSISTENT);
      REGISTER_LONG_CONSTANT("MAXDB_ISOLATIONLEVEL", MAXDB_ISOLATIONLEVEL, CONST_CS | CONST_PERSISTENT);
      REGISTER_LONG_CONSTANT("MAXDB_PACKETCOUNT", MAXDB_PACKETCOUNT, CONST_CS | CONST_PERSISTENT);
      REGISTER_LONG_CONSTANT("MAXDB_STATEMENTCACHESIZE", MAXDB_STATEMENTCACHESIZE, CONST_CS | CONST_PERSISTENT);
      REGISTER_LONG_CONSTANT("MAXDB_CURSORPREFIX", MAXDB_CURSORPREFIX, CONST_CS | CONST_PERSISTENT);

      REGISTER_LONG_CONSTANT("MAXDB_STORE_RESULT", 0, CONST_CS | CONST_PERSISTENT);
      REGISTER_LONG_CONSTANT("MAXDB_USE_RESULT", 1, CONST_CS | CONST_PERSISTENT);

      REGISTER_LONG_CONSTANT("MAXDB_ASSOC", MAXDB_ASSOC, CONST_CS | CONST_PERSISTENT);
      REGISTER_LONG_CONSTANT("MAXDB_ASSOC_UPPER", MAXDB_ASSOC_UPPER, CONST_CS | CONST_PERSISTENT);
      REGISTER_LONG_CONSTANT("MAXDB_ASSOC_LOWER", MAXDB_ASSOC_LOWER, CONST_CS | CONST_PERSISTENT);
      REGISTER_LONG_CONSTANT("MAXDB_NUM", MAXDB_NUM, CONST_CS | CONST_PERSISTENT);
      REGISTER_LONG_CONSTANT("MAXDB_BOTH", MAXDB_BOTH, CONST_CS | CONST_PERSISTENT);

      REGISTER_LONG_CONSTANT("MAXDB_REPORT_ERROR", MAXDB_REPORT_ERROR, CONST_CS | CONST_PERSISTENT);
      REGISTER_LONG_CONSTANT("MAXDB_REPORT_OFF", 0, CONST_CS | CONST_PERSISTENT);

      return SUCCESS;
}
/* }}} */


/* {{{ PHP_MSHUTDOWN_FUNCTION
 */
PHP_MSHUTDOWN_FUNCTION(maxdb)
{
      /* uncomment this line if you have INI entries */
      UNREGISTER_INI_ENTRIES();

      if (MAXDB_G(conn_prop)) {
            SQLDBC_ConnectProperties_delete_SQLDBC_ConnectProperties(MAXDB_G(conn_prop));
      }
      if (MAXDB_G(trace_prop)) {
            SQLDBC_ConnectProperties_delete_SQLDBC_ConnectProperties(MAXDB_G(trace_prop));
      }

      if (MAXDB_G(m_maxDBEnv)) {
            SQLDBC_Environment_delete_SQLDBC_Environment (MAXDB_G(m_maxDBEnv));
            MAXDB_G(m_maxDBEnv) = NULL;
      }

      if (MAXDB_G(error_msg)) {
            efree(MAXDB_G(error_msg));
            MAXDB_G(error_msg) = NULL;
      }

#ifdef MAXDB_OO
      zend_hash_destroy(&maxdb_link_properties);
      zend_hash_destroy(&classes);
#endif

      return SUCCESS;
}
/* }}} */


/* Remove if there's nothing to do at request start */
/* {{{ PHP_RINIT_FUNCTION
 */
PHP_RINIT_FUNCTION(maxdb)
{
      return SUCCESS;
}
/* }}} */


/* Remove if there's nothing to do at request end */
/* {{{ PHP_RSHUTDOWN_FUNCTION
 */
PHP_RSHUTDOWN_FUNCTION(maxdb)
{
      if (MAXDB_G(error_msg)) {
            efree (MAXDB_G(error_msg));
            MAXDB_G(error_msg) = NULL;
      }

      return SUCCESS;
}
/* }}} */


/* {{{ PHP_MINFO_FUNCTION
 */
PHP_MINFO_FUNCTION(maxdb)
{
      php_info_print_table_start();
      php_info_print_table_header(2, "maxdb support", "enabled");
      php_info_print_table_row(2, "PHP MaxDB Library version", "7.5.00.20");
      php_info_print_table_row(2, "SQLDBC Client API version", SQLDBC_Environment_getLibraryVersion (MAXDB_G(m_maxDBEnv)));
      php_info_print_table_end();

      DISPLAY_INI_ENTRIES();
}
/* }}} */

static bool maxdb_matchcommand(const char *check, size_t check_len, const char* match, int necessaryprefix)
{
    size_t command_len;
    int i;

    if((check == 0) || (*check==0)) {
        return 0;
    }
    command_len=strlen(match);
    if(check_len < (size_t)necessaryprefix ||  check_len > command_len) {
        return 0;
    }
    for(i=0; i<(int)check_len; ++i) {
        if(check[i]==0 && i >= necessaryprefix-1) {
            return 1;
        }
        if(toupper(check[i]) != toupper(match[i])) {
            return 0;
        }
    }
    return 1;
}

#define MAXDB_EAT_BLANKS while((debug[pos] == ' ') && (pos < debug_len)) pos++;

#define SYNTAX_ERROR(expected)                                               \
    php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU,               \
                             PHP_ERR_SYNTAX_ERROR_S,                         \
                             expected);                                      \
    return;

/* {{{ proto void maxdb_debug(string debug)
*/
/* TODO: Implement function */
PHP_FUNCTION(maxdb_debug)
{
      char *debug;
      int   debug_len;
    int pos;
    enum Command command = C_NONE;
    int m_on = 0, m_size = 0;
    char tracesize[64];

      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &debug, &debug_len) == FAILURE) {
            return;
      }

#if defined(SQLDBC_FEATURE_TRACEOPTION)
      if (!MAXDB_G(m_maxDBEnv)) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "No environment available");
        return;
      }

      if (!MAXDB_G(trace_prop)) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "No trace properties");
            return;
      }

    pos = 0;
    MAXDB_EAT_BLANKS
    if (maxdb_matchcommand(&debug[pos], 6, "TRACE ", 1)) {
        pos += 5;
        MAXDB_EAT_BLANKS
        if (maxdb_matchcommand(&debug[pos], 5, "SHORT ", 2)) {
            command = C_TRACE_SHORT;
            pos += 5;
        } else if (maxdb_matchcommand(&debug[pos], 5, "LONG ", 1)) {
            command = C_TRACE_LONG;
            pos += 4;
        } else if (maxdb_matchcommand(&debug[pos], 5, "PACKET ", 2)) {
            command = C_TRACE_PACKET;
            pos += 6;
        } else if (maxdb_matchcommand(&debug[pos], 5, "SQL ", 2)) {
            command = C_TRACE_SQL;
            pos += 3;
        } else if (maxdb_matchcommand(&debug[pos], 5, "SIZE ", 2)) {
            command = C_TRACE_SIZE;
            pos += 4;
        } else if (maxdb_matchcommand(&debug[pos], 5, "TIMESTAMP ", 1)) {
            command = C_TRACE_TIMESTAMP;
            pos += 9;
        } else {
            SYNTAX_ERROR("one of SHORT,LONG,PACKET,TIMESTAMP,SIZE,SQL,STOP");
        }
        MAXDB_EAT_BLANKS
        if (command == C_TRACE_SHORT ||
            command == C_TRACE_LONG ||
            command == C_TRACE_TIMESTAMP ||
            command == C_TRACE_SQL) {
            if (maxdb_matchcommand(&debug[pos], 2, "ON", 2)) {
                m_on = 1;
            } else if (maxdb_matchcommand(&debug[pos], 3, "OFF", 2)) {
                m_on = 0;
            } else {
                SYNTAX_ERROR("one of ON, OFF");
            }
        } else if (command == C_TRACE_PACKET) {
            if (maxdb_matchcommand(&debug[pos], 2, "ON", 2)) {
                m_on = 1;
            } else if (maxdb_matchcommand(&debug[pos], 3, "OFF", 2)) {
                m_on = 0;
            } else {
                int start, end;
                start = pos;
                end = pos;
                while ((debug[end] != ' ') && (end < debug_len)) end++;
                strncpy (tracesize, &debug[start], end-start+1);
                tracesize[end-start] = '\0';
                if (atoi(tracesize) > 0) {
                    m_on = 1;
                    m_size = atoi(tracesize);
                } else {
                    SYNTAX_ERROR("one of ON, OFF, <size>");
                }
            }
        } else if (command == C_TRACE_SIZE) {
            if (maxdb_matchcommand(&debug[pos], 9, "UNLIMITED", 1)) {
                m_size = -1;
            } else {
                int start, end;
                start = pos;
                end = pos;
                while ((debug[end] == ' ') && (end < debug_len)) end++;
                strncpy (tracesize, &debug[start], end-start+1);
                tracesize[end-start] = '\0';
                m_size = atoi(tracesize);
                if (m_size < 8192) {
                    php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                             PHP_ERR_SYNTAX_ERROR_S,
                                             "expected UNLIMITED or a number > 8192");
                    return;
                }
            }
        } else {
            SYNTAX_ERROR("TRACE");
        }
    }

    switch (command) {
    case C_NONE: {
        return;
    }
    case C_TRACE_SHORT: {
        if (m_on) {
            SQLDBC_ConnectProperties_setProperty (MAXDB_G(trace_prop), "SHORT", "TRUE");
        } else {
            SQLDBC_ConnectProperties_setProperty (MAXDB_G(trace_prop), "SHORT", "FALSE");
        }
        break;
    }
    case C_TRACE_LONG: {
        if (m_on) {
            SQLDBC_ConnectProperties_setProperty (MAXDB_G(trace_prop), "LONG", "TRUE");
        } else {
            SQLDBC_ConnectProperties_setProperty (MAXDB_G(trace_prop), "LONG", "FALSE");
        }
        break;
    }
    case C_TRACE_TIMESTAMP: {
        if (m_on) {
            SQLDBC_ConnectProperties_setProperty (MAXDB_G(trace_prop), "TIMESTAMP", "TRUE");
        } else {
            SQLDBC_ConnectProperties_setProperty (MAXDB_G(trace_prop), "TIMESTAMP", "FALSE");
        }
        break;
    }
    case C_TRACE_SQL: {
        if (m_on) {
            SQLDBC_ConnectProperties_setProperty (MAXDB_G(trace_prop), "SQL", "TRUE");
        } else {
            SQLDBC_ConnectProperties_setProperty (MAXDB_G(trace_prop), "SQL", "FALSE");
        }
        break;
    }
    case C_TRACE_PACKET: {
        if (m_on) {
            SQLDBC_ConnectProperties_setProperty (MAXDB_G(trace_prop), "PACKET", "TRUE");
            if (m_size > 0) {
                SQLDBC_ConnectProperties_setProperty (MAXDB_G(trace_prop), "FILESIZE", tracesize);
            }
        } else {
            SQLDBC_ConnectProperties_setProperty (MAXDB_G(trace_prop), "PACKET", "FALSE");
        }
        break;
    }
    case C_TRACE_SIZE: {
        if (m_size > 0) {
            SQLDBC_ConnectProperties_setProperty (MAXDB_G(trace_prop), "FILESIZE", tracesize);
        }
        break;
    }
    default: {
        break;
    }
    };
    SQLDBC_Environment_setTraceOptions(MAXDB_G(m_maxDBEnv), MAXDB_G(trace_prop));
#endif

    return;
}
/* }}} */

#undef MAXDB_EAT_BLANKS
#undef SYNTAX_ERROR

/* {{{ proto void maxdb_enable_reads_from_master(resource link)
*/
PHP_FUNCTION(maxdb_enable_reads_from_master)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto void maxdb_disable_reads_from_master(resource link)
*/
/* TODO: Implement function */
PHP_FUNCTION(maxdb_disable_reads_from_master)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto void maxdb_enable_rpl_parse(resource link)
*/
PHP_FUNCTION(maxdb_enable_rpl_parse)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto void maxdb_disable_rpl_parse(resource link)
*/
/* TODO: Implement function */
PHP_FUNCTION(maxdb_disable_rpl_parse)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto int maxdb_rpl_parse_enabled(resource link)
*/
PHP_FUNCTION(maxdb_rpl_parse_enabled)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      RETURN_LONG(0);
}
/* }}} */


/* {{{ proto bool maxdb_rpl_probe(resource link)
*/
PHP_FUNCTION(maxdb_rpl_probe)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      RETURN_FALSE;
}
/* }}} */


/* {{{ proto int maxdb_rpl_query_type(string query)
*/
PHP_FUNCTION(maxdb_rpl_query_type)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      RETURN_LONG(0);
}
/* }}} */


/* {{{ proto bool maxdb_dump_debug_info(resource link)
*/
/* TODO: Implement function */
PHP_FUNCTION(maxdb_dump_debug_info)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto resource maxdb_embedded_connect(void)
   Open a connection to a embedded MaxDB server */ 
PHP_FUNCTION(maxdb_embedded_connect)
{
#ifdef MAXDB_OO
      MAXDB_RESOURCE    *maxdb_resource;
#endif
      maxdb_connection *conn = NULL;
      char *dbname = NULL;
      int dblen = 0;

      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &dbname,  &dblen) == FAILURE) {
            return;
      }

      conn = (maxdb_connection *) emalloc (sizeof (maxdb_connection));
      if (!conn) {
            RETURN_FALSE;
      }
      php_maxdb_init_connection (conn);

      conn->m_connection = SQLDBC_Environment_createConnection(MAXDB_G(m_maxDBEnv));
      if (!conn->m_connection) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "Cannot get connection from environment");
            efree (conn);
            RETURN_FALSE;
      }
      conn->m_connprop = MAXDB_G(conn_prop);
      SQLDBC_ConnectProperties_setProperty (conn->m_connprop, "KEY", "DEFAULT");
      if (SQLDBC_Connection_connectPROP(conn->m_connection, 
                                                        conn->m_connprop) != SQLDBC_OK) {
            php_maxdb_handle_connect_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, conn);
            efree (conn);
            RETURN_FALSE;
      }
#ifdef MAXDB_OO
    maxdb_resource = (MAXDB_RESOURCE *)ecalloc (1, sizeof(MAXDB_RESOURCE));
    maxdb_resource->ptr = (void *)conn;
    MAXDB_REGISTER_RESOURCE(maxdb_resource, maxdb_link_class_entry);
#else
      conn->m_id = ZEND_REGISTER_RESOURCE(return_value, conn, le_conn);
#endif
}
/* }}} */


/* {{{ proto string maxdb_select_db(resource link, string dbname)
   Select a MaxDB database */
PHP_FUNCTION(maxdb_select_db) 
{
      zval *pv_conn;
      char *dbname;
      int dbname_len;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &pv_conn, maxdb_link_class_entry, 
                                     &dbname, &dbname_len) == FAILURE) {
            return;
      } 
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb conn");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pv_conn, &dbname, &dbname_len) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      if (SQLDBC_Connection_isConnected(conn->m_connection)) {
            if (SQLDBC_Connection_disconnect(conn->m_connection) != SQLDBC_OK) {
                  php_maxdb_handle_connect_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, conn);
                  RETURN_FALSE;
            }
            if (SQLDBC_Connection_connectASCII(conn->m_connection, 
                                                               conn->m_host, 
                                                               dbname, 
                                                               conn->m_user, 
                                                               conn->m_passwd,
                                                               conn->m_connprop) != SQLDBC_OK) {
                  php_maxdb_handle_connect_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, conn);
                  RETURN_FALSE;
            }
            MAXDB_G(thread_id) = MAXDB_G(thread_id) + 1;
            if (conn->m_db) {
                  efree(conn->m_db);
                  conn->m_db = NULL;
            }
            if (dbname) {
                  conn->m_db = estrdup(dbname);
            }
      } else {
            RETURN_FALSE;
      }

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto mixed maxdb_stat(resource link) 
   Get current system status */
PHP_FUNCTION(maxdb_stat)
{
      zval *pv_conn;
      maxdb_connection *conn;
      SQLDBC_PreparedStatement *stmt;
      SQLDBC_Length ind;
      char ver[128];

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      stmt = SQLDBC_Connection_createPreparedStatement(conn->m_connection);
      if (!stmt) {
            return;
      }
      if (SQLDBC_PreparedStatement_prepareASCII(stmt, "SELECT KERNEL INTO ? FROM DOMAIN.VERSIONS") != SQLDBC_OK) {
            SQLDBC_Connection_releasePreparedStatement (conn->m_connection, stmt);
            return;
      }
      if (SQLDBC_PreparedStatement_bindParameter (stmt,
                                                                        1,
                                                                        SQLDBC_HOSTTYPE_ASCII,
                                                                        ver,
                                                                        &ind,
                                                                        sizeof(ver),
                                                                        SQLDBC_TRUE) != SQLDBC_OK) {
            SQLDBC_Connection_releasePreparedStatement (conn->m_connection, stmt);
            return;
      }

      if (SQLDBC_PreparedStatement_executeASCII (stmt) != SQLDBC_OK) {
            SQLDBC_Connection_releasePreparedStatement (conn->m_connection, stmt);
          return;
      }

      RETURN_STRING(ver, 1);;
}
/* }}} */

#ifdef MAXDB_OO
static int maxdb_prop_stmt_field_count(maxdb_prepstmt *stmt TSRMLS_DC)
{
    if (stmt->m_result) {
        return stmt->m_result->m_numcols;
    } else {
        return -1;
    }
}

static int maxdb_prop_type_read (maxdb_result *result TSRMLS_DC)
{
    return MAXDB_USE_RESULT;
}
#endif

static int maxdb_prop_thread_id (maxdb_connection *conn TSRMLS_DC)
{
    return MAXDB_G(thread_id);
}

/* {{{ proto int maxdb_thread_id(resource link)
   Return the current thread ID */
PHP_FUNCTION(maxdb_thread_id)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      RETURN_LONG(maxdb_prop_thread_id(conn TSRMLS_CC));
}
/* }}} */


static int maxdb_prop_get_proto_info (maxdb_connection *conn TSRMLS_DC)
{
    return MAXDB_PROTOCOL_VERSION;
}

/* {{{ proto int maxdb_get_proto_info(resource link)
   Get MaxDB protocol information */
PHP_FUNCTION(maxdb_get_proto_info)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      RETURN_LONG(maxdb_prop_get_proto_info(conn TSRMLS_CC));
}
/* }}} */

static char *maxdb_prop_get_server_info (maxdb_connection *conn TSRMLS_DC)
{
    strcpy (MAXDB_G(messbuf), php_maxdb_get_server_info (conn, MAXDB_G(messbuf), sizeof(MAXDB_G(messbuf))));
    return MAXDB_G(messbuf);
}

/* {{{ proto string maxdb_get_server_info(resource link) 
   Get MaxDB server info */
PHP_FUNCTION(maxdb_get_server_info)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      RETURN_STRING(maxdb_prop_get_server_info (conn TSRMLS_CC), 1);
}
/* }}} */


/* {{{ proto bool maxdb_server_init(void)
 initialize embedded server */
PHP_FUNCTION(maxdb_server_init)
{
      zval  *server;
      zval  *groups;

      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|aa", &server, &groups) == FAILURE) {
            return;
      }

      RETURN_FALSE;
}
/* }}} */


/* {{{ proto void maxdb_server_end(void)
*/
PHP_FUNCTION(maxdb_server_end)
{
}
/* }}} */

static int maxdb_prop_get_server_version (maxdb_connection *conn TSRMLS_DC)
{
      char ver[512];

    return php_maxdb_get_version_number (php_maxdb_get_server_info (conn, ver, sizeof(ver)));
}

/* {{{ proto int maxdb_get_server_version(resource link) 
   Return the MaxDB version for the server referenced by the given link */
PHP_FUNCTION(maxdb_get_server_version)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      RETURN_LONG(maxdb_prop_get_server_version(conn TSRMLS_CC));
}
/* }}} */

static char *maxdb_prop_get_client_info (maxdb_connection *conn TSRMLS_DC)
{
    return SQLDBC_Environment_getLibraryVersion (MAXDB_G(m_maxDBEnv));
}

/* {{{ proto string maxdb_get_client_info(void) 
   Get MaxDB client info */
PHP_FUNCTION(maxdb_get_client_info)
{
    maxdb_connection *conn = NULL;

      RETURN_STRING(maxdb_prop_get_client_info(conn TSRMLS_CC), 1);
}
/* }}} */

static int maxdb_prop_get_client_version (maxdb_connection *conn TSRMLS_DC)
{
    return php_maxdb_get_version_number (SQLDBC_Environment_getLibraryVersion (MAXDB_G(m_maxDBEnv)));
}

/* {{{ proto int maxdb_get_client_version(void) 
   Get MaxDB client info */
PHP_FUNCTION(maxdb_get_client_version)
{
    maxdb_connection *conn = NULL;

      RETURN_LONG(maxdb_prop_get_client_version(conn TSRMLS_CC));
}
/* }}} */

static char *maxdb_prop_get_host_info (maxdb_connection *conn TSRMLS_DC)
{
      if (strlen(conn->m_host)) {
            return conn->m_host;
      } else {
            return "Localhost via UNIX socket";
      }
}

/* {{{ proto string maxdb_get_host_info (resource link) 
   Get MaxDB host info */
PHP_FUNCTION(maxdb_get_host_info)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

    RETURN_STRING(maxdb_prop_get_host_info(conn TSRMLS_CC), 1);
}
/* }}} */


/* {{{ proto bool maxdb_autocommit(resource link, bool mode)
   Turn auto commit on or of */
PHP_FUNCTION(maxdb_autocommit)
{
      zval *pv_conn;
      maxdb_connection *conn;
      SQLDBC_Bool automode;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ob", &pv_conn, maxdb_link_class_entry, 
                                     &automode) == FAILURE) {
            return;     
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rb", &pv_conn, &automode) == FAILURE) {
            return;
      }
      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      SQLDBC_Connection_setAutoCommit(conn->m_connection, automode);

      RETURN_TRUE;
}
/* }}} */


/* {{{ bool maxdb_report(int flags)
   sets report level */
PHP_FUNCTION(maxdb_report)
{
      long flags;

      
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &flags) == FAILURE) {
            return;
      }

      MAXDB_G(report_mode) = flags;

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto bool maxdb_options(resource link, int flags, mixed values)
   Set options */
PHP_FUNCTION(maxdb_options)
{
      zval *pv_conn;
      maxdb_connection *conn;
      long maxdb_option;
      zval *maxdb_value;
    char *c_value;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olz", &pv_conn, 
                                     maxdb_link_class_entry, &maxdb_option, &maxdb_value) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz", &pv_conn, &maxdb_option, &maxdb_value) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      if (!MAXDB_G(conn_prop)) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "No connect properties");
            RETURN_FALSE;
      }
    
      switch (Z_TYPE_PP(&maxdb_value)) {
    case IS_STRING:
        SQLDBC_ConnectProperties_setProperty (MAXDB_G(conn_prop), maxdb_optionlist[maxdb_option], 
                                              Z_STRVAL_PP(&maxdb_value));
        break;
    case IS_LONG:
        convert_to_string(maxdb_value);
        c_value = Z_STRVAL_PP(&maxdb_value);
        SQLDBC_ConnectProperties_setProperty (MAXDB_G(conn_prop), maxdb_optionlist[maxdb_option],
                                              c_value);
        break;
    default:
        break;
      }

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto resource maxdb_init(void)
   Initialize maxdb and return a resource for use with maxdb_real_connect */
PHP_FUNCTION(maxdb_init)
{
      maxdb_connection *conn = NULL;
#ifdef MAXDB_OO
    MAXDB_RESOURCE *maxdb_resource = (MAXDB_RESOURCE *) ecalloc (1, sizeof(MAXDB_RESOURCE));
#endif

      conn = (maxdb_connection *) emalloc (sizeof (maxdb_connection));
      if (!conn) {
            RETURN_FALSE;
      }
      php_maxdb_init_connection (conn);

#ifdef MAXDB_OO
    maxdb_resource->ptr = (void *) conn;
    MAXDB_RETURN_RESOURCE(maxdb_resource, maxdb_link_class_entry);
#else
      conn->m_id = ZEND_REGISTER_RESOURCE(return_value, conn, le_conn);

      RETURN_RESOURCE(conn->m_id);
#endif
}
/* }}} */


/* {{{ proto bool maxdb_real_connect(resource link [,string hostname [,string username [,string passwd [,string dbname]]]])
   Open a connection to a MaxDB server */ 
PHP_FUNCTION(maxdb_real_connect)
{
      zval *pv_conn;
      char *hostname = NULL, *username = NULL, *passwd = NULL, *dbname = NULL, *socket = NULL;
      unsigned int hostname_len, username_len, passwd_len, dbname_len, socket_len;
      long port = 0;
      long flags = 0;
      maxdb_connection *conn = NULL;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sssslsl", &pv_conn, maxdb_link_class_entry,
                                     &hostname, &hostname_len, 
                                     &username, &username_len, 
                                     &passwd, &passwd_len, 
                                     &dbname, &dbname_len, 
                                     &port, &socket, 
                                     &socket_len, &flags) == FAILURE) {
            return;
      }
#else
      if (getThis() && !ZEND_NUM_ARGS()) {
            RETURN_NULL();
      }

      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ssssls", &pv_conn, &hostname, &hostname_len, 
                                            &username, &username_len, 
                                            &passwd, &passwd_len, 
                                            &dbname, &dbname_len, 
                                            &port, &socket, 
                                            &socket_len, &flags) == FAILURE) {
            return;
      }
#endif

#ifdef MAXDB_OO
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb conn");
#else
      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      if (MAXDB_G(ssl_error)) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "SSL setup is incorrect");
            RETURN_FALSE;
      }

      if (!dbname) {
            dbname = MAXDB_G(default_db);
            if (!passwd) {
                  passwd = MAXDB_G(default_pw);
                  if (!username){
                        username = MAXDB_G(default_user);
                        if (!hostname) {
                              hostname = MAXDB_G(default_host);
                        }
                  }
            }
      }

    php_maxdb_init_environment (INTERNAL_FUNCTION_PARAM_PASSTHRU);

      if (!MAXDB_G(m_maxDBEnv)) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "No environment available");
            RETURN_FALSE;
      }
      
      conn->m_connection = SQLDBC_Environment_createConnection(MAXDB_G(m_maxDBEnv));
      if (!conn) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "Cannot get connection from environment");
            RETURN_FALSE;
      }
      conn->m_connprop = MAXDB_G(conn_prop);
      if (SQLDBC_Connection_connectASCII(conn->m_connection, 
                                                         hostname, 
                                                         dbname, 
                                                         username, 
                                                         passwd,
                                                         conn->m_connprop) != SQLDBC_OK) {
            php_maxdb_handle_connect_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, conn);
            RETURN_FALSE;
      }
      MAXDB_G(thread_id) = MAXDB_G(thread_id) + 1;
      if (hostname) {
            conn->m_host = estrdup(hostname);
      }
      if (conn->m_db) {
            efree(conn->m_db);
      }
      if (dbname) {
            conn->m_db = estrdup(dbname);
      }
    if (conn->m_user) {
        efree (conn->m_user);
    }
    if (conn->m_passwd) {
        efree (conn->m_passwd);
    }
      conn->m_user = estrdup(username);
      conn->m_passwd = estrdup(passwd);

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto bool maxdb_ssl_set(resource link ,string key ,string cert ,string ca ,string capath ,string cipher])
*/
PHP_FUNCTION(maxdb_ssl_set)
{
      zval *pv_conn;
      maxdb_connection *conn;
      char *ssl_parm[5];
      int   ssl_parm_len[5];

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osssss", &pv_conn, maxdb_link_class_entry, 
                                     &ssl_parm[0], &ssl_parm_len[0], 
                                     &ssl_parm[1], &ssl_parm_len[1], 
                                     &ssl_parm[2], &ssl_parm_len[2], 
                                     &ssl_parm[3], &ssl_parm_len[3], 
                                     &ssl_parm[4], &ssl_parm_len[4])   == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsssss", &pv_conn, &ssl_parm[0], &ssl_parm_len[0], 
                                            &ssl_parm[1], &ssl_parm_len[1],
                                            &ssl_parm[2], &ssl_parm_len[2], 
                                            &ssl_parm[3], &ssl_parm_len[3], 
                                            &ssl_parm[4], &ssl_parm_len[4]) == FAILURE) {
            return;
      }
      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      MAXDB_G(ssl_error) = 1;

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto resource maxdb_connect([string hostname [,string username [,string passwd [,string dbname [,int port]]]]])
   Connects to a database */
PHP_FUNCTION(maxdb_connect)
{
      char *hostname = NULL, *username = NULL, *passwd = NULL, *dbname = NULL, *socket = NULL;
      unsigned int hostname_len, username_len, passwd_len, dbname_len, socket_len;
      long port = 0;
      maxdb_connection *conn = NULL;
#ifdef MAXDB_OO
    MAXDB_RESOURCE *maxdb_resource;
    zval *object = getThis();
#endif

      if (getThis() && !ZEND_NUM_ARGS()) {
            RETURN_NULL();
      }

      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ssssls", &hostname, &hostname_len, &username, &username_len, 
                                            &passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len) == FAILURE) {
            return;
      }
      
      if (!dbname) {
            dbname = MAXDB_G(default_db);
            if (!passwd) {
                  passwd = MAXDB_G(default_pw);
                  if (!username){
                        username = MAXDB_G(default_user);
                        if (!hostname) {
                              hostname = MAXDB_G(default_host);
                        }
                  }
            }
      }
      
    php_maxdb_init_environment (INTERNAL_FUNCTION_PARAM_PASSTHRU);

      if (!MAXDB_G(m_maxDBEnv)) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "No environment available");
            RETURN_FALSE;
      }
      
      conn = (maxdb_connection *) emalloc (sizeof (maxdb_connection));
      if (!conn) {
            RETURN_FALSE;
      }
      php_maxdb_init_connection (conn);

      conn->m_connection = SQLDBC_Environment_createConnection(MAXDB_G(m_maxDBEnv));
      if (!conn->m_connection) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "Cannot get connection from environment");
            efree (conn);
            RETURN_FALSE;
      }
      conn->m_connprop = MAXDB_G(conn_prop);
      SQLDBC_ConnectProperties_setProperty (conn->m_connprop, "SELECTFETCHOPTIMIZE", "0");
      if (hostname) {
            conn->m_host = estrdup (hostname);        
      }
      if (conn->m_db) {
            efree(conn->m_db);
            conn->m_db = NULL;
      }
      if (dbname) {
            conn->m_db = estrdup(dbname);
      }
    if (conn->m_user) {
        efree (conn->m_user);
    }
    if (conn->m_passwd) {
        efree (conn->m_passwd);
    }
      conn->m_user = estrdup(username);
      conn->m_passwd = estrdup(passwd);

      if (SQLDBC_Connection_connectASCII(conn->m_connection, 
                                                         conn->m_host, 
                                                         conn->m_db, 
                                                         username, 
                                                         passwd,
                                                         conn->m_connprop) != SQLDBC_OK) {
            php_maxdb_handle_connect_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, conn);
            if (conn->m_host) {
                  efree (conn->m_host);
                  conn->m_host = NULL;
            }
            if (conn->m_db) {
                  efree (conn->m_db);
                  conn->m_db = NULL;
            }
        if (conn->m_user) {
            efree (conn->m_user);
        }
        if (conn->m_passwd) {
            efree (conn->m_passwd);
        }
        efree (conn);
            RETURN_FALSE;
      }
      MAXDB_G(thread_id) = MAXDB_G(thread_id) + 1;
#ifdef MAXDB_OO
    maxdb_resource = (MAXDB_RESOURCE *)ecalloc (1, sizeof(MAXDB_RESOURCE));
    maxdb_resource->ptr = (void *)conn;
    if (!object) {
        MAXDB_RETURN_RESOURCE(maxdb_resource, maxdb_link_class_entry);
    } else {
        ((maxdb_object *) zend_object_store_get_object(object TSRMLS_CC))->ptr = maxdb_resource;
            ((maxdb_object *) zend_object_store_get_object(object TSRMLS_CC))->valid = 1;
    }
#else
    conn->m_id = ZEND_REGISTER_RESOURCE(return_value, conn, le_conn);
#endif
}
/* }}} */

static int maxdb_prop_connect_errno (maxdb_connection *conn TSRMLS_DC)
{
    return MAXDB_G(error_no);
}

/* {{{ proto int maxdb_connect_errno(void)
   Returns the numerical value of the error message from last connect command */
PHP_FUNCTION(maxdb_connect_errno)
{
    maxdb_connection *conn = NULL;

      RETURN_LONG(maxdb_prop_connect_errno(conn TSRMLS_CC));
}
/* }}} */

static char *maxdb_prop_connect_error (maxdb_connection *conn TSRMLS_DC)
{
      if (MAXDB_G(error_msg)) {
            return MAXDB_G(error_msg);
      } else {
            return empty_string;
      }
}

/* {{{ proto string maxdb_connect_error(void)
   Returns the text of the error message from previous MaxDB operation */
PHP_FUNCTION(maxdb_connect_error) 
{
    maxdb_connection *conn = NULL;

    RETURN_STRING(maxdb_prop_connect_error(conn TSRMLS_CC), 1);
}
/* }}} */


/* {{{ proto bool maxdb_rollback(resource link)
   Undo actions from current transaction */
PHP_FUNCTION(maxdb_rollback)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }
      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      if (SQLDBC_Connection_rollback(conn->m_connection) != SQLDBC_OK) {
            php_maxdb_sqldbc_error(INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                             SQLDBC_Connection_getError(conn->m_connection));
            RETURN_FALSE;
      }

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto bool maxdb_kill(resource link, int processid)
   Kill a MaxDB process on the server */
PHP_FUNCTION(maxdb_kill)
{
      zval *pv_conn;
      maxdb_connection *conn;
      int processid;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &pv_conn, 
                                     maxdb_link_class_entry, &processid) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &pv_conn, &processid) == FAILURE) {
            return;
      }
      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      if (SQLDBC_Connection_disconnect(conn->m_connection) != SQLDBC_OK) {
            php_maxdb_handle_connect_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, conn);
            RETURN_FALSE;
      }

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto bool maxdb_change_user(resource link, string user, string password, string database)
   Change logged-in user of the active connection */
PHP_FUNCTION(maxdb_change_user)
{
      zval *pv_conn;
      maxdb_connection *conn;
      char *user, *password, *dbname;
      int user_len, password_len, dbname_len;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osss", &pv_conn, maxdb_link_class_entry, 
                                     &user, &user_len, &password, &password_len, &dbname, &dbname_len) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsss", &pv_conn, 
                              &user, &user_len, &password, &password_len, &dbname, &dbname_len) == FAILURE) {
            return;
      }
      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      if (SQLDBC_Connection_disconnect(conn->m_connection) != SQLDBC_OK) {
            php_maxdb_sqldbc_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                             SQLDBC_Connection_getError(conn->m_connection));
            RETURN_FALSE;
      }

      if (SQLDBC_Connection_connectASCII(conn->m_connection, 
                                                         conn->m_host, 
                                                         dbname, 
                                                         user, 
                                                         password,
                                                         conn->m_connprop) != SQLDBC_OK) {
            php_maxdb_sqldbc_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                             SQLDBC_Connection_getError(conn->m_connection));
            RETURN_FALSE;
      }
      MAXDB_G(thread_id) = MAXDB_G(thread_id) + 1;
      if (conn->m_db) {
            efree(conn->m_db);
            conn->m_db = NULL;
      }
      if (dbname) {
            conn->m_db = estrdup(dbname);
      }
    if (conn->m_user) {
        efree (conn->m_user);
    }
    if (conn->m_passwd) {
        efree (conn->m_passwd);
    }
      conn->m_user = estrdup(user);
      conn->m_passwd = estrdup(password);

      RETURN_TRUE;
}
/* }}} */


#define INSERTID_LEN 100

#ifdef MAXDB_OO
static int maxdb_prop_insert_id (maxdb_connection *conn TSRMLS_DC)
{
      SQLDBC_Length ind;
      char id[INSERTID_LEN];
      SQLDBC_UInt4 ul = 0;
    memset (id, '\0', sizeof(id));

      ind = SQLDBC_NTS;
      if (conn->m_isprepared) {
            if (SQLDBC_PreparedStatement_getLastInsertedKey(conn->m_prepstmt,
                                                                                    SQLDBC_LAST_INSERTED_SERIAL,
                                                                                    SQLDBC_HOSTTYPE_UINT4,
                                                                                    &ul,
                                                                                    &ind,
                                                                                    sizeof(SQLDBC_UInt4),
                                                                                    1) == SQLDBC_OVERFLOW) {
            return 0;
        } else {
            return ul;
        }
      } else {
            if (SQLDBC_Statement_getLastInsertedKey(conn->m_stmt,
                                                                        SQLDBC_LAST_INSERTED_SERIAL,
                                                                        SQLDBC_HOSTTYPE_UINT4,
                                                                        &ul,
                                                                        &ind,
                                                                        sizeof(SQLDBC_UInt4),
                                                                        1) == SQLDBC_OVERFLOW) {
            return 0;
            } else {
                  return ul;
            }
      }
}

static int maxdb_prop_stmt_insert_id (maxdb_prepstmt *stmt TSRMLS_DC)
{
      SQLDBC_Length ind;
      char id[INSERTID_LEN];
      SQLDBC_UInt4 ul = 0;
    memset (id, '\0', sizeof(id));

      ind = SQLDBC_NTS;
    if (SQLDBC_PreparedStatement_getLastInsertedKey(stmt->m_prepstmt,
                                                    SQLDBC_LAST_INSERTED_SERIAL,
                                                    SQLDBC_HOSTTYPE_UINT4,
                                                    &ul,
                                                    &ind,
                                                    sizeof(SQLDBC_UInt4),
                                                    1) == SQLDBC_OVERFLOW) {
        return 0;
    } else {
        return ul;
    }
}
#endif

/* {{{ proto mixed maxdb_insert_id(resource link)
   Get the ID generated from the previous INSERT operation */
PHP_FUNCTION(maxdb_insert_id)
{
      zval *pv_conn;
      maxdb_connection *conn;
      SQLDBC_Length ind;
      char id[INSERTID_LEN];
      SQLDBC_UInt4 ul = 0;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif
    memset (id, '\0', sizeof(id));

      ind = SQLDBC_NTS;
      if (conn->m_isprepared) {
            if (SQLDBC_PreparedStatement_getLastInsertedKey(conn->m_prepstmt,
                                                                                    SQLDBC_LAST_INSERTED_SERIAL,
                                                                                    SQLDBC_HOSTTYPE_UINT4,
                                                                                    &ul,
                                                                                    &ind,
                                                                                    sizeof(SQLDBC_UInt4),
                                                                                    1) == SQLDBC_OVERFLOW) {
                  if (SQLDBC_PreparedStatement_getLastInsertedKey(conn->m_prepstmt,
                                                                                          SQLDBC_LAST_INSERTED_SERIAL,
                                                                                          SQLDBC_HOSTTYPE_ASCII,
                                                                                          id,
                                                                                          &ind,
                                                                                          INSERTID_LEN,
                                                                                          1) != SQLDBC_OK) {
                        php_maxdb_sqldbc_error (INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                                            SQLDBC_PreparedStatement_getError(conn->m_prepstmt));
                        RETURN_NULL();
                  } else {
                        RETURN_STRING(id, 1);
                  }
            } else {
                  RETURN_LONG(ul);
            }
      } else {
            if (SQLDBC_Statement_getLastInsertedKey(conn->m_stmt,
                                                                        SQLDBC_LAST_INSERTED_SERIAL,
                                                                        SQLDBC_HOSTTYPE_UINT4,
                                                                        &ul,
                                                                        &ind,
                                                                        sizeof(SQLDBC_UInt4),
                                                                        1) == SQLDBC_OVERFLOW) {
                  if (SQLDBC_Statement_getLastInsertedKey(conn->m_stmt,
                                                                              SQLDBC_LAST_INSERTED_SERIAL,
                                                                              SQLDBC_HOSTTYPE_ASCII,
                                                                              id,
                                                                              &ind,
                                                                              INSERTID_LEN,
                                                                              1) != SQLDBC_OK) {
                        php_maxdb_sqldbc_error (INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                                            SQLDBC_PreparedStatement_getError(conn->m_prepstmt));
                        RETURN_NULL();
                  } else {
                        RETURN_STRING(id, 1);
                  }
            } else {
                  RETURN_LONG(ul);
            }
      }
}
/* }}} */
#undef INSERTID_LEN


/* {{{ proto string maxdb_real_escape_string(resource link, string escapestr) 
   Escapes special characters in a string for use in a SQL statement, taking into account the current charset of the connection */
PHP_FUNCTION(maxdb_real_escape_string)
{
      zval *pv_conn;
      char *escapestr, *newstr;
      int escapestr_len;
      maxdb_connection *conn;
      int i, j;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &pv_conn, maxdb_link_class_entry, 
                                     &escapestr, &escapestr_len) == FAILURE) {
            return;
      }     
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pv_conn, &escapestr, &escapestr_len) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      newstr = safe_emalloc(2, escapestr_len, 1);
      if (!newstr) {
            RETURN_STRING(empty_string, 1);
      }
      j = 0;
      for (i = 0; i < escapestr_len; i++) {
            newstr[j] = escapestr[i];
            if (escapestr[i] == '\'') {
                  newstr[++j] = '\'';
            }
            j++;
      }
      newstr = erealloc(newstr, j + 1);
    newstr[j] = '\0';

      RETURN_STRING(newstr, 0);
}
/* }}} */


/* {{{ proto resource maxdb_query(string query [, int connection_identifier])
   Sends an SQL query to MaxDB */
PHP_FUNCTION(maxdb_query)
{
      zval *pv_conn;
      char *query;
      int query_len;
#ifdef MAXDB_OO
      MAXDB_RESOURCE    *maxdb_resource;
#endif
      maxdb_connection *conn;
    maxdb_result *result = NULL;
    unsigned int resultmode = 0;
    bool err;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l", &pv_conn, maxdb_link_class_entry, 
                                     &query, &query_len, &resultmode) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb conn");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &pv_conn, &query, &query_len, &resultmode) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

#ifdef MAXDB_OO
    if (conn->m_result != 0) {
#else
    if (conn->m_resultid != 0) {
#endif
        php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_CMD_OUT_OF_SYNC);
        RETURN_FALSE;
    }

      php_maxdb_do_query_general (INTERNAL_FUNCTION_PARAM_PASSTHRU, query, conn, &result, &err);
    if (err == 1) {
        RETURN_FALSE;
    }
    if (conn->m_result) {
        php_maxdb_free_result(conn->m_result);
    }
    conn->m_result = result;
    if (result) {
        result->m_conn = conn;
    }
#ifdef MAXDB_OO
    if (result) {
        result->m_conn = conn;
        maxdb_resource = (MAXDB_RESOURCE *)ecalloc (1, sizeof(MAXDB_RESOURCE));
        maxdb_resource->ptr = (void *)result;
        MAXDB_RETURN_RESOURCE(maxdb_resource, maxdb_result_class_entry);
    } else {
        RETURN_TRUE;
    }
#else
      if (conn->m_resultid) {
            RETURN_RESOURCE(conn->m_resultid);
      } else {
            RETURN_TRUE;
      }
#endif
}
/* }}} */


/* {{{ proto bool maxdb_send_query(resource link, string query)
*/
PHP_FUNCTION(maxdb_send_query)
{
      zval *pv_conn;
      char *query;
      int query_len;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &pv_conn, maxdb_link_class_entry, 
                                     &query, &query_len) == FAILURE) {
            return;
      } 
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb conn");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pv_conn, &query, &query_len) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      RETURN_FALSE;
}
/* }}} */


/* {{{ proto bool maxdb_real_query(resource link, string query)
   Binary-safe version of maxdb_query() */
PHP_FUNCTION(maxdb_real_query)
{
      zval *pv_conn;
      char *query;
      int query_len;
#ifdef MAXDB_OO
      MAXDB_RESOURCE    *maxdb_resource;
#endif
      maxdb_connection *conn;
    maxdb_result *result = NULL;
    bool err;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &pv_conn, maxdb_link_class_entry, 
                                     &query, &query_len) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pv_conn, &query, &query_len) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      php_maxdb_do_query_general (INTERNAL_FUNCTION_PARAM_PASSTHRU, query, conn, &result, &err);
    if (err == 1) {
        RETURN_FALSE;
    }
    if (conn->m_result) {
        php_maxdb_free_result(conn->m_result);
    }
    conn->m_result = result;
    if (result) {
        result->m_conn = conn;
    }
#ifdef MAXDB_OO
    if (result) {
        result->m_conn = conn;
        maxdb_resource = (MAXDB_RESOURCE *)ecalloc (1, sizeof(MAXDB_RESOURCE));
        maxdb_resource->ptr = (void *)result;
        MAXDB_REGISTER_RESOURCE(maxdb_resource, maxdb_result_class_entry);
    }
#endif

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto bool maxdb_master_query(resource link, string query)
   Enforce execution of a query on the master in a master/slave setup */
PHP_FUNCTION(maxdb_master_query)
{
      zval *pv_conn;
      char *query;
      int query_len;
      maxdb_connection *conn;
    maxdb_result *result = NULL;
    bool err;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &pv_conn, maxdb_link_class_entry, 
                                     &query, &query_len) == FAILURE) {
            return;
      } 
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb conn");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pv_conn, &query, &query_len) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      php_maxdb_do_query_general (INTERNAL_FUNCTION_PARAM_PASSTHRU, query, conn, &result, &err);
}
/* }}} */


/* {{{ proto bool maxdb_multi_query(resource link, string query)
   Binary-safe version of maxdb_query() */
PHP_FUNCTION(maxdb_multi_query)
{
      zval *pv_conn;
      char *query;
      int query_len;
      maxdb_connection *conn;
    maxdb_result *result = NULL;
    bool err;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &pv_conn, maxdb_link_class_entry, 
                                     &query, &query_len) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pv_conn, &query, &query_len) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      php_maxdb_do_query_general (INTERNAL_FUNCTION_PARAM_PASSTHRU, query, conn, &result, &err);
}
/* }}} */


/* {{{ proto resource maxdb_store_result(resource link)
   Buffer result set on client */
PHP_FUNCTION(maxdb_store_result)
{
      zval *pv_conn;
#ifdef MAXDB_OO
      MAXDB_RESOURCE    *maxdb_resource;
#else
    zval *pv_result;
#endif
      maxdb_connection *conn;
      maxdb_result *result, *mresult;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
    result = conn->m_result;
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
      ZEND_FETCH_RESOURCE(result, maxdb_result *, &pv_result, conn->m_resultid, "maxdb result", le_result);
#endif

      if (result) {
            result->m_noclose = SQLDBC_TRUE;
            mresult = php_maxdb_copy_result(result);
#ifdef MAXDB_OO
        maxdb_resource = (MAXDB_RESOURCE *)ecalloc (1, sizeof(MAXDB_RESOURCE));
        maxdb_resource->ptr = (void *)mresult;
        MAXDB_RETURN_RESOURCE(maxdb_resource, maxdb_result_class_entry);
#else
            mresult->m_id = ZEND_REGISTER_RESOURCE(return_value, mresult, le_result);
            RETURN_RESOURCE(mresult->m_id);
#endif
      } else {
            RETURN_FALSE;
      }
}
/* }}} */


/* {{{ proto mixed maxdb_use_result(resource link)
   Directly retrieve query results - do not buffer results on client side */
PHP_FUNCTION(maxdb_use_result)
{
      zval *pv_conn;
#ifdef MAXDB_OO
      MAXDB_RESOURCE    *maxdb_resource;
#endif
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }
      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

    if (conn->m_result) {
#ifdef MAXDB_OO
        maxdb_resource = (MAXDB_RESOURCE *)ecalloc (1, sizeof(MAXDB_RESOURCE));
        maxdb_resource->ptr = (void *)conn->m_result;
        MAXDB_RETURN_RESOURCE(maxdb_resource, maxdb_result_class_entry);
#else
        RETURN_RESOURCE(conn->m_resultid);
#endif        
    } else {
        RETURN_FALSE;
    }
}
/* }}} */


/* {{{ proto bool maxdb_next_result(resource link)
   read next result from multi_query */
PHP_FUNCTION(maxdb_next_result)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, 
                                     maxdb_link_class_entry) == FAILURE) {
            return;
      } 
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb conn");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      RETURN_FALSE;
}
/* }}} */


/* {{{ proto bool maxdb_more_results(resource link)
   check if there any more query results from a multi query */
PHP_FUNCTION(maxdb_more_results)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, 
                                     maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }
      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      RETURN_FALSE;
}
/* }}} */

static char *maxdb_prop_sqlstate (maxdb_connection *conn TSRMLS_DC)
{
      if (conn->m_errhndl) {
            return ((char *) SQLDBC_ErrorHndl_getSQLState(conn->m_errhndl));
      } else {
            return ("<no sqlstate available>");
      }
}

/* {{{ proto string maxdb_sqlstate(resource link)
   Returns the SQLSTATE error from previous MaxDB operation */
PHP_FUNCTION(maxdb_sqlstate)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }
      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

    RETURN_STRING(maxdb_prop_sqlstate(conn TSRMLS_CC), 1);
}
/* }}} */


/* {{{ proto mixed maxdb_prepare(resource link, string query)
   Prepare a SQL statement for execution */
PHP_FUNCTION(maxdb_prepare)
{
      zval *pv_conn;
#ifdef MAXDB_OO
    MAXDB_RESOURCE *maxdb_resource;
#endif
      maxdb_connection *conn;
      maxdb_prepstmt *prepstmt = NULL;
      char *query = NULL;
      SQLDBC_UInt4 query_len;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os",&pv_conn, maxdb_link_class_entry, 
                                     &query, &query_len) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb conn");
#else
      if (getThis() && !ZEND_NUM_ARGS()) {
            RETURN_NULL();
      }

      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pv_conn, &query, &query_len) == FAILURE) {
            return;
      }
      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      prepstmt = (maxdb_prepstmt *) emalloc (sizeof (maxdb_prepstmt));
      if (!prepstmt) {
            RETURN_FALSE;
      }
      php_init_prepared_statement (prepstmt);
      prepstmt->m_prepstmt = SQLDBC_Connection_createPreparedStatement (conn->m_connection);
      if (!prepstmt->m_prepstmt) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, "Cannot create prepared statement");
            RETURN_FALSE;
      }
      prepstmt->m_isexecuted = SQLDBC_FALSE;

      if (SQLDBC_PreparedStatement_prepareASCII  (prepstmt->m_prepstmt, query) != SQLDBC_OK) {
        php_maxdb_sqldbc_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                               SQLDBC_PreparedStatement_getError(prepstmt->m_prepstmt));
        efree (prepstmt);
        RETURN_FALSE;
    }
      prepstmt->m_parammetadata = SQLDBC_PreparedStatement_getParameterMetaData (prepstmt->m_prepstmt);
      
      if (!prepstmt->m_parammetadata) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, "Cannot get parameter metadata");
            RETURN_FALSE;
      } else {
          prepstmt->m_parcnt = SQLDBC_ParameterMetaData_getParameterCount (prepstmt->m_parammetadata);
      }

#ifndef MAXDB_OO
      prepstmt->m_id = ZEND_REGISTER_RESOURCE(return_value, prepstmt, le_prepstmt);
#endif
    prepstmt->m_result = (maxdb_result *) emalloc (sizeof(maxdb_result));
      if (!prepstmt->m_result) {
            RETURN_FALSE;
      }
      php_init_result (prepstmt->m_result);
      prepstmt->m_clink = pv_conn;

#ifdef MAXDB_OO
      maxdb_resource = (MAXDB_RESOURCE *)ecalloc (1, sizeof(MAXDB_RESOURCE));
      maxdb_resource->ptr = (void *)prepstmt;
      MAXDB_RETURN_RESOURCE(maxdb_resource, maxdb_stmt_class_entry);
#else
      RETURN_RESOURCE(prepstmt->m_id);
#endif
}
/* }}} */


/* {{{ proto mixed maxdb_stmt_init(resource link)
   Initialize statement resource
*/
PHP_FUNCTION(maxdb_stmt_init)
{
      zval *pv_conn;
      maxdb_connection *conn;
      maxdb_prepstmt *prepstmt = NULL;
#ifdef MAXDB_OO
      MAXDB_RESOURCE *maxdb_resource;
#endif

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",&pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            RETURN_NULL();
      }
      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      prepstmt = (maxdb_prepstmt *) emalloc (sizeof (maxdb_prepstmt));
      if (!prepstmt) {
            RETURN_NULL();
      }
    php_init_prepared_statement (prepstmt);

      prepstmt->m_prepstmt = SQLDBC_Connection_createPreparedStatement (conn->m_connection);
      if (!prepstmt->m_prepstmt) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, "Cannot create prepared statement");
            RETURN_NULL();
      }
      prepstmt->m_clink = pv_conn;
#ifdef MAXDB_OO
      maxdb_resource = (MAXDB_RESOURCE *)ecalloc (1, sizeof(MAXDB_RESOURCE));
      maxdb_resource->ptr = (void *)prepstmt;
      MAXDB_RETURN_RESOURCE(maxdb_resource, maxdb_stmt_class_entry);
#else
      prepstmt->m_id = ZEND_REGISTER_RESOURCE(return_value, prepstmt, le_prepstmt);

      RETURN_RESOURCE(prepstmt->m_id);
#endif
}
/* }}} */


/* {{{ proto bool maxdb_stmt_prepare(resource stmt, string query)
   prepare server side statement with query
*/
PHP_FUNCTION(maxdb_stmt_prepare)
{
      zval *pv_prepstmt;
      maxdb_prepstmt *prepstmt;
      char *query;
      int query_len;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &pv_prepstmt, maxdb_stmt_class_entry, 
                                     &query, &query_len) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pv_prepstmt, &query, &query_len) == FAILURE) {
            RETURN_FALSE;     
      }

      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (!prepstmt->m_prepstmt) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_ERR_STATEMENT_NOT_PREPARED);
            RETURN_FALSE;
      }
      if (SQLDBC_PreparedStatement_prepareASCII  (prepstmt->m_prepstmt, query) != SQLDBC_OK) {
        php_maxdb_sqldbc_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                               SQLDBC_PreparedStatement_getError(prepstmt->m_prepstmt));
        RETURN_FALSE;
    }
      prepstmt->m_parammetadata = SQLDBC_PreparedStatement_getParameterMetaData (prepstmt->m_prepstmt);
      
      if (!prepstmt->m_parammetadata) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, "Cannot get parameter metadata");
            RETURN_FALSE;
      } else {
          prepstmt->m_parcnt = SQLDBC_ParameterMetaData_getParameterCount (prepstmt->m_parammetadata);
      }

    prepstmt->m_result = (maxdb_result *) emalloc (sizeof(maxdb_result));
      if (!prepstmt->m_result) {
            RETURN_FALSE;
      }
      php_init_result (prepstmt->m_result);

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto bool maxdb_stmt_execute(resource stmt)
   Execute a prepared statement */
PHP_FUNCTION(maxdb_stmt_execute)
{
      zval *pv_prepstmt;
      maxdb_prepstmt *prepstmt;
      maxdb_connection *conn;
      SQLDBC_Retcode exec_rc;
      long lval;
      double dval;
      int i;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_prepstmt, 
                                     maxdb_stmt_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt"); 
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_prepstmt) == FAILURE) {
            RETURN_FALSE;     
      }

      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (!prepstmt->m_prepstmt) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_ERR_STATEMENT_NOT_PREPARED);
            RETURN_FALSE;
      }

#ifdef MAXDB_OO
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &prepstmt->m_clink, "maxdb conn");
#else
      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &prepstmt->m_clink, -1, "maxdb conn", le_conn);
#endif
      conn->m_isprepared = 1;
      conn->m_prepstmt = prepstmt->m_prepstmt;

      if (!php_maxdb_bind_parameters (INTERNAL_FUNCTION_PARAM_PASSTHRU, prepstmt)){
            RETURN_FALSE;
      }

      exec_rc = SQLDBC_PreparedStatement_executeASCII (prepstmt->m_prepstmt); 
      if ((exec_rc != SQLDBC_OK) && (exec_rc != SQLDBC_NO_DATA_FOUND) && (exec_rc != SQLDBC_DATA_TRUNC)) {
            php_maxdb_sqldbc_error (INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                                SQLDBC_PreparedStatement_getError(prepstmt->m_prepstmt));
            RETURN_FALSE;
      }
      prepstmt->m_isexecuted = SQLDBC_TRUE;

      conn->m_rowsaffected = SQLDBC_PreparedStatement_getRowsAffected(prepstmt->m_prepstmt);
      if (SQLDBC_PreparedStatement_isQuery (prepstmt->m_prepstmt)) {

            prepstmt->m_result->m_resultset = SQLDBC_PreparedStatement_getResultSet  (prepstmt->m_prepstmt);
            if (!prepstmt->m_result->m_resultset) {
                  php_maxdb_sqldbc_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                   SQLDBC_PreparedStatement_getError(prepstmt->m_prepstmt)) ;
                  RETURN_FALSE; 
            }
            if (!prepstmt->m_result->m_rsmd) {
                  prepstmt->m_result->m_rsmd = SQLDBC_ResultSet_getResultSetMetaData(prepstmt->m_result->m_resultset);
                  if (!prepstmt->m_result->m_rsmd) {
                        php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                             PHP_ERR_INITIALIZATION_FAILED_S, 
                                                             "Cannot get resultset metadata");
                        RETURN_FALSE;
                  }
            }
            
            prepstmt->m_result->m_numcols = SQLDBC_ResultSetMetaData_getColumnCount (prepstmt->m_result->m_rsmd);
        prepstmt->m_result->m_conn = conn;
            conn->m_numcols = prepstmt->m_result->m_numcols;

            if (exec_rc == SQLDBC_NO_DATA_FOUND){
                  prepstmt->m_rownotfound = SQLDBC_TRUE;
                  RETURN_TRUE; 
            }

            if (!php_maxdb_register_resultset(INTERNAL_FUNCTION_PARAM_PASSTHRU, prepstmt->m_result)) {
                  RETURN_FALSE;
            }
      } else {
        for (i = 0; i < prepstmt->m_parcnt; i++) {
            ParameterMode pMode = SQLDBC_ParameterMetaData_getParameterMode  (prepstmt->m_parammetadata, i+1);
            if (pMode == parameterModeInOut || pMode == parameterModeOut) {
                switch (prepstmt->m_bindparams[i].hostType) {
                case SQLDBC_HOSTTYPE_INT1 : {
                    SQLDBC_Int1 tmp;
                    memcpy (&tmp, prepstmt->m_bindparams[i].buf, sizeof(SQLDBC_Int1));
                    ZVAL_BOOL(prepstmt->m_bindparams[i].var, tmp);
                    break;
                }
                case SQLDBC_HOSTTYPE_BINARY: {
                    ZVAL_STRINGL(prepstmt->m_bindparams[i].var, 
                                 prepstmt->m_bindparams[i].buf, 
                                 prepstmt->m_bindparams[i].indicator,
                                 1);
                    break;
                }
                case SQLDBC_HOSTTYPE_ASCII: {
                    if (prepstmt->m_bindparams[i].isint) {
                        char tmp[40];
                        char intmin[40], intmax[40];
                        int rc;
                        int isneg;
                        
                        memset (tmp, ' ', sizeof(tmp));
                        memset (intmin, ' ', sizeof(intmin));
                        memset (intmax, ' ', sizeof(intmax));
                        rc = sprintf (tmp, "%d", INT_MIN);
                        memcpy (&intmin[sizeof(intmin)-rc], &tmp[1], rc-1);
                        memset (tmp, ' ', sizeof(tmp));
                        rc = sprintf (tmp, "%d", INT_MAX);
                        memcpy (&intmax[sizeof(intmax)-rc], tmp, rc);
                        
                        memset (tmp, ' ', sizeof(tmp));
                        if (prepstmt->m_bindparams[i].buf[0] == '-') {
                            isneg = 1;
                            memcpy (&tmp[sizeof(tmp)-prepstmt->m_bindparams[i].indicator], 
                                    &prepstmt->m_bindparams[i].buf[1], 
                                    prepstmt->m_bindparams[i].indicator-1);
                        } else {
                            isneg = 0;
                            memcpy (&tmp[sizeof(tmp)-prepstmt->m_bindparams[i].indicator], 
                                    prepstmt->m_bindparams[i].buf,
                                    prepstmt->m_bindparams[i].indicator);
                        }

                        if (strncmp (tmp, isneg ? intmin : intmax, 40) >= 0) {
                            ZVAL_STRING(prepstmt->m_bindparams[i].var, prepstmt->m_bindparams[i].buf, 1);
                        } else {
                            dval = atof(prepstmt->m_bindparams[i].buf);
                            ZVAL_DOUBLE(prepstmt->m_bindparams[i].var, dval);
                        }
                    } else {
                        char *buf = prepstmt->m_bindparams[i].buf;
                        int len = prepstmt->m_bindparams[i].paramlen;
                        while (buf[len-2] == ' ')
                            --len;
                        buf[len-1] = '\0';
                        ZVAL_STRING(prepstmt->m_bindparams[i].var, prepstmt->m_bindparams[i].buf, 1);
                    }
                    break;
                }
                case SQLDBC_HOSTTYPE_INT4: {
                    memcpy(&lval, prepstmt->m_bindparams[i].buf, sizeof(long));
                    ZVAL_LONG(prepstmt->m_bindparams[i].var, lval);
                    break;
                }
                case SQLDBC_HOSTTYPE_DOUBLE: {
                    memcpy(&dval, prepstmt->m_bindparams[i].buf, sizeof(double));
                    ZVAL_DOUBLE(prepstmt->m_bindparams[i].var, dval);
                    break;
                }
                default: {
                    break;
                }
                }
                if (prepstmt->m_bindparams[i].buf) {
                    efree(prepstmt->m_bindparams[i].buf);
                    prepstmt->m_bindparams[i].buf = NULL;
                }
            }
        }
    }

      for (i = 0; i < prepstmt->m_parcnt; i++) {
            if ((prepstmt->m_bindparams[i].hostType == SQLDBC_HOSTTYPE_ASCII_CLOB) &&
                  (prepstmt->m_bindparams[i].paramlen != 0)) {
                  SQLDBC_Length ind = SQLDBC_NTS;
                  prepstmt->m_bindparams[i].lob = erealloc(prepstmt->m_bindparams[i].lob,
                                                                               prepstmt->m_bindparams[i].paramlen+1);
                  if (!prepstmt->m_bindparams[i].lob) {
                        RETURN_FALSE;
                  }
                  prepstmt->m_bindparams[i].lob[prepstmt->m_bindparams[i].paramlen] = '\0';
                  
                  if (SQLDBC_LOB_putData ((SQLDBC_LOB *) prepstmt->m_bindparams[i].buf,
                                                      prepstmt->m_bindparams[i].lob,
                                                      &ind) != SQLDBC_OK) {
                        php_maxdb_sqldbc_error (INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                                            SQLDBC_PreparedStatement_getError(prepstmt->m_prepstmt));
                        RETURN_FALSE;
                  }
                  if (SQLDBC_LOB_close ((SQLDBC_LOB *) prepstmt->m_bindparams[i].buf) != SQLDBC_OK) {
                        php_maxdb_sqldbc_error (INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                                            SQLDBC_PreparedStatement_getError(prepstmt->m_prepstmt));
                        RETURN_FALSE;
                  }
                  efree (prepstmt->m_bindparams[i].lob);
            }
      }

      RETURN_TRUE;
}
/* }}} */

static int maxdb_prop_stmt_errno(maxdb_prepstmt *stmt TSRMLS_DC)
{
      SQLDBC_ErrorHndl *errhndl = NULL;

      errhndl = SQLDBC_PreparedStatement_getError (stmt->m_prepstmt);
      return SQLDBC_ErrorHndl_getErrorCode (errhndl);
}

/* {{{ proto int maxdb_stmt_errno(resource stmt)
*/
PHP_FUNCTION(maxdb_stmt_errno)
{
      zval *pv_prepstmt;
      maxdb_prepstmt *prepstmt;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_prepstmt, 
                                     maxdb_stmt_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_prepstmt) == FAILURE) {
            return;     
      }

      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (!prepstmt->m_prepstmt) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_ERR_STATEMENT_NOT_PREPARED);
            return;
      }
    RETURN_LONG(maxdb_prop_stmt_errno(prepstmt TSRMLS_CC));
}
/* }}} */

static char *maxdb_prop_stmt_error(maxdb_prepstmt *stmt TSRMLS_DC)
{
      SQLDBC_ErrorHndl *errhndl = NULL;

      errhndl = SQLDBC_PreparedStatement_getError (stmt->m_prepstmt);
      return SQLDBC_ErrorHndl_getErrorText (errhndl);
}

/* {{{ proto string maxdb_stmt_error(resource stmt)
*/
PHP_FUNCTION(maxdb_stmt_error) 
{
      zval *pv_prepstmt;
      maxdb_prepstmt *prepstmt;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_prepstmt, 
                                     maxdb_stmt_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_prepstmt) == FAILURE) {
            return;     
      }

      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (!prepstmt->m_prepstmt) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_ERR_STATEMENT_NOT_PREPARED);
            return;
      }
      RETURN_STRING(maxdb_prop_stmt_error(prepstmt TSRMLS_CC), 1);
}
/* }}} */

static SQLDBC_Retcode maxdb_get_real_rows_in_result (maxdb_result *result, SQLDBC_UInt4 *row)
{
    char *cprop;

    *row = -1;
    if (result && result->m_conn && result->m_conn->m_connprop) {
        if (!(cprop = SQLDBC_ConnectProperties_getProperty(result->m_conn->m_connprop, "SELECTFETCHOPTIMIZE", 0))) {
            return SQLDBC_NOT_OK;
        }
        if (!strcmp(cprop, "0")) {
            if (result->m_resultset) {
                SQLDBC_Retcode res = SQLDBC_OK;
                SQLDBC_UInt4 actrow = SQLDBC_ResultSet_getRowNumber (result->m_resultset);
                
                if ((res = SQLDBC_ResultSet_last (result->m_resultset)) == SQLDBC_OK) {
                    *row = SQLDBC_ResultSet_getRowNumber (result->m_resultset);
                } else {
                    return res;
                }
                res = SQLDBC_ResultSet_absolute (result->m_resultset, actrow);
                return res;
            } else {
                return SQLDBC_NOT_OK;
            }
        }
    } else {
        return SQLDBC_NOT_OK;
    }
    return SQLDBC_OK;
}

int maxdb_prop_stmt_affected_rows(maxdb_prepstmt *prepstmt TSRMLS_DC)
{
    SQLDBC_UInt4 row = -1;
    if (prepstmt->m_prepstmt && prepstmt->m_result) {
        if ((row = SQLDBC_PreparedStatement_getRowsAffected (prepstmt->m_prepstmt)) == -1) {
            if (maxdb_get_real_rows_in_result (prepstmt->m_result, &row) != SQLDBC_NOT_OK) {
                return row;
            }
        }
    }

    return row;
}

/* {{{ proto mixed maxdb_stmt_affected_rows(resource stmt)
   Return the number of rows affected in the last query for the given link */
PHP_FUNCTION(maxdb_stmt_affected_rows)
{
      zval *pv_prepstmt;
      maxdb_prepstmt *prepstmt;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_prepstmt, 
                                     maxdb_stmt_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_prepstmt) == FAILURE) {
            RETURN_FALSE;     
      }

      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (!prepstmt->m_prepstmt) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_ERR_STATEMENT_NOT_PREPARED);
            RETURN_FALSE;
      }
      RETURN_LONG(maxdb_prop_stmt_affected_rows(prepstmt TSRMLS_CC));
}
/* }}} */

static char *maxdb_prop_stmt_sqlstate(maxdb_prepstmt *stmt TSRMLS_DC)
{
      SQLDBC_ErrorHndl *errhndl = NULL;

      errhndl = SQLDBC_PreparedStatement_getError (stmt->m_prepstmt);
      return SQLDBC_ErrorHndl_getSQLState (errhndl);
}

/* {{{ proto string maxdb_stmt_sqlstate(resource stmt)
*/
PHP_FUNCTION(maxdb_stmt_sqlstate) 
{
      zval *pv_prepstmt;
      maxdb_prepstmt *prepstmt;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_prepstmt, 
                                     maxdb_stmt_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_prepstmt) == FAILURE) {
            RETURN_FALSE;     
      }

      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (!prepstmt->m_prepstmt) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_ERR_STATEMENT_NOT_PREPARED);
            RETURN_STRING(empty_string, 1);
      }
      RETURN_STRING(maxdb_prop_stmt_sqlstate(prepstmt TSRMLS_CC), 1);
}
/* }}} */


static int maxdb_prop_stmt_param_count(maxdb_prepstmt *prepstmt TSRMLS_DC)
{
      SQLDBC_ParameterMetaData *metadata = NULL;

      if ((metadata = SQLDBC_PreparedStatement_getParameterMetaData(prepstmt->m_prepstmt)) == NULL) {
        return -1;
      }

      return SQLDBC_ParameterMetaData_getParameterCount (metadata);
}

/* {{{ proto int maxdb_stmt_param_count(resource stmt) {
   Return the number of parameter for the given statement */
PHP_FUNCTION(maxdb_stmt_param_count)
{
      zval *pv_prepstmt;
      maxdb_prepstmt *prepstmt;
      SQLDBC_ParameterMetaData *metadata = NULL;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_prepstmt, 
                                     maxdb_stmt_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_prepstmt) == FAILURE) {
            RETURN_FALSE;     
      }

      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (!prepstmt->m_prepstmt) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_ERR_STATEMENT_NOT_PREPARED);
            RETURN_FALSE;
      }

      if ((metadata = SQLDBC_PreparedStatement_getParameterMetaData(prepstmt->m_prepstmt)) == NULL) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "No parameter metadata available");
            RETURN_LONG(-1);
      }

      RETURN_LONG(maxdb_prop_stmt_param_count(prepstmt TSRMLS_CC));
}
/* }}} */

static int maxdb_prop_stmt_num_rows(maxdb_prepstmt *stmt TSRMLS_DC)
{
    SQLDBC_UInt4 row = -1;
    if (stmt && stmt->m_result && stmt->m_result->m_resultset) {
        if ((row = SQLDBC_ResultSet_getResultCount(stmt->m_result->m_resultset)) == -1) {
            if (maxdb_get_real_rows_in_result (stmt->m_result, &row) != SQLDBC_NOT_OK) {
                return row;
            }
        }
    }

    return row;
}

/* {{{ proto mixed maxdb_stmt_num_rows(resource stmt)
   Return the number of rows in statements result set */
PHP_FUNCTION(maxdb_stmt_num_rows)
{
      zval *pv_prepstmt;
      maxdb_prepstmt *prepstmt;
    
#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_prepstmt, maxdb_stmt_class_entry) == FAILURE) {
            return;
      }

      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_prepstmt) == FAILURE) {
            RETURN_FALSE;     
      }

      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (!prepstmt->m_prepstmt) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_ERR_STATEMENT_NOT_PREPARED);
            RETURN_FALSE;
      }

      if (!prepstmt->m_result || !prepstmt->m_result->m_resultset) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                                  PHP_ERR_NO_RESULTSET);
            RETURN_FALSE;
      }
 
      RETURN_LONG(maxdb_prop_stmt_num_rows(prepstmt TSRMLS_CC));
}
/* }}} */


/* {{{ proto bool maxdb_stmt_bind_result(resource stmt, mixed var, [,mixed, ...])
   Bind variables to a prepared statement for result storage */
PHP_FUNCTION(maxdb_stmt_bind_result)
{
      zval *pv_prepstmt;
      zval ***args;
      int argc = ZEND_NUM_ARGS();
      unsigned int start = 1;
      int var_cnt;
      unsigned int i;
      maxdb_prepstmt *prepstmt;

      if (argc < (getThis() ? 1 : 2))  {
            WRONG_PARAM_COUNT;
      }

      args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
      if (!args) {
            RETURN_FALSE;
      }

      if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
            efree(args);
            WRONG_PARAM_COUNT;
      }

      if (getThis()) {
            start = 0;
      }

#ifdef MAXDB_OO
      if (zend_parse_method_parameters((getThis()) ? 0:1 TSRMLS_CC, getThis(), "O", &pv_prepstmt, 
                                     maxdb_stmt_class_entry) == FAILURE) {
            return;     
      }

      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt"); 
#else
      if (zend_parse_parameters((getThis()) ? 0 : 1 TSRMLS_CC, "r", &pv_prepstmt) == FAILURE) {
            efree(args);
            RETURN_FALSE;     
      }

      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (prepstmt->m_result) {
            if (prepstmt->m_result->m_vars) {
                  for (i = 0; i < prepstmt->m_result->m_varscnt; i++) {
                        zval_ptr_dtor(&prepstmt->m_result->m_vars[i]);
                  }
                  efree (prepstmt->m_result->m_vars);
            }
      } else {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_NO_RESULTSET);
            efree(args);
            RETURN_FALSE;
      }

      var_cnt = argc - start;

      prepstmt->m_result->m_vars = (zval **) safe_emalloc ((var_cnt), sizeof(zval), 0);
      if (!prepstmt->m_result->m_vars) {
            efree(args);
            RETURN_FALSE;
      }
      prepstmt->m_result->m_varscnt = 0;
      for (i = start; i < var_cnt+start; i++) {
            int ofs = i-start;
            ZVAL_ADDREF(*args[i]);
            prepstmt->m_result->m_vars[ofs] = *args[i];
            prepstmt->m_result->m_varscnt++;
      }
      
      efree(args);

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto mixed maxdb_stmt_fetch(resource stmt)
   Fetch results from a prepared statement into the bound variables */
PHP_FUNCTION(maxdb_stmt_fetch)
{
      zval *pv_prepstmt;
      maxdb_prepstmt *prepstmt;
      SQLDBC_RowSet *rowset = 0;
      SQLDBC_Retcode rc;
      long lval;
    double dval;
      unsigned int i;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_prepstmt, 
                                     maxdb_stmt_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_prepstmt) == FAILURE) {
            RETURN_FALSE;     
      }
      
      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (!prepstmt->m_prepstmt) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_ERR_STATEMENT_NOT_PREPARED);
            RETURN_FALSE;
      }

      if (!prepstmt->m_result || !prepstmt->m_result->m_resultset) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_NO_RESULTSET); 
            RETURN_FALSE;
      }

      if ((rc = SQLDBC_ResultSet_next (prepstmt->m_result->m_resultset)) == SQLDBC_NO_DATA_FOUND) {
            RETURN_NULL();
      } else if (rc == SQLDBC_NOT_OK) {
            php_maxdb_sqldbc_error (INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                                SQLDBC_ResultSet_getError(prepstmt->m_result->m_resultset));
            RETURN_NULL();
      }
      rowset = SQLDBC_ResultSet_getRowSet (prepstmt->m_result->m_resultset);
      
      if ((rc = SQLDBC_RowSet_fetch (rowset)) == SQLDBC_NOT_OK) {
            php_maxdb_sqldbc_error (INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                                SQLDBC_RowSet_getError(rowset));
            RETURN_NULL(); 
      }

      for (i = 0; i < prepstmt->m_result->m_numcols; i++) {
            if ((prepstmt->m_result->m_vars[i]->type == IS_STRING) && 
                  (prepstmt->m_result->m_vars[i]->value.str.len)) {
                  efree(prepstmt->m_result->m_vars[i]->value.str.val);
            }
            if (prepstmt->m_result->m_cols[i].indicator == SQLDBC_NULL_DATA) {
                  prepstmt->m_result->m_vars[i]->type = IS_NULL;
                  continue;
            }

            if (prepstmt->m_result->m_cols[i].indicator >= prepstmt->m_result->m_cols[i].bufLen) {
                  php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                       PHP_ERR_LONG_COLUMN_TRUNCATED_D, 
                                                       i+1);
                  prepstmt->m_result->m_cols[i].indicator = prepstmt->m_result->m_cols[i].bufLen+1;
            }

            switch (prepstmt->m_result->m_cols[i].hostType) {
            case SQLDBC_HOSTTYPE_INT1 : {
                  SQLDBC_Int1 tmp;
                  memcpy (&tmp, prepstmt->m_result->m_cols[i].buf, sizeof(SQLDBC_Int1));
                  ZVAL_BOOL(prepstmt->m_result->m_vars[i], tmp);
                  break;
            }
            case SQLDBC_HOSTTYPE_BINARY: {
                  ZVAL_STRINGL(prepstmt->m_result->m_vars[i], 
                                     prepstmt->m_result->m_cols[i].buf, 
                                     prepstmt->m_result->m_cols[i].indicator,
                                     1);
                  break;
            }
            case SQLDBC_HOSTTYPE_ASCII: {
                  if (prepstmt->m_result->m_cols[i].isint) {
                        char tmp[40];
                        char intmin[40], intmax[40];
                        int rc;
                        int isneg;
                        maxdb_result_value *col = &prepstmt->m_result->m_cols[i];

                        memset (tmp, ' ', sizeof(tmp));
                        memset (intmin, ' ', sizeof(intmin));
                        memset (intmax, ' ', sizeof(intmax));
                        rc = sprintf (tmp, "%d", INT_MIN);
                        memcpy (&intmin[sizeof(intmin)-rc], &tmp[1], rc-1);
                        memset (tmp, ' ', sizeof(tmp));
                        rc = sprintf (tmp, "%d", INT_MAX);
                        memcpy (&intmax[sizeof(intmax)-rc], tmp, rc);

                        memset (tmp, ' ', sizeof(tmp));
                        if (col->buf[0] == '-') {
                              isneg = 1;
                              memcpy (&tmp[sizeof(tmp)-col->indicator], &col->buf[1], col->indicator-1);
                        } else {
                              isneg = 0;
                              memcpy (&tmp[sizeof(tmp)-col->indicator], col->buf, col->indicator);
                        }

                        if (strncmp (tmp, isneg ? intmin : intmax, 40) >= 0) {
                              ZVAL_STRING(prepstmt->m_result->m_vars[i], col->buf, 1);
                        } else {
                              lval = atoi(prepstmt->m_result->m_cols[i].buf);
                    ZVAL_LONG(prepstmt->m_result->m_vars[i], lval);
                        }
                  } else {
                        if (prepstmt->m_result->m_cols[i].chopBlanks) {
                              maxdb_result_value *col = &prepstmt->m_result->m_cols[i];
                              char *buf = col->buf;
                              buf[col->bufLen-1] = '\0';
                              while (col->indicator && buf[col->indicator-1] == ' ')
                                    --col->indicator;
                              buf[col->indicator] = '\0';
                        }
                        ZVAL_STRING(prepstmt->m_result->m_vars[i], prepstmt->m_result->m_cols[i].buf, 1);
                  }
                  break;
            }
            case SQLDBC_HOSTTYPE_INT4: {
                  memcpy(&lval, prepstmt->m_result->m_cols[i].buf, sizeof(long));
                  ZVAL_LONG(prepstmt->m_result->m_vars[i], lval);
                  break;
            }
            case SQLDBC_HOSTTYPE_DOUBLE: {
                  memcpy(&dval, prepstmt->m_result->m_cols[i].buf, sizeof(double));
                  ZVAL_DOUBLE(prepstmt->m_result->m_vars[i], dval);
                  break;
            }
            default: {
                  break;
            }
            }
      }

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto void maxdb_stmt_data_seek(resource stmt, int offset)
   Move internal result pointer */
PHP_FUNCTION(maxdb_stmt_data_seek)
{
      zval *pv_prepstmt;
      maxdb_prepstmt *prepstmt;
      maxdb_result *result;
      int offset;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &pv_prepstmt, maxdb_stmt_class_entry, 
                                     &offset) == FAILURE) {
            return;
      }

      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &pv_prepstmt, &offset) == FAILURE) {
            RETURN_FALSE;     
      }

      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (!prepstmt->m_prepstmt) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_ERR_STATEMENT_NOT_PREPARED);
            RETURN_FALSE;
      }

      if (!prepstmt->m_result || !prepstmt->m_result->m_resultset) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                                  PHP_ERR_NO_RESULTSET);
            RETURN_FALSE;
      }
 
      result = prepstmt->m_result;

      if (SQLDBC_ResultSet_absolute (result->m_resultset, offset) != SQLDBC_OK) {
            php_maxdb_sqldbc_error(INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                             SQLDBC_ResultSet_getError(result->m_resultset));
            RETURN_FALSE;
      }

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto bool maxdb_send_long_data(resource stmt, int param_nr, string data)
*/
PHP_FUNCTION(maxdb_stmt_send_long_data)
{
      zval *pv_prepstmt;
      maxdb_prepstmt *prepstmt;
      long param_nr;
      char *data;
      long data_len;
      SQLDBC_Length ind;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols", &pv_prepstmt, maxdb_stmt_class_entry, 
                                     &param_nr, &data, &data_len) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rls", &pv_prepstmt, &param_nr, &data, &data_len) == FAILURE) {
            RETURN_FALSE;     
      }
      
      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (!php_maxdb_check_long_param (INTERNAL_FUNCTION_PARAM_PASSTHRU, prepstmt, param_nr)) {
            RETURN_FALSE;
      }

      if (prepstmt->m_isexecuted) {
            ind = SQLDBC_NTS;
            if (SQLDBC_LOB_putData ((SQLDBC_LOB *)prepstmt->m_bindparams[param_nr].buf,
                                                data,
                                                &ind) != SQLDBC_OK) {
                  php_maxdb_sqldbc_error (INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                                      SQLDBC_PreparedStatement_getError(prepstmt->m_prepstmt));
                  RETURN_FALSE;
            }
      } else {
            if (prepstmt->m_bindparams[param_nr].paramlen == 0) {
                  if (data) {
                        prepstmt->m_bindparams[param_nr].lob = estrdup(data);
                  }
            } else {
                  prepstmt->m_bindparams[param_nr].lob = erealloc(prepstmt->m_bindparams[param_nr].lob,
                                                                               prepstmt->m_bindparams[param_nr].paramlen+data_len);
                  if (!prepstmt->m_bindparams[param_nr].lob) {
                        RETURN_FALSE;
                  }
                  memcpy (&prepstmt->m_bindparams[param_nr].lob[prepstmt->m_bindparams[param_nr].paramlen],
                              data,
                              data_len);
            }
            prepstmt->m_bindparams[param_nr].paramlen += data_len;
      }

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto bool maxdb_close_long_data(resource stmt, int param_nr)
*/
PHP_FUNCTION(maxdb_stmt_close_long_data)
{
      zval *pv_prepstmt;
      maxdb_prepstmt *prepstmt;
      long param_nr;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &pv_prepstmt, 
                                     maxdb_stmt_class_entry, &param_nr) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &pv_prepstmt, &param_nr) == FAILURE) {
            RETURN_FALSE;     
      }
      
      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (!php_maxdb_check_long_param (INTERNAL_FUNCTION_PARAM_PASSTHRU, prepstmt, param_nr)) {
            RETURN_FALSE;
      }

      if (SQLDBC_LOB_close ((SQLDBC_LOB *) prepstmt->m_bindparams[param_nr].buf) != SQLDBC_OK) {
            php_maxdb_sqldbc_error (INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                                SQLDBC_PreparedStatement_getError(prepstmt->m_prepstmt));
            RETURN_FALSE;
      }     
}
/* }}} */


/* {{{ proto bool maxdb_stmt_store_result(stmt)
*/
PHP_FUNCTION(maxdb_stmt_store_result)
{
      zval *pv_prepstmt;
      maxdb_prepstmt *prepstmt;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_prepstmt, 
                                     maxdb_stmt_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_prepstmt) == FAILURE) {
            RETURN_FALSE;     
      }

      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (!prepstmt->m_prepstmt) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_ERR_STATEMENT_NOT_PREPARED);
            RETURN_FALSE;
      }

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto void maxdb_stmt_free_result(resource stmt)
   Free stored result memory for the given statement handle */
PHP_FUNCTION(maxdb_stmt_free_result) 
{
      zval *pv_prepstmt;
      maxdb_prepstmt *prepstmt;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_prepstmt, 
                                     maxdb_stmt_class_entry) == FAILURE) {
            return;
      }

      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_prepstmt) == FAILURE) {
            return;     
      }

      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (!prepstmt->m_prepstmt) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_ERR_STATEMENT_NOT_PREPARED);
            return;
      }

      php_maxdb_free_result (prepstmt->m_result);
}
/* }}} */


/* {{{ proto bool maxdb_stmt_reset(resource stmt)
   reset a prepared statement */
PHP_FUNCTION(maxdb_stmt_reset) 
{
      zval *pv_prepstmt;
      maxdb_prepstmt *prepstmt;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_prepstmt, 
                                     maxdb_stmt_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_prepstmt) == FAILURE) {
            RETURN_FALSE;     
      }

      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (!prepstmt->m_prepstmt) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_ERR_STATEMENT_NOT_PREPARED);
            RETURN_FALSE;
      }

      RETURN_FALSE;
}
/* }}}*/


/* {{{ proto bool maxdb_stmt_close(resource stmt) 
   Close statement */
PHP_FUNCTION(maxdb_stmt_close)
{
      zval *pv_prepstmt;
      maxdb_prepstmt *prepstmt;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_prepstmt, 
                                     maxdb_stmt_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_prepstmt) == FAILURE) {
            RETURN_FALSE;     
      }
      
      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto mixed maxdb_stmt_result_metadata(resource stmt)
   return result set from statement */
PHP_FUNCTION(maxdb_stmt_result_metadata)
{
      zval *pv_prepstmt;
      maxdb_prepstmt *prepstmt;
      maxdb_result *result;
#ifdef MAXDB_OO
      MAXDB_RESOURCE    *maxdb_resource;
#endif

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_prepstmt, 
                                     maxdb_stmt_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_prepstmt) == FAILURE) {
            RETURN_FALSE;     
      }

      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (!prepstmt->m_prepstmt) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_ERR_STATEMENT_NOT_PREPARED);
            RETURN_FALSE;
      }

      if (!prepstmt->m_result) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                                  PHP_ERR_NO_RESULTSET);
            RETURN_FALSE;
      }

      if (!prepstmt->m_result->m_rsmd) {
            php_maxdb_internal_error (INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                                  PHP_ERR_INITIALIZATION_FAILED_S,
                                                  "No result set metadata available");
            RETURN_FALSE;
      }

      result = (maxdb_result *) emalloc (sizeof(maxdb_result));

      if (result) {
            php_init_result (result);
            result->m_rsmd = prepstmt->m_result->m_rsmd;
#ifdef MAXDB_OO
        maxdb_resource = (MAXDB_RESOURCE *)ecalloc (1, sizeof(MAXDB_RESOURCE));
        maxdb_resource->ptr = (void *)result;
        MAXDB_RETURN_RESOURCE(maxdb_resource, maxdb_result_class_entry);
#else
            result->m_id = ZEND_REGISTER_RESOURCE(return_value, result, le_result);
            RETURN_RESOURCE(result->m_id);
#endif
      } else {
            RETURN_FALSE;
      }
}
/* }}} */


/* {{{ proto void maxdb_free_result(resource result)
   Free query result memory for the given result handle */
PHP_FUNCTION(maxdb_free_result) 
{
      zval *pv_result;
      maxdb_result *result;
#ifndef MAXDB_OO
    maxdb_connection *conn;
    int type;
#endif

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_result, 
                                     maxdb_result_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(result, maxdb_result *, &pv_result, "maxdb_result");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_result) == FAILURE) {
            return;     
      }
      
      ZEND_FETCH_RESOURCE(result, maxdb_result *, &pv_result, -1, "maxdb result", le_result);
#endif

    if (result->m_conn) {
        result->m_conn->m_resultid = 0;
        result->m_conn->m_result = NULL;
    }
#ifndef MAXDB_OO
    if ((conn = (maxdb_connection *) zend_list_find (result->m_connid, &type))) {
        conn->m_resultid = 0;
    }
#endif

      php_maxdb_free_result (result);
}
/* }}} */


/* {{{ proto bool maxdb_stmt_bind_param(resource stmt, string types, mixed variable [,mixed,....])
   Bind variables to a prepared statement as parameters */
PHP_FUNCTION(maxdb_stmt_bind_param)
{
      zval *pv_prepstmt;
      zval ***args;
      int num_vars;
      int start = 2;
      int  argc = ZEND_NUM_ARGS();
      int index, i;
      char *types = NULL;
      SQLDBC_UInt4 types_len;
    maxdb_prepstmt *prepstmt;

      num_vars = argc - 1;
      if (!getThis()) {
            --num_vars; 
      }
      if (argc < 2) {
            WRONG_PARAM_COUNT;
      }

#ifdef MAXDB_OO
      if (zend_parse_method_parameters((getThis()) ? 1:2 TSRMLS_CC, getThis(), "Os", &pv_prepstmt, maxdb_stmt_class_entry, 
                                     &types, &types_len) == FAILURE) {
            return;     
      }

      MAXDB_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, "maxdb_stmt"); 
#else
      if (zend_parse_parameters((getThis()) ? 1:2 TSRMLS_CC, "rs", &pv_prepstmt, &types, &types_len) == FAILURE) {
            return;     
      }

      ZEND_FETCH_RESOURCE(prepstmt, maxdb_prepstmt *, &pv_prepstmt, -1, "maxdb prepstmt", le_prepstmt);
#endif

      if (getThis()) {
            start = 1;
      }

      if (strlen(types) != argc - start) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "Number of elements in type definition string doesn't match number of bind variables");
      }

      if (argc - start != prepstmt->m_parcnt) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_PARAMETER_CNT_MISMATCH);
            prepstmt->m_parcnt = 0;
            RETURN_FALSE;
      }

      if (prepstmt->m_bindparams) {
            php_maxdb_free_stmt_bind_buffer(prepstmt);
      }

      args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
      if (!args) {
            RETURN_FALSE;
      }

      if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
            efree(args);
            WRONG_PARAM_COUNT;
      }

      prepstmt->m_bindparams = (maxdb_bind_param *)emalloc(num_vars*sizeof(maxdb_bind_param));
      php_maxdb_init_bindparams (prepstmt->m_bindparams, num_vars);
      if (!prepstmt->m_bindparams) {
            RETURN_FALSE;
      }

      index = 0;
      for (i = start; i < argc; i++) {
            ZVAL_ADDREF(*args[i]);
            prepstmt->m_bindparams[index].var = *args[i];
            switch (types[index]) {
            case 'd': {
                  prepstmt->m_bindparams[index].hostType = SQLDBC_HOSTTYPE_DOUBLE;
                  prepstmt->m_bindparams[index].buf = (char *) &Z_DVAL_PP(args[i]);
                  prepstmt->m_bindparams[index].paramlen = sizeof(double);
                  prepstmt->m_bindparams[index].indicator = 0;
                  break;
            }
            case 'i': {
                  prepstmt->m_bindparams[index].hostType = SQLDBC_HOSTTYPE_INT4;
            prepstmt->m_bindparams[index].buf = (char *) &Z_LVAL_PP(args[i]);
                  prepstmt->m_bindparams[index].paramlen = sizeof(int);
                  prepstmt->m_bindparams[index].indicator = 0;
                  break;
            }
            case 'b': {
                  prepstmt->m_bindparams[index].hostType = SQLDBC_HOSTTYPE_ASCII_CLOB;
                  prepstmt->m_bindparams[index].buf = (char *) Z_STRVAL_PP(args[i]);
                  prepstmt->m_bindparams[index].paramlen = 0;
                  prepstmt->m_bindparams[index].indicator = 0;
                  break;
            }
            case 's': {
                  prepstmt->m_bindparams[index].hostType = SQLDBC_HOSTTYPE_ASCII;
                  prepstmt->m_bindparams[index].buf = (char *) Z_STRVAL_PP(args[i]);
                  prepstmt->m_bindparams[index].paramlen = Z_STRLEN_PP(args[i]);
                  prepstmt->m_bindparams[index].indicator = 0;
                  break;
            }
            default: {
                  efree (args);
                  efree (prepstmt->m_bindparams);
                  prepstmt->m_bindparams = NULL;
                  RETURN_FALSE;
                  break;
            }
            }
            index++;
      }

      efree(args);
      RETURN_TRUE;
}
/* }}} */


/* {{{ proto bool maxdb_data_seek(resource result, int row_number)
   Move internal result pointer */
PHP_FUNCTION(maxdb_data_seek)
{
      zval *pv_result;
      maxdb_result *result;
      long offset;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &pv_result, maxdb_result_class_entry, &offset) == FAILURE) {
            return;
      }

      MAXDB_FETCH_RESOURCE(result, maxdb_result *, &pv_result, "maxdb_result");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &pv_result, &offset) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(result, maxdb_result *, &pv_result, -1, "maxdb result", le_result);
#endif

      if (SQLDBC_ResultSet_absolute (result->m_resultset, offset) != SQLDBC_OK) {
            php_maxdb_sqldbc_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                             SQLDBC_ResultSet_getError(result->m_resultset));
            RETURN_FALSE;
      }

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto array maxdb_fetch_row(resource result)
   Gets a result row as an enumerated array */
PHP_FUNCTION(maxdb_fetch_row)
{
      php_maxdb_fetch_hash (INTERNAL_FUNCTION_PARAM_PASSTHRU, MAXDB_NUM, 1, 0);
}
/* }}} */


/* {{{ proto array maxdb_fetch_assoc(resource result)
   Fetch a result row as an associative array */
PHP_FUNCTION(maxdb_fetch_assoc)
{
      php_maxdb_fetch_hash (INTERNAL_FUNCTION_PARAM_PASSTHRU, MAXDB_ASSOC, 1, 0);
}
/* }}} */


/* {{{ proto array maxdb_fetch_array(resource result [, int result_type])
   Fetch a result row as an array (associative, numeric or both) */
PHP_FUNCTION(maxdb_fetch_array)
{
      php_maxdb_fetch_hash (INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 2, 0);
}
/* }}} */


/* {{{ proto resource maxdb_fetch_object(resource result [, int result_type])
   Fetch a result row as an object */
PHP_FUNCTION(maxdb_fetch_object)
{
      php_maxdb_fetch_hash (INTERNAL_FUNCTION_PARAM_PASSTHRU, MAXDB_ASSOC, 2, 1);

      if (Z_TYPE_P(return_value) == IS_ARRAY) {
            object_and_properties_init(return_value, ZEND_STANDARD_CLASS_DEF_PTR, Z_ARRVAL_P(return_value));
      }
}
/* }}} */


/* {{{ proto int maxdb_num_fields(resource result)
   Gets number of fields (columns) in a result */
PHP_FUNCTION(maxdb_num_fields)
{
      zval *pv_result;
      maxdb_result *result;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_result, maxdb_result_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(result, maxdb_result *, &pv_result, "maxdb_result");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_result) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(result, maxdb_result *, &pv_result, -1, "maxdb result", le_result);
#endif

      if (!result->m_rsmd) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "Missing resultset meta data");
            RETURN_FALSE;
      }

      RETURN_LONG(SQLDBC_ResultSetMetaData_getColumnCount (result->m_rsmd))
}
/* }}} */

static int maxdb_prop_num_rows (maxdb_result *result TSRMLS_DC)
{
    SQLDBC_UInt4 row = -1;
    if (result && result->m_resultset) {
        if ((row = SQLDBC_ResultSet_getResultCount(result->m_resultset)) == -1) {
            if (maxdb_get_real_rows_in_result (result, &row) != SQLDBC_NOT_OK) {
                return row;
            }
        }
    }

    return row;
}

/* {{{ proto mixed maxdb_num_rows(resource result)
   Get number of rows in result */
PHP_FUNCTION(maxdb_num_rows)
{
      zval *pv_result;
      maxdb_result *result;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_result, 
                                     maxdb_result_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(result, maxdb_result *, &pv_result, "maxdb_result");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_result) == FAILURE) {
            RETURN_FALSE;     
      }
      
      ZEND_FETCH_RESOURCE(result, maxdb_result *, &pv_result, -1, "maxdb result", le_result);
#endif

      RETURN_LONG(maxdb_prop_num_rows(result TSRMLS_CC));
}
/* }}} */


#define META_DATA_STRING_LEN 256
/* {{{ proto resource maxdb_fetch_field(resource result [, int field_offset])
   Gets column information from a result and return as an resource */
PHP_FUNCTION(maxdb_fetch_field)
{
      zval *pv_result;
      maxdb_result *result;
      int index;
      char colname[META_DATA_STRING_LEN];
      SQLDBC_Int4 collen;
      SQLDBC_SQLType coltype;
      SQLDBC_Int4 colprec;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_result, maxdb_result_class_entry) == FAILURE) {
            return;
      }

      MAXDB_FETCH_RESOURCE(result, maxdb_result *, &pv_result, "maxdb_result");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_result) == FAILURE) {
            RETURN_FALSE;     
      }
      
      ZEND_FETCH_RESOURCE(result, maxdb_result *, &pv_result, -1, "maxdb result", le_result);
#endif

      if (!result->m_rsmd) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "Missing resultset meta data");
            RETURN_FALSE;
      }

      if (object_init (return_value) == FAILURE) {
            RETURN_FALSE;
      }

      index = ++result->m_lastindex;

      if (index < 0) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INVALID_PARAMETER_INDEX_D, 
                                                 index);
            RETURN_FALSE;
      }

    if (index > SQLDBC_ResultSetMetaData_getColumnCount(result->m_rsmd)) {
        RETURN_FALSE;
    }

      php_maxdb_get_field_info (INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                            result, index, colname, &collen, META_DATA_STRING_LEN, 
                                            &coltype, &colprec);

      add_property_string(return_value, "name", (colname ? colname : ""), 1);
    add_property_string(return_value, "orgname", "", 1);
    add_property_string(return_value, "table", "", 1);
    add_property_string(return_value, "orgtable", "", 1);
    add_property_string(return_value, "def", "", 1);
      add_property_long(return_value, "max_length", collen);
    add_property_long(return_value, "flags", -1);
      add_property_long(return_value, "type", coltype);
      add_property_long(return_value, "decimals", colprec);
}
/* }}} */


/* {{{ proto mixed maxdb_fetch_fields (resource result)
   Return array of resources containing field meta-data */
PHP_FUNCTION(maxdb_fetch_fields) 
{
      zval *pv_result;
      zval *obj;
      maxdb_result *result;
      int index;
      char colname[META_DATA_STRING_LEN];
      SQLDBC_Int4 collen;
      SQLDBC_SQLType coltype;
      SQLDBC_Int4 colprec;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_result, 
                                     maxdb_result_class_entry) == FAILURE) {
            return;
      }

      MAXDB_FETCH_RESOURCE(result, maxdb_result *, &pv_result, "maxdb_result");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_result) == FAILURE) {
            RETURN_FALSE;     
      }
      
      ZEND_FETCH_RESOURCE(result, maxdb_result *, &pv_result, -1, "maxdb result", le_result);
#endif

      if (!result->m_rsmd) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "Missing resultset meta data");
            RETURN_FALSE;
      }

      array_init (return_value);

      for (index = 0; index < SQLDBC_ResultSetMetaData_getColumnCount(result->m_rsmd); index++) {

            php_maxdb_get_field_info (INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                                  result, index+1, colname, &collen, META_DATA_STRING_LEN, 
                                                  &coltype, &colprec);

            MAKE_STD_ZVAL(obj);
            object_init(obj);

            add_property_string(obj, "name", (colname ? colname : ""), 1);
        add_property_string(obj, "orgname", "", 1);
        add_property_string(obj, "table", "", 1);
        add_property_string(obj, "orgtable", "", 1);
        add_property_string(obj, "def", "", 1);
            add_property_long(obj, "max_length", collen);
        add_property_long(obj, "flags", -1);
            add_property_long(obj, "type", coltype);
            add_property_long(obj, "decimals", colprec);

            add_index_zval(return_value, index, obj);
      }
}
/* }}} */


/* {{{ proto mixed maxdb_fetch_field_direct (resource result, int offset)
   Fetch meta-data for a single field */
PHP_FUNCTION(maxdb_fetch_field_direct) 
{
      zval *pv_result;
      maxdb_result *result;
      int index;
      char colname[META_DATA_STRING_LEN];
      SQLDBC_Int4 collen;
      SQLDBC_SQLType coltype;
      SQLDBC_Int4 colprec;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &pv_result, 
                                     maxdb_result_class_entry, &index) == FAILURE) {
            return;
      }

      MAXDB_FETCH_RESOURCE(result, maxdb_result *, &pv_result, "maxdb_result");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &pv_result, &index) == FAILURE) {
            RETURN_FALSE;     
      }
      
      ZEND_FETCH_RESOURCE(result, maxdb_result *, &pv_result, -1, "maxdb result", le_result);
#endif

      if (!result->m_rsmd) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INITIALIZATION_FAILED_S, 
                                                 "Missing resultset meta data");
            RETURN_FALSE;
      }

      if (object_init (return_value) == FAILURE) {
            RETURN_FALSE;
      }

      if ((index < 0) || (index > SQLDBC_ResultSetMetaData_getColumnCount(result->m_rsmd))) {
            RETURN_FALSE;
      }

      php_maxdb_get_field_info (INTERNAL_FUNCTION_PARAM_PASSTHRU,
                                            result, index+1, colname, &collen, META_DATA_STRING_LEN, 
                                            &coltype, &colprec);

      add_property_string(return_value, "name", (colname ? colname : ""), 1);
    add_property_string(return_value, "orgname", "", 1);
    add_property_string(return_value, "table", "", 1);
    add_property_string(return_value, "orgtable", "", 1);
    add_property_string(return_value, "def", "", 1);
      add_property_long(return_value, "max_length", collen);
    add_property_long(return_value, "flags", -1);
      add_property_long(return_value, "type", coltype);
      add_property_long(return_value, "decimals", colprec);
}
/* }}} */
#undef META_DATA_STRING_LEN

#ifdef MAXDB_OO
static int maxdb_result_field_count_read (maxdb_object *obj, zval **retval TSRMLS_DC)
{
    maxdb_result *p = (maxdb_result *)((MAXDB_RESOURCE *)(obj->ptr))->ptr;

      ALLOC_ZVAL(*retval);
      if (!p || !p->m_numcols) {
            ZVAL_NULL(*retval);
      } else {
        ZVAL_LONG(*retval, p->m_numcols);
      }
      return SUCCESS;    
}

static int maxdb_result_lengths_read(maxdb_object *obj, zval **retval TSRMLS_DC)
{
    maxdb_result *p = (maxdb_result *)((MAXDB_RESOURCE *)(obj->ptr))->ptr;

      ALLOC_ZVAL(*retval);
      if (!p || !p->m_numcols) {
            ZVAL_NULL(*retval);
      } else {
            ulong i;
            zval *l;
      
            array_init(*retval);

            for (i=0; i < p->m_numcols; i++) {
                  MAKE_STD_ZVAL(l);
                  ZVAL_LONG(l, p->m_cols[i].indicator);
                  add_index_zval(*retval, i, l);
            }     
      }
      return SUCCESS;
}
#endif

/* {{{ proto mixed maxdb_fetch_lengths (resource result)
   Get the length of each output in a result */
PHP_FUNCTION(maxdb_fetch_lengths) 
{
      zval *pv_result;
      maxdb_result *result;
      unsigned int i;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_result, 
                                     maxdb_result_class_entry) == FAILURE) {
            return;
      }

      MAXDB_FETCH_RESOURCE(result, maxdb_result *, &pv_result, "maxdb_result");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_result) == FAILURE) {
            RETURN_FALSE;     
      }
      
      ZEND_FETCH_RESOURCE(result, maxdb_result *, &pv_result, -1, "maxdb result", le_result);
#endif

      array_init(return_value);

      for (i = 0; i < result->m_numcols; i++) {
            add_index_long(return_value, i, result->m_cols[i].indicator);
      }
}
/* }}} */

static int maxdb_prop_field_count (maxdb_connection *conn TSRMLS_DC)
{
    return conn->m_numcols;
}

/* {{{ proto int maxdb_field_count(resource link)
   Fetch the number of fields returned by the last query for the given link
*/
PHP_FUNCTION(maxdb_field_count) 
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      RETURN_LONG(maxdb_prop_field_count(conn TSRMLS_CC));
}
/* }}} */


/* {{{ proto int maxdb_field_seek(resource result, int fieldnr)
   Set result pointer to a specified field offset
*/
PHP_FUNCTION(maxdb_field_seek)
{
      zval *pv_result;
      maxdb_result *result;
      int index;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &pv_result, maxdb_result_class_entry, 
                                     &index) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(result, maxdb_result *, &pv_result, "maxdb_result");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &pv_result, &index) == FAILURE) {
            RETURN_FALSE;     
      }
      
      ZEND_FETCH_RESOURCE(result, maxdb_result *, &pv_result, -1, "maxdb result", le_result);
#endif

      if ((index < 0) || (index > SQLDBC_ResultSetMetaData_getColumnCount(result->m_rsmd))) {
            php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                 PHP_ERR_INVALID_PARAMETER_INDEX_D, 
                                                 index);
            RETURN_FALSE;
      }

      result->m_lastindex = index - 1;

      RETURN_TRUE;
}
/* }}} */


static int maxdb_prop_field_tell (maxdb_result *result TSRMLS_DC)
{
    return result->m_lastindex;
}

/* {{{ proto int maxdb_field_tell(resource result)
   Get current field offset of result pointer */
PHP_FUNCTION(maxdb_field_tell)
{
      zval *pv_result;
      maxdb_result *result;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_result, 
                                     maxdb_result_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(result, maxdb_result *, &pv_result, "maxdb_result");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_result) == FAILURE) {
            RETURN_FALSE;     
      }
      
      ZEND_FETCH_RESOURCE(result, maxdb_result *, &pv_result, -1, "maxdb result", le_result);
#endif

      RETURN_LONG(maxdb_prop_field_tell(result TSRMLS_CC));
}
/* }}} */


static int maxdb_prop_affected_rows (maxdb_connection *conn TSRMLS_DC)
{
      if (conn) {
        if (conn->m_rowsaffected == -1) {
            SQLDBC_UInt4 row = -1;
            if (maxdb_get_real_rows_in_result (conn->m_result, &row) != SQLDBC_NOT_OK) {
                return row;
            }
        }
            return conn->m_rowsaffected;
      }
    return -1;
}

/* {{{ proto int maxdb_affected_rows([int link_identifier])
   Gets number of affected rows in previous MaxDB operation 
   or -1 if affected rows could not determined */
PHP_FUNCTION(maxdb_affected_rows)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }

      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

    RETURN_LONG(maxdb_prop_affected_rows(conn TSRMLS_CC));
}
/* }}} */

static char *maxdb_prop_info (maxdb_connection *conn TSRMLS_DC)
{
      if (conn) {
            sprintf (MAXDB_G(messbuf), "Records: %d Duplicates: %d Warnings: %d", conn->m_rowsaffected, 0, 0);
            return MAXDB_G(messbuf);
      } else {
        strcpy(MAXDB_G(messbuf), empty_string);
            return MAXDB_G(messbuf);
      }
}

/* {{{ proto string maxdb_info(resource link)
   Get information about the most recent query */
PHP_FUNCTION(maxdb_info)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif
    RETURN_STRING(maxdb_prop_info(conn TSRMLS_CC), 1);
}
/* }}} */


/* {{{ proto string maxdb_character_set_name(resource link)
   Returns the name of the character set used for this connection */
PHP_FUNCTION(maxdb_character_set_name)
{
      zval *pv_conn = NULL;
      maxdb_connection *conn;
      char *cprop;
      
#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }

      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      cprop = SQLDBC_ConnectProperties_getProperty(conn->m_connprop, "UNICODE", 0);

      if (!cprop || !strcmp (cprop, "FALSE")) {
            RETURN_STRING("ascii", 1);
      } else {
            RETURN_STRING("unicode", 1);
      }
}
/* }}} */


/* {{{ proto bool maxdb_ping([int link_identifier])
   Tests if already connected to MaxDB database. */
PHP_FUNCTION(maxdb_ping)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (0 == ZEND_NUM_ARGS()) {
            CHECK_MAXDB_CONNECTION (-1);
      } else if (zend_parse_parameters (ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      if (SQLDBC_Connection_isConnected (conn->m_connection)) {
            RETURN_TRUE;
      } else {
            if (SQLDBC_Connection_connectASCII(conn->m_connection, 
                                                               conn->m_host, 
                                                               conn->m_db, 
                                                               conn->m_user, 
                                                               conn->m_passwd,
                                                               conn->m_connprop) != SQLDBC_OK) {
                  php_maxdb_handle_connect_error (INTERNAL_FUNCTION_PARAM_PASSTHRU, conn);
                  RETURN_FALSE;
            }
            MAXDB_G(thread_id) = MAXDB_G(thread_id) + 1;
            RETURN_TRUE;
      }

      RETURN_TRUE;
}
/* }}} */

static char *maxdb_prop_error (maxdb_connection *conn TSRMLS_DC)
{
      if (MAXDB_G(error_msg)) {
            return MAXDB_G(error_msg);
      } else {
            return empty_string;
      }
}

/* {{{ proto string maxdb_error([int connection_identifier])
   Returns the text of the error message from previous MaxDB operation */
PHP_FUNCTION(maxdb_error)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif
    RETURN_STRING(maxdb_prop_error(conn TSRMLS_CC), 1);
}
/* }}} */

static int maxdb_prop_errno (maxdb_connection *conn TSRMLS_DC)
{
    return MAXDB_G(error_no);
}

/* {{{ proto int maxdb_errno([int connection_identifier])
   Returns the number of the error message from previous MaxDB operation */
PHP_FUNCTION(maxdb_errno)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif
      RETURN_LONG(maxdb_prop_errno(conn TSRMLS_CC));
}
/* }}} */

static int maxdb_prop_warning_count (maxdb_connection *conn TSRMLS_DC)
{
    return 0;
}

/* {{{ proto int maxdb_warning_count (resource link)
   Return number of warnings from the last query for the given link */
PHP_FUNCTION(maxdb_warning_count)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }

      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif
      RETURN_LONG(maxdb_prop_warning_count(conn TSRMLS_CC));
}
/* }}} */


/* {{{ proto bool maxdb_close([int connection_identifier])
   Close a MaxDB connection */
PHP_FUNCTION(maxdb_close)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }
#endif

#ifdef MAXDB_OO
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb conn");
#else
      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      if (SQLDBC_Connection_close (conn->m_connection) != SQLDBC_OK) {
            if (conn->m_connection) {
                  php_maxdb_sqldbc_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                   SQLDBC_Connection_getError(conn->m_connection));
            } else {
                  php_maxdb_internal_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                                       PHP_ERR_INITIALIZATION_FAILED_S, 
                                                       "Error while closeing connection");
            }
            RETURN_FALSE;
      }

      RETURN_TRUE;
}
/* }}} */


/* {{{ proto bool maxdb_commit([int connection_identifier])
   Commits all changes to the database session */
PHP_FUNCTION(maxdb_commit)
{
      zval *pv_conn;
      maxdb_connection *conn;

#ifdef MAXDB_OO
      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &pv_conn, maxdb_link_class_entry) == FAILURE) {
            return;
      }
      MAXDB_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, "maxdb_link");
#else
      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
            return;
      }
      ZEND_FETCH_RESOURCE(conn, maxdb_connection *, &pv_conn, -1, "maxdb conn", le_conn);
#endif

      if (SQLDBC_Connection_commit (conn->m_connection) != SQLDBC_OK) {
            php_maxdb_sqldbc_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
                                             SQLDBC_Connection_getError(conn->m_connection));
            RETURN_FALSE;
      } else {
            RETURN_TRUE;
      }
}
/* }}} */


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4

 */

Generated by  Doxygen 1.6.0   Back to index