Commit 138b29e4 authored by Maciej Sobczak's avatar Maciej Sobczak

Lazy initialization of the temporary LOB objects for Oracle.

parent 4b642ac5
......@@ -36,6 +36,7 @@ public:
virtual ~into_type_base() {}
virtual void define(statement_impl & st, int & position) = 0;
virtual void pre_exec(int num) = 0;
virtual void pre_fetch() = 0;
virtual void post_fetch(bool gotData, bool calledFromFetch) = 0;
virtual void clean_up() = 0;
......@@ -63,6 +64,7 @@ protected:
private:
virtual void define(statement_impl & st, int & position);
virtual void pre_exec(int num);
virtual void pre_fetch();
virtual void clean_up();
......@@ -108,6 +110,7 @@ protected:
virtual void post_fetch(bool gotData, bool calledFromFetch);
virtual void define(statement_impl & st, int & position);
virtual void pre_exec(int num);
virtual void pre_fetch();
virtual void clean_up();
virtual void resize(std::size_t sz);
......
......@@ -60,6 +60,7 @@ struct oracle_standard_into_type_backend : details::standard_into_type_backend
void read_from_lob(OCILobLocator * lobp, std::string & value);
virtual void pre_exec(int num);
virtual void pre_fetch();
virtual void post_fetch(bool gotData, bool calledFromFetch,
indicator *ind);
......@@ -143,6 +144,10 @@ struct oracle_standard_use_type_backend : details::standard_use_type_backend
// common helper for pre_use for LOB-directed wrapped types
void write_to_lob(OCILobLocator * lobp, const std::string & value);
// common lazy initialization of the temporary LOB object
void lazy_temp_lob_init();
virtual void pre_exec(int num);
virtual void pre_use(indicator const *ind);
virtual void post_use(bool gotData, indicator *ind);
......
......@@ -41,6 +41,7 @@ private:
// as part of the statement execute
}
virtual void pre_exec(int /* num */) {}
virtual void pre_fetch() {}
virtual void post_fetch(bool gotData, bool /* calledFromFetch */)
{
......
......@@ -71,6 +71,7 @@ public:
virtual void define_by_pos(int& position, void* data, exchange_type type) = 0;
virtual void pre_exec(int /* num */) {}
virtual void pre_fetch() = 0;
virtual void post_fetch(bool gotData, bool calledFromFetch, indicator* ind) = 0;
......@@ -96,6 +97,7 @@ public:
virtual void define_by_pos(int& position, void* data, exchange_type type) = 0;
virtual void pre_exec(int /* num */) {}
virtual void pre_fetch() = 0;
virtual void post_fetch(bool gotData, indicator* ind) = 0;
......@@ -121,6 +123,7 @@ public:
virtual void bind_by_name(std::string const& name,
void* data, exchange_type type, bool readOnly) = 0;
virtual void pre_exec(int /* num */) {}
virtual void pre_use(indicator const* ind) = 0;
virtual void post_use(bool gotData, indicator * ind) = 0;
......@@ -153,6 +156,7 @@ public:
throw soci_error("use bulk iterators are not supported with this backend");
}
virtual void pre_exec(int /* num */) {}
virtual void pre_use(indicator const* ind) = 0;
virtual std::size_t size() = 0;
......
......@@ -151,6 +151,7 @@ private:
std::size_t intos_size();
std::size_t uses_size();
void pre_exec(int num);
void pre_fetch();
void pre_use();
void post_fetch(bool gotData, bool calledFromFetch);
......
......@@ -32,6 +32,7 @@ public:
virtual void bind(statement_impl & st, int & position) = 0;
virtual std::string get_name() const = 0;
virtual void dump_value(std::ostream& os) const = 0;
virtual void pre_exec(int num) = 0;
virtual void pre_use() = 0;
virtual void post_use(bool gotData) = 0;
virtual void clean_up() = 0;
......@@ -86,6 +87,7 @@ protected:
virtual void pre_use();
private:
virtual void pre_exec(int num);
virtual void post_use(bool gotData);
virtual void clean_up();
virtual std::size_t size() const { return 1; }
......@@ -156,6 +158,7 @@ private:
virtual void bind(statement_impl& st, int & position);
virtual std::string get_name() const { return name_; }
virtual void dump_value(std::ostream& os) const;
virtual void pre_exec(int num);
virtual void pre_use();
virtual void post_use(bool) { /* nothing to do */ }
virtual void clean_up();
......
......@@ -80,6 +80,8 @@ public:
os << "<value>";
}
virtual void pre_exec(int /* num */) {}
virtual void post_use(bool /*gotData*/)
{
v_.reset_get_counter();
......
......@@ -149,22 +149,11 @@ void oracle_standard_into_type_backend::define_by_pos(
{
oracleType = SQLT_CLOB;
OCILobLocator * lobp;
sword res = OCIDescriptorAlloc(statement_.session_.envhp_,
reinterpret_cast<dvoid**>(&lobp), OCI_DTYPE_LOB, 0, 0);
if (res != OCI_SUCCESS)
{
throw_oracle_soci_error(res, statement_.session_.errhp_);
}
// lazy initialization of the temporary LOB object,
// actual creation of this object is in pre_exec, which
// is called right before statement's execute
res = OCILobCreateTemporary(statement_.session_.svchp_,
statement_.session_.errhp_,
lobp, 0, SQLCS_IMPLICIT,
OCI_TEMP_CLOB, OCI_ATTR_NOCACHE, OCI_DURATION_SESSION);
if (res != OCI_SUCCESS)
{
throw_oracle_soci_error(res, statement_.session_.errhp_);
}
OCILobLocator * lobp = NULL;
size = sizeof(lobp);
data = &ociData_;
......@@ -184,6 +173,33 @@ void oracle_standard_into_type_backend::define_by_pos(
}
}
void oracle_standard_into_type_backend::pre_exec(int /* num */)
{
if (type_ == x_xmltype || type_ == x_longstring)
{
// lazy initialization of the temporary LOB object
OCILobLocator * lobp;
sword res = OCIDescriptorAlloc(statement_.session_.envhp_,
reinterpret_cast<dvoid**>(&lobp), OCI_DTYPE_LOB, 0, 0);
if (res != OCI_SUCCESS)
{
throw_oracle_soci_error(res, statement_.session_.errhp_);
}
res = OCILobCreateTemporary(statement_.session_.svchp_,
statement_.session_.errhp_,
lobp, 0, SQLCS_IMPLICIT,
OCI_TEMP_CLOB, OCI_ATTR_NOCACHE, OCI_DURATION_SESSION);
if (res != OCI_SUCCESS)
{
throw_oracle_soci_error(res, statement_.session_.errhp_);
}
ociData_ = lobp;
}
}
void oracle_standard_into_type_backend::pre_fetch()
{
// nothing to do except with Statement into objects
......
......@@ -147,22 +147,11 @@ void oracle_standard_use_type_backend::prepare_for_bind(
{
oracleType = SQLT_CLOB;
OCILobLocator * lobp;
sword res = OCIDescriptorAlloc(statement_.session_.envhp_,
reinterpret_cast<dvoid**>(&lobp), OCI_DTYPE_LOB, 0, 0);
if (res != OCI_SUCCESS)
{
throw_oracle_soci_error(res, statement_.session_.errhp_);
}
// lazy initialization of the temporary LOB object,
// actual creation of this object is in pre_exec, which
// is called right before statement's execute
res = OCILobCreateTemporary(statement_.session_.svchp_,
statement_.session_.errhp_,
lobp, 0, SQLCS_IMPLICIT,
OCI_TEMP_CLOB, OCI_ATTR_NOCACHE, OCI_DURATION_SESSION);
if (res != OCI_SUCCESS)
{
throw_oracle_soci_error(res, statement_.session_.errhp_);
}
OCILobLocator * lobp = NULL;
size = sizeof(lobp);
data = &ociData_;
......@@ -270,6 +259,62 @@ void oracle_standard_use_type_backend::write_to_lob(OCILobLocator * lobp, const
}
}
void oracle_standard_use_type_backend::lazy_temp_lob_init()
{
OCILobLocator * lobp;
sword res = OCIDescriptorAlloc(statement_.session_.envhp_,
reinterpret_cast<dvoid**>(&lobp), OCI_DTYPE_LOB, 0, 0);
if (res != OCI_SUCCESS)
{
throw_oracle_soci_error(res, statement_.session_.errhp_);
}
res = OCILobCreateTemporary(statement_.session_.svchp_,
statement_.session_.errhp_,
lobp, 0, SQLCS_IMPLICIT,
OCI_TEMP_CLOB, OCI_ATTR_NOCACHE, OCI_DURATION_SESSION);
if (res != OCI_SUCCESS)
{
throw_oracle_soci_error(res, statement_.session_.errhp_);
}
ociData_ = lobp;
}
void oracle_standard_use_type_backend::pre_exec(int /* num */)
{
switch (type_)
{
case x_xmltype:
{
// lazy initialization of the temporary LOB object
lazy_temp_lob_init();
OCILobLocator * lobp = static_cast<OCILobLocator *>(ociData_);
xml_type * xml = static_cast<xml_type *>(data_);
write_to_lob(lobp, xml->value);
}
break;
case x_longstring:
{
// lazy initialization of the temporary LOB object
lazy_temp_lob_init();
OCILobLocator * lobp = static_cast<OCILobLocator *>(ociData_);
long_string * ls = static_cast<long_string *>(data_);
write_to_lob(lobp, ls->value);
}
break;
default:
// nothing to do
break;
}
}
void oracle_standard_use_type_backend::pre_use(indicator const *ind)
{
// first deal with data
......@@ -347,22 +392,7 @@ void oracle_standard_use_type_backend::pre_use(indicator const *ind)
break;
case x_xmltype:
{
OCILobLocator * lobp = static_cast<OCILobLocator *>(ociData_);
xml_type * xml = static_cast<xml_type *>(data_);
write_to_lob(lobp, xml->value);
}
break;
case x_longstring:
{
OCILobLocator * lobp = static_cast<OCILobLocator *>(ociData_);
long_string * ls = static_cast<long_string *>(data_);
write_to_lob(lobp, ls->value);
}
break;
case x_rowid:
case x_blob:
// nothing to do
......
......@@ -27,6 +27,11 @@ void standard_into_type::define(statement_impl & st, int & position)
backEnd_->define_by_pos(position, data_, type_);
}
void standard_into_type::pre_exec(int num)
{
backEnd_->pre_exec(num);
}
void standard_into_type::pre_fetch()
{
backEnd_->pre_fetch();
......@@ -73,6 +78,11 @@ void vector_into_type::define(statement_impl & st, int & position)
}
}
void vector_into_type::pre_exec(int num)
{
backEnd_->pre_exec(num);
}
void vector_into_type::pre_fetch()
{
backEnd_->pre_fetch();
......
......@@ -313,6 +313,8 @@ bool statement_impl::execute(bool withDataExchange)
num = static_cast<int>(bindSize);
}
}
pre_exec(num);
statement_backend::exec_fetch_result res = backEnd_->execute(num);
......@@ -530,6 +532,27 @@ void statement_impl::truncate_intos()
}
}
void statement_impl::pre_exec(int num)
{
std::size_t const isize = intos_.size();
for (std::size_t i = 0; i != isize; ++i)
{
intos_[i]->pre_exec(num);
}
std::size_t const ifrsize = intosForRow_.size();
for (std::size_t i = 0; i != ifrsize; ++i)
{
intosForRow_[i]->pre_exec(num);
}
std::size_t const usize = uses_.size();
for (std::size_t i = 0; i != usize; ++i)
{
uses_[i]->pre_exec(num);
}
}
void statement_impl::pre_fetch()
{
std::size_t const isize = intos_.size();
......
......@@ -116,6 +116,11 @@ void standard_use_type::dump_value(std::ostream& os) const
os << "<unknown>";
}
void standard_use_type::pre_exec(int num)
{
backEnd_->pre_exec(num);
}
void standard_use_type::pre_use()
{
// Handle IN direction of parameters of SQL statements and procedures
......@@ -188,6 +193,11 @@ void vector_use_type::dump_value(std::ostream& os) const
os << "<vector>";
}
void vector_use_type::pre_exec(int num)
{
backEnd_->pre_exec(num);
}
void vector_use_type::pre_use()
{
convert_to_base();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment