📄 interbase.c
字号:
/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Jouni Ahto <jouni.ahto@exdec.fi> | | Andrew Avdeev <andy@rsc.mv.ru> | +----------------------------------------------------------------------+ *//* $Id: interbase.c,v 1.91.2.34.2.5 2007/02/16 07:11:33 tony2001 Exp $ *//* TODO: Arrays, roles?A lot... *//* Changes: 2001-05-31: Jeremy Bettis <jeremy@deadbeef.com> - If a blob handle was expected and something else was received create a blob and add the value to it. - If the incoming argument to a bind parameter is NULL then store a NULL in the database. - More verbose date errors. 1999-09-21: Ivo Panacek <ivop@regionet.cz> - added COMPILE_DL section - more verbose php_info_ibase function mostly stolen from pgsql.c for now 1999-10-05: Ivo Panacek <ivop@regionet.cz> - safe rinit/rfinish: check for NULL so rfinish could be called repeatedly emalloc & co. replaced with malloc & co.*/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "php.h"#include "php_ini.h"#include "ext/standard/php_standard.h"#include "php_globals.h"#include "php_interbase.h"#if HAVE_IBASE#include <ibase.h>#ifndef SQLDA_CURRENT_VERSION#define SQLDA_CURRENT_VERSION SQLDA_VERSION1#endif#include <time.h>#include "ext/standard/fsock.h"#include "ext/standard/info.h"#ifdef SQL_INT64#include <math.h>#endif#ifndef SQL_DIALECT_CURRENT#define SQL_DIALECT_CURRENT 1#endif/*#define IBDEBUG(a) php_printf("::: %s (%d)\n", a, __LINE__);*/#define IBDEBUG(a)#define SAFE_STRING(s) ((s)?(s):"")/* {{{ extension definition structures */function_entry ibase_functions[] = { PHP_FE(ibase_connect, NULL) PHP_FE(ibase_pconnect, NULL) PHP_FE(ibase_close, NULL) PHP_FE(ibase_query, NULL) PHP_FE(ibase_fetch_row, NULL) PHP_FE(ibase_fetch_assoc, NULL) PHP_FE(ibase_fetch_object, NULL) PHP_FE(ibase_free_result, NULL) PHP_FE(ibase_prepare, NULL) PHP_FE(ibase_execute, NULL) PHP_FE(ibase_free_query, NULL)#if HAVE_STRFTIME PHP_FE(ibase_timefmt, NULL)#endif PHP_FE(ibase_num_fields, NULL) PHP_FE(ibase_field_info, NULL) PHP_FE(ibase_trans, NULL) PHP_FE(ibase_commit, NULL) PHP_FE(ibase_rollback, NULL) PHP_FE(ibase_blob_info, NULL) PHP_FE(ibase_blob_create, NULL) PHP_FE(ibase_blob_add, NULL) PHP_FE(ibase_blob_cancel, NULL) PHP_FE(ibase_blob_close, NULL) PHP_FE(ibase_blob_open, NULL) PHP_FE(ibase_blob_get, NULL) PHP_FE(ibase_blob_echo, NULL) PHP_FE(ibase_blob_import, NULL) PHP_FE(ibase_errmsg, NULL)#ifdef SQL_DIALECT_V6 PHP_FE(ibase_add_user, NULL) PHP_FE(ibase_modify_user, NULL) PHP_FE(ibase_delete_user, NULL)#endif {NULL, NULL, NULL}};zend_module_entry ibase_module_entry = { STANDARD_MODULE_HEADER, "interbase", ibase_functions, PHP_MINIT(ibase), PHP_MSHUTDOWN(ibase), PHP_RINIT(ibase), PHP_RSHUTDOWN(ibase), PHP_MINFO(ibase), NO_VERSION_YET, STANDARD_MODULE_PROPERTIES};#ifdef COMPILE_DL_INTERBASEZEND_GET_MODULE(ibase)#define DL_MALLOC(size) malloc(size)#define DL_STRDUP(str) strdup(str)#define DL_FREE(ptr) free(ptr)#else#define DL_MALLOC(size) emalloc(size)#define DL_STRDUP(str) estrdup(str)#define DL_FREE(ptr) efree(ptr)#endif/* True globals, no need for thread safety */static int le_blob, le_link, le_plink, le_result, le_query, le_trans;ZEND_DECLARE_MODULE_GLOBALS(ibase)/* }}} *//* {{{ internal macros, functions and structures */#define IB_STATUS (IBG(status))/* Fill ib_link and trans_n with the correct database link and transaction slot number. */static void get_link_trans(INTERNAL_FUNCTION_PARAMETERS, zval **link_id, ibase_db_link **ib_link, int *trans_n, int *trans_id){ int type; void *resource = NULL; ibase_tr_link *ib_trans; IBDEBUG("Transaction or database link?"); if ((resource = zend_list_find(Z_LVAL_PP(link_id), &type))) { IBDEBUG("Found in list"); if (type == le_trans) { /* Transaction resource. Fetch it, database link resource is stored in ib_trans->link_rsrc. */ IBDEBUG("Type is le_trans"); *trans_id = (Z_LVAL_PP(link_id)); ZEND_FETCH_RESOURCE(ib_trans, ibase_tr_link *, link_id, -1, "InterBase transaction", le_trans); *trans_n = ib_trans->trans_num; ZEND_FETCH_RESOURCE2(resource, ibase_db_link *, NULL, ib_trans->link_rsrc, "InterBase link", le_link, le_plink); } else { IBDEBUG("Type is le_[p]link"); /* Database link resource, use default transaction (=0). */ *trans_n = 0; ZEND_FETCH_RESOURCE2(resource, ibase_db_link *, link_id, -1, "InterBase link", le_link, le_plink); } } *ib_link = resource;} #define RESET_ERRMSG { IBG(errmsg)[0] = '\0';}#define TEST_ERRMSG ( IBG(errmsg)[0] != '\0')/* sql variables union * used for convert and binding input variables */typedef struct { union { short sval; float fval; ISC_QUAD qval;#ifdef ISC_TIMESTAMP ISC_TIMESTAMP tsval; ISC_DATE dtval; ISC_TIME tmval;#endif } val; short sqlind;} BIND_BUF;/* get blob identifier from argument * on empty unset argument ib_blob set to NULL */#define GET_BLOB_ID_ARG(blob_arg, ib_blob)\{\ if (Z_TYPE_P(blob_arg) == IS_STRING && Z_STRLEN_P(blob_arg) == 0) {\ ib_blob = NULL;\ } else if (Z_TYPE_P(blob_arg) != IS_STRING\ || Z_STRLEN_P(blob_arg) != sizeof(ibase_blob_handle)\ || ((ibase_blob_handle *)(Z_STRVAL_P(blob_arg)))->bl_handle != 0) {\ _php_ibase_module_error("Invalid blob id");\ RETURN_FALSE;\ } else {\ ib_blob = (ibase_blob_handle *)Z_STRVAL_P(blob_arg);\ }\}/* get blob handle from argument * note: blob already open when handle active */#define GET_BLOB_HANDLE_ARG(blob_arg, blob_ptr) \{ \ int type; \ convert_to_long_ex(blob_arg); \ blob_ptr = (ibase_blob_handle *) zend_list_find(Z_LVAL_PP(blob_arg), &type); \ if (type!=le_blob) { \ _php_ibase_module_error("%d is not blob handle", Z_LVAL_PP(blob_arg)); \ RETURN_FALSE; \ } \}/* blob information struct */typedef struct { ISC_LONG max_segment; /* Length of longest segment */ ISC_LONG num_segments; /* Total number of segments */ ISC_LONG total_length; /* Total length of blob */ int bl_stream; /* blob is stream ? */} IBASE_BLOBINFO;/* }}} *//* error handling ---------------------------- *//* {{{ proto string ibase_errmsg(void) Return error message */PHP_FUNCTION(ibase_errmsg){ if (ZEND_NUM_ARGS() != 0) { WRONG_PARAM_COUNT; } if (IBG(errmsg[0])) { RETURN_STRING(IBG(errmsg), 1); } RETURN_FALSE;}/* }}} *//* {{{ _php_ibase_error(TSRMLS_D) print interbase error and save it for ibase_errmsg() */static void _php_ibase_error(TSRMLS_D){ char *s; ISC_STATUS *statusp; s = IBG(errmsg); statusp = IB_STATUS; while ((s - IBG(errmsg)) < MAX_ERRMSG - (IBASE_MSGSIZE + 2) && isc_interprete(s, &statusp)) { strcat(IBG(errmsg), " "); s = IBG(errmsg) + strlen(IBG(errmsg)); } php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", IBG(errmsg));}/* }}} *//* {{{ _php_ibase_module_error() print php interbase module error and save it for ibase_errmsg() */static void _php_ibase_module_error(char *msg, ...){ va_list ap; TSRMLS_FETCH(); va_start(ap, msg); /* vsnprintf NUL terminates the buf and writes at most n-1 chars+NUL */ vsnprintf(IBG(errmsg), MAX_ERRMSG, msg, ap); va_end(ap); php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", IBG(errmsg));}/* }}} *//* destructors ---------------------- *//* {{{ _php_ibase_free_xsqlda() (not actual destructor) */static void _php_ibase_free_xsqlda(XSQLDA *sqlda){ int i; XSQLVAR *var; IBDEBUG("Free XSQLDA?"); if (sqlda) { IBDEBUG("Freeing XSQLDA..."); var = sqlda->sqlvar; for (i = 0; i < sqlda->sqld; i++, var++) { efree(var->sqldata); if (var->sqlind) { efree(var->sqlind); } } efree(sqlda); }}/* }}} *//* {{{ _php_ibase_commit_link() */static void _php_ibase_commit_link(ibase_db_link *link TSRMLS_DC){ int i; IBDEBUG("Checking transactions to close..."); if (link->trans[0] != NULL) { /* commit default */ IBDEBUG("Committing default transaction..."); if (isc_commit_transaction(IB_STATUS, &link->trans[0])) { _php_ibase_error(TSRMLS_C); } link->trans[0] = NULL; } for (i = 1; i < IBASE_TRANS_ON_LINK; i++) { if (link->trans[i] != NULL) { IBDEBUG("Rolling back other transactions..."); if (isc_rollback_transaction(IB_STATUS, &link->trans[i])) { _php_ibase_error(TSRMLS_C); } link->trans[i] = NULL; } }}/* }}} */static void php_ibase_commit_link_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC){ ibase_db_link *link = (ibase_db_link *) rsrc->ptr; _php_ibase_commit_link(link TSRMLS_CC);}/* {{{ _php_ibase_close_link() */static void _php_ibase_close_link(zend_rsrc_list_entry *rsrc TSRMLS_DC){ ibase_db_link *link = (ibase_db_link *) rsrc->ptr; _php_ibase_commit_link(link TSRMLS_CC); IBDEBUG("Closing normal link..."); isc_detach_database(IB_STATUS, &link->link); IBG(num_links)--; efree(link);}/* }}} *//* {{{ _php_ibase_close_plink() */static void _php_ibase_close_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC){ ibase_db_link *link = (ibase_db_link *) rsrc->ptr; _php_ibase_commit_link(link TSRMLS_CC); IBDEBUG("Closing permanent link..."); isc_detach_database(IB_STATUS, &link->link); IBG(num_persistent)--; IBG(num_links)--; free(link);}/* }}} *//* {{{ _php_ibase_free_result() */static void _php_ibase_free_result(zend_rsrc_list_entry *rsrc TSRMLS_DC){ ibase_result *ib_result = (ibase_result *) rsrc->ptr; IBDEBUG("Freeing result by dtor..."); if (ib_result) { _php_ibase_free_xsqlda(ib_result->out_sqlda); if (ib_result->drop_stmt && ib_result->stmt) { IBDEBUG("Dropping statement handle (free_result dtor)..."); isc_dsql_free_statement(IB_STATUS, &ib_result->stmt, DSQL_drop); } else { /* Shouldn't be here unless query was select and had parameter placeholders, in which case ibase_execute handles this??? (Testing seems to confirm the decision was a right one.) */ IBDEBUG("Closing statement handle..."); /* if (isc_dsql_free_statement(IB_STATUS, &ib_result->stmt, DSQL_close)) { _php_ibase_error(); } */ } if (ib_result->out_array) { efree(ib_result->out_array); } efree(ib_result); }}/* }}} *//* {{{ _php_ibase_free_query() */static void _php_ibase_free_query(ibase_query *ib_query TSRMLS_DC){ IBDEBUG("Freeing query..."); if (ib_query) { if (ib_query->in_sqlda) { efree(ib_query->in_sqlda); } if (ib_query->out_sqlda) { efree(ib_query->out_sqlda); } if (ib_query->stmt) { IBDEBUG("Dropping statement handle (free_query)..."); if (isc_dsql_free_statement(IB_STATUS, &ib_query->stmt, DSQL_drop)) { _php_ibase_error(TSRMLS_C); } } if (ib_query->in_array) { efree(ib_query->in_array); } if (ib_query->out_array) { efree(ib_query->out_array); } efree(ib_query); }}/* }}} *//* {{{ php_ibase_free_query_rsrc() */static void php_ibase_free_query_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC){ ibase_query *ib_query = (ibase_query *)rsrc->ptr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -