EXPORT RM_ENTRY(rmc_close_blob) { ClearParamPool(); ISC_STATUS *stat = AllocStatusPool(); isc_close_blob(stat, (isc_blob_handle *)arg_vector[1].a_address); StatusToCobol(&arg_vector[0], stat); return (0); }
static USHORT snarf_blob(ISC_QUAD* blob_id, USHORT buffer_length, TEXT* buffer) { AliceGlobals* tdgbl = AliceGlobals::getSpecific(); if (buffer_length) buffer[0] = 0; if (buffer_length > 1) buffer[1] = 0; FB_API_HANDLE blob = 0; if (isc_open_blob(gds_status, &DB, &gds_trans, &blob, blob_id)) { ALICE_print_status(true, gds_status); return 0; } // get the blob into the buffer, if it fits TEXT* ptr = buffer; const TEXT* const end = buffer + buffer_length; for (;;) { if (ptr >= end) break; if (!(buffer_length = end - ptr)) break; USHORT returned_length; ISC_STATUS status = isc_get_segment(gds_status, &blob, &returned_length, buffer_length, ptr); if (status && status != isc_segment) break; ptr += returned_length; } // snarf failed, get length of blob for retry if (!buffer_length) { for (;;) { USHORT returned_length; ISC_STATUS status = isc_get_segment(gds_status, &blob, &returned_length, buffer_length, buffer); if (status && status != isc_segment) break; buffer_length += returned_length; } } else buffer_length = 0; isc_close_blob(gds_status, &blob); *ptr = 0; return buffer_length; }
bool UserBlob::close(bool force_internal_SV) { bool rc = false; if (m_blob) { rc = !isc_close_blob(force_internal_SV ? m_default_status : m_status, &m_blob); m_blob = 0; m_direction = dir_none; } return rc; }
/* ** Pushes the indexed value onto the lua stack */ static void push_column(lua_State *L, int i, cur_data *cur) { int varcharlen; struct tm timevar; char timestr[256]; ISC_STATUS blob_stat; isc_blob_handle blob_handle = NULL; ISC_QUAD blob_id; luaL_Buffer b; char *buffer; unsigned short actual_seg_len; if( (cur->out_sqlda->sqlvar[i].sqlind != NULL) && (*(cur->out_sqlda->sqlvar[i].sqlind) != 0) ) { /* a null field? */ lua_pushnil(L); } else { switch(cur->out_sqlda->sqlvar[i].sqltype & ~1) { case SQL_VARYING: varcharlen = (int)isc_vax_integer(cur->out_sqlda->sqlvar[i].sqldata, 2); lua_pushlstring(L, cur->out_sqlda->sqlvar[i].sqldata+2, varcharlen); break; case SQL_TEXT: lua_pushlstring(L, cur->out_sqlda->sqlvar[i].sqldata, cur->out_sqlda->sqlvar[i].sqllen); break; case SQL_SHORT: lua_pushnumber(L, *(short*)(cur->out_sqlda->sqlvar[i].sqldata)); break; case SQL_LONG: lua_pushnumber(L, *(long*)(cur->out_sqlda->sqlvar[i].sqldata)); break; case SQL_INT64: lua_pushnumber(L, (lua_Number)*(ISC_INT64*)(cur->out_sqlda->sqlvar[i].sqldata)); break; case SQL_FLOAT: lua_pushnumber(L, *(float*)(cur->out_sqlda->sqlvar[i].sqldata)); break; case SQL_DOUBLE: lua_pushnumber(L, *(double*)(cur->out_sqlda->sqlvar[i].sqldata)); break; case SQL_TYPE_TIME: isc_decode_sql_time((ISC_TIME*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar); strftime(timestr, 255, "%X", &timevar); lua_pushstring(L, timestr); break; case SQL_TYPE_DATE: isc_decode_sql_date((ISC_DATE*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar); strftime(timestr, 255, "%x", &timevar); lua_pushstring(L, timestr); break; case SQL_TIMESTAMP: isc_decode_timestamp((ISC_TIMESTAMP*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar); strftime(timestr, 255, "%x %X", &timevar); lua_pushstring(L, timestr); break; case SQL_BLOB: /* get the BLOB ID and open it */ memcpy(&blob_id, cur->out_sqlda->sqlvar[i].sqldata, sizeof(ISC_QUAD)); isc_open_blob2( cur->env->status_vector, &cur->conn->db, &cur->conn->transaction, &blob_handle, &blob_id, 0, NULL ); /* fetch the blob data */ luaL_buffinit(L, &b); buffer = luaL_prepbuffer(&b); blob_stat = isc_get_segment( cur->env->status_vector, &blob_handle, &actual_seg_len, LUAL_BUFFERSIZE, buffer ); while(blob_stat == 0 || cur->env->status_vector[1] == isc_segment) { luaL_addsize(&b, actual_seg_len); buffer = luaL_prepbuffer(&b); blob_stat = isc_get_segment( cur->env->status_vector, &blob_handle, &actual_seg_len, LUAL_BUFFERSIZE, buffer ); } /* finnished, close the BLOB */ isc_close_blob(cur->env->status_vector, &blob_handle); blob_handle = NULL; luaL_pushresult(&b); break; default: lua_pushstring(L, "<unsupported data type>"); break; } } }
static bool sleuth( qli_nod* node, const dsc* desc1, const dsc* desc2, const dsc* desc3) { /************************************** * * s l e u t h * ************************************** * * Functional description * Return true if a string (p1, l1) matches a given pattern (p2, l2), * using a pattern language defined in p3, l3. * **************************************/ // Get operator definition string (control string) Firebird::VaryStr<TEMP_STR_LENGTH> temp1; const TEXT* p1; SSHORT l1 = MOVQ_get_string(desc3, &p1, &temp1, TEMP_STR_LENGTH); // Get address and length of search string Firebird::VaryStr<TEMP_STR_LENGTH> temp2; const TEXT* p2; SSHORT l2 = MOVQ_get_string(desc2, &p2, &temp2, TEMP_STR_LENGTH); // Merge search and control strings UCHAR control[256]; l2 = sleuth_merge((const UCHAR*) p2, (const UCHAR*) p1, (const UCHAR*) (p1 + l1), control); // If source is not a blob, do a simple search if (desc1->dsc_dtype != dtype_blob) { l1 = MOVQ_get_string(desc1, &p1, &temp1, TEMP_STR_LENGTH); return sleuth_check(0, (const UCHAR*) p1, (const UCHAR*) (p1 + l1), control, control + l2); } // Source string is a blob, things get interesting bool result = false; FB_API_HANDLE blob = EXEC_open_blob(node->nod_arg[0]); TEXT fixed_buffer[512]; USHORT buffer_length = sizeof(fixed_buffer); TEXT* buffer = make_blob_buffer( blob, &buffer_length); if (!buffer) buffer = fixed_buffer; ISC_STATUS_ARRAY status_vector; while (!isc_get_segment(status_vector, &blob, (USHORT*) &l1, buffer_length, buffer)) if (sleuth_check(0, (UCHAR*) buffer, (UCHAR*) (buffer + l1), control, control + l2)) { result = true; break; } if (buffer != fixed_buffer) gds__free(buffer); if (isc_close_blob(status_vector, &blob)) { qli_ctx* context = (qli_ctx*) node->nod_arg[e_fld_context]; qli_req* request = context->ctx_request; qli_dbb* dbb = request->req_database; ERRQ_database_error(dbb, status_vector); } return result; }
static bool string_boolean( qli_nod* node) { /************************************** * * s t r i n g _ b o o l e a n * ************************************** * * Functional description * Perform one of the complex string functions CONTAINING, MATCHES, * or STARTS WITH. * **************************************/ const DSC *desc1, *desc2, *desc3; if (!(desc1 = EVAL_value(node->nod_arg[0])) || (desc1->dsc_missing & DSC_missing) || !(desc2 = EVAL_value(node->nod_arg[1])) || (desc2->dsc_missing & DSC_missing) || (node->nod_arg[2] && (!(desc3 = EVAL_value(node->nod_arg[2])) || (desc3->dsc_missing & DSC_missing)))) { return false; } if (node->nod_type == nod_sleuth) return sleuth(node, desc1, desc2, desc3); // Get address and length of strings const TEXT* p2; Firebird::VaryStr<TEMP_STR_LENGTH> temp2; SSHORT l2 = MOVQ_get_string(desc2, &p2, &temp2, TEMP_STR_LENGTH); // If source is not a blob, do a simple search if (desc1->dsc_dtype != dtype_blob) { Firebird::VaryStr<TEMP_STR_LENGTH> temp1; const TEXT* p1; SSHORT l1 = MOVQ_get_string(desc1, &p1, &temp1, TEMP_STR_LENGTH); return string_function(node, l1, p1, l2, p2); } // Source string is a blob, things get interesting bool result = false; FB_API_HANDLE blob = EXEC_open_blob(node->nod_arg[0]); TEXT fixed_buffer[512]; USHORT buffer_length = sizeof(fixed_buffer); TEXT* buffer = make_blob_buffer( blob, &buffer_length); if (!buffer) buffer = fixed_buffer; ISC_STATUS_ARRAY status_vector; SSHORT l3 = 0; while (!isc_get_segment(status_vector, &blob, (USHORT*) &l3, buffer_length, buffer)) { if (string_function(node, l3, buffer, l2, p2)) { result = true; break; } } if (buffer != fixed_buffer) gds__free(buffer); if (isc_close_blob(status_vector, &blob)) { qli_ctx* context = (qli_ctx*) node->nod_arg[e_fld_context]; qli_req* request = context->ctx_request; qli_dbb* database = request->req_database; ERRQ_database_error(database, status_vector); } return result; }
int _get_row_data(dbi_result_t *result, dbi_row_t *row, unsigned long long rowidx) { unsigned int curfield = 0; XSQLVAR var; long fetch_stat = 0, blob_stat = 0; ISC_QUAD bid; isc_blob_handle blob_handle = NULL; /* Blob handle. */ char blob_segment[80]; unsigned short actual_seg_len; struct tm times; char date_s[25]; unsigned int sizeattrib; dbi_data_t *data = NULL; ibase_stmt_t *istmt = (ibase_stmt_t *)result->result_handle; ibase_conn_t *iconn = (ibase_conn_t *)result->conn->connection; fetch_stat = isc_dsql_fetch(iconn->status_vector, &(istmt->stmt), SQL_DIALECT_V6, istmt->osqlda); if (fetch_stat != 0) { result->numrows_matched--; return 0; } while (curfield < result->numfields) { var = istmt->osqlda->sqlvar[curfield]; data = &row->field_values[curfield]; /** * If the column holds a NULL value mark it as NULL */ if ( (var.sqltype & 1) && ( *var.sqlind < 0)) { _set_field_flag( row, curfield, DBI_VALUE_NULL, 1); curfield++; continue; } switch ( result->field_types[curfield] ) { case DBI_TYPE_STRING: if(result->field_attribs[curfield] & DBI_STRING_FIXEDSIZE) { data->d_string = strdup(var.sqldata); row->field_sizes[curfield] = (unsigned long long) var.sqllen; } else { vary_t *vary = NULL; vary = (vary_t *) var.sqldata; data->d_string = malloc(vary->vary_length+1); memcpy(data->d_string, vary->vary_string, vary->vary_length); data->d_string[vary->vary_length] = '\0'; row->field_sizes[curfield] = (unsigned long long) vary->vary_length; } break; case DBI_TYPE_INTEGER: sizeattrib = _isolate_attrib(result->field_attribs[curfield], DBI_INTEGER_SIZE1, DBI_INTEGER_SIZE8); switch (sizeattrib) { case DBI_INTEGER_SIZE1: case DBI_INTEGER_SIZE2: data->d_short = *(short *) var.sqldata; break; case DBI_INTEGER_SIZE3: case DBI_INTEGER_SIZE4: data->d_long = *(int *) var.sqldata; break; case DBI_INTEGER_SIZE8: data->d_longlong = *(ISC_INT64 *) var.sqldata; break; default: break; } break; case DBI_TYPE_DECIMAL: sizeattrib = _isolate_attrib(result->field_attribs[curfield], DBI_DECIMAL_SIZE4, DBI_DECIMAL_SIZE8); switch (sizeattrib) { case DBI_DECIMAL_SIZE4: data->d_float = *(float *) (var.sqldata); break; case DBI_DECIMAL_SIZE8: data->d_double = *(double *) (var.sqldata); break; default: break; } break; case DBI_TYPE_DATETIME: sizeattrib = _isolate_attrib(result->field_attribs[curfield], DBI_DATETIME_DATE, DBI_DATETIME_TIME); if (sizeattrib&DBI_DATETIME_TIME && sizeattrib&DBI_DATETIME_DATE) { isc_decode_timestamp((ISC_TIMESTAMP *)var.sqldata, ×); sprintf(date_s, "%04d-%02d-%02d %02d:%02d:%02d", times.tm_year + 1900, times.tm_mon+1, times.tm_mday, times.tm_hour, times.tm_min, times.tm_sec); } else if (sizeattrib&DBI_DATETIME_TIME) { isc_decode_sql_time((ISC_TIME *)var.sqldata, ×); sprintf(date_s, "%02d:%02d:%02d", times.tm_hour, times.tm_min, times.tm_sec); } else { isc_decode_sql_date((ISC_DATE *)var.sqldata, ×); sprintf(date_s, "%04d-%02d-%02d", times.tm_year + 1900, times.tm_mon+1, times.tm_mday); } data->d_datetime = _dbd_parse_datetime(date_s, sizeattrib); break; case DBI_TYPE_BINARY: bid = *(ISC_QUAD *) var.sqldata; isc_open_blob2( iconn->status_vector, &(iconn->db), &(iconn->trans), &blob_handle, &bid, 0, NULL ); blob_stat = isc_get_segment( iconn->status_vector, &blob_handle, &actual_seg_len, sizeof(blob_segment), blob_segment ); data->d_string = malloc(sizeof(actual_seg_len)); memcpy(data->d_string, blob_segment, actual_seg_len); row->field_sizes[curfield] = actual_seg_len; while (blob_stat == 0 || iconn->status_vector[1] == isc_segment) { blob_stat = isc_get_segment(iconn->status_vector, &blob_handle, &actual_seg_len, sizeof(blob_segment), blob_segment); data->d_string = realloc(data->d_string, row->field_sizes[curfield] + actual_seg_len); memcpy(data->d_string+row->field_sizes[curfield], blob_segment, actual_seg_len); row->field_sizes[curfield] += actual_seg_len; } isc_close_blob(iconn->status_vector, &blob_handle); row->field_sizes[curfield] = _dbd_decode_binary(data->d_string, data->d_string); break; default: break; } curfield++; } if( fetch_stat != 100L ) { result->rows = realloc(result->rows, (sizeof(dbi_row_t *) * (result->numrows_matched+1))); result->numrows_matched++; } return result->numrows_matched; }
ISC_STATUS API_ROUTINE gds__close_blob(ISC_STATUS* status_vector, FB_API_HANDLE* blob_handle) { return isc_close_blob(status_vector, blob_handle); }