- added session "bulk" feature

- removed ODBC driver capability check
This commit is contained in:
Aleksandar Fabijanic
2007-12-17 00:20:04 +00:00
parent c26de87394
commit 1c4e777ab3
6 changed files with 67 additions and 85 deletions

View File

@@ -93,17 +93,6 @@ public:
bool isTransaction(); bool isTransaction();
/// Returns true iff a transaction is in progress. /// Returns true iff a transaction is in progress.
void setEnforceCapability(const std::string&, bool val);
/// Configures session to enforce driver capability check
/// after connection.
/// If capability check is enforced and driver is not capable,
/// connection is terminated.
/// Since some drivers do not cooperate, the default behavior
/// is not checking capability.
bool getEnforceCapability(const std::string& name="");
/// Returns the driver capability check configuration value.
bool canTransact(); bool canTransact();
/// Returns true if connection is transaction-capable. /// Returns true if connection is transaction-capable.
@@ -149,13 +138,6 @@ private:
void open(); void open();
/// Opens a connection to the Database /// Opens a connection to the Database
bool isCapable(int function = 0);
/// Returns true if driver supports specified function, or if
/// specified function is zero, all required functions.
/// Called upon succesful connection if _enforceCapability is true.
/// This function code should be updated whenever a new
/// ODBC API call is introduced anywhere in ODBC data connector.
void checkError(SQLRETURN rc, const std::string& msg=""); void checkError(SQLRETURN rc, const std::string& msg="");
std::string _connect; std::string _connect;
@@ -222,18 +204,6 @@ inline Poco::Any SessionImpl::dataTypeInfo(const std::string& rName)
} }
inline void SessionImpl::setEnforceCapability(const std::string&, bool val)
{
_enforceCapability = val;
}
inline bool SessionImpl::getEnforceCapability(const std::string&)
{
return _enforceCapability;
}
inline void SessionImpl::autoBind(const std::string&, bool val) inline void SessionImpl::autoBind(const std::string&, bool val)
{ {
_autoBind = val; _autoBind = val;

View File

@@ -58,6 +58,7 @@ SessionImpl::SessionImpl(const std::string& connect,
_autoBind(autoBind), _autoBind(autoBind),
_autoExtract(autoExtract) _autoExtract(autoExtract)
{ {
setFeature("bulk", true);
open(); open();
} }
@@ -103,10 +104,6 @@ void SessionImpl::open()
&SessionImpl::setDataTypeInfo, &SessionImpl::setDataTypeInfo,
&SessionImpl::dataTypeInfo); &SessionImpl::dataTypeInfo);
addFeature("enforceCapability",
&SessionImpl::setEnforceCapability,
&SessionImpl::getEnforceCapability);
addFeature("autoCommit", addFeature("autoCommit",
&SessionImpl::autoCommit, &SessionImpl::autoCommit,
&SessionImpl::isAutoCommit); &SessionImpl::isAutoCommit);
@@ -123,13 +120,6 @@ void SessionImpl::open()
&SessionImpl::setMaxFieldSize, &SessionImpl::setMaxFieldSize,
&SessionImpl::getMaxFieldSize); &SessionImpl::getMaxFieldSize);
if (_enforceCapability && !isCapable())
{
close();
throw ODBCException("Connection closed "
"(capability enforcement required but not all required functions supported).");
}
SQLSetConnectAttr(_db, SQL_ATTR_QUIET_MODE, 0, 0); SQLSetConnectAttr(_db, SQL_ATTR_QUIET_MODE, 0, 0);
if (!canTransact()) autoCommit("", true); if (!canTransact()) autoCommit("", true);
@@ -212,45 +202,6 @@ void SessionImpl::close()
} }
bool SessionImpl::isCapable(int function)
{
SQLUSMALLINT exists[FUNCTIONS] = {0};
if (Utility::isError(SQLGetFunctions(_db, SQL_API_ODBC3_ALL_FUNCTIONS, exists)))
{
throw ConnectionException(_db,
"SQLGetFunctions(SQL_API_ODBC3_ALL_FUNCTIONS)");
}
if (0 != function) return 0 != exists[function];
else return
exists[SQL_API_SQLBINDPARAMETER] &&
exists[SQL_API_SQLBINDCOL] &&
exists[SQL_API_SQLGETDATA] &&
exists[SQL_API_SQLPUTDATA] &&
exists[SQL_API_SQLPARAMDATA] &&
exists[SQL_API_SQLDESCRIBECOL] &&
exists[SQL_API_SQLDESCRIBEPARAM] &&
exists[SQL_API_SQLGETINFO] &&
exists[SQL_API_SQLGETTYPEINFO] &&
exists[SQL_API_SQLGETDIAGREC] &&
exists[SQL_API_SQLGETDIAGFIELD] &&
exists[SQL_API_SQLPREPARE] &&
exists[SQL_API_SQLEXECUTE] &&
exists[SQL_API_SQLEXECDIRECT] &&
exists[SQL_API_SQLFETCH] &&
exists[SQL_API_SQLNUMRESULTCOLS] &&
exists[SQL_API_SQLALLOCHANDLE] &&
exists[SQL_API_SQLFREEHANDLE] &&
exists[SQL_API_SQLCLOSECURSOR] &&
exists[SQL_API_SQLSETCONNECTATTR] &&
exists[SQL_API_SQLSETSTMTATTR] &&
exists[SQL_API_SQLENDTRAN] &&
exists[SQL_API_SQLNATIVESQL] &&
exists[SQL_API_SQLCOLATTRIBUTE];
}
int SessionImpl::maxStatementLength() int SessionImpl::maxStatementLength()
{ {
SQLUINTEGER info; SQLUINTEGER info;

View File

@@ -1502,7 +1502,7 @@ void SQLExecutor::doBulk(Poco::UInt32 size)
try try
{ {
session() << "INSERT INTO MiscTest VALUES (?,?,?,?,?,?)", session() << "INSERT INTO MiscTest VALUES (?,?,?,?,?,?)",
use(strings, bulk), use(strings, bulk),
use(blobs, bulk), use(blobs, bulk),
use(ints, bulk), use(ints, bulk),

View File

@@ -81,12 +81,21 @@ public:
/// Storage type can be reconfigured at runtime both globally (for the /// Storage type can be reconfigured at runtime both globally (for the
/// duration of the session) and locally (for a single statement execution only). /// duration of the session) and locally (for a single statement execution only).
/// See StatementImpl for details on how this property is used at runtime. /// See StatementImpl for details on how this property is used at runtime.
/// Bulk feature determines whether the session is capable of bulk operations.
/// Connectors that are capable of it must set this feature prior to attempting
/// bulk operations.
{ {
addProperty("storage", addProperty("storage",
&AbstractSessionImpl<C>::setStorage, &AbstractSessionImpl<C>::setStorage,
&AbstractSessionImpl<C>::getStorage); &AbstractSessionImpl<C>::getStorage);
setProperty("storage", std::string("deque")); setProperty("storage", std::string("deque"));
addFeature("bulk",
&AbstractSessionImpl<C>::setBulk,
&AbstractSessionImpl<C>::getBulk);
setFeature("bulk", false);
} }
~AbstractSessionImpl() ~AbstractSessionImpl()
@@ -172,6 +181,18 @@ public:
return _storage; return _storage;
} }
void setBulk(const std::string& name, bool bulk)
/// Sets the storage type.
{
_bulk = bulk;
}
bool getBulk(const std::string& name="")
/// Returns the storage type
{
return _bulk;
}
protected: protected:
void addFeature(const std::string& name, FeatureSetter setter, FeatureGetter getter) void addFeature(const std::string& name, FeatureSetter setter, FeatureGetter getter)
/// Adds a feature to the map of supported features. /// Adds a feature to the map of supported features.
@@ -216,6 +237,7 @@ private:
FeatureMap _features; FeatureMap _features;
PropertyMap _properties; PropertyMap _properties;
std::string _storage; std::string _storage;
bool _bulk;
}; };

