Skip to content

Commit

Permalink
Integrate Firebird fixes.
Browse files Browse the repository at this point in the history
Fix backend compilation, correct a few bugs and implement get_affected_rows().
  • Loading branch information
vadz committed Jul 10, 2012
2 parents cbeda1d + 4afaae6 commit a706189
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 37 deletions.
6 changes: 3 additions & 3 deletions src/backends/firebird/error-firebird.cpp
Expand Up @@ -37,16 +37,16 @@ namespace firebird
void get_iscerror_details(ISC_STATUS * status_vector, std::string &msg)
{
char msg_buffer[SOCI_FIREBIRD_ERRMSG];
long *pvector = status_vector;
const ISC_STATUS *pvector = status_vector;

try
{
// fetching first error message
isc_interprete(msg_buffer, &pvector);
fb_interpret(msg_buffer, SOCI_FIREBIRD_ERRMSG, &pvector);
msg = msg_buffer;

// fetching next errors
while (isc_interprete(msg_buffer, &pvector))
while (fb_interpret(msg_buffer, SOCI_FIREBIRD_ERRMSG, &pvector))
{
msg += "\n";
msg += msg_buffer;
Expand Down
2 changes: 0 additions & 2 deletions src/backends/firebird/row-id.cpp
Expand Up @@ -18,6 +18,4 @@ firebird_rowid_backend::firebird_rowid_backend(firebird_session_backend & /* ses

firebird_rowid_backend::~firebird_rowid_backend()
{
// Unsupported in Firebird backend
throw soci_error("RowIDs are not supported");
}
27 changes: 12 additions & 15 deletions src/backends/firebird/standard-into-type.cpp
Expand Up @@ -85,6 +85,12 @@ void firebird_standard_into_type_backend::exchangeData()
}
break;
case x_integer:
{
int t = from_isc<int>(var);
*reinterpret_cast<int *>(data_) = t;
}
break;
case x_long_long:
{
long long t = from_isc<long long>(var);
*reinterpret_cast<long long *>(data_) = t;
Expand All @@ -98,27 +104,18 @@ void firebird_standard_into_type_backend::exchangeData()
break;

// cases that require adjustments and buffer management
case x_cstring:
{
details::cstring_descriptor *tmp =
static_cast<details::cstring_descriptor*>(data_);

std::string stmp = getTextParam(var);
std::strncpy(tmp->str_, stmp.c_str(), tmp->bufSize_ - 1);
tmp->str_[tmp->bufSize_ - 1] = '\0';

if (stmp.size() >= tmp->bufSize_)
{
statement_.inds_[position_][0] = i_truncated;
}
}
break;
case x_stdstring:
*(reinterpret_cast<std::string*>(data_)) = getTextParam(var);
break;
case x_stdtm:
tmDecode(var->sqltype,
buf_, static_cast<std::tm*>(data_));

// isc_decode_timestamp() used by tmDecode() incorrectly sets
// tm_isdst to 0 in the struct that it creates, see
// http://tracker.firebirdsql.org/browse/CORE-3877, work around it
// by pretending the DST is actually unknown.
static_cast<std::tm*>(data_)->tm_isdst = -1;
break;

// cases that require special handling
Expand Down
15 changes: 0 additions & 15 deletions src/backends/firebird/standard-use-type.cpp
Expand Up @@ -118,21 +118,6 @@ void firebird_standard_use_type_backend::exchangeData()
to_isc<double>(data_, var);
break;

// cases that require adjustments and buffer management
case x_cstring:
{
details::cstring_descriptor *tmp
= static_cast<cstring_descriptor*>(data_);

// remove trailing nulls
while (tmp->str_[tmp->bufSize_-1] == '\0')
{
--tmp->bufSize_;
}

setTextParam(tmp->str_, tmp->bufSize_, buf_, var);
}
break;
case x_stdstring:
{
std::string *tmp = static_cast<std::string*>(data_);
Expand Down
58 changes: 56 additions & 2 deletions src/backends/firebird/statement.cpp
Expand Up @@ -542,8 +542,62 @@ void firebird_statement_backend::exchangeData(bool gotData, int row)

long long firebird_statement_backend::get_affected_rows()
{
// ...
return -1;
ISC_STATUS_ARRAY stat;
char type_item[] = { isc_info_sql_records };
char res_buffer[256];

if (isc_dsql_sql_info(stat, &stmtp_, sizeof(type_item), type_item,
sizeof(res_buffer), res_buffer))
{
throw_iscerror(stat);
}

// We must get back a isc_info_sql_records block, that we parse below,
// followed by isc_info_end.
if (res_buffer[0] != isc_info_sql_records)
{
throw soci_error("Can't determine the number of affected rows");
}

char* sql_rec_buf = res_buffer + 1;
const int length = isc_vax_integer(sql_rec_buf, 2);
sql_rec_buf += 2;

if (sql_rec_buf[length] != isc_info_end)
{
throw soci_error("Unexpected isc_info_sql_records return format");
}

// Examine the 4 sub-blocks each of which has a header indicating the block
// type, its value length in bytes and the value itself.
long long row_count = 0;

for ( char* p = sql_rec_buf; p < sql_rec_buf + length; )
{
switch (*p++)
{
case isc_info_req_select_count:
case isc_info_req_insert_count:
case isc_info_req_update_count:
case isc_info_req_delete_count:
{
int len = isc_vax_integer(p, 2);
p += 2;

row_count += isc_vax_integer(p, len);
p += len;
}
break;

case isc_info_end:
break;

default:
throw soci_error("Unknown record counter");
}
}

return row_count;
}

int firebird_statement_backend::get_number_of_rows()
Expand Down

0 comments on commit a706189

Please sign in to comment.