📄 interbase.c
字号:
Z_STRLEN_P(val) = sprintf (string_data, "%ld.%0*ld", n / f, -scale, n % f ); }else if ((n/f) != 0 ){ Z_STRLEN_P(val) = sprintf (string_data, "%ld.%0*ld", n / f, -scale, -(n % f) ); }else{ Z_STRLEN_P(val) = sprintf (string_data, "%s.%0*ld","-0", -scale, -(n % f) ); } Z_TYPE_P(val) = IS_STRING; Z_STRVAL_P(val) = estrdup(string_data); } else { Z_TYPE_P(val) = IS_LONG; if ( (type & ~1) == SQL_SHORT) { Z_LVAL_P(val) = *(short *) data; }else{ Z_LVAL_P(val) = *(ISC_LONG *) data; } } break; case SQL_FLOAT: Z_TYPE_P(val) = IS_DOUBLE; Z_DVAL_P(val) = *(float *) (data); break; case SQL_DOUBLE: if (scale) { Z_TYPE_P(val) = IS_STRING; Z_STRLEN_P(val) = sprintf(string_data, "%.*f", -scale, *(double *) data); Z_STRVAL_P(val) = estrdup(string_data); } else { Z_TYPE_P(val) = IS_DOUBLE; Z_DVAL_P(val) = *(double *) data; } break;#ifdef SQL_INT64 case SQL_INT64: { ISC_INT64 n = *(ISC_INT64 *) data; Z_TYPE_P(val) = IS_STRING; if (scale < 0) { short j; ISC_INT64 f = 1; for (j = 0; j < -scale; ++j) { f *= 10; } if (n >= 0) { Z_STRLEN_P(val) = sprintf (string_data, "%" ISC_INT64_FORMAT "d.%0*" ISC_INT64_FORMAT "d", n / f, -scale, n % f); } else if (n <= -f) { Z_STRLEN_P(val) = sprintf (string_data, "%" ISC_INT64_FORMAT "d.%0*" ISC_INT64_FORMAT "d", n / f, -scale, -n % f); } else { Z_STRLEN_P(val) = sprintf (string_data, "-0.%0*" ISC_INT64_FORMAT "d", -scale, -n % f); } } else { Z_STRLEN_P(val) = sprintf (string_data, "%" ISC_INT64_FORMAT "d", n); } Z_STRVAL_P(val) = estrdup(string_data); break; }#endif#ifndef SQL_TIMESTAMP case SQL_DATE:#else case SQL_TIMESTAMP: case SQL_TYPE_DATE: case SQL_TYPE_TIME:#endif { struct tm t; char *format = NULL; long timestamp = -1;#ifndef SQL_TIMESTAMP isc_decode_date((ISC_QUAD *) data, &t); format = IBG(timestampformat);#else switch (type & ~1) { case SQL_TIMESTAMP: isc_decode_timestamp((ISC_TIMESTAMP *) data, &t); format = IBG(timestampformat); break; case SQL_TYPE_DATE: isc_decode_sql_date((ISC_DATE *) data, &t); format = IBG(dateformat); break; case SQL_TYPE_TIME: isc_decode_sql_time((ISC_TIME *) data, &t); format = IBG(timeformat); break; }#endif /* XXX - Might have to remove this later - seems that isc_decode_date() always sets tm_isdst to 0, sometimes incorrectly (InterBase 6 bug?) */ t.tm_isdst = -1; timestamp = mktime(&t);#if HAVE_TM_ZONE t.tm_zone = tzname[0];#endif if (flag & PHP_IBASE_UNIXTIME) { Z_TYPE_P(val) = IS_LONG; Z_LVAL_P(val) = timestamp; } else { Z_TYPE_P(val) = IS_STRING;#if HAVE_STRFTIME Z_STRLEN_P(val) = strftime(string_data, sizeof(string_data), format, &t);#else /* FIXME */ if (!t.tm_hour && !t.tm_min && !t.tm_sec) { Z_STRLEN_P(val) = sprintf(string_data, "%02d/%02d/%4d", t.tm_mon + 1, t.tm_mday, t.tm_year + 1900); } else { Z_STRLEN_P(val) = sprintf(string_data, "%02d/%02d/%4d %02d:%02d:%02d", t.tm_mon+1, t.tm_mday, t.tm_year + 1900, t.tm_hour, t.tm_min, t.tm_sec); }#endif Z_STRVAL_P(val) = estrdup(string_data); break; } } default: return FAILURE; } /* switch (type) */ return SUCCESS;}/* }}} *//* {{{ _php_ibase_arr_zval() *//* create multidimension array - resursion function * (*datap) argument changed */static int _php_ibase_arr_zval(zval *ar_zval, char **datap, ibase_array *ib_array, int dim, int flag TSRMLS_DC){ zval tmp; int i, dim_len, l_bound, u_bound; if (dim > 16) { /* InterBase limit */ _php_ibase_module_error("Too many dimensions"); return FAILURE; } u_bound = ib_array->ar_desc.array_desc_bounds[dim].array_bound_upper; l_bound = ib_array->ar_desc.array_desc_bounds[dim].array_bound_lower; dim_len = 1 + u_bound - l_bound; if (dim < ib_array->ar_desc.array_desc_dimensions - 1) { /* array again */ for (i = 0; i < dim_len; i++) { /* recursion here */ if (_php_ibase_arr_zval(ar_zval, datap, ib_array, dim + 1, flag TSRMLS_CC) == FAILURE) { return FAILURE; } } } else { /* data at last */ array_init(ar_zval); for (i = 0; i < dim_len; i++) { if (_php_ibase_var_zval(&tmp, *datap, ib_array->el_type, ib_array->ar_desc.array_desc_length, ib_array->ar_desc.array_desc_scale, flag TSRMLS_CC) == FAILURE) { return FAILURE; } /* FIXME ??? */ zend_hash_index_update(Z_ARRVAL_P(ar_zval), l_bound + i, (void *) &tmp, sizeof(zval), NULL); *datap += ib_array->el_size; } } return SUCCESS;}/* }}} *//* {{{ _php_ibase_blob_get */static int _php_ibase_blob_get(zval *return_value, ibase_blob_handle *ib_blob, unsigned long max_len TSRMLS_DC){ if (ib_blob->bl_qd.gds_quad_high || ib_blob->bl_qd.gds_quad_low) { /*not null ?*/ ISC_STATUS stat; char *bl_data; unsigned long cur_len; unsigned short seg_len; bl_data = safe_emalloc(1, max_len, 1); for (cur_len = stat = 0; (stat == 0 || stat == isc_segment) && cur_len < max_len; cur_len += seg_len) { unsigned short chunk_size = (max_len-cur_len) > USHRT_MAX ? USHRT_MAX : (unsigned short)(max_len-cur_len); stat = isc_get_segment(IB_STATUS, &ib_blob->bl_handle, &seg_len, chunk_size, &bl_data[cur_len]); } bl_data[cur_len] = '\0'; if (IB_STATUS[0] == 1 && (stat != 0 && stat != isc_segstr_eof && stat != isc_segment)) { efree(bl_data); _php_ibase_error(TSRMLS_C); return FAILURE; } RETVAL_STRINGL(bl_data, cur_len, 0); } else { /* null blob */ RETVAL_STRING("", 1); /* empty string */ } return SUCCESS;}/* }}} *//* {{{ _php_ibase_fetch_hash() */#define FETCH_ROW 2#define FETCH_ARRAY 4static void _php_ibase_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int fetch_type){ zval **result_arg, **flag_arg; long flag = 0; int i, arr_cnt; ibase_result *ib_result; XSQLVAR *var; RESET_ERRMSG; switch (ZEND_NUM_ARGS()) { case 1: if (ZEND_NUM_ARGS() == 1 && zend_get_parameters_ex(1, &result_arg) == FAILURE) { RETURN_FALSE; } break; case 2: if (ZEND_NUM_ARGS() == 2 && zend_get_parameters_ex(2, &result_arg, &flag_arg) == FAILURE) { RETURN_FALSE; } convert_to_long_ex(flag_arg); flag = Z_LVAL_PP(flag_arg); break; default: WRONG_PARAM_COUNT; break; } ZEND_FETCH_RESOURCE(ib_result, ibase_result *, result_arg, -1, "InterBase result", le_result); if (ib_result->out_sqlda == NULL || !ib_result->has_more_rows) { RETURN_FALSE; } if (isc_dsql_fetch(IB_STATUS, &ib_result->stmt, 1, ib_result->out_sqlda)) { ib_result->has_more_rows = 0; if (IB_STATUS[0] && IB_STATUS[1]) { /* error in fetch */ _php_ibase_error(TSRMLS_C); } RETURN_FALSE; } array_init(return_value); arr_cnt = 0; var = ib_result->out_sqlda->sqlvar; for (i = 0; i < ib_result->out_sqlda->sqld; i++, var++) { if (((var->sqltype & 1) == 0) || *var->sqlind != -1) { zval tmp; switch (var->sqltype & ~1) { case SQL_VARYING: case SQL_TEXT: case SQL_SHORT: case SQL_LONG: case SQL_FLOAT: case SQL_DOUBLE:#ifdef SQL_INT64 case SQL_INT64:#endif#ifndef SQL_TIMESTAMP case SQL_DATE:#else case SQL_TIMESTAMP: case SQL_TYPE_DATE: case SQL_TYPE_TIME:#endif _php_ibase_var_zval(&tmp, var->sqldata, var->sqltype, var->sqllen, var->sqlscale, flag TSRMLS_CC); break; case SQL_BLOB: if (flag & PHP_IBASE_TEXT) { /* text ? */ ibase_blob_handle blob_handle; unsigned long max_len = 0; static char bl_items[] = {isc_info_blob_total_length}; char bl_info[20]; unsigned short i; blob_handle.bl_handle = NULL; blob_handle.bl_qd = *(ISC_QUAD ISC_FAR *) var->sqldata; if (isc_open_blob(IB_STATUS, &ib_result->link, &ib_result->trans, &blob_handle.bl_handle, &blob_handle.bl_qd)) { _php_ibase_error(TSRMLS_C); RETURN_FALSE; } if (isc_blob_info(IB_STATUS, &blob_handle.bl_handle, sizeof(bl_items), bl_items, sizeof(bl_info), bl_info)) { _php_ibase_error(TSRMLS_C); RETURN_FALSE; } /* find total length of blob's data */ for (i = 0; i < sizeof(bl_info); ) { unsigned short item_len; char item = bl_info[i++]; if (item == isc_info_end || item == isc_info_truncated || item == isc_info_error || i >= sizeof(bl_info)) { _php_ibase_module_error("Could not determine BLOB size (internal error)"); RETURN_FALSE; } item_len = (unsigned short) isc_vax_integer(&bl_info[i], 2); if (item == isc_info_blob_total_length) { max_len = isc_vax_integer(&bl_info[i+2], item_len); break; } i += item_len+2; } if (max_len == 0) { ZVAL_STRING(&tmp, "", 1); } else if (_php_ibase_blob_get(&tmp, &blob_handle, max_len TSRMLS_CC) != SUCCESS) { RETURN_FALSE; } if (isc_close_blob(IB_STATUS, &blob_handle.bl_handle)) { zval_dtor(&tmp); _php_ibase_error(TSRMLS_C); RETURN_FALSE; } } else { /* blob id only */ ibase_blob_handle *ib_blob_id = (ibase_blob_handle *) ecalloc(1, sizeof(ibase_blob_handle) + 1); ib_blob_id->link = ib_result->link; ib_blob_id->trans_handle = ib_result->trans; ib_blob_id->bl_qd = *(ISC_QUAD ISC_FAR *) var->sqldata; ZVAL_STRINGL(&tmp, (char *) ib_blob_id, sizeof(ibase_blob_handle),0); } break; case SQL_ARRAY: { ISC_QUAD ar_qd = *(ISC_QUAD ISC_FAR *) var->sqldata; ibase_array *ib_array = &ib_result->out_array[arr_cnt]; void *ar_data; char *tmp_ptr; ar_data = emalloc(ib_array->ar_size); if (isc_array_get_slice(IB_STATUS, &ib_result->link, &ib_result->trans, &ar_qd, &ib_array->ar_desc, ar_data, &ib_array->ar_size)) { _php_ibase_error(TSRMLS_C); RETURN_FALSE; } tmp_ptr = ar_data; /* avoid changes in _arr_zval */ if (_php_ibase_arr_zval(&tmp, &tmp_ptr, ib_array, 0, flag TSRMLS_CC) == FAILURE) { RETURN_FALSE; } efree(ar_data); } break; default: break; } /* switch */ if (fetch_type & FETCH_ROW) { switch (Z_TYPE(tmp)) { case IS_STRING: add_index_stringl(return_value, i, Z_STRVAL(tmp), Z_STRLEN(tmp), 0); break; case IS_LONG: add_index_long(return_value, i, Z_LVAL(tmp)); break; case IS_DOUBLE: add_index_double(return_value, i, Z_DVAL(tmp)); break; } } else { switch (Z_TYPE(tmp)) { case IS_STRING: add_assoc_stringl(return_value, var->aliasname, Z_STRVAL(tmp), Z_STRLEN(tmp), 0); break; case IS_LONG: add_assoc_long(return_value, var->aliasname, Z_LVAL(tmp)); break; case IS_DOUBLE: add_assoc_double(return_value, var->aliasname, Z_DVAL(tmp)); break; } } } else { if (fetch_type & FETCH_ROW) { add_index_null(return_value, i); } else { add_assoc_null(return_value, var->aliasname); } } if ((var->sqltype & ~1) == SQL_ARRAY) { arr_cnt++; } } /* for field */}/* }}} *//* {{{ proto array ibase_fetch_row(resource result [, int blob_flag]) Fetch a row from the results of a query */PHP_FUNCTION(ibase_fetch_row){ _php_ibase_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, FETCH_ROW);}/* }}} *//* {{{ proto array ibase_fetch_assoc(resource result [, int blob_flag]) Fetch a row from the results of a query */PHP_FUNCTION(ibase_fetch_assoc){ _php_ibase_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, FETCH_ARRAY);}/* }}} *//* {{{ proto object ibase_fetch_object(resource result [, int blob_flag]) Fetch a object from the results of a query */PHP_FUNCTION(ibase_fetch_object){ _php_ibase_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, FETCH_ARRAY); 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 bool ibase_free_result(resource result) Free the memory used by a result */PHP_FUNCTION(ibase_free_result){ zval **result_arg; ibase_result *ib_result; RESET_ERRMSG; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &result_arg) == FAILUR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -