some compilation refactoring

This commit is contained in:
Aleksandar Fabijanic 2008-01-22 02:05:04 +00:00
parent 277101a054
commit bc8f7e8680
10 changed files with 69 additions and 59 deletions

View File

@ -1,7 +1,7 @@
# #
# Makefile # Makefile
# #
# $Id: //poco/Main/DataConnectors/ODBC/Makefile#2 $ # $Id: //poco/Main/Data/ODBC/Makefile#2 $
# #
# Makefile for Poco ODBC # Makefile for Poco ODBC
# #

View File

@ -94,12 +94,12 @@ protected:
bool canBind() const; bool canBind() const;
/// Returns true if a valid statement is set and we can bind. /// Returns true if a valid statement is set and we can bind.
bool compileImpl(); bool canCompile() const;
/// Returns true if another compile is possible.
void compileImpl();
/// Compiles the statement, doesn't bind yet. /// Compiles the statement, doesn't bind yet.
/// Does nothing if the statement has already been compiled. /// Does nothing if the statement has already been compiled.
/// In this implementation, batch statements are compiled in a single step.
/// Therefore, this function always return false indicating no need for
/// subsequent compilation.
void bindImpl(); void bindImpl();
/// Binds all parameters and executes the statement. /// Binds all parameters and executes the statement.
@ -174,7 +174,7 @@ private:
ColumnPtrVecVec _columnPtrs; ColumnPtrVecVec _columnPtrs;
bool _prepared; bool _prepared;
mutable Poco::UInt32 _affectedRowCount; mutable Poco::UInt32 _affectedRowCount;
bool _compiled; bool _canCompile;
}; };
@ -216,6 +216,12 @@ inline bool ODBCStatementImpl::nextRowReady() const
} }
inline bool ODBCStatementImpl::canCompile() const
{
return _canCompile;
}
} } } // namespace Poco::Data::ODBC } } } // namespace Poco::Data::ODBC

View File

@ -66,7 +66,7 @@ ODBCStatementImpl::ODBCStatementImpl(SessionImpl& rSession):
_nextResponse(0), _nextResponse(0),
_prepared(false), _prepared(false),
_affectedRowCount(0), _affectedRowCount(0),
_compiled(false) _canCompile(true)
{ {
} }
@ -84,11 +84,10 @@ ODBCStatementImpl::~ODBCStatementImpl()
} }
bool ODBCStatementImpl::compileImpl() void ODBCStatementImpl::compileImpl()
{ {
if (_compiled) return false; if (!_canCompile) return;
clear();
_stepCalled = false; _stepCalled = false;
_nextResponse = 0; _nextResponse = 0;
@ -121,8 +120,7 @@ bool ODBCStatementImpl::compileImpl()
makeInternalExtractors(); makeInternalExtractors();
doPrepare(); doPrepare();
_compiled = true; _canCompile = false;
return false;
} }

View File

@ -602,7 +602,7 @@ void ODBCOracleTest::testMultipleResults()
*_pSession << sql, now; *_pSession << sql, now;
session().setFeature("autoBind", bindValue(i)); session().setFeature("autoBind", bindValue(i));
session().setFeature("autoExtract", bindValue(i+1)); session().setFeature("autoExtract", bindValue(i+1));
executor().multipleResults("{call multiResultsProcedure(?, ?)}"); executor().multipleResults("{call multiResultsProcedure(?, ?, ?)}");
i += 2; i += 2;
} }

View File

@ -95,15 +95,16 @@ protected:
bool canBind() const; bool canBind() const;
/// Returns true if a valid statement is set and we can bind. /// Returns true if a valid statement is set and we can bind.
bool compileImpl(); bool canCompile() const;
/// Returns true if statement can compile.
void compileImpl();
/// Compiles the statement, doesn't bind yet. /// Compiles the statement, doesn't bind yet.
/// Returns true if the statement was succesfully compiled. /// Returns true if the statement was succesfully compiled.
/// The way SQLite handles batches of statmeents is by compiling /// The way SQLite handles batches of statmeents is by compiling
/// one at a time and returning a pointer to the next one. /// one at a time and returning a pointer to the next one.
/// The remainder of the statement is remebered in a string /// The remainder of the statement is kept in a string
/// buffer pointed to by _pLeftover member. Non-zero _pLeftover /// buffer pointed to by _pLeftover member.
/// pointing to an empty string means no more statements left
/// to compile.
void bindImpl(); void bindImpl();
/// Binds parameters /// Binds parameters
@ -139,6 +140,7 @@ private:
BindIt _bindBegin; BindIt _bindBegin;
bool _canBind; bool _canBind;
bool _isExtracted; bool _isExtracted;
bool _canCompile;
}; };
@ -163,6 +165,12 @@ inline bool SQLiteStatementImpl::canBind() const
} }
inline bool SQLiteStatementImpl::canCompile() const
{
return _canCompile;
}
} } } // namespace Poco::Data::SQLite } } } // namespace Poco::Data::SQLite

View File

@ -56,7 +56,8 @@ SQLiteStatementImpl::SQLiteStatementImpl(Poco::Data::SessionImpl& rSession, sqli
_nextResponse(0), _nextResponse(0),
_affectedRowCount(0), _affectedRowCount(0),
_canBind(false), _canBind(false),
_isExtracted(false) _isExtracted(false),
_canCompile(true)
{ {
_columns.resize(1); _columns.resize(1);
} }
@ -68,15 +69,9 @@ SQLiteStatementImpl::~SQLiteStatementImpl()
} }
bool SQLiteStatementImpl::compileImpl() void SQLiteStatementImpl::compileImpl()
{ {
if (_pLeftover && _pLeftover->empty()) if (!_pLeftover) _bindBegin = bindings().begin();
{
_pLeftover = 0;
return false;
}
else if (!_pLeftover)
_bindBegin = bindings().begin();
std::string statement(toString()); std::string statement(toString());
sqlite3_stmt* pStmt = 0; sqlite3_stmt* pStmt = 0;
@ -119,10 +114,15 @@ bool SQLiteStatementImpl::compileImpl()
//For last statement in a batch (or a single statement), pLeftover == "", so the next call //For last statement in a batch (or a single statement), pLeftover == "", so the next call
// to compileImpl() shall return false immediately when there are no more statements left. // to compileImpl() shall return false immediately when there are no more statements left.
std::string leftOver(pLeftover); std::string leftOver(pLeftover);
trimInPlace(leftOver);
clear(); clear();
_pStmt = pStmt; _pStmt = pStmt;
_pLeftover = new std::string(leftOver); if (!leftOver.empty())
trimInPlace(*_pLeftover); {
_pLeftover = new std::string(leftOver);
_canCompile = true;
}
else _canCompile = false;
_pBinder = new Binder(_pStmt); _pBinder = new Binder(_pStmt);
_pExtractor = new Extractor(_pStmt); _pExtractor = new Extractor(_pStmt);
@ -150,8 +150,6 @@ bool SQLiteStatementImpl::compileImpl()
_columns[curDataSet].push_back(mc); _columns[curDataSet].push_back(mc);
} }
} }
return true;
} }
@ -226,7 +224,6 @@ void SQLiteStatementImpl::clear()
_pStmt=0; _pStmt=0;
} }
_pLeftover = 0; _pLeftover = 0;
_canBind = false;
} }

View File

@ -198,18 +198,13 @@ protected:
/// Expects the statement to be compiled and bound. /// Expects the statement to be compiled and bound.
virtual bool canBind() const = 0; virtual bool canBind() const = 0;
/// Returns if another bind is possible. /// Returns true if another bind is possible.
virtual bool compileImpl() = 0; virtual bool canCompile() const = 0;
/// Returns true if another compile is possible.
virtual void compileImpl() = 0;
/// Compiles the statement, doesn't bind yet. /// Compiles the statement, doesn't bind yet.
/// Returns true if compilation was succesful.
/// This function will be called at least twice, so
/// for connectors requiring one call only, this function
/// should always return false and internall protect itself
/// against multiple calls.
/// This design is to conform to the connectors (e.g. SQLite)
/// that handle batches of statements as a sequence of independent
/// statements, each with its own prepare/bind/execute operations.
virtual void bindImpl() = 0; virtual void bindImpl() = 0;
/// Binds parameters. /// Binds parameters.
@ -304,9 +299,8 @@ protected:
/// Returns the extraction limit. /// Returns the extraction limit.
private: private:
bool compile(); void compile();
/// Compiles the statement, if not yet compiled. /// Compiles the statement.
/// Returns true if more compile calls are needed.
void bind(); void bind();
/// Binds the statement, if not yet bound. /// Binds the statement, if not yet bound.

