/* ** 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; }
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; }
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; }
int IB_Statement::statementType() { if (isc_dsql_sql_info (status_->vector(), &stmtHandle_, sizeof (stmtTypeInfoRequest__), (IB_BUFF_PTR) stmtTypeInfoRequest__, stmtTypeRequestedInfoSize__, stmtTypeRequestedInfo_)) throw new IB_SQLException (IB_SQLException::engine__default_0__, status_); return IB_Information::getInteger (stmtTypeRequestedInfo_ + 1); }
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; }
// 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; }
/* ** 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; }