summaryrefslogtreecommitdiff
path: root/ext/interbase/interbase.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/interbase/interbase.c')
-rw-r--r--ext/interbase/interbase.c1129
1 files changed, 1129 insertions, 0 deletions
diff --git a/ext/interbase/interbase.c b/ext/interbase/interbase.c
new file mode 100644
index 0000000000..c239cb610c
--- /dev/null
+++ b/ext/interbase/interbase.c
@@ -0,0 +1,1129 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997,1998 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Authors: Jouni Ahto <jah@cultnet.fi> |
+ | |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+/* TODO: A lot... */
+
+#include "config.h"
+#include "php.h"
+#include "php3_interbase.h"
+
+#if HAVE_IBASE
+#include <ibase.h>
+#include <time.h>
+#include "php3_string.h"
+#include "php_globals.h"
+
+/* {{{ extension definition structures */
+function_entry ibase_functions[] = {
+ {"ibase_connect", php3_ibase_connect, NULL},
+ {"ibase_pconnect", php3_ibase_pconnect, NULL},
+ {"ibase_close", php3_ibase_close, NULL},
+ {"ibase_query", php3_ibase_query, NULL},
+ {"ibase_fetch_row", php3_ibase_fetch_row, NULL},
+ {"ibase_free_result", php3_ibase_free_result, NULL},
+ {"ibase_prepare", php3_ibase_prepare, NULL},
+ {"ibase_bind", php3_ibase_bind, NULL},
+ {"ibase_execute", php3_ibase_execute, NULL},
+ {"ibase_free_query", php3_ibase_free_query, NULL},
+ {"ibase_timefmt", php3_ibase_timefmt, NULL},
+ {NULL, NULL, NULL}
+};
+
+php3_module_entry ibase_module_entry =
+{
+ "InterBase",
+ ibase_functions,
+ php3_minit_ibase,
+ NULL,
+ php3_rinit_ibase,
+ NULL,
+ php3_info_ibase,
+ STANDARD_MODULE_PROPERTIES
+};
+/* }}} */
+
+/* {{{ thread safety stuff */
+#if defined(THREAD_SAFE)
+typedef ibase_global_struct{
+ ibase_module php3_ibase_module;
+} ibase_global_struct;
+
+#define IBASE_GLOBAL(a) ibase_globals->a
+
+#define IBASE_TLS_VARS \
+ ibase_global_struct *ibase_globals; \
+ ibase_globals=TlsGetValue(IBASETls);
+
+#else
+#define IBASE_GLOBAL(a) a
+#define IBASE_TLS_VARS
+ibase_module php3_ibase_module;
+#endif
+/* }}} */
+
+/* {{{ _php3_ibase_close_link() */
+static void _php3_ibase_close_link(isc_db_handle db)
+{
+ ISC_STATUS status[20];
+ IBASE_TLS_VARS;
+
+ isc_detach_database(status, &db);
+ IBASE_GLOBAL(php3_ibase_module).num_links--;
+}
+/* }}} */
+
+/* {{{ _php3_ibase_close_plink() */
+static void _php3_ibase_close_plink(isc_db_handle db)
+{
+ ISC_STATUS status[20];
+ IBASE_TLS_VARS;
+
+ isc_detach_database(status, &db);
+ php3_ibase_module.num_persistent--;
+ php3_ibase_module.num_links--;
+}
+/* }}} */
+
+/* {{{ _php3_ibase_free_result() */
+static void _php3_ibase_free_result(ibase_result_handle *result)
+{
+ int i;
+ ISC_STATUS status[20];
+ IBASE_TLS_VARS;
+
+ if (!IBASE_GLOBAL(php3_ibase_module).manualtransactions && result->commitok) {
+ isc_commit_transaction(status, &result->trans);
+ }
+ if (result->sqlda != NULL) {
+ for (i = 0; i < result->sqlda->sqld; i++) {
+ efree(result->sqlda->sqlvar[i].sqldata);
+ efree(result->sqlda->sqlvar[i].sqlind);
+ }
+ efree(result->sqlda);
+ }
+ isc_dsql_free_statement(status, &result->result, DSQL_drop);
+ efree(result);
+}
+/* }}} */
+
+/* {{{ _php3_ibase_free_query() */
+static void _php3_ibase_free_query(ibase_query_handle *query)
+{
+ int i;
+ ISC_STATUS status[20];
+
+ if (query->sqlda != NULL) {
+ if (query->alloced) {
+ for (i = 0; i < query->sqlda->sqld; i++) {
+ efree(query->sqlda->sqlvar[i].sqldata);
+ efree(query->sqlda->sqlvar[i].sqlind);
+ }
+ }
+ efree(query->sqlda);
+ }
+ isc_dsql_free_statement(status, &query->query, DSQL_drop);
+ efree(query);
+}
+/* }}} */
+
+/* {{{ startup, shutdown and info functions */
+int php3_minit_ibase(INIT_FUNC_ARGS)
+{
+ IBASE_TLS_VARS;
+
+ if (cfg_get_long("ibase.allow_persistent", &IBASE_GLOBAL(php3_ibase_module).allow_persistent) == FAILURE) {
+ IBASE_GLOBAL(php3_ibase_module).allow_persistent = 1;
+ }
+ if (cfg_get_long("ibase.max_persistent", &IBASE_GLOBAL(php3_ibase_module).max_persistent) == FAILURE) {
+ IBASE_GLOBAL(php3_ibase_module).max_persistent = -1;
+ }
+ if (cfg_get_long("ibase.max_links", &IBASE_GLOBAL(php3_ibase_module).max_links) == FAILURE) {
+ IBASE_GLOBAL(php3_ibase_module).max_links = -1;
+ }
+ /*
+ if (cfg_get_long("ibase.manualtransactions", &IBASE_GLOBAL(php3_ibase_module).manualtransactions) == FAILURE) {
+ IBASE_GLOBAL(php3_ibase_module).manualtransactions = 0;
+ }
+ */
+ IBASE_GLOBAL(php3_ibase_module).manualtransactions = 0;
+ if (cfg_get_string("ibase.default_user", &IBASE_GLOBAL(php3_ibase_module).default_user) == FAILURE
+ || IBASE_GLOBAL(php3_ibase_module).default_user[0] == 0) {
+ IBASE_GLOBAL(php3_ibase_module).default_user = "";
+ }
+ if (cfg_get_string("ibase.default_password", &IBASE_GLOBAL(php3_ibase_module).default_password) == FAILURE
+ || IBASE_GLOBAL(php3_ibase_module).default_password[0] == 0) {
+ IBASE_GLOBAL(php3_ibase_module).default_password = "";
+ }
+ if (cfg_get_string("ibase.timeformat", &IBASE_GLOBAL(php3_ibase_module).timeformat) == FAILURE) {
+ IBASE_GLOBAL(php3_ibase_module).timeformat = "%Y-%m-%d %H:%M:%S";
+ }
+ IBASE_GLOBAL(php3_ibase_module).num_persistent=0;
+ IBASE_GLOBAL(php3_ibase_module).le_result = register_list_destructors(_php3_ibase_free_result, NULL);
+ IBASE_GLOBAL(php3_ibase_module).le_query = register_list_destructors(_php3_ibase_free_query, NULL);
+ IBASE_GLOBAL(php3_ibase_module).le_link = register_list_destructors(_php3_ibase_close_link, NULL);
+ IBASE_GLOBAL(php3_ibase_module).le_plink = register_list_destructors(NULL, _php3_ibase_close_plink);
+ return SUCCESS;
+}
+
+int php3_rinit_ibase(INIT_FUNC_ARGS)
+{
+ IBASE_TLS_VARS;
+
+ IBASE_GLOBAL(php3_ibase_module).default_link=-1;
+ IBASE_GLOBAL(php3_ibase_module).num_links = php3_ibase_module.num_persistent;
+ return SUCCESS;
+}
+
+/* TODO IF NEEDED
+
+int php3_mfinish_ibase(void)
+{
+}
+
+int php3_rfinish_ibase(void)
+{
+}
+*/
+
+void php3_info_ibase(void)
+{
+ /* TODO */
+}
+/* }}} */
+
+/* {{{ _php_ibase_attach_db() */
+static int _php_ibase_attach_db(char *server, char *uname, int uname_len, char *passwd, int passwd_len, isc_db_handle *db)
+{
+ ISC_STATUS status[20];
+ int db_parbuf_len = 4;
+ short foo = 4;
+ char dpb[255], *db_parbuf;
+
+ if (uname_len) {
+ db_parbuf_len += uname_len + 2;
+ }
+
+ if (passwd_len) {
+ db_parbuf_len += passwd_len + 2;
+ }
+
+ db_parbuf = dpb;
+ *db_parbuf++ = isc_dpb_version1;
+ *db_parbuf++ = isc_dpb_num_buffers;
+ *db_parbuf++ = 1;
+ *db_parbuf++ = 90;
+
+ if (uname_len) {
+ if (passwd_len) {
+ isc_expand_dpb(&db_parbuf, &foo, isc_dpb_user_name, uname, isc_dpb_password, passwd, NULL);
+ } else {
+ isc_expand_dpb(&db_parbuf, &foo, isc_dpb_user_name, uname, NULL);
+ }
+ }
+
+ isc_attach_database(status, strlen(server), server, db, db_parbuf_len, dpb);
+
+ if (status[0] == 1 && status[1]) {
+ php3_error(E_WARNING,"Unable to connect to InterBase server: %s", "XXX");
+ return 1;
+ }
+ return 0;
+}
+/* }}} */
+
+/* {{{ _php3_ibase_connect() */
+static void _php3_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
+{
+ pval *server, *uname, *passwd;
+
+ char *ib_server, *ib_uname, *ib_passwd;
+ int ib_server_len, ib_uname_len, ib_passwd_len;
+ isc_db_handle db_handle = NULL;
+ char *hashed_details;
+ int hashed_details_length;
+ IBASE_TLS_VARS;
+
+ ib_uname = IBASE_GLOBAL(php3_ibase_module).default_user;
+ ib_passwd = IBASE_GLOBAL(php3_ibase_module).default_password;
+ ib_uname_len = ib_uname ? strlen(ib_uname) : 0;
+ ib_passwd_len = ib_passwd ? strlen(ib_passwd) : 0;
+
+ switch(ARG_COUNT(ht)) {
+ case 1:
+ {
+ if (getParameters(ht, 1, &server) == FAILURE) {
+ RETURN_FALSE;
+ }
+ convert_to_string(server);
+ ib_server = server->value.str.val;
+ ib_server_len = server->value.str.len;
+ hashed_details_length = server->value.str.len+ib_uname_len+ib_passwd_len+5+3;
+ hashed_details = (char *) emalloc(hashed_details_length+1);
+ sprintf(hashed_details, "ibase_%s_%s_%s", ib_server, ib_uname, ib_passwd);
+ }
+ break;
+ case 2:
+ {
+ if (getParameters(ht, 2, &server, &uname) == FAILURE) {
+ RETURN_FALSE;
+ }
+ convert_to_string(server);
+ convert_to_string(uname);
+ ib_server = server->value.str.val;
+ ib_uname = uname->value.str.val;
+ ib_server_len = server->value.str.len;
+ ib_uname_len = uname->value.str.len;
+ hashed_details_length = server->value.str.len+uname->value.str.len+ib_passwd_len+5+3;
+ hashed_details = (char *) emalloc(hashed_details_length+1);
+ sprintf(hashed_details, "ibase_%s_%s_%s", ib_server, ib_uname, ib_passwd);
+ }
+ break;
+ case 3:
+ {
+ if (getParameters(ht, 3, &server, &uname, &passwd) == FAILURE) {
+ RETURN_FALSE;
+ }
+ convert_to_string(server);
+ convert_to_string(uname);
+ convert_to_string(passwd);
+ ib_server = server->value.str.val;
+ ib_uname = uname->value.str.val;
+ ib_passwd = passwd->value.str.val;
+ ib_server_len = server->value.str.len;
+ ib_uname_len = uname->value.str.len;
+ ib_passwd_len = passwd->value.str.len;
+ hashed_details_length = server->value.str.len+uname->value.str.len+passwd->value.str.len+5+3;
+ hashed_details = (char *) emalloc(hashed_details_length+1);
+ sprintf(hashed_details, "ibase_%s_%s_%s", ib_server, ib_uname, ib_passwd);
+ }
+ break;
+ default:
+ WRONG_PARAM_COUNT;
+ break;
+ }
+
+ if (persistent) {
+ list_entry *le;
+
+ if (_php3_hash_find(plist, hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) {
+ list_entry new_le;
+
+ if (IBASE_GLOBAL(php3_ibase_module).max_links!=-1 && IBASE_GLOBAL(php3_ibase_module).num_links>=IBASE_GLOBAL(php3_ibase_module).max_links) {
+ php3_error(E_WARNING,"InterBase: Too many open links (%d)", IBASE_GLOBAL(php3_ibase_module).num_links);
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+ if (IBASE_GLOBAL(php3_ibase_module).max_persistent!=-1 && IBASE_GLOBAL(php3_ibase_module).num_persistent>=IBASE_GLOBAL(php3_ibase_module).max_persistent) {
+ php3_error(E_WARNING,"InterBase: Too many open persistent links (%d)", IBASE_GLOBAL(php3_ibase_module).num_persistent);
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+
+ /* create the link */
+
+ if (_php_ibase_attach_db(ib_server, ib_uname, ib_uname_len, ib_passwd, ib_passwd_len, &db_handle)) {
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+
+ /* hash it up */
+ new_le.type = php3_ibase_module.le_plink;
+ new_le.ptr = db_handle;
+ if (_php3_hash_update(plist, hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(list_entry), NULL)==FAILURE) {
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+ IBASE_GLOBAL(php3_ibase_module).num_links++;
+ IBASE_GLOBAL(php3_ibase_module).num_persistent++;
+ } else {
+ if (le->type != IBASE_GLOBAL(php3_ibase_module).le_plink) {
+ RETURN_FALSE;
+ }
+ /* TODO: ensure that the link did not die */
+
+ db_handle = (isc_db_handle) le->ptr;
+ }
+ return_value->value.lval = php3_list_insert(db_handle, IBASE_GLOBAL(php3_ibase_module).le_plink);
+ return_value->type = IS_LONG;
+ } else {
+ list_entry *index_ptr, new_index_ptr;
+
+ /* first we check the hash for the hashed_details key. if it exists,
+ * it should point us to the right offset where the actual pgsql link sits.
+ * if it doesn't, open a new pgsql link, add it to the resource list,
+ * and add a pointer to it with hashed_details as the key.
+ */
+ if (_php3_hash_find(list,hashed_details,hashed_details_length+1,(void **) &index_ptr)==SUCCESS) {
+ int type,link;
+ void *ptr;
+
+ if (index_ptr->type != le_index_ptr) {
+ RETURN_FALSE;
+ }
+ link = (int) index_ptr->ptr;
+ ptr = php3_list_find(link,&type); /* check if the link is still there */
+ if (ptr && (type==IBASE_GLOBAL(php3_ibase_module).le_link || type==IBASE_GLOBAL(php3_ibase_module).le_plink)) {
+ return_value->value.lval = IBASE_GLOBAL(php3_ibase_module).default_link = link;
+ return_value->type = IS_LONG;
+ efree(hashed_details);
+ return;
+ } else {
+ _php3_hash_del(list,hashed_details,hashed_details_length+1);
+ }
+ }
+ if (IBASE_GLOBAL(php3_ibase_module).max_links!=-1 && IBASE_GLOBAL(php3_ibase_module).num_links>=IBASE_GLOBAL(php3_ibase_module).max_links) {
+ php3_error(E_WARNING,"InterBase: Too many open links (%d)", IBASE_GLOBAL(php3_ibase_module).num_links);
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+ /* create the link */
+
+ if (_php_ibase_attach_db(ib_server, ib_uname, ib_uname_len, ib_passwd, ib_passwd_len, &db_handle)) {
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+
+ /* add it to the list */
+ return_value->value.lval = php3_list_insert(db_handle, IBASE_GLOBAL(php3_ibase_module).le_link);
+ return_value->type = IS_LONG;
+
+ /* add it to the hash */
+ new_index_ptr.ptr = (void *) return_value->value.lval;
+ new_index_ptr.type = le_index_ptr;
+ if (_php3_hash_update(list,hashed_details,hashed_details_length+1,(void *) &new_index_ptr, sizeof(list_entry), NULL)==FAILURE) {
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+ IBASE_GLOBAL(php3_ibase_module).num_links++;
+ }
+ efree(hashed_details);
+ IBASE_GLOBAL(php3_ibase_module).default_link=return_value->value.lval;
+}
+/* }}} */
+
+/* {{{ proto int ibase_connect(string database [, string username] [, string password])
+ Open a connection to an InterBase database */
+void php3_ibase_connect(INTERNAL_FUNCTION_PARAMETERS)
+{
+ _php3_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+}
+/* }}} */
+
+/* {{{ proto int ibase_pconnect(string database [, string username] [, string password])
+ Open a persistent connection to an InterBase database */
+void php3_ibase_pconnect(INTERNAL_FUNCTION_PARAMETERS)
+{
+ _php3_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+}
+/* }}} */
+
+/* {{{ proto int ibase_close([int link_identifier])
+ Close an InterBase connection */
+void php3_ibase_close(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *ibase_link;
+ int id, type;
+ isc_db_handle db_handle;
+ IBASE_TLS_VARS;
+
+ switch (ARG_COUNT(ht)) {
+ case 0:
+ id = IBASE_GLOBAL(php3_ibase_module).default_link;
+ break;
+ case 1:
+ if (getParameters(ht, 1, &ibase_link) == FAILURE) {
+ RETURN_FALSE;
+ }
+ convert_to_long(ibase_link);
+ id = ibase_link->value.lval;
+ break;
+ default:
+ WRONG_PARAM_COUNT;
+ break;
+ }
+
+ db_handle = (isc_db_handle) php3_list_find(id, &type);
+ if (type!=IBASE_GLOBAL(php3_ibase_module).le_link && type!=IBASE_GLOBAL(php3_ibase_module).le_plink) {
+ php3_error(E_WARNING, "%d is not an InterBase link index",id);
+ RETURN_FALSE;
+ }
+
+ php3_list_delete(ibase_link->value.lval);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ _php3_ibase_prepare() */
+static XSQLDA *_php3_ibase_prepare(isc_db_handle db, isc_tr_handle tr, isc_stmt_handle *query_handle, char *query)
+{
+ ISC_STATUS status[20];
+ XSQLDA *isqlda;
+
+ isqlda = (XSQLDA *) emalloc(XSQLDA_LENGTH(0));
+ isqlda->sqln = 0;
+ isqlda->version = SQLDA_VERSION1;
+
+ if (isc_dsql_allocate_statement(status, &db, query_handle)) {
+ php3_error(E_WARNING, "InterBase: couldn't allocate space for query");
+ return NULL;
+ }
+
+ if (isc_dsql_prepare(status, &tr, query_handle, 0, query, 1, isqlda)) {
+ php3_error(E_WARNING, "InterBase: couldn't prepare query");
+ return NULL;
+ }
+
+ /*
+ * Check if query has placeholders and needs binding. If it has, allocate
+ * input sqlda big enough and return it.
+ */
+
+
+ if (isc_dsql_describe_bind(status, query_handle, 1, isqlda)) {
+ php3_error(E_WARNING, "InterBase: couldn't describe placeholders in query");
+ }
+
+ if (isqlda->sqld > 1) {
+ isqlda = (XSQLDA *) erealloc(isqlda, XSQLDA_LENGTH(isqlda->sqld));
+ isqlda->sqln = isqlda->sqld;
+ isqlda->version = SQLDA_VERSION1;
+ if (isc_dsql_describe(status, query_handle, 1, isqlda)) {
+ php3_error(E_WARNING, "InterBase: couldn't describe query");
+ }
+ return isqlda;
+ } else if (isqlda->sqld == 1) {
+ return isqlda;
+ } else {
+ efree(isqlda);
+ return NULL;
+ }
+}
+/* }}} */
+
+/* {{{ _php3_ibase_execute() */
+static XSQLDA *_php3_ibase_execute(isc_tr_handle tr_handle, isc_stmt_handle query_handle, XSQLDA *isqlda, ISC_STATUS *status)
+{
+ int i, coltype;
+ static char query_info[] = { isc_info_sql_stmt_type };
+ char info_buffer[18];
+ short l;
+ long query_type;
+ XSQLDA *osqlda;
+
+ /*
+ * Find out what kind of query is to be executed.
+ */
+
+ if (!isc_dsql_sql_info(status, &query_handle, sizeof(query_info), query_info, sizeof(info_buffer), info_buffer)) {
+ l = (short) isc_vax_integer((char ISC_FAR *) info_buffer + 1, 2);
+ query_type = isc_vax_integer((char ISC_FAR *) info_buffer + 3, l);
+ }
+
+ if (query_type == isc_info_sql_stmt_select || query_type == isc_info_sql_stmt_select_for_upd) {
+ /*
+ * Select, need to allocate output sqlda and and prepare it for use.
+ */
+
+ osqlda = (XSQLDA *) emalloc(XSQLDA_LENGTH(0));
+ osqlda->sqln = 0;
+ osqlda->version = SQLDA_VERSION1;
+
+ if (isc_dsql_describe(status, &query_handle, 1, osqlda)) {
+ php3_error(E_WARNING, "InterBase: couldn't describe query");
+ }
+
+ if (osqlda->sqld) {
+ osqlda = (XSQLDA *) erealloc(osqlda, XSQLDA_LENGTH(osqlda->sqld));
+ osqlda->sqln = osqlda->sqld;
+ osqlda->version = SQLDA_VERSION1;
+ if (isc_dsql_describe(status, &query_handle, 1, osqlda)) {
+ php3_error(E_WARNING, "InterBase: couldn't describe query");
+ }
+ }
+ for (i = 0; i < osqlda->sqld; i++) {
+ osqlda->sqlvar[i].sqlind = (short *) emalloc(sizeof(short));
+ coltype = osqlda->sqlvar[i].sqltype & ~1;
+ switch(coltype)
+ {
+ case SQL_TEXT:
+ osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(char)*(osqlda->sqlvar[i].sqllen));
+ break;
+ case SQL_VARYING:
+ osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(char)*(osqlda->sqlvar[i].sqllen+2));
+ break;
+ case SQL_SHORT:
+ osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(short));
+ break;
+ case SQL_LONG:
+ osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(long));
+ break;
+ case SQL_FLOAT:
+ osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(float));
+ break;
+ case SQL_DOUBLE:
+ osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(double));
+ break;
+ case SQL_DATE:
+ osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(ISC_QUAD));
+ break;
+ case SQL_BLOB:
+ osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(ISC_QUAD));
+ break;
+ case SQL_ARRAY:
+ osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(ISC_QUAD));
+ break;
+ }
+ }
+ if (isqlda == NULL) {
+ if (isc_dsql_execute(status, &tr_handle, &query_handle, 1, NULL)) {
+ php3_error(E_WARNING, "InterBase: couldn't execute query");
+ return NULL;
+ } else {
+ return osqlda;
+ }
+
+ } else {
+ if (isc_dsql_execute2(status, &tr_handle, &query_handle, 1, isqlda, osqlda)) {
+ php3_error(E_WARNING, "InterBase: couldn't execute query");
+ return NULL;
+ } else {
+ return osqlda;
+ }
+
+ }
+ } else {
+ /* Not select */
+ if (isc_dsql_execute(status, &tr_handle, &query_handle, 1, isqlda)) {
+ php3_error(E_WARNING, "InterBase: couldn't execute query");
+ }
+ /*
+ if (!php3_ibase_module.manualtransactions) {
+ if(0) {
+ isc_commit_transaction(status, tr_handle);
+ } else {
+ isc_rollback_transaction(status, tr_handle);
+ }
+ }
+ */
+ }
+
+ return NULL;
+}
+/* }}} */
+
+/* {{{ proto int ibase_query([int link_identifier, ]string query)
+ Execute a query (without parameter placeholders). */
+void php3_ibase_query(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *query, *ibase_link;
+ int id, type;
+ isc_db_handle db_handle;
+ isc_tr_handle tr_handle = NULL;
+ isc_stmt_handle query_handle = NULL;
+ ISC_STATUS status[20];
+ XSQLDA *isqlda, *osqlda;
+ ibase_result_handle *ibase_result;
+ IBASE_TLS_VARS;
+
+ switch (ARG_COUNT(ht)) {
+ case 1:
+ if (getParameters(ht, 1, &query) == FAILURE) {
+ RETURN_FALSE;
+ }
+ id = IBASE_GLOBAL(php3_ibase_module).default_link;
+ break;
+ case 2:
+ if (getParameters(ht, 2, &ibase_link, &query) == FAILURE) {
+ RETURN_FALSE;
+ }
+ convert_to_long(ibase_link);
+ id = ibase_link->value.lval;
+ break;
+ default:
+ WRONG_PARAM_COUNT;
+ break;
+ }
+
+ db_handle = (isc_db_handle) php3_list_find(id, &type);
+ if (type!=IBASE_GLOBAL(php3_ibase_module).le_link && type!=IBASE_GLOBAL(php3_ibase_module).le_plink) {
+ php3_error(E_WARNING, "%d is not an InterBase link index", id);
+ RETURN_FALSE;
+ }
+
+ convert_to_string(query);
+
+ if (!IBASE_GLOBAL(php3_ibase_module).manualtransactions) {
+ if (isc_start_transaction(status, &tr_handle, 1, &db_handle, 0, NULL)) {
+ php3_error(E_WARNING, "InterBase: couldn't start transaction");
+ RETURN_FALSE;
+ }
+ }
+
+ isqlda = _php3_ibase_prepare(db_handle, tr_handle, &query_handle, query->value.str.val);
+ if (isqlda != NULL) {
+ isc_rollback_transaction(status, &tr_handle);
+ isc_dsql_free_statement(status, &query_handle, DSQL_drop);
+ php3_error(E_WARNING, "InterBase: ibase_query doesn't support parameter placeholders in query");
+ RETURN_FALSE;
+ }
+
+ osqlda = _php3_ibase_execute(tr_handle, query_handle, isqlda, status);
+ if (osqlda != NULL) {
+ ibase_result = (ibase_result_handle *) emalloc(sizeof(ibase_result_handle));
+ ibase_result->result = query_handle;
+ ibase_result->sqlda = osqlda;
+ ibase_result->trans = tr_handle;
+ ibase_result->commitok = 1;
+ return_value->value.lval = php3_list_insert(ibase_result, php3_ibase_module.le_result);
+ return_value->type = IS_LONG;
+ } else {
+ if (status[0] == 1 && status[1]) {
+ if (!IBASE_GLOBAL(php3_ibase_module).manualtransactions) {
+ isc_rollback_transaction(status, &tr_handle);
+ isc_dsql_free_statement(status, &query_handle, DSQL_drop);
+ RETURN_FALSE;
+ }
+ } else {
+ if (!IBASE_GLOBAL(php3_ibase_module).manualtransactions) {
+ isc_commit_transaction(status, &tr_handle);
+ isc_dsql_free_statement(status, &query_handle, DSQL_drop);
+ RETURN_FALSE;
+ }
+ }
+ }
+}
+/* }}} */
+
+/* {{{ proto int ibase_fetch_row(int result)
+ Fetch a row from the results of a query. */
+void php3_ibase_fetch_row(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *result;
+ pval *pval_ptr;
+ int type;
+ int i, coltype, collen;
+ char string_data[255];
+ char *fieldname;
+ char *char_data;
+ /*
+ struct tm t;
+ */
+ ibase_result_handle *ibase_result;
+ ISC_STATUS status[20];
+ XSQLVAR *var;
+ IBASE_VCHAR *vchar;
+ IBASE_TLS_VARS;
+ PLS_FETCH();
+
+ if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &result)==FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long(result);
+ ibase_result = (ibase_result_handle *) php3_list_find(result->value.lval, &type);
+
+ if (type!=IBASE_GLOBAL(php3_ibase_module).le_result) {
+ php3_error(E_WARNING,"%d is not an InterBase result index", result->value.lval);
+ RETURN_FALSE;
+ }
+
+ if (ibase_result->sqlda == NULL) {
+ php3_error(E_WARNING,"InterBase: trying to fetch results from a non-select query");
+ RETURN_FALSE;
+ }
+
+ var = ibase_result->sqlda->sqlvar;
+
+ if (isc_dsql_fetch(status, &ibase_result->result, 1, ibase_result->sqlda) != 100L) {
+ if (array_init(return_value)==FAILURE) {
+ RETURN_FALSE;
+ }
+
+ for (i = 0; i < ibase_result->sqlda->sqld; i++) {
+ var[i].sqlname[var[i].sqlname_length] = '\0';
+ fieldname = var[i].sqlname;
+ if (*var[i].sqlind < 0) {
+ /* XXX. Column is NULL. This is not the best idea to do, think something... */
+ add_get_index_stringl(return_value, i, NULL, 0, (void **) &pval_ptr, 1);
+ _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+ continue;
+ }
+ coltype = var[i].sqltype & ~1;
+ switch(coltype) {
+ case SQL_TEXT:
+ {
+ int len = var[i].sqllen;
+ char_data = (char *)emalloc(sizeof(char)*(var[i].sqllen));
+ collen = sprintf(char_data, "%*.*s", len, len, ibase_result->sqlda->sqlvar[i].sqldata);
+ if (PG(magic_quotes_runtime)) {
+ int newlen;
+ char *tmp = _php3_addslashes(char_data, collen, &newlen, 0);
+ add_get_index_stringl(return_value, i, tmp, newlen, (void **) &pval_ptr, 0);
+ } else {
+ add_get_index_stringl(return_value, i, char_data, collen, (void **) &pval_ptr, 1);
+ }
+ _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+ efree(char_data);
+ }
+ break;
+ case SQL_VARYING:
+ {
+ vchar = (IBASE_VCHAR *) var[i].sqldata;
+ char_data = (char *)emalloc(sizeof(char)*(vchar->var_len));
+ collen = sprintf(char_data, "%*.*s", vchar->var_len, vchar->var_len, vchar->var_str);
+ if (PG(magic_quotes_runtime)) {
+ int newlen;
+ char *tmp = _php3_addslashes(char_data, collen, &newlen, 0);
+ add_get_index_stringl(return_value, i, tmp, newlen, (void **) &pval_ptr, 0);
+ } else {
+ add_get_index_stringl(return_value, i, char_data, collen, (void **) &pval_ptr, 1);
+ }
+ _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+ efree(char_data);
+ }
+ break;
+ case SQL_SHORT:
+ collen = sprintf(string_data, "%d", *(short *)(var[i].sqldata));
+ add_get_index_stringl(return_value, i, string_data, collen, (void **) &pval_ptr, 1);
+ _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+ break;
+ case SQL_LONG:
+ if (var[i].sqlscale) {
+ int j, f = 1;
+ float n;
+ n = *(long *)(var[i].sqldata);
+ for (j = 0; j < -var[i].sqlscale; j++)
+ f *= 10;
+ n /= f;
+ collen = sprintf(string_data, "%.*f", -var[i].sqlscale, n);
+
+ } else {
+ collen = sprintf(string_data, "%ld", *(long *)(var[i].sqldata));
+ }
+ add_get_index_stringl(return_value, i, string_data, collen, (void **) &pval_ptr, 1);
+ _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+ break;
+ case SQL_FLOAT:
+ collen = sprintf(string_data, "%f", *(float *)(var[i].sqldata));
+ add_get_index_stringl(return_value, i, string_data, collen, (void **) &pval_ptr, 1);
+ _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+ break;
+ case SQL_DOUBLE:
+ if (ibase_result->sqlda->sqlvar[i].sqlscale) {
+ collen = sprintf(string_data, "%.*f", -var[i].sqlscale, *(double *)(var[i].sqldata));
+ } else {
+ collen = sprintf(string_data, "%f", *(double *)(var[i].sqldata));
+ }
+ add_get_index_stringl(return_value, i, string_data, collen, (void **) &pval_ptr, 1);
+ _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+ break;
+ case SQL_DATE: {
+ struct tm *t;
+ t = emalloc(sizeof(struct tm));
+
+ isc_decode_date((ISC_QUAD *) var[i].sqldata, t);
+ /*
+#if HAVE_STRFTIME
+ collen = (int) strftime(string_data, 255, IBASE_GLOBAL(php3_ibase_module).timeformat, t);
+#else
+ */
+ collen = sprintf(string_data, "%4d-%02d-%02d %02d:%02d:%02d", t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
+ /* #endif */
+ add_get_index_stringl(return_value, i, string_data, collen, (void **) &pval_ptr, 1);
+ _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+ efree(t);
+ }
+ break;
+ case SQL_BLOB:
+ case SQL_ARRAY:
+ {
+ /* TODO, currently just show the id */
+ ISC_QUAD bid;
+ bid = *(ISC_QUAD ISC_FAR *) var[i].sqldata;
+ sprintf(string_data, "%lx:%lx", bid.isc_quad_high, bid.isc_quad_low);
+ add_get_index_stringl(return_value, i, string_data, collen, (void **) &pval_ptr, 1);
+ _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto int ibase_free_result(int result)
+ Free the memory used by a result. */
+void php3_ibase_free_result(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *result;
+ ibase_result_handle *ibase_result;
+ int type;
+ IBASE_TLS_VARS;
+
+ if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &result)==FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long(result);
+ if (result->value.lval==0) {
+ RETURN_FALSE;
+ }
+
+ ibase_result = (ibase_result_handle *) php3_list_find(result->value.lval,&type);
+
+ if (type!=IBASE_GLOBAL(php3_ibase_module).le_result) {
+ php3_error(E_WARNING,"%d is not an InterBase result index",result->value.lval);
+ RETURN_FALSE;
+ }
+ php3_list_delete(result->value.lval);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto int ibase_prepare([int link_identifier, ]string query)
+ Prepare a query for later binding of parameter placeholders and execution. */
+void php3_ibase_prepare(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *query, *ibase_link;
+ int id, type;
+ isc_db_handle db_handle;
+ isc_tr_handle tr_handle = NULL;
+ isc_stmt_handle query_handle = NULL;
+ ISC_STATUS status[20];
+ XSQLDA *isqlda;
+ ibase_query_handle *ibase_query;
+ IBASE_TLS_VARS;
+
+ switch (ARG_COUNT(ht)) {
+ case 1:
+ if (getParameters(ht, 1, &query) == FAILURE) {
+ RETURN_FALSE;
+ }
+ id = IBASE_GLOBAL(php3_ibase_module).default_link;
+ break;
+ case 2:
+ if (getParameters(ht, 2, &ibase_link, &query) == FAILURE) {
+ RETURN_FALSE;
+ }
+ convert_to_long(ibase_link);
+ id = ibase_link->value.lval;
+ break;
+ default:
+ WRONG_PARAM_COUNT;
+ break;
+ }
+
+ db_handle = (isc_db_handle) php3_list_find(id, &type);
+ if (type!=IBASE_GLOBAL(php3_ibase_module).le_link && type!=IBASE_GLOBAL(php3_ibase_module).le_plink) {
+ php3_error(E_WARNING, "%d is not an InterBase link index", id);
+ RETURN_FALSE;
+ }
+
+ convert_to_string(query);
+
+ if (!IBASE_GLOBAL(php3_ibase_module).manualtransactions) {
+ if (isc_start_transaction(status, &tr_handle, 1, &db_handle, 0, NULL)) {
+ php3_error(E_WARNING, "InterBase: couldn't start transaction");
+ RETURN_FALSE;
+ }
+ }
+
+ isqlda = _php3_ibase_prepare(db_handle, tr_handle, &query_handle, query->value.str.val);
+ ibase_query = (ibase_query_handle *) emalloc(sizeof(ibase_query_handle));
+ ibase_query->query = query_handle;
+ ibase_query->sqlda = isqlda;
+ ibase_query->trans = tr_handle;
+ ibase_query->alloced = 0;
+ return_value->value.lval = php3_list_insert(ibase_query, php3_ibase_module.le_query);
+ return_value->type = IS_LONG;
+}
+/* }}} */
+
+/* {{{ proto int ibase_bind (int query)
+ Bind parameter placeholders in a previously prepared query. Still nonfunctional. */
+void php3_ibase_bind(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *query;
+ ibase_query_handle *ibase_query;
+ int type;
+ IBASE_TLS_VARS;
+
+ if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &query)==FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long(query);
+ if (query->value.lval==0) {
+ RETURN_FALSE;
+ }
+
+ ibase_query = (ibase_query_handle *) php3_list_find(query->value.lval,&type);
+
+ if (type!=IBASE_GLOBAL(php3_ibase_module).le_query) {
+ php3_error(E_WARNING,"%d is not an InterBase query index",query->value.lval);
+ RETURN_FALSE;
+ }
+
+ if (ibase_query->sqlda == NULL) {
+ php3_error(E_WARNING,"InterBase: trying to bind a query having no parameter placeholders");
+ RETURN_FALSE;
+ }
+
+ /* TODO
+ for (i = 0; i < ibase_query->sqlda->sqld; i++) {
+ ibase_query->sqlda->sqlvar[i].sqlind = (short *) emalloc(sizeof(short));
+ coltype = ibase_query->sqlda->sqlvar[i].sqltype & ~1;
+ switch(coltype)
+ {
+ case SQL_TEXT:
+ break;
+ case SQL_VARYING:
+ break;
+ case SQL_SHORT:
+ break;
+ case SQL_LONG:
+ break;
+ case SQL_FLOAT:
+ break;
+ case SQL_DOUBLE:
+ break;
+ case SQL_DATE:
+ break;
+ case SQL_BLOB:
+ break;
+ case SQL_ARRAY:
+ break;
+ }
+ }
+ */
+}
+/* }}} */
+
+/* {{{ proto int ibase_execute(int query)
+ Execute a previously prepared (and possibly binded) query. */
+void php3_ibase_execute(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *query;
+ ibase_query_handle *ibase_query;
+ ibase_result_handle *ibase_result;
+ int type;
+ ISC_STATUS status[20];
+ XSQLDA *osqlda;
+ IBASE_TLS_VARS;
+
+ if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &query)==FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long(query);
+ if (query->value.lval==0) {
+ RETURN_FALSE;
+ }
+
+ ibase_query = (ibase_query_handle *) php3_list_find(query->value.lval,&type);
+
+ if (type!=IBASE_GLOBAL(php3_ibase_module).le_query) {
+ php3_error(E_WARNING,"%d is not an InterBase query index", query->value.lval);
+ RETURN_FALSE;
+ }
+
+ osqlda = _php3_ibase_execute(ibase_query->trans, ibase_query->query, ibase_query->sqlda, status);
+ ibase_result = (ibase_result_handle *) emalloc(sizeof(ibase_result_handle));
+ ibase_result->result = ibase_query->query;
+ ibase_result->sqlda = osqlda;
+ return_value->value.lval = php3_list_insert(ibase_result, IBASE_GLOBAL(php3_ibase_module).le_result);
+ return_value->type = IS_LONG;
+}
+/* }}} */
+
+/* {{{ proto int ibase_free_query(int query)
+ Free memory used by a query */
+void php3_ibase_free_query(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *query;
+ ibase_query_handle *ibase_query;
+ int type;
+ IBASE_TLS_VARS;
+
+ if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &query)==FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long(query);
+ if (query->value.lval==0) {
+ RETURN_FALSE;
+ }
+
+ ibase_query = (ibase_query_handle *) php3_list_find(query->value.lval, &type);
+
+ if (type!=IBASE_GLOBAL(php3_ibase_module).le_query) {
+ php3_error(E_WARNING,"%d is not an InterBase query index", query->value.lval);
+ RETURN_FALSE;
+ }
+ php3_list_delete(query->value.lval);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto int ibase_timefmt(string format)
+ Sets the format of datetime columns returned from queries. Still nonfunctional. */
+void php3_ibase_timefmt(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *pmode;
+ IBASE_TLS_VARS;
+
+#if HAVE_STRFTIME
+ if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &pmode)==FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_string(pmode);
+
+ RETURN_TRUE;
+#else
+ php3_error(E_WARNING,"InterBase: ibase_timefmt not supported on this platform");
+ RETURN_FALSE;
+#endif
+}
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */