int fb_affected_rows(rlm_sql_firebird_conn_t *conn) { static char count_info[] = {isc_info_sql_records}; char info_buffer[128]; char *p ; int affected_rows = -1; if (!conn->stmt) return -1; isc_dsql_sql_info(conn->status, &conn->stmt, sizeof (count_info), count_info, sizeof (info_buffer), info_buffer); if (IS_ISC_ERROR(conn->status)) { return fb_error(conn); } p = info_buffer + 3; while (*p != isc_info_end) { p++; short len = (short)isc_vax_integer(p, 2); p += 2; affected_rows = isc_vax_integer(p, len); if (affected_rows > 0) { break; } p += len; } return affected_rows; }
/* ** Returns the statement type */ static int get_statement_type(cur_data* cur) { int length, type; char type_item[] = { isc_info_sql_stmt_type }; char res_buffer[88], *pres; pres = res_buffer; isc_dsql_sql_info( cur->env->status_vector, &cur->stmt, sizeof(type_item), type_item, sizeof(res_buffer), res_buffer ); if (cur->env->status_vector[0] == 1 && cur->env->status_vector[1] > 0) return -1; /* check the type of the statement */ if (*pres == isc_info_sql_stmt_type) { pres++; length = isc_vax_integer(pres, 2); pres += 2; type = isc_vax_integer(pres, length); pres += length; } else return -2; /* should have had the isc_info_sql_stmt_type info */ return type; }
static int fb_prepare(rlm_sql_firebird_conn_t *conn, char const *query) { static char stmt_info[] = { isc_info_sql_stmt_type }; char info_buffer[128]; short l; if (!conn->trh) { isc_start_transaction(conn->status, &conn->trh, 1, &conn->dbh, conn->tpb_len, conn->tpb); if (!conn->trh) { return -4; } } fb_free_statement(conn); if (!conn->stmt) { isc_dsql_allocate_statement(conn->status, &conn->dbh, &conn->stmt); if (!conn->stmt) { return -1; } } fb_free_sqlda(conn->sqlda_out); isc_dsql_prepare(conn->status, &conn->trh, &conn->stmt, 0, query, conn->sql_dialect, conn->sqlda_out); if (IS_ISC_ERROR(conn->status)) { return -2; } if (conn->sqlda_out->sqln<conn->sqlda_out->sqld) { conn->sqlda_out->sqln = conn->sqlda_out->sqld; conn->sqlda_out = (XSQLDA ISC_FAR *) realloc(conn->sqlda_out, XSQLDA_LENGTH(conn->sqlda_out->sqld)); isc_dsql_describe(conn->status, &conn->stmt, SQL_DIALECT_V6, conn->sqlda_out); if (IS_ISC_ERROR(conn->status)) { return -3; } } /* * Get statement type */ isc_dsql_sql_info(conn->status, &conn->stmt, sizeof(stmt_info), stmt_info, sizeof(info_buffer), info_buffer); if (IS_ISC_ERROR(conn->status)) return -4; l = (short) isc_vax_integer((char ISC_FAR *) info_buffer + 1, 2); conn->statement_type = isc_vax_integer((char ISC_FAR *) info_buffer + 3, l); if (conn->sqlda_out->sqld) { fb_set_sqlda(conn->sqlda_out); //set out sqlda } return 0; }
IB_SLONG32 IB_Statement::getUpdateCount () { int countType = 0; // Get the statement type count indicator as it will appear // in the requested info buffer. switch (stmtType_) { case isc_info_sql_stmt_update: countType = isc_info_req_update_count; break; case isc_info_sql_stmt_delete: countType = isc_info_req_delete_count; break; case isc_info_sql_stmt_insert: countType = isc_info_req_insert_count; break; case isc_info_sql_stmt_select: countType = isc_info_req_select_count; break; default: return 0; } if (isc_dsql_sql_info (status_->vector(), &stmtHandle_, sizeof (rowCountsInfoRequest__), (IB_BUFF_PTR) rowCountsInfoRequest__, rowCountsRequestedInfoSize__, rowCountsRequestedInfo_)) throw new IB_SQLException (IB_SQLException::engine__default_0__, status_); int rowCountLength; int countTypeIndicator=0; IB_SLONG32 count = 0; // skip over isc_info_sql_records, and overall 2 byte length field IB_BUFF_PTR iterator = rowCountsRequestedInfo_ + 3; while (*iterator != isc_info_end) { countTypeIndicator = *iterator++; // !!! should call IB_Information::getInteger() here. // HP-UX port (old CC): added type cast (int) rowCountLength = (int) isc_vax_integer (iterator, 2); iterator += 2; // skip over rowCountLength count = isc_vax_integer (iterator, rowCountLength); iterator += rowCountLength; // skip over rowCount if (countTypeIndicator == countType) // found it break; } return count; }
bool printLine(const unsigned char*& p) { const ISC_USHORT length = (ISC_USHORT) isc_vax_integer((char*)p, sizeof(ISC_USHORT)); p += sizeof(ISC_USHORT); if (length > 0) printf("%*.*s\n", length, length, p); p += length; return length > 0; }
// Returns number of rows afected by last statement // or -1 if there is no such counter available. long getRowCount(soci::statement & statement, eRowCountType type) { ISC_STATUS stat[20]; char cnt_req[2], cnt_info[128]; cnt_req[0]=isc_info_sql_records; cnt_req[1]=isc_info_end; firebird_statement_backend* statementBackEnd = static_cast<firebird_statement_backend*>(statement.get_backend()); // Note: This is very poorly documented function. // It can extract number of rows returned by select statement, // but it appears that this is only number of rows prefetched by // client library, not total number of selected rows. if (isc_dsql_sql_info(stat, &statementBackEnd->stmtp_, sizeof(cnt_req), cnt_req, sizeof(cnt_info), cnt_info)) { soci::details::firebird::throw_iscerror(stat); } long count = -1; char type_ = static_cast<char>(type); for (char *ptr = cnt_info + 3; *ptr != isc_info_end;) { char count_type = *ptr++; int m = isc_vax_integer(ptr, 2); ptr += 2; count = isc_vax_integer(ptr, m); if (count_type == type_) { // this is requested number break; } ptr += m; } return count; }
IB_BUFF_PTR IB_Information::findInfoItem (const IB_UBYTE requestedItem) const { IB_BUFF_PTR iterator = (IB_BUFF_PTR) requestedInfo_.buffer(); while (*iterator != isc_info_end) { if (*iterator == requestedItem) return ++iterator; iterator++; // Increment iterator over length indicator and over length bytes iterator += sizeof(IB_SSHORT16) + isc_vax_integer (iterator, sizeof (IB_SSHORT16)); } throw new IB_SQLException (IB_SQLException::bugCheck__0__, 10003, IB_SQLException::bugCheckException__); // This is just to please MSVC return NULL; }
/* ** 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; } } }
/* ** Return the number of rows affected by last operation */ static int count_rows_affected(cur_data* cur) { int length, type, res=0; int del_count = 0, ins_count = 0, upd_count = 0, sel_count = 0; char type_item[] = { isc_info_sql_stmt_type, isc_info_sql_records }; char res_buffer[88], *pres; pres = res_buffer; isc_dsql_sql_info( cur->env->status_vector, &cur->stmt, sizeof(type_item), type_item, sizeof(res_buffer), res_buffer ); if (cur->env->status_vector[0] == 1 && cur->env->status_vector[1] > 0) return -1; /* check the type of the statement */ if (*pres == isc_info_sql_stmt_type) { pres++; length = isc_vax_integer(pres, 2); pres += 2; type = isc_vax_integer(pres, length); pres += length; } else return -2; /* should have had the isc_info_sql_stmt_type info */ if(type > 4) return 0; /* not a SELECT, INSERT, UPDATE or DELETE SQL statement */ if (*pres == isc_info_sql_records) { pres++; length = isc_vax_integer(pres, 2); /* normally 29 bytes */ pres += 2; while(*pres != 1) { switch(*pres) { case isc_info_req_select_count: pres++; length = isc_vax_integer(pres, 2); pres += 2; sel_count = isc_vax_integer(pres, length); pres += length; break; case isc_info_req_insert_count: pres++; length = isc_vax_integer(pres, 2); pres += 2; ins_count = isc_vax_integer(pres, length); pres += length; break; case isc_info_req_update_count: pres++; length = isc_vax_integer(pres, 2); pres += 2; upd_count = isc_vax_integer(pres, length); pres += length; break; case isc_info_req_delete_count: pres++; length = isc_vax_integer(pres, 2); pres += 2; del_count = isc_vax_integer(pres, length); pres += length; break; default: pres++; break; } } } else return -3; switch(type) { case isc_info_sql_stmt_select: res = sel_count; break; case isc_info_sql_stmt_delete: res = del_count; break; case isc_info_sql_stmt_update: res = upd_count; break; case isc_info_sql_stmt_insert: res = ins_count; break; } return res; }
static void perf_get_info(FB_API_HANDLE* handle, P* perf) { /************************************** * * P E R F _ g e t _ i n f o * ************************************** * * Functional description * Acquire timing and performance information. Some info comes * from the system and some from the database. * **************************************/ SSHORT buffer_length, item_length; ISC_STATUS_ARRAY jrd_status; #ifdef HAVE_GETTIMEOFDAY struct timeval tp; #else struct timeb time_buffer; #define LARGE_NUMBER 696600000 // to avoid overflow, get rid of decades) #endif // If there isn't a database, zero everything out if (!*handle) { memset(perf, 0, sizeof(PERF)); } // Get system time times(&perf->perf_times); #ifdef HAVE_GETTIMEOFDAY GETTIMEOFDAY(&tp); perf->perf_elapsed = tp.tv_sec * 100 + tp.tv_usec / 10000; #else ftime(&time_buffer); perf->perf_elapsed = (time_buffer.time - LARGE_NUMBER) * 100 + (time_buffer.millitm / 10); #endif if (!*handle) return; SCHAR buffer[256]; buffer_length = sizeof(buffer); item_length = sizeof(items); isc_database_info(jrd_status, handle, item_length, items, buffer_length, buffer); const char* p = buffer; while (true) switch (*p++) { case isc_info_reads: perf->perf_reads = get_parameter(&p); break; case isc_info_writes: perf->perf_writes = get_parameter(&p); break; case isc_info_marks: perf->perf_marks = get_parameter(&p); break; case isc_info_fetches: perf->perf_fetches = get_parameter(&p); break; case isc_info_num_buffers: perf->perf_buffers = get_parameter(&p); break; case isc_info_page_size: perf->perf_page_size = get_parameter(&p); break; case isc_info_current_memory: perf->perf_current_memory = get_parameter(&p); break; case isc_info_max_memory: perf->perf_max_memory = get_parameter(&p); break; case isc_info_end: return; case isc_info_error: switch (p[2]) { case isc_info_marks: perf->perf_marks = 0; break; case isc_info_current_memory: perf->perf_current_memory = 0; break; case isc_info_max_memory: perf->perf_max_memory = 0; break; } { const SLONG temp = isc_vax_integer(p, 2); fb_assert(temp <= MAX_SSHORT); p += temp + 2; } perf->perf_marks = 0; break; default: return; } }
void TraceSvcUtil::runService(size_t spbSize, const UCHAR* spb) { os_utils::CtrlCHandler ctrlCHandler; ISC_STATUS_ARRAY status; if (isc_service_start(status, &m_svcHandle, 0, static_cast<USHORT>(spbSize), reinterpret_cast<const char*>(spb))) { status_exception::raise(status); } const char query[] = {isc_info_svc_to_eof, isc_info_end}; // use one second timeout to poll service char send[16]; char* p = send; *p++ = isc_info_svc_timeout; ADD_SPB_LENGTH(p, 4); ADD_SPB_NUMERIC(p, 1); *p++ = isc_info_end; const USHORT sendSize = (p - send); char results[MAXBUF]; bool noData; do { if (isc_service_query(status, &m_svcHandle, 0, sendSize, send, sizeof(query), query, sizeof(results) - 1, results)) { status_exception::raise(status); } p = results; bool ignoreTruncation = false; bool dirty = false; noData = true; while (*p != isc_info_end) { const UCHAR item = *p++; switch (item) { case isc_info_svc_to_eof: ignoreTruncation = true; case isc_info_svc_line: { const unsigned short l = isc_vax_integer(p, sizeof(l)); p += sizeof(l); if (l) { const char ch = p[l]; p[l] = 0; fprintf(stdout, "%s", p); p[l] = ch; p += l; dirty = true; } noData = (l == 0); } break; case isc_info_truncated: if (!ignoreTruncation) return; break; case isc_info_svc_timeout: case isc_info_data_not_ready: noData = false; if (dirty) { fflush(stdout); dirty = false; } break; default: status_exception::raise(Arg::Gds(isc_fbsvcmgr_query_err) << Arg::Num(static_cast<unsigned char>(p[-1]))); } } } while (!(ctrlCHandler.getTerminated() || noData)); }
int IB_Information::getInteger (const IB_BUFF_PTR p) { return isc_vax_integer (p+2, (short) isc_vax_integer (p, 2)); }