📄 interbase.c
字号:
var->sqltype = SQL_TEXT; } /* switch */ } /* if */ } /* for */ return rv;}/* }}} *//* {{{ _php_ibase_alloc_xsqlda() */static void _php_ibase_alloc_xsqlda(XSQLDA *sqlda){ int i; XSQLVAR *var = sqlda->sqlvar; for (i = 0; i < sqlda->sqld; i++, var++) { switch (var->sqltype & ~1) { case SQL_TEXT: var->sqldata = emalloc(sizeof(char) * (var->sqllen)); break; case SQL_VARYING: var->sqldata = emalloc(sizeof(char) * (var->sqllen + sizeof(short))); break; case SQL_SHORT: var->sqldata = emalloc(sizeof(short)); break; case SQL_LONG: var->sqldata = emalloc(sizeof(long)); break; case SQL_FLOAT: var->sqldata = emalloc(sizeof(float)); break; case SQL_DOUBLE: var->sqldata = emalloc(sizeof(double)); break;#ifdef SQL_INT64 case SQL_INT64: var->sqldata = emalloc(sizeof(ISC_INT64)); break;#endif#ifdef SQL_TIMESTAMP case SQL_TIMESTAMP: var->sqldata = emalloc(sizeof(ISC_TIMESTAMP)); break; case SQL_TYPE_DATE: var->sqldata = emalloc(sizeof(ISC_DATE)); break; case SQL_TYPE_TIME: var->sqldata = emalloc(sizeof(ISC_TIME)); break;#else case SQL_DATE:#endif case SQL_BLOB: case SQL_ARRAY: var->sqldata = emalloc(sizeof(ISC_QUAD)); break; } /* switch */ if (var->sqltype & 1) { /* sql NULL flag */ var->sqlind = emalloc(sizeof(short)); } else { var->sqlind = NULL; } } /* for */}/* }}} *//* {{{ _php_ibase_exec() */static int _php_ibase_exec(ibase_result **ib_resultp, ibase_query *ib_query, int argc, zval ***args TSRMLS_DC){#define IB_RESULT (*ib_resultp) XSQLDA *in_sqlda = NULL, *out_sqlda = NULL; BIND_BUF *bind_buf = NULL; int i, rv = FAILURE; IB_RESULT = NULL; for (i = 0; i < argc; ++i) { SEPARATE_ZVAL(args[i]); } /* allocate sqlda and output buffers */ if (ib_query->out_sqlda) { /* output variables in select, select for update */ IBDEBUG("Query wants XSQLDA for output"); IB_RESULT = emalloc(sizeof(ibase_result)); IB_RESULT->link = ib_query->link; IB_RESULT->trans = ib_query->trans; IB_RESULT->stmt = ib_query->stmt; IB_RESULT->drop_stmt = 0; /* when free result close but not drop!*/ IB_RESULT->has_more_rows = 1; out_sqlda = IB_RESULT->out_sqlda = emalloc(XSQLDA_LENGTH(ib_query->out_sqlda->sqld)); memcpy(out_sqlda, ib_query->out_sqlda, XSQLDA_LENGTH(ib_query->out_sqlda->sqld)); _php_ibase_alloc_xsqlda(out_sqlda); if (ib_query->out_array) { IB_RESULT->out_array = emalloc(sizeof(ibase_array) * ib_query->out_array_cnt); memcpy(IB_RESULT->out_array, ib_query->out_array, sizeof(ibase_array) * ib_query->out_array_cnt); } else { IB_RESULT->out_array = NULL; } } if (ib_query->in_sqlda) { /* has placeholders */ IBDEBUG("Query wants XSQLDA for input"); if (ib_query->in_sqlda->sqld != argc) { _php_ibase_module_error("Placeholders (%d) and variables (%d) mismatch", ib_query->in_sqlda->sqld, argc); goto _php_ibase_exec_error; /* yes mommy, goto! */ } in_sqlda = emalloc(XSQLDA_LENGTH(ib_query->in_sqlda->sqld)); memcpy(in_sqlda, ib_query->in_sqlda, XSQLDA_LENGTH(ib_query->in_sqlda->sqld)); bind_buf = emalloc(sizeof(BIND_BUF) * ib_query->in_sqlda->sqld); if (_php_ibase_bind(in_sqlda, args, bind_buf, ib_query TSRMLS_CC) == FAILURE) { IBDEBUG("Could not bind input XSQLDA"); goto _php_ibase_exec_error; } } if (isc_dsql_execute(IB_STATUS, &ib_query->trans, &ib_query->stmt, ib_query->dialect, in_sqlda)) { IBDEBUG("Could not execute query"); _php_ibase_error(TSRMLS_C); goto _php_ibase_exec_error; } rv = SUCCESS; _php_ibase_exec_error: /* I'm a bad boy... */ if (in_sqlda) { efree(in_sqlda); } if (bind_buf) efree(bind_buf); if (rv == FAILURE) { if (IB_RESULT) { efree(IB_RESULT); IB_RESULT = NULL; } if (out_sqlda) { _php_ibase_free_xsqlda(out_sqlda); } } return rv;#undef IB_RESULT}/* }}} *//* {{{ proto resource ibase_trans([int trans_args [, resource link_identifier]]) Start transaction */PHP_FUNCTION(ibase_trans){ zval ***args; char tpb[20], *tpbp = NULL; long trans_argl = 0; int tpb_len = 0, argn, link_id, trans_n = 0; ibase_db_link *ib_link; ibase_tr_link *ib_trans; RESET_ERRMSG; /* TODO: multi-databases trans */ argn = ZEND_NUM_ARGS(); if (argn < 0 || argn > 20) { WRONG_PARAM_COUNT; } if (argn) { args = (zval ***) emalloc(sizeof(zval **) * argn); if (zend_get_parameters_array_ex(argn, args) == FAILURE) { efree(args); RETURN_FALSE; } /* Handle all database links, although we don't support multibase transactions yet, so only the last one is will be used. */ if (argn > 1) { ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, args[argn-1], -1, "InterBase link", le_link, le_plink); link_id = Z_LVAL_PP(args[argn-1]); } /* First argument is transaction parameters */ convert_to_long_ex(args[0]); trans_argl = Z_LVAL_PP(args[0]); efree(args); } if (argn < 2) { link_id = IBG(default_link); ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, link_id, "InterBase link", le_link, le_plink); } if (trans_argl) { tpb[tpb_len++] = isc_tpb_version3; tpbp = tpb; /* access mode */ if (trans_argl & PHP_IBASE_READ) { /* READ ONLY TRANSACTION */ tpb[tpb_len++] = isc_tpb_read; } else { tpb[tpb_len++] = isc_tpb_write; /* default access mode */ } /* isolation level */ if (trans_argl & PHP_IBASE_COMMITTED) { tpb[tpb_len++] = isc_tpb_read_committed; if (trans_argl & PHP_IBASE_REC_VERSION) { tpb[tpb_len++] = isc_tpb_rec_version; }else{ tpb[tpb_len++] = isc_tpb_no_rec_version; /* default in read_committed */ } } else if (trans_argl & PHP_IBASE_CONSISTENCY) { tpb[tpb_len++] = isc_tpb_consistency; } else { tpb[tpb_len++] = isc_tpb_concurrency; /* default isolation level */ } /* lock resolution */ if (trans_argl & PHP_IBASE_NOWAIT) { tpb[tpb_len++] = isc_tpb_nowait; } else { tpb[tpb_len++] = isc_tpb_wait; /* default lock resolution */ } } /* find empty transaction slot */ for (trans_n = 0; trans_n < IBASE_TRANS_ON_LINK && ib_link->trans[trans_n]; trans_n++); if (trans_n == IBASE_TRANS_ON_LINK) { _php_ibase_module_error("Too many transactions on link"); RETURN_FALSE; } if (isc_start_transaction(IB_STATUS, &ib_link->trans[trans_n], 1, &ib_link->link, tpb_len, tpbp)) { _php_ibase_error(TSRMLS_C); RETURN_FALSE; } ib_trans = (ibase_tr_link *) emalloc(sizeof(ibase_tr_link)); ib_trans->trans_num = trans_n; ib_trans->link_rsrc = link_id; ZEND_REGISTER_RESOURCE(return_value, ib_trans, le_trans);}/* }}} *//* {{{ _php_ibase_def_trans() *//* open default transaction */static int _php_ibase_def_trans(ibase_db_link * ib_link, int trans_n TSRMLS_DC){ if (ib_link == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid database link"); return FAILURE; } if (trans_n == 0 && ib_link->trans[0] == NULL) { if (isc_start_transaction(IB_STATUS, &ib_link->trans[0], 1, &ib_link->link, 0, NULL)) { _php_ibase_error(TSRMLS_C); return FAILURE; } } return SUCCESS;}/*}}}*//* {{{ _php_ibase_trans_end() */#define COMMIT 1#define ROLLBACK 0static void _php_ibase_trans_end(INTERNAL_FUNCTION_PARAMETERS, int commit){ zval **link_trans_arg = NULL; int link_id = 0, trans_n = 0, trans_id = 0; ibase_db_link *ib_link; RESET_ERRMSG; switch (ZEND_NUM_ARGS()) { case 0: link_id = IBG(default_link); ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, link_trans_arg, link_id, "InterBase link", le_link, le_plink); break; case 1: if (zend_get_parameters_ex(1, &link_trans_arg) == FAILURE) { RETURN_FALSE; } get_link_trans(INTERNAL_FUNCTION_PARAM_PASSTHRU, link_trans_arg, &ib_link, &trans_n, &trans_id); break; default: WRONG_PARAM_COUNT; break; } if (ib_link == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid database link"); RETURN_FALSE; } if (ib_link->trans[trans_n] == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Trying to commit or rollback an already handled transaction"); RETURN_FALSE; } if (commit) { if (isc_commit_transaction(IB_STATUS, &ib_link->trans[trans_n])) { _php_ibase_error(TSRMLS_C); RETURN_FALSE; } } else { if (isc_rollback_transaction(IB_STATUS, &ib_link->trans[trans_n])) { _php_ibase_error(TSRMLS_C); RETURN_FALSE; } } ib_link->trans[trans_n] = NULL; /* Don't try to destroy imnplicitly opened transaction from list... */ if (trans_id) { zend_list_delete(trans_id); } RETURN_TRUE;}/* }}} *//* {{{ proto bool ibase_commit( resource link_identifier ) Commit transaction */PHP_FUNCTION(ibase_commit){ _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, COMMIT);}/* }}} *//* {{{ proto bool ibase_rollback( resource link_identifier ) Rollback transaction */PHP_FUNCTION(ibase_rollback){ _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, ROLLBACK);}/* }}} *//* {{{ proto resource ibase_query([resource link_identifier [, string query [, int bind_args]]]) Execute a query */PHP_FUNCTION(ibase_query){ zval ***args, ***bind_args = NULL, **dummy = NULL; int i, link_id = 0, trans_n = 0, bind_n = 0, trans_id = 0; char *query; ibase_db_link *ib_link; ibase_query *ib_query; ibase_result *ib_result; RESET_ERRMSG; if (ZEND_NUM_ARGS() < 1) { WRONG_PARAM_COUNT; } args = (zval ***) emalloc(sizeof(zval **) * ZEND_NUM_ARGS()); if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) { efree(args); RETURN_FALSE; } i = 0; if (Z_TYPE_PP(args[i]) == IS_RESOURCE) { /* link or transaction argument */ get_link_trans(INTERNAL_FUNCTION_PARAM_PASSTHRU, args[i], &ib_link, &trans_n, &trans_id); i++; /* next arg */ } else { link_id = IBG(default_link); ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, dummy, link_id, "InterBase link", le_link, le_plink); } if (Z_TYPE_PP(args[i]) == IS_STRING) { /* query argument */ convert_to_string_ex(args[i]); query = Z_STRVAL_PP(args[i]); i++; /* next arg */ } else { _php_ibase_module_error("Query argument missed"); efree(args); RETURN_FALSE; } if (ZEND_NUM_ARGS() > i) { /* have variables to bind */ /* XXX Remove or fix??? Variable placeholders and binding makes absolutely no sense if not using a prepared SQL statement. */ bind_n = ZEND_NUM_ARGS() - i; bind_args = &args[i]; } /* open default transaction */ if (_php_ibase_def_trans(ib_link, trans_n TSRMLS_CC) == FAILURE) { efree(args); RETURN_FALSE; } if (_php_ibase_alloc_query(&ib_query, ib_link->link, ib_link->trans[trans_n], query, ib_link->dialect TSRMLS_CC) == FAILURE) { efree(args); RETURN_FALSE; } if (_php_ibase_exec(&ib_result, ib_query, bind_n, bind_args TSRMLS_CC) == FAILURE) { _php_ibase_free_query(ib_query TSRMLS_CC); efree(args); RETURN_FALSE; } efree(args); if (ib_result) { /* select statement */ ib_result->drop_stmt = 1; /* drop stmt when free result */ ib_query->stmt = NULL; /* keep stmt when free query */ _php_ibase_free_query(ib_query TSRMLS_CC); ZEND_REGISTER_RESOURCE(return_value, ib_result, le_result); } else { _php_ibase_free_query(ib_query TSRMLS_CC); RETURN_TRUE; }}/* }}} *//* {{{ _php_ibase_var_zval() */static int _php_ibase_var_zval(zval *val, void *data, int type, int len, int scale, int flag TSRMLS_DC){ char string_data[255]; switch (type & ~1) { case SQL_VARYING: len = ((IBASE_VCHAR *) data)->var_len; data = ((IBASE_VCHAR *) data)->var_str; /* fallout */ case SQL_TEXT: Z_STRVAL_P(val) = (char *) emalloc(sizeof(char) * (len + 1)); memcpy(Z_STRVAL_P(val), data, len); Z_STRVAL_P(val)[len] = '\0'; if (PG(magic_quotes_runtime)) { Z_STRVAL_P(val) = php_addslashes(Z_STRVAL_P(val), len, &len, 1 TSRMLS_CC); } Z_TYPE_P(val) = IS_STRING; Z_STRLEN_P(val) = len; break; case SQL_LONG: case SQL_SHORT: if (scale) { short j; long n, f = 1; if ( (type & ~1) == SQL_SHORT) { n = *(short *) data; }else { n = *(ISC_LONG *) data; } for (j = 0; j < -scale; j++) { f *= 10; } if (n >= 0){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -