From 89821afa0e8346df6772a479754c9a1947300b57 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 19 Sep 2014 14:43:55 +0200 Subject: Call tracer::prepare() before actually preparing statement This way we give the user the ability to see an invalid statement that would cause the preparation step to fail. --- odb/sqlite/statement.cxx | 75 +++++++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/odb/sqlite/statement.cxx b/odb/sqlite/statement.cxx index 62103fc..d56f45f 100644 --- a/odb/sqlite/statement.cxx +++ b/odb/sqlite/statement.cxx @@ -24,21 +24,21 @@ namespace odb statement:: ~statement () { - if (empty ()) - return; - + if (stmt_ != 0) { - odb::tracer* t; - if ((t = conn_.transaction_tracer ()) || - (t = conn_.tracer ()) || - (t = conn_.database ().tracer ())) - t->deallocate (conn_, *this); - } + { + odb::tracer* t; + if ((t = conn_.transaction_tracer ()) || + (t = conn_.tracer ()) || + (t = conn_.database ().tracer ())) + t->deallocate (conn_, *this); + } - if (next_ != this) - list_remove (); + if (next_ != this) + list_remove (); - stmt_.reset (); + stmt_.reset (); + } } void statement:: @@ -48,6 +48,10 @@ namespace odb const binding* proc, bool optimize) { + active_ = false; + prev_ = 0; + next_ = this; + string tmp; if (proc != 0) { @@ -81,11 +85,34 @@ namespace odb text_size = tmp.size (); } +#if SQLITE_VERSION_NUMBER < 3005003 + text_.assign (text, text_size); +#endif + // Empty statement. // if (*text == '\0') return; + { + odb::tracer* t; + if ((t = conn_.transaction_tracer ()) || + (t = conn_.tracer ()) || + (t = conn_.database ().tracer ())) + { + // Temporarily store the statement text in prev_ so that + // text() which may be called by the tracer can access it. + // +#if SQLITE_VERSION_NUMBER >= 3005003 + prev_ = reinterpret_cast (const_cast (text)); +#endif + t->prepare (conn_, *this); +#if SQLITE_VERSION_NUMBER >= 3005003 + prev_ = 0; +#endif + } + } + int e; sqlite3_stmt* stmt (0); @@ -113,23 +140,6 @@ namespace odb translate_error (e, conn_); stmt_.reset (stmt); - -#if SQLITE_VERSION_NUMBER < 3005003 - text_.assign (text, text_size); -#endif - - active_ = false; - - prev_ = 0; - next_ = this; - - { - odb::tracer* t; - if ((t = conn_.transaction_tracer ()) || - (t = conn_.tracer ()) || - (t = conn_.database ().tracer ())) - t->prepare (conn_, *this); - } } const char* statement:: @@ -138,7 +148,12 @@ namespace odb // sqlite3_sql() is only available since 3.5.3. // #if SQLITE_VERSION_NUMBER >= 3005003 - return sqlite3_sql (stmt_); + if (stmt_ == 0) + // See init() above for details on what's going on here. + // + return prev_ != 0 ? reinterpret_cast (prev_) : ""; + else + return sqlite3_sql (stmt_); #else return text_.c_str (); #endif -- cgit v1.1