View File

@@ -89,10 +89,20 @@ public:
enum BulkType enum BulkType
{ {
BULK_UNDEFINED, BULK_UNDEFINED,
BULK_BINDING, /// Bulk mode not defined yet.
BULK_EXTRACTION, BULK_BINDING,
BULK_FORBIDDEN /// Binding in bulk mode.
/// If extraction is present in the same statement,
/// it must also be bulk.
BULK_EXTRACTION,
/// Extraction in bulk mode.
/// If binding is present in the same statement,
/// it must also be bulk.
BULK_FORBIDDEN,
/// Bulk forbidden.
/// Happens when the statement has already been
/// configured as non-bulk.
}; };
static const std::string DEQUE; static const std::string DEQUE;
@@ -336,6 +346,9 @@ private:
void setBulkExtraction(const Bulk& l); void setBulkExtraction(const Bulk& l);
/// Sets the bulk extraction flag and extraction limit. /// Sets the bulk extraction flag and extraction limit.
void resetBulk();
/// Resets the bulk extraction and binding flag.
bool bulkBindingAllowed() const; bool bulkBindingAllowed() const;
/// Returns true if statement can be set to bind data in bulk. /// Returns true if statement can be set to bind data in bulk.
@@ -353,6 +366,9 @@ private:
bool isBulkExtraction() const; bool isBulkExtraction() const;
/// Returns true if statement is set to extract data in bulk. /// Returns true if statement is set to extract data in bulk.
bool isBulkSupported() const;
/// Returns true if connector and session support bulk operation.
StatementImpl(const StatementImpl& stmt); StatementImpl(const StatementImpl& stmt);
StatementImpl& operator = (const StatementImpl& stmt); StatementImpl& operator = (const StatementImpl& stmt);
@@ -532,6 +548,20 @@ inline bool StatementImpl::isBulkExtraction() const
return BULK_EXTRACTION == _bulkExtraction; return BULK_EXTRACTION == _bulkExtraction;
} }
inline void StatementImpl::resetBulk()
{
_bulkExtraction = BULK_UNDEFINED;
_bulkBinding = BULK_UNDEFINED;\
setExtractionLimit(Limit(Limit::LIMIT_UNLIMITED, false, false));
}
inline bool StatementImpl::isBulkSupported() const
{
return _rSession.getFeature("bulk");
}
} } // namespace Poco::Data } } // namespace Poco::Data

