📄 interbase.c
字号:
efree(hashed_details); RETURN_FALSE; } ib_link = (ibase_db_link *) emalloc(sizeof(ibase_db_link)); ib_link->link = db_handle; ib_link->dialect = (ib_dialect ? (unsigned short) strtoul(ib_dialect, NULL, 10) : SQL_DIALECT_CURRENT); for (i = 0; i < IBASE_TRANS_ON_LINK; i++) { ib_link->trans[i] = NULL; } ZEND_REGISTER_RESOURCE(return_value, ib_link, le_link); /* add it to the hash */ new_index_ptr.ptr = (void *) Z_LVAL_P(return_value); Z_TYPE(new_index_ptr) = le_index_ptr; if (zend_hash_update(&EG(regular_list), hashed_details, hashed_details_length + 1, (void *) &new_index_ptr, sizeof(list_entry), NULL) == FAILURE) { efree(hashed_details); RETURN_FALSE; } IBG(num_links)++; } efree(hashed_details); zend_list_addref(Z_LVAL_P(return_value)); IBG(default_link) = Z_LVAL_P(return_value);}/* }}} *//* {{{ proto resource ibase_connect(string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role]]]]]]) Open a connection to an InterBase database */PHP_FUNCTION(ibase_connect){ _php_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);}/* }}} *//* {{{ proto resource ibase_pconnect(string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role]]]]]]) Open a persistent connection to an InterBase database */PHP_FUNCTION(ibase_pconnect){ _php_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, IBG(allow_persistent));}/* }}} *//* {{{ proto bool ibase_close([resource link_identifier]) Close an InterBase connection */PHP_FUNCTION(ibase_close){ ibase_db_link *ib_link; int link_id; RESET_ERRMSG; switch (ZEND_NUM_ARGS()) { zval **link_arg; case 0: link_id = IBG(default_link); break; case 1: if (zend_get_parameters_ex(1, &link_arg) == FAILURE) { RETURN_FALSE; } convert_to_long_ex(link_arg); link_id = Z_LVAL_PP(link_arg); break; default: WRONG_PARAM_COUNT; break; } ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, link_id, "InterBase link", le_link, le_plink); zend_list_delete(link_id); RETURN_TRUE;}/* }}} *//* {{{ _php_ibase_alloc_array() */static int _php_ibase_alloc_array(ibase_array **ib_arrayp, int *array_cntp, XSQLDA *sqlda, isc_db_handle link, isc_tr_handle trans TSRMLS_DC){#define IB_ARRAY (*ib_arrayp) int i, dim, ar_cnt, ar_length; XSQLVAR *var; IB_ARRAY = NULL; ar_cnt = 0; /* find arrays */ var = sqlda->sqlvar; for (i = 0; i < sqlda->sqld; i++, var++) { if ((var->sqltype & ~1) == SQL_ARRAY) { ar_cnt++; } } if (ar_cnt) { /* have arrays ? */ *array_cntp = ar_cnt; IB_ARRAY = emalloc(sizeof(ibase_array)*ar_cnt); ar_cnt = 0; var = sqlda->sqlvar; for (i = 0; i < sqlda->sqld; i++, var++) { if ((var->sqltype & ~1) == SQL_ARRAY) { ISC_ARRAY_DESC *ar_desc = &IB_ARRAY[ar_cnt].ar_desc; if (isc_array_lookup_bounds(IB_STATUS, &link, &trans, var->relname, var->sqlname, ar_desc)) { _php_ibase_error(TSRMLS_C); efree(IB_ARRAY); IB_ARRAY = NULL; return FAILURE; } switch (ar_desc->array_desc_dtype) { case blr_text: case blr_text2: IB_ARRAY[ar_cnt].el_type = SQL_TEXT; IB_ARRAY[ar_cnt].el_size = ar_desc->array_desc_length + 1; break; case blr_short: IB_ARRAY[ar_cnt].el_type = SQL_SHORT; IB_ARRAY[ar_cnt].el_size = sizeof(short); break; case blr_long: IB_ARRAY[ar_cnt].el_type = SQL_LONG; IB_ARRAY[ar_cnt].el_size = sizeof(long); break; case blr_float: IB_ARRAY[ar_cnt].el_type = SQL_FLOAT; IB_ARRAY[ar_cnt].el_size = sizeof(float); break; case blr_double: IB_ARRAY[ar_cnt].el_type = SQL_DOUBLE; IB_ARRAY[ar_cnt].el_size = sizeof(double); break; case blr_date: IB_ARRAY[ar_cnt].el_type = SQL_DATE; IB_ARRAY[ar_cnt].el_size = sizeof(ISC_QUAD); break; case blr_varying: case blr_varying2: /* changed to SQL_TEXT ? */ /* sql_type = SQL_VARYING; Why? FIXME: ??? */ IB_ARRAY[ar_cnt].el_type = SQL_TEXT; IB_ARRAY[ar_cnt].el_size = ar_desc->array_desc_length + sizeof(short); break; default: _php_ibase_module_error("Unexpected array type %d in relation '%s' column '%s'", ar_desc->array_desc_dtype, var->relname, var->sqlname); efree(IB_ARRAY); IB_ARRAY = NULL; return FAILURE; } /* switch array_desc_type */ ar_length = 0; /* calculate elements count */ for (dim = 0; dim < ar_desc->array_desc_dimensions; dim++) { ar_length += 1 + ar_desc->array_desc_bounds[dim].array_bound_upper - ar_desc->array_desc_bounds[dim].array_bound_lower; } IB_ARRAY[ar_cnt].ar_size = IB_ARRAY[ar_cnt].el_size * ar_length; ar_cnt++; } /* if SQL_ARRAY */ } /* for column */ } /* if array_cnt */ return SUCCESS;#undef IB_ARRAY}/* }}} *//* {{{ _php_ibase_alloc_query() *//* allocate and prepare query */static int _php_ibase_alloc_query(ibase_query **ib_queryp, isc_db_handle link, isc_tr_handle trans, char *query, unsigned short dialect TSRMLS_DC){#define IB_QUERY (*ib_queryp) IB_QUERY = emalloc(sizeof(ibase_query)); IB_QUERY->link = link; IB_QUERY->trans = trans; IB_QUERY->stmt = NULL; IB_QUERY->out_sqlda = NULL; IB_QUERY->in_sqlda = NULL; IB_QUERY->in_array = NULL; IB_QUERY->in_array_cnt = 0; IB_QUERY->out_array = NULL; IB_QUERY->out_array_cnt = 0; IB_QUERY->dialect = dialect; if (isc_dsql_allocate_statement(IB_STATUS, &link, &IB_QUERY->stmt)) { _php_ibase_error(TSRMLS_C); goto _php_ibase_alloc_query_error; } IB_QUERY->out_sqlda = (XSQLDA *) emalloc(XSQLDA_LENGTH(1)); IB_QUERY->out_sqlda->sqln = 1; IB_QUERY->out_sqlda->version = SQLDA_CURRENT_VERSION; if (isc_dsql_prepare(IB_STATUS, &IB_QUERY->trans, &IB_QUERY->stmt, 0, query, dialect, IB_QUERY->out_sqlda)) { _php_ibase_error(TSRMLS_C); goto _php_ibase_alloc_query_error; } /* not enough output variables ? */ if (IB_QUERY->out_sqlda->sqld > IB_QUERY->out_sqlda->sqln) { IB_QUERY->out_sqlda = erealloc(IB_QUERY->out_sqlda, XSQLDA_LENGTH(IB_QUERY->out_sqlda->sqld)); IB_QUERY->out_sqlda->sqln = IB_QUERY->out_sqlda->sqld; IB_QUERY->out_sqlda->version = SQLDA_CURRENT_VERSION; if (isc_dsql_describe(IB_STATUS, &IB_QUERY->stmt, SQLDA_CURRENT_VERSION, IB_QUERY->out_sqlda)) { _php_ibase_error(TSRMLS_C); goto _php_ibase_alloc_query_error; } } /* maybe have input placeholders? */ IB_QUERY->in_sqlda = emalloc(XSQLDA_LENGTH(1)); IB_QUERY->in_sqlda->sqln = 1; IB_QUERY->in_sqlda->version = SQLDA_CURRENT_VERSION; if (isc_dsql_describe_bind(IB_STATUS, &IB_QUERY->stmt, SQLDA_CURRENT_VERSION, IB_QUERY->in_sqlda)) { _php_ibase_error(TSRMLS_C); goto _php_ibase_alloc_query_error; } /* not enough input variables ? */ if (IB_QUERY->in_sqlda->sqln < IB_QUERY->in_sqlda->sqld) { IB_QUERY->in_sqlda = erealloc(IB_QUERY->in_sqlda, XSQLDA_LENGTH(IB_QUERY->in_sqlda->sqld)); IB_QUERY->in_sqlda->sqln = IB_QUERY->in_sqlda->sqld; IB_QUERY->in_sqlda->version = SQLDA_CURRENT_VERSION; if (isc_dsql_describe_bind(IB_STATUS, &IB_QUERY->stmt, SQLDA_CURRENT_VERSION, IB_QUERY->in_sqlda)) { _php_ibase_error(TSRMLS_C); goto _php_ibase_alloc_query_error; } } /* allocate arrays... */ if (_php_ibase_alloc_array(&IB_QUERY->in_array, &IB_QUERY->in_array_cnt, IB_QUERY->in_sqlda, link, trans TSRMLS_CC) == FAILURE) { goto _php_ibase_alloc_query_error; /* error report already done */ } if (_php_ibase_alloc_array(&IB_QUERY->out_array, &IB_QUERY->out_array_cnt, IB_QUERY->out_sqlda, link, trans TSRMLS_CC) == FAILURE) { goto _php_ibase_alloc_query_error; } /* no, haven't placeholders at all */ if (IB_QUERY->in_sqlda->sqld == 0) { efree(IB_QUERY->in_sqlda); IB_QUERY->in_sqlda = NULL; } if (IB_QUERY->out_sqlda->sqld == 0) { efree(IB_QUERY->out_sqlda); IB_QUERY->out_sqlda = NULL; } return SUCCESS; _php_ibase_alloc_query_error: if (IB_QUERY->out_sqlda) { efree(IB_QUERY->out_sqlda); } if (IB_QUERY->in_sqlda) { efree(IB_QUERY->in_sqlda); } if (IB_QUERY->out_array) { efree(IB_QUERY->out_array); } efree(IB_QUERY); IB_QUERY = NULL; return FAILURE;#undef IB_QUERY}/* }}} *//* ((( _php_ibase_blob_add */static int _php_ibase_blob_add(zval **string_arg, ibase_blob_handle *ib_blob TSRMLS_DC){ unsigned long put_cnt = 0, rem_cnt; unsigned short chunk_size; convert_to_string_ex(string_arg); for (rem_cnt = Z_STRLEN_PP(string_arg); rem_cnt > 0; rem_cnt -= chunk_size) { chunk_size = rem_cnt > USHRT_MAX ? USHRT_MAX : (unsigned short)rem_cnt; if (isc_put_segment(IB_STATUS, &ib_blob->bl_handle, chunk_size, &Z_STRVAL_PP(string_arg)[put_cnt] )) { _php_ibase_error(TSRMLS_C); return FAILURE; } put_cnt += chunk_size; } return SUCCESS;} /* }}} *//* {{{ _php_ibase_bind() Bind parameter placeholders in a previously prepared query */static int _php_ibase_bind(XSQLDA *sqlda, zval ***b_vars, BIND_BUF *buf, ibase_query *ib_query TSRMLS_DC){ int i , rv = SUCCESS; XSQLVAR *var = sqlda->sqlvar; for (i = 0; i < sqlda->sqld; ++var, ++i) { /* bound vars */ zval *b_var = *b_vars[i]; var->sqlind = &buf[i].sqlind; if (Z_TYPE_P(b_var) == IS_NULL) { if ((var->sqltype & 1) != 1) { _php_ibase_module_error("Parameter %d must have a value" TSRMLS_CC, i+1); rv = FAILURE; } buf[i].sqlind = -1; } else { buf[i].sqlind = 0; if (var->sqlscale < 0) { /* DECIMAL or NUMERIC field are stored internally as scaled integers. Coerce it to string and let InterBase's internal routines handle it. */ var->sqltype = SQL_TEXT; } switch (var->sqltype & ~1) { case SQL_SHORT: convert_to_long(b_var); if (Z_LVAL_P(b_var) > SHRT_MAX || Z_LVAL_P(b_var) < SHRT_MIN) { _php_ibase_module_error("Parameter %d exceeds field width" TSRMLS_CC, i+1); rv = FAILURE; } buf[i].val.sval = (short) Z_LVAL_P(b_var); var->sqldata = (void *) &buf[i].val.sval; break; case SQL_LONG: convert_to_long(b_var); var->sqldata = (void *) &Z_LVAL_P(b_var); break; case SQL_FLOAT: convert_to_double(b_var); buf[i].val.fval = (float) Z_DVAL_P(b_var); var->sqldata = (void *) &buf[i].val.fval; break; case SQL_DOUBLE: convert_to_double(b_var); var->sqldata = (void *) &Z_DVAL_P(b_var); break;#ifndef SQL_TIMESTAMP case SQL_DATE: convert_to_string(b_var); { struct tm t;#ifdef HAVE_STRPTIME strptime(Z_STRVAL_P(b_var), IBG(timestampformat), &t);#else /* Parsing doesn't seem to happen with older versions... */ int n; t.tm_year = t.tm_mon = t.tm_mday = t.tm_hour = t.tm_min = t.tm_sec = 0; n = sscanf(Z_STRVAL_P(b_var), "%d%*[/]%d%*[/]%d %d%*[:]%d%*[:]%d", &t.tm_mon, &t.tm_mday, &t.tm_year, &t.tm_hour, &t.tm_min, &t.tm_sec); if (n != 3 && n != 6) { _php_ibase_module_error("Parameter %d: invalid date/time format (expected 3 or 6 fields, got %d. Use format m/d/Y H:i:s. You gave '%s')" TSRMLS_CC, i+1, n, Z_STRVAL_P(b_var)); rv = FAILURE; } t.tm_year -= 1900; t.tm_mon--;#endif isc_encode_date(&t, &buf[i].val.qval); var->sqldata = (void *) (&buf[i].val.qval); }#else#ifdef HAVE_STRPTIME case SQL_TIMESTAMP: case SQL_TYPE_DATE: case SQL_TYPE_TIME: { struct tm t; convert_to_string(b_var); switch (var->sqltype & ~1) { case SQL_TIMESTAMP: strptime(Z_STRVAL_P(b_var), IBG(timestampformat), &t); isc_encode_timestamp(&t, &buf[i].val.tsval); var->sqldata = (void *) (&buf[i].val.tsval); break; case SQL_TYPE_DATE: strptime(Z_STRVAL_P(b_var), IBG(dateformat), &t); isc_encode_sql_date(&t, &buf[i].val.dtval); var->sqldata = (void *) (&buf[i].val.dtval); break; case SQL_TYPE_TIME: strptime(Z_STRVAL_P(b_var), IBG(timeformat), &t); isc_encode_sql_time(&t, &buf[i].val.tmval); var->sqldata = (void *) (&buf[i].val.tmval); break; } }#endif#endif break; case SQL_BLOB: { ibase_blob_handle *ib_blob_id; if (Z_TYPE_P(b_var) != IS_STRING || Z_STRLEN_P(b_var) != sizeof(ibase_blob_handle) || ((ibase_blob_handle *)(Z_STRVAL_P(b_var)))->bl_handle != 0) { ibase_blob_handle *ib_blob; ib_blob = (ibase_blob_handle *) emalloc(sizeof(ibase_blob_handle)); ib_blob->trans_handle = ib_query->trans; ib_blob->link = ib_query->link; ib_blob->bl_handle = NULL; if (isc_create_blob(IB_STATUS, &ib_blob->link, &ib_blob->trans_handle, &ib_blob->bl_handle, &ib_blob->bl_qd)) { efree(ib_blob); _php_ibase_error(TSRMLS_C); return FAILURE; } if (_php_ibase_blob_add(&b_var, ib_blob TSRMLS_CC) != SUCCESS) { efree(ib_blob); return FAILURE; } if (isc_close_blob(IB_STATUS, &ib_blob->bl_handle)) { _php_ibase_error(TSRMLS_C); efree(ib_blob); return FAILURE; } buf[i].val.qval = ib_blob->bl_qd; var->sqldata = (void ISC_FAR *) &buf[i].val.qval; efree(ib_blob); } else { ib_blob_id = (ibase_blob_handle *) Z_STRVAL_P(b_var); var->sqldata = (void ISC_FAR *) &ib_blob_id->bl_qd; } } break; case SQL_ARRAY: _php_ibase_module_error("Parameter %d: arrays not supported" TSRMLS_CC, i+1); rv = FAILURE; break; default: convert_to_string(b_var); var->sqldata = Z_STRVAL_P(b_var); var->sqllen = Z_STRLEN_P(b_var);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -