Commit 48714abc authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen
Browse files

sqlite: Statement: Move non template definitions into the source file

This saves a bit of space in the resulting binary (about 30KB)
parent a52b9ebc
......@@ -55,6 +55,82 @@ std::string Tools::sanitizePattern( const std::string& pattern )
return res;
}
Statement::Statement(Connection::Handle dbConnection, const std::string& req)
: m_stmt( nullptr, [](sqlite3_stmt* stmt) {
sqlite3_clear_bindings( stmt );
sqlite3_reset( stmt );
})
, m_dbConn( dbConnection )
, m_bindIdx( 0 )
, m_isCommit( false )
{
std::lock_guard<compat::Mutex> lock( StatementsCacheLock );
auto& connMap = StatementsCache[ dbConnection ];
auto it = connMap.find( req );
if ( it == end( connMap ) )
{
sqlite3_stmt* stmt;
int res = sqlite3_prepare_v2( dbConnection, req.c_str(),
req.size() + 1, &stmt, nullptr );
if ( res != SQLITE_OK )
{
errors::mapToException( req.c_str(), sqlite3_errmsg( dbConnection ),
res );
}
m_stmt.reset( stmt );
connMap.emplace( req, CachedStmtPtr( stmt, &sqlite3_finalize ) );
}
else
{
m_stmt.reset( it->second.get() );
}
if ( req == "COMMIT" )
m_isCommit = true;
}
Statement::Statement( const std::string& req )
: Statement( Connection::Context::handle(), req )
{
}
Row Statement::row()
{
auto maxRetries = 10;
while ( true )
{
auto extRes = sqlite3_step( m_stmt.get() );
auto res = extRes & 0xFF;
if ( res == SQLITE_ROW )
return Row( m_stmt.get() );
else if ( res == SQLITE_DONE )
return Row{};
else if ( ( Transaction::isInProgress() == false ||
m_isCommit == true ) &&
errors::isInnocuous( res ) && maxRetries-- > 0 )
continue;
auto errMsg = sqlite3_errmsg( m_dbConn );
const char* reqStr = sqlite3_sql( m_stmt.get() );
if ( reqStr == nullptr )
reqStr = "<unknown request>";
errors::mapToException( reqStr, errMsg, extRes );
assert( !"unreachable" );
}
}
void Statement::FlushStatementCache()
{
std::lock_guard<compat::Mutex> lock( StatementsCacheLock );
StatementsCache.clear();
}
void Statement::FlushConnectionStatementCache( Connection::Handle h )
{
std::lock_guard<compat::Mutex> lock( StatementsCacheLock );
auto it = StatementsCache.find( h );
if ( it != end( StatementsCache ) )
StatementsCache.erase( it );
}
}
}
......@@ -144,43 +144,9 @@ private:
class Statement
{
public:
Statement( Connection::Handle dbConnection, const std::string& req )
: m_stmt( nullptr, [](sqlite3_stmt* stmt) {
sqlite3_clear_bindings( stmt );
sqlite3_reset( stmt );
})
, m_dbConn( dbConnection )
, m_bindIdx( 0 )
, m_isCommit( false )
{
std::lock_guard<compat::Mutex> lock( StatementsCacheLock );
auto& connMap = StatementsCache[ dbConnection ];
auto it = connMap.find( req );
if ( it == end( connMap ) )
{
sqlite3_stmt* stmt;
int res = sqlite3_prepare_v2( dbConnection, req.c_str(),
req.size() + 1, &stmt, nullptr );
if ( res != SQLITE_OK )
{
errors::mapToException( req.c_str(), sqlite3_errmsg( dbConnection ),
res );
}
m_stmt.reset( stmt );
connMap.emplace( req, CachedStmtPtr( stmt, &sqlite3_finalize ) );
}
else
{
m_stmt.reset( it->second.get() );
}
if ( req == "COMMIT" )
m_isCommit = true;
}
Statement( Connection::Handle dbConnection, const std::string& req );
Statement( const std::string& req )
: Statement( Connection::Context::handle(), req )
{
}
Statement( const std::string& req );
template <typename... Args>
void execute(Args&&... args)
......@@ -189,43 +155,11 @@ public:
(void)std::initializer_list<bool>{ _bind( std::forward<Args>( args ) )... };
}
Row row()
{
auto maxRetries = 10;
while ( true )
{
auto extRes = sqlite3_step( m_stmt.get() );
auto res = extRes & 0xFF;
if ( res == SQLITE_ROW )
return Row( m_stmt.get() );
else if ( res == SQLITE_DONE )
return Row{};
else if ( ( Transaction::isInProgress() == false ||
m_isCommit == true ) &&
errors::isInnocuous( res ) && maxRetries-- > 0 )
continue;
auto errMsg = sqlite3_errmsg( m_dbConn );
const char* reqStr = sqlite3_sql( m_stmt.get() );
if ( reqStr == nullptr )
reqStr = "<unknown request>";
errors::mapToException( reqStr, errMsg, extRes );
assert( !"unreachable" );
}
}
Row row();
static void FlushStatementCache()
{
std::lock_guard<compat::Mutex> lock( StatementsCacheLock );
StatementsCache.clear();
}
static void FlushStatementCache();
static void FlushConnectionStatementCache( Connection::Handle h )
{
std::lock_guard<compat::Mutex> lock( StatementsCacheLock );
auto it = StatementsCache.find( h );
if ( it != end( StatementsCache ) )
StatementsCache.erase( it );
}
static void FlushConnectionStatementCache( Connection::Handle h );
private:
template <typename T>
......
Supports Markdown
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