View File

@ -87,14 +87,14 @@ Poco::UInt32 StatementImpl::execute()
if (_lowerLimit > _extrLimit.value()) if (_lowerLimit > _extrLimit.value())
throw LimitException("Illegal Statement state. Upper limit must not be smaller than the lower limit."); throw LimitException("Illegal Statement state. Upper limit must not be smaller than the lower limit.");
compile();
do do
{ {
compile();
if (_extrLimit.value() == Limit::LIMIT_UNLIMITED) if (_extrLimit.value() == Limit::LIMIT_UNLIMITED)
lim += executeWithoutLimit(); lim += executeWithoutLimit();
else else
lim += executeWithLimit(); lim += executeWithLimit();
} while (compile()); } while (canCompile());
if (_extrLimit.value() == Limit::LIMIT_UNLIMITED) if (_extrLimit.value() == Limit::LIMIT_UNLIMITED)
_state = ST_DONE; _state = ST_DONE;
@ -145,15 +145,13 @@ Poco::UInt32 StatementImpl::executeWithoutLimit()
} }
bool StatementImpl::compile() void StatementImpl::compile()
{ {
bool retval = false;
if (_state == ST_INITIALIZED || if (_state == ST_INITIALIZED ||
_state == ST_RESET || _state == ST_RESET ||
_state == ST_BOUND) _state == ST_BOUND)
{ {
retval = compileImpl(); compileImpl();
_state = ST_COMPILED; _state = ST_COMPILED;
if (!extractions().size() && !isStoredProcedure()) if (!extractions().size() && !isStoredProcedure())
@ -165,8 +163,6 @@ bool StatementImpl::compile()
fixupExtraction(); fixupExtraction();
fixupBinding(); fixupBinding();
} }
return retval;
} }

View File

@ -40,7 +40,8 @@ namespace Test {
TestStatementImpl::TestStatementImpl(SessionImpl& rSession): TestStatementImpl::TestStatementImpl(SessionImpl& rSession):
Poco::Data::StatementImpl(rSession) Poco::Data::StatementImpl(rSession),
_compiled(false)
{ {
} }
@ -50,13 +51,13 @@ TestStatementImpl::~TestStatementImpl()
} }
bool TestStatementImpl::compileImpl() void TestStatementImpl::compileImpl()
{ {
// prepare binding // prepare binding
_ptrBinder = new Binder; _ptrBinder = new Binder;
_ptrExtractor = new Extractor; _ptrExtractor = new Extractor;
_ptrPrepare = new Preparation; _ptrPrepare = new Preparation;
return false; _compiled = true;
} }

View File

@ -83,7 +83,10 @@ protected:
bool canBind() const; bool canBind() const;
/// Returns true if a valid statement is set and we can bind. /// Returns true if a valid statement is set and we can bind.
bool compileImpl(); bool canCompile() const;
/// Returns true if statement was not compiled.
void compileImpl();
/// Compiles the statement, doesn't bind yet /// Compiles the statement, doesn't bind yet
void bindImpl(); void bindImpl();
@ -96,9 +99,10 @@ protected:
/// Returns the concrete binder used by the statement. /// Returns the concrete binder used by the statement.
private: private:
Poco::SharedPtr<Binder> _ptrBinder; Poco::SharedPtr<Binder> _ptrBinder;
Poco::SharedPtr<Extractor> _ptrExtractor; Poco::SharedPtr<Extractor> _ptrExtractor;
Poco::SharedPtr<Preparation> _ptrPrepare; Poco::SharedPtr<Preparation> _ptrPrepare;
bool _compiled;
}; };
@ -123,6 +127,12 @@ inline Poco::UInt32 TestStatementImpl::affectedRowCount() const
} }
inline bool TestStatementImpl::canCompile() const
{
return !_compiled;
}
} } } // namespace Poco::Data::Test } } } // namespace Poco::Data::Test