- 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();
/// 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();
/// Returns true if connection is transaction-capable.
@ -149,13 +138,6 @@ private:
void open();
/// 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="");
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)
{
_autoBind = val;

View File

@ -58,6 +58,7 @@ SessionImpl::SessionImpl(const std::string& connect,
_autoBind(autoBind),
_autoExtract(autoExtract)
{
setFeature("bulk", true);
open();
}
@ -103,10 +104,6 @@ void SessionImpl::open()
&SessionImpl::setDataTypeInfo,
&SessionImpl::dataTypeInfo);
addFeature("enforceCapability",
&SessionImpl::setEnforceCapability,
&SessionImpl::getEnforceCapability);
addFeature("autoCommit",
&SessionImpl::autoCommit,
&SessionImpl::isAutoCommit);
@ -123,13 +120,6 @@ void SessionImpl::open()
&SessionImpl::setMaxFieldSize,
&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);
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()
{
SQLUINTEGER info;

View File

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

View File

@ -81,12 +81,21 @@ public:
/// Storage type can be reconfigured at runtime both globally (for the
/// duration of the session) and locally (for a single statement execution only).
/// 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",
&AbstractSessionImpl<C>::setStorage,
&AbstractSessionImpl<C>::getStorage);
setProperty("storage", std::string("deque"));
addFeature("bulk",
&AbstractSessionImpl<C>::setBulk,
&AbstractSessionImpl<C>::getBulk);
setFeature("bulk", false);
}
~AbstractSessionImpl()
@ -172,6 +181,18 @@ public:
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:
void addFeature(const std::string& name, FeatureSetter setter, FeatureGetter getter)
/// Adds a feature to the map of supported features.
@ -216,6 +237,7 @@ private:
FeatureMap _features;
PropertyMap _properties;
std::string _storage;
bool _bulk;
};

View File

@ -89,10 +89,20 @@ public:
enum BulkType
{
BULK_UNDEFINED,
BULK_BINDING,
BULK_EXTRACTION,
BULK_FORBIDDEN
BULK_UNDEFINED,
/// Bulk mode not defined yet.
BULK_BINDING,
/// 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;
@ -336,6 +346,9 @@ private:
void setBulkExtraction(const Bulk& l);
/// Sets the bulk extraction flag and extraction limit.
void resetBulk();
/// Resets the bulk extraction and binding flag.
bool bulkBindingAllowed() const;
/// Returns true if statement can be set to bind data in bulk.
@ -353,6 +366,9 @@ private:
bool isBulkExtraction() const;
/// 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& operator = (const StatementImpl& stmt);
@ -532,6 +548,20 @@ inline bool StatementImpl::isBulkExtraction() const
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

View File

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