View File

@@ -201,6 +201,9 @@ Statement& Statement::operator , (AbstractBinding* pBind)
{ {
if (pBind->isBulk()) if (pBind->isBulk())
{ {
if (!_pImpl->isBulkSupported())
throw InvalidAccessException("Bulk not supported by this session.");
if(_pImpl->bulkBindingAllowed()) if(_pImpl->bulkBindingAllowed())
_pImpl->setBulkBinding(); _pImpl->setBulkBinding();
else else
@@ -217,6 +220,9 @@ Statement& Statement::operator , (AbstractExtraction* pExtract)
{ {
if (pExtract->isBulk()) if (pExtract->isBulk())
{ {
if (!_pImpl->isBulkSupported())
throw InvalidAccessException("Bulk not supported by this session.");
if(_pImpl->bulkExtractionAllowed()) if(_pImpl->bulkExtractionAllowed())
{ {
Bulk b(pExtract->getLimit()); Bulk b(pExtract->getLimit());
@@ -255,6 +261,9 @@ Statement& Statement::operator , (const Range& extrRange)
Statement& Statement::operator , (const Bulk& bulk) Statement& Statement::operator , (const Bulk& bulk)
{ {
if (!_pImpl->isBulkSupported())
throw InvalidAccessException("Bulk not supported by this session.");
if (0 == _pImpl->extractions().size() && if (0 == _pImpl->extractions().size() &&
0 == _pImpl->bindings().size() && 0 == _pImpl->bindings().size() &&
_pImpl->bulkExtractionAllowed() && _pImpl->bulkExtractionAllowed() &&