Skip to content

Commit

Permalink
Add CLOB support to Firebird backend
Browse files Browse the repository at this point in the history
Reuse the existing BLOB support, however we now need to allocate a BLOB
inside firebird_standard_use_type_backend objects as, unlike when using
soci::blob objects, we don't have any way to associate backend-specific
data with the parameter otherwise.

This difference between CLOB and BLOB support is not ideal, but there
doesn't seem to be any way to avoid it.
  • Loading branch information
vadz committed Sep 13, 2017
1 parent 85159db commit 059faf5
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 1 deletion.
7 changes: 6 additions & 1 deletion include/soci/firebird/soci-firebird.h
Expand Up @@ -59,6 +59,7 @@ enum BuffersType
eStandard, eVector
};

struct firebird_blob_backend;
struct firebird_statement_backend;
struct firebird_standard_into_type_backend : details::standard_into_type_backend
{
Expand Down Expand Up @@ -117,7 +118,8 @@ struct firebird_vector_into_type_backend : details::vector_into_type_backend
struct firebird_standard_use_type_backend : details::standard_use_type_backend
{
firebird_standard_use_type_backend(firebird_statement_backend &st)
: statement_(st), data_(NULL), type_(), position_(0), buf_(NULL), indISCHolder_(0)
: statement_(st), data_(NULL), type_(), position_(0), buf_(NULL), indISCHolder_(0),
blob_(NULL)
{}

virtual void bind_by_pos(int &position,
Expand All @@ -139,6 +141,9 @@ struct firebird_standard_use_type_backend : details::standard_use_type_backend

char *buf_;
short indISCHolder_;

// This is used for types mapping to CLOB.
firebird_blob_backend* blob_;
};

struct firebird_vector_use_type_backend : details::vector_use_type_backend
Expand Down
24 changes: 24 additions & 0 deletions src/backends/firebird/standard-into-type.cpp
Expand Up @@ -11,6 +11,8 @@
#include "firebird/common.h"
#include "soci/soci.h"

#include <sstream>

using namespace soci;
using namespace soci::details;
using namespace soci::details::firebird;
Expand Down Expand Up @@ -119,6 +121,28 @@ void firebird_standard_into_type_backend::exchangeData()
blob->assign(*reinterpret_cast<ISC_QUAD*>(buf_));
}
break;

case x_longstring:
{
long_string* const dst = static_cast<long_string*>(data_);

firebird_blob_backend blob(statement_.session_);
blob.assign(*reinterpret_cast<ISC_QUAD*>(buf_));

std::size_t const len_total = blob.get_len();
dst->value.resize(len_total);

std::size_t len_read = blob.read(0, &dst->value[0], len_total);
if (len_read != len_total)
{
std::ostringstream os;
os << "Read " << len_read << " bytes instead of expected "
<< len_total << " from Firebird text blob object";
throw soci_error(os.str());
}
}
break;

default:
throw soci_error("Into element used with non-supported type.");
} // switch
Expand Down
19 changes: 19 additions & 0 deletions src/backends/firebird/standard-use-type.cpp
Expand Up @@ -147,6 +147,18 @@ void firebird_standard_use_type_backend::exchangeData()
memcpy(buf_, &blob->bid_, var->sqllen);
}
break;

case x_longstring:
{
long_string const* const src = static_cast<long_string*>(data_);

blob_ = new firebird_blob_backend(statement_.session_);
blob_->append(src->value.c_str(), src->value.length());
blob_->save();
memcpy(buf_, &blob_->bid_, var->sqllen);
}
break;

default:
throw soci_error("Use element used with non-supported type.");
} // switch
Expand Down Expand Up @@ -175,6 +187,13 @@ void firebird_standard_use_type_backend::clean_up()
delete [] buf_;
buf_ = NULL;
}

if (blob_)
{
delete blob_;
blob_ = NULL;
}

std::vector<void*>::iterator it =
std::find(statement_.uses_.begin(), statement_.uses_.end(), this);
if (it != statement_.uses_.end())
Expand Down
16 changes: 16 additions & 0 deletions tests/firebird/test-firebird.cpp
Expand Up @@ -1274,6 +1274,17 @@ struct TableCreator4 : public tests::table_creator_base
}
};

struct TableCreatorCLOB : public tests::table_creator_base
{
TableCreatorCLOB(soci::session & sql)
: tests::table_creator_base(sql)
{
sql << "create table soci_test(id integer, s blob sub_type text)";
sql.commit();
sql.begin();
}
};

class test_context : public tests::test_context_base
{
public:
Expand Down Expand Up @@ -1302,6 +1313,11 @@ class test_context : public tests::test_context_base
return new TableCreator4(s);
}

tests::table_creator_base* table_creator_clob(soci::session& s) const
{
return new TableCreatorCLOB(s);
}

std::string to_date_time(std::string const &datdt_string) const
{
return "'" + datdt_string + "'";
Expand Down

0 comments on commit 059faf5

Please sign in to comment.