8 #define SOCI_FIREBIRD_SOURCE 20 : session_(session), stmtp_(0), sqldap_(NULL), sqlda2p_(NULL),
21 boundByName_(false), boundByPos_(false), rowsFetched_(0), endOfRowSet_(false), rowsAffectedBulk_(-1LL),
29 *sqldap =
reinterpret_cast<XSQLDA*
>(realloc(*sqldap, XSQLDA_LENGTH(size)));
33 *sqldap =
reinterpret_cast<XSQLDA*
>(malloc(XSQLDA_LENGTH(size)));
36 (*sqldap)->sqln = size;
37 (*sqldap)->version = 1;
58 if (isc_dsql_free_statement(stat, &
stmtp_, DSQL_drop))
79 std::string
const & src, std::vector<char> & dst)
81 std::vector<char>::iterator dst_it = dst.begin();
86 enum { eNormal, eInQuotes, eInName } state = eNormal;
91 for (std::string::const_iterator it = src.begin(), end = src.end();
123 if (std::isalnum(*it) || *it ==
'_')
129 names_.insert(std::pair<std::string, int>(name, position++));
139 if (state == eInName)
141 names_.insert(std::pair<std::string, int>(name, position++));
150 int statementType(isc_stmt_handle stmt)
154 char type_item[] = {isc_info_sql_stmt_type};
159 if (isc_dsql_sql_info(stat, &stmt,
sizeof(type_item),
160 type_item,
sizeof(res_buffer), res_buffer))
165 if (res_buffer[0] == isc_info_sql_stmt_type)
167 length = isc_vax_integer(res_buffer+1, 2);
168 stype = isc_vax_integer(res_buffer+3, length);
172 throw soci_error(
"Can't determine statement type.");
180 std::string
const &query, std::vector<char> &buffer)
183 std::vector<char> tmpQuery;
184 std::vector<char>::iterator qItr;
187 std::vector<char> rewQuery(query.size() + 1);
192 std::string
const prefix(
"execute procedure ");
193 std::string
const prefix2(
"select * from ");
199 tmpQuery.resize(prefix.size() + rewQuery.size());
200 qItr = tmpQuery.begin();
201 std::copy(prefix.begin(), prefix.end(), qItr);
202 qItr += prefix.size();
206 tmpQuery.resize(rewQuery.size());
207 qItr = tmpQuery.begin();
211 std::copy(rewQuery.begin(), rewQuery.end(), qItr);
220 isc_stmt_handle tmpStmtp = 0;
223 if (isc_dsql_allocate_statement(stat, &
session_.
dbhp_, &tmpStmtp))
230 &tmpQuery[0], SQL_DIALECT_V6,
sqldap_))
236 int stType = statementType(tmpStmtp);
239 if (isc_dsql_free_statement(stat, &tmpStmtp, DSQL_drop))
251 buffer.resize(prefix2.size() + rewQuery.size());
252 qItr = buffer.begin();
253 std::copy(prefix2.begin(), prefix2.end(), qItr);
254 qItr += prefix2.size();
255 std::copy(rewQuery.begin(), rewQuery.end(), qItr);
267 if (stType == isc_info_sql_stmt_ddl)
271 buffer.resize(query.size() + 1);
272 std::copy(query.begin(), query.end(), buffer.begin());
282 buffer.resize(tmpQuery.size());
283 std::copy(tmpQuery.begin(), tmpQuery.end(), buffer.begin());
296 std::vector<char> queryBuffer;
306 &queryBuffer[0], SQL_DIALECT_V6,
sqldap_))
316 if (isc_dsql_describe(stat, &
stmtp_, SQL_DIALECT_V6,
sqldap_))
328 if (isc_dsql_describe_bind(stat, &
stmtp_, SQL_DIALECT_V6,
sqlda2p_))
338 if (isc_dsql_describe_bind(stat, &
stmtp_, SQL_DIALECT_V6,
sqlda2p_))
360 void checkSize(std::size_t actual, std::size_t expected,
361 std::string
const & name)
363 if (actual != expected)
365 std::ostringstream msg;
366 msg <<
"Incorrect number of " << name <<
" variables. " 367 <<
"Expected " << expected <<
", got " << actual;
379 std::size_t usize =
uses_.size();
384 checkSize(usize,
sqlda2p_->sqld,
"use");
393 for (std::size_t col=0; col<usize; ++col)
401 if (isc_dsql_free_statement(stat, &
stmtp_, DSQL_close))
412 long long rowsAffectedBulkTemp = 0;
417 for (std::size_t
row=0;
row < rows; ++
row)
420 for (std::size_t col=0; col<usize; ++col)
461 return fetch(number);
484 for (
size_t i = 0; i<static_cast<unsigned int>(
sqldap_->sqld); ++i)
486 inds_[i].resize(number > 0 ? number : 1);
493 for (
int i = 0; i < number; ++i)
495 long fetch_stat = isc_dsql_fetch(stat, &
stmtp_, SQL_DIALECT_V6,
sqldap_);
503 else if (fetch_stat == 100L)
525 for (
size_t i = 0; i < static_cast<unsigned int>(
sqldap_->sqld); ++i)
528 if (((
sqldap_->sqlvar+i)->sqltype & 1) == 0)
533 else if (*((
sqldap_->sqlvar+i)->sqlind) == 0)
537 else if (*((
sqldap_->sqlvar+i)->sqlind) == -1)
543 throw soci_error(
"Unknown state in firebird_statement_backend::exchangeData()");
571 ISC_STATUS_ARRAY stat;
572 char type_item[] = { isc_info_sql_records };
573 char res_buffer[256];
575 if (isc_dsql_sql_info(stat, &
stmtp_,
sizeof(type_item), type_item,
576 sizeof(res_buffer), res_buffer))
583 if (res_buffer[0] != isc_info_sql_records)
585 throw soci_error(
"Can't determine the number of affected rows");
588 char* sql_rec_buf = res_buffer + 1;
589 const int length = isc_vax_integer(sql_rec_buf, 2);
592 if (sql_rec_buf[length] != isc_info_end)
594 throw soci_error(
"Unexpected isc_info_sql_records return format");
599 long long row_count = 0;
601 for (
char* p = sql_rec_buf; !row_count && p < sql_rec_buf + length; )
605 case isc_info_req_select_count:
606 case isc_info_req_insert_count:
607 case isc_info_req_update_count:
608 case isc_info_req_delete_count:
610 int len = isc_vax_integer(p, 2);
613 row_count += isc_vax_integer(p, len);
635 std::string
const &query)
643 return static_cast<int>(
sqldap_->sqld);
647 data_type & type, std::string & columnName)
649 XSQLVAR * var =
sqldap_->sqlvar+(colNum-1);
651 columnName.assign(var->aliasname, var->aliasname_length);
653 switch (var->sqltype & ~1)
670 if (var->sqlscale < 0)
683 if (var->sqlscale < 0)
698 std::ostringstream msg;
699 msg <<
"Type of column ["<< colNum <<
"] \"" << columnName
700 <<
"\" is not supported for dynamic queries";
std::vector< void * > uses_
virtual void prepare(std::string const &query, details::statement_type eType)
virtual void exchangeData(bool gotData, int row)
virtual void describe_column(int colNum, data_type &dtype, std::string &columnName)
firebird_statement_backend(firebird_session_backend &session)
virtual firebird_vector_into_type_backend * make_vector_into_type_backend()
bool check_iscerror(ISC_STATUS const *status_vector, long errNum)
virtual exec_fetch_result execute(int number)
std::vector< void * > intos_
friend struct firebird_vector_use_type_backend
std::size_t const stat_size
virtual std::string rewrite_for_procedure_call(std::string const &query)
virtual firebird_vector_use_type_backend * make_vector_use_type_backend()
virtual void prepareSQLDA(XSQLDA **sqldap, int size=10)
virtual int prepare_for_describe()
friend struct firebird_standard_into_type_backend
void throw_iscerror(ISC_STATUS *status_vector)
bool get_option_decimals_as_strings()
firebird_session_backend & session_
virtual void rewriteParameters(std::string const &src, std::vector< char > &dst)
std::map< std::string, int > names_
virtual void rewriteQuery(std::string const &query, std::vector< char > &buffer)
virtual firebird_standard_into_type_backend * make_into_type_backend()
virtual int get_number_of_rows()
friend struct firebird_vector_into_type_backend
virtual firebird_standard_use_type_backend * make_use_type_backend()
long long rowsAffectedBulk_
friend struct firebird_standard_use_type_backend
virtual exec_fetch_result fetch(int number)
std::vector< std::vector< indicator > > inds_
virtual long long get_affected_rows()