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
#
# $Id: //poco/Main/DataConnectors/ODBC/Makefile#2 $
# $Id: //poco/Main/Data/ODBC/Makefile#2 $
#
# Makefile for Poco ODBC
#

View File

@ -94,12 +94,12 @@ protected:
bool canBind() const;
/// 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.
/// 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();
/// Binds all parameters and executes the statement.
@ -174,7 +174,7 @@ private:
ColumnPtrVecVec _columnPtrs;
bool _prepared;
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

View File

@ -66,7 +66,7 @@ ODBCStatementImpl::ODBCStatementImpl(SessionImpl& rSession):
_nextResponse(0),
_prepared(false),
_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;
_nextResponse = 0;
@ -121,8 +120,7 @@ bool ODBCStatementImpl::compileImpl()
makeInternalExtractors();
doPrepare();
_compiled = true;
return false;
_canCompile = false;
}

View File

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

View File

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

View File

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

View File

@ -198,18 +198,13 @@ protected:
/// Expects the statement to be compiled and bound.
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.
/// 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;
/// Binds parameters.
@ -304,9 +299,8 @@ protected:
/// Returns the extraction limit.
private:
bool compile();
/// Compiles the statement, if not yet compiled.
/// Returns true if more compile calls are needed.
void compile();
/// Compiles the statement.
void bind();
/// Binds the statement, if not yet bound.

View File

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

View File

@ -40,7 +40,8 @@ namespace Test {
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
_ptrBinder = new Binder;
_ptrExtractor = new Extractor;
_ptrPrepare = new Preparation;
return false;
_compiled = true;
}

View File

@ -83,7 +83,10 @@ protected:
bool canBind() const;
/// 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
void bindImpl();
@ -96,9 +99,10 @@ protected:
/// Returns the concrete binder used by the statement.
private:
Poco::SharedPtr<Binder> _ptrBinder;
Poco::SharedPtr<Extractor> _ptrExtractor;
Poco::SharedPtr<Binder> _ptrBinder;
Poco::SharedPtr<Extractor> _ptrExtractor;
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