diff --git a/rdbms/OcciStmt.cpp b/rdbms/OcciStmt.cpp index caab6da43def77b7e21d9db58c512ffcab883679..b43403ae38bd227b337861aba59030c18688dae7 100644 --- a/rdbms/OcciStmt.cpp +++ b/rdbms/OcciStmt.cpp @@ -38,8 +38,7 @@ OcciStmt::OcciStmt( const std::string &sql, OcciConn &conn, oracle::occi::Statement *const stmt) : - Stmt(autocommitMode), - m_sql(sql), + Stmt(sql, autocommitMode), m_paramNameToIdx(sql), m_conn(conn), m_stmt(stmt) { @@ -60,11 +59,11 @@ OcciStmt::OcciStmt( } catch(exception::Exception &ex) { close(); throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + - sql.substr(0, c_maxSqlLenInExceptions) + ": " + ex.getMessage().str()); + getSqlForException() + ": " + ex.getMessage().str()); } catch(std::exception &se) { close(); throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + - sql.substr(0, c_maxSqlLenInExceptions) + ": " + se.what()); + getSqlForException() + ": " + se.what()); } } @@ -92,20 +91,13 @@ void OcciStmt::close() { } } catch(exception::Exception &ex) { throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + - getSql().substr(0, c_maxSqlLenInExceptions) + ": " + ex.getMessage().str()); + getSqlForException() + ": " + ex.getMessage().str()); } catch(std::exception &se) { throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + - getSql().substr(0, c_maxSqlLenInExceptions) + ": " + se.what()); + getSqlForException() + ": " + se.what()); } } -//------------------------------------------------------------------------------ -// getSql -//------------------------------------------------------------------------------ -const std::string &OcciStmt::getSql() const { - return m_sql; -} - //------------------------------------------------------------------------------ // bindUint64 //------------------------------------------------------------------------------ @@ -131,10 +123,10 @@ void OcciStmt::bindOptionalUint64(const std::string ¶mName, const optional<u } } catch(exception::Exception &ex) { throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + - getSql().substr(0, c_maxSqlLenInExceptions) + ": " + ex.getMessage().str()); + getSqlForException() + ": " + ex.getMessage().str()); } catch(std::exception &se) { throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + - getSql().substr(0, c_maxSqlLenInExceptions) + ": " + se.what()); + getSqlForException() + ": " + se.what()); } } @@ -167,10 +159,10 @@ void OcciStmt::bindOptionalString(const std::string ¶mName, const optional<s } } catch(exception::Exception &ex) { throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + - getSql().substr(0, c_maxSqlLenInExceptions) + ": " + ex.getMessage().str()); + getSqlForException() + ": " + ex.getMessage().str()); } catch(std::exception &se) { throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + - getSql().substr(0, c_maxSqlLenInExceptions) + ": " + se.what()); + getSqlForException() + ": " + se.what()); } } @@ -196,7 +188,7 @@ std::unique_ptr<Rset> OcciStmt::executeQuery() { } } throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + - getSql().substr(0, c_maxSqlLenInExceptions) + ": " + ex.what()); + getSqlForException() + ": " + ex.what()); } } @@ -222,7 +214,7 @@ void OcciStmt::executeNonQuery() { } } throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + - getSql().substr(0, c_maxSqlLenInExceptions) + ": " + ex.what()); + getSqlForException() + ": " + ex.what()); } } diff --git a/rdbms/OcciStmt.hpp b/rdbms/OcciStmt.hpp index 4dc223610afdc5a6d727ae039a1946232514b14e..66208ef221c78cfdb6a999ddfd921dc7c0a95a23 100644 --- a/rdbms/OcciStmt.hpp +++ b/rdbms/OcciStmt.hpp @@ -76,13 +76,6 @@ public: */ virtual void close() override; - /** - * Returns the SQL statement. - * - * @return The SQL statement. - */ - virtual const std::string &getSql() const override; - /** * Binds an SQL parameter. * @@ -165,11 +158,6 @@ private: */ std::mutex m_mutex; - /** - * The SQL statement. - */ - std::string m_sql; - /** * Map from SQL parameter name to parameter index. */ diff --git a/rdbms/SqliteConn.cpp b/rdbms/SqliteConn.cpp index 2af7829764e20fa58648186c9999be9732d44c09..246f13066de1750b9682cbeaf498aade25f2dfdb 100644 --- a/rdbms/SqliteConn.cpp +++ b/rdbms/SqliteConn.cpp @@ -89,8 +89,7 @@ std::unique_ptr<Stmt> SqliteConn::createStmt(const std::string &sql, const Stmt: return cta::make_unique<SqliteStmt>(autocommitMode , *this, sql); } catch(exception::Exception &ex) { - throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + sql + ": " + - ex.getMessage().str()); + throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str()); } } diff --git a/rdbms/SqliteStmt.cpp b/rdbms/SqliteStmt.cpp index 063643b10ffb9853c9bf8aae54e25fd87b9253ae..481e84e112707d9ddef635b36a3be3d4a571e969 100644 --- a/rdbms/SqliteStmt.cpp +++ b/rdbms/SqliteStmt.cpp @@ -39,9 +39,8 @@ SqliteStmt::SqliteStmt( const AutocommitMode autocommitMode, SqliteConn &conn, const std::string &sql): - Stmt(autocommitMode), + Stmt(sql, autocommitMode), m_conn(conn), - m_sql(sql), m_paramNameToIdx(sql), m_nbAffectedRows(0) { m_stmt = nullptr; @@ -49,7 +48,7 @@ SqliteStmt::SqliteStmt( const uint maxPrepareRetries = 20; // A worst case scenario of 2 seconds for(unsigned int i = 1; i <= maxPrepareRetries; i++) { - const int prepareRc = sqlite3_prepare_v2(m_conn.m_sqliteConn, sql.c_str(), nByte, &m_stmt, nullptr); + const int prepareRc = sqlite3_prepare_v2(m_conn.m_sqliteConn, m_sql.c_str(), nByte, &m_stmt, nullptr); if(SQLITE_OK == prepareRc) { break; @@ -66,14 +65,15 @@ SqliteStmt::SqliteStmt( // Try to prepare the statement again continue; } else { - throw exception::Exception(std::string(__FUNCTION__) + " failed: sqlite3_prepare_v2 returned SQLITE_LOCKED the" - " maximum number of " + std::to_string(i) + " times"); + throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + getSqlForException() + + ": sqlite3_prepare_v2 returned SQLITE_LOCKED the maximum number of " + std::to_string(i) + " times"); } } const std::string msg = sqlite3_errmsg(m_conn.m_sqliteConn); sqlite3_finalize(m_stmt); - throw exception::Exception(std::string(__FUNCTION__) + " failed: sqlite3_prepare_v2 failed: " + msg); + throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + getSqlForException() + + ": sqlite3_prepare_v2 failed: " + msg); } // m_stmt has been set so it is safe to call close() from now on @@ -94,12 +94,12 @@ SqliteStmt::SqliteStmt( } } catch(exception::Exception &ex) { close(); - throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + - sql.substr(0, c_maxSqlLenInExceptions) + ": " + ex.getMessage().str()); + throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + getSqlForException() + ": " + + ex.getMessage().str()); } catch(std::exception &se) { close(); - throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + - sql.substr(0, c_maxSqlLenInExceptions) + ": " + se.what()); + throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + getSqlForException() + ": " + + se.what()); } } @@ -132,18 +132,11 @@ void SqliteStmt::close() { sqlite3_stmt *SqliteStmt::get() const { if(nullptr == m_stmt) { throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + - getSql().substr(0, c_maxSqlLenInExceptions) + ": nullptr pointer"); + getSqlForException() + ": nullptr pointer"); } return m_stmt; } -//------------------------------------------------------------------------------ -// getSql -//------------------------------------------------------------------------------ -const std::string &SqliteStmt::getSql() const { - return m_sql; -} - //------------------------------------------------------------------------------ // bindUint64 //------------------------------------------------------------------------------ @@ -172,7 +165,7 @@ void SqliteStmt::bindOptionalUint64(const std::string ¶mName, const optional } } catch(exception::Exception &ex) { throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + - getSql().substr(0, c_maxSqlLenInExceptions) + ": " + ex.getMessage().str()); + getSqlForException() + ": " + ex.getMessage().str()); } } @@ -208,7 +201,7 @@ void SqliteStmt::bindOptionalString(const std::string ¶mName, const optional } } catch(exception::Exception &ex) { throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + - getSql().substr(0, c_maxSqlLenInExceptions) + ": " + ex.getMessage().str()); + getSqlForException() + ": " + ex.getMessage().str()); } } @@ -230,7 +223,7 @@ void SqliteStmt::executeNonQuery() { // Throw an exception if the call to sqlite3_step() failed if(SQLITE_DONE != stepRc && SQLITE_ROW != stepRc) { throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + - getSql().substr(0, c_maxSqlLenInExceptions) + ": " + Sqlite::rcToStr(stepRc)); + getSqlForException() + ": " + Sqlite::rcToStr(stepRc)); } m_nbAffectedRows = sqlite3_changes(m_conn.m_sqliteConn); @@ -238,7 +231,7 @@ void SqliteStmt::executeNonQuery() { // Throw an exception if the SQL statement returned a result set if(SQLITE_ROW == stepRc) { throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + - getSql().substr(0, c_maxSqlLenInExceptions) + ": The SQL statment returned a result set"); + getSqlForException() + ": The SQL statment returned a result set"); } } diff --git a/rdbms/SqliteStmt.hpp b/rdbms/SqliteStmt.hpp index c70758dfafcd3332bb486dbed878484a78c93cd1..845e0f6def013b696b6da1f59dc45ddf4f0494c4 100644 --- a/rdbms/SqliteStmt.hpp +++ b/rdbms/SqliteStmt.hpp @@ -71,13 +71,6 @@ public: */ sqlite3_stmt *get() const; - /** - * Returns the SQL statement. - * - * @return The SQL statement. - */ - virtual const std::string &getSql() const override; - /** * Binds an SQL parameter. * @@ -151,11 +144,6 @@ private: */ SqliteConn &m_conn; - /** - * The SQL statement. - */ - std::string m_sql; - /** * Map from SQL parameter name to parameter index. */ diff --git a/rdbms/Stmt.cpp b/rdbms/Stmt.cpp index 8d275f167e8497adda5c7c11634a002adf7a5275..6655ea0c529c23010cb74cff077890d7bcb5c7a9 100644 --- a/rdbms/Stmt.cpp +++ b/rdbms/Stmt.cpp @@ -24,7 +24,9 @@ namespace rdbms { //------------------------------------------------------------------------------ // constructor //------------------------------------------------------------------------------ -Stmt::Stmt(const AutocommitMode autocommitMode): m_autoCommitMode(autocommitMode) { +Stmt::Stmt(const std::string &sql, const AutocommitMode autocommitMode): + m_sql(sql), + m_autoCommitMode(autocommitMode) { } //------------------------------------------------------------------------------ @@ -33,6 +35,28 @@ Stmt::Stmt(const AutocommitMode autocommitMode): m_autoCommitMode(autocommitMode Stmt::~Stmt() throw() { } +//------------------------------------------------------------------------------ +// getSql +//------------------------------------------------------------------------------ +const std::string &Stmt::getSql() const { + return m_sql; +} + +//------------------------------------------------------------------------------ +// getSqlForException +//------------------------------------------------------------------------------ +std::string Stmt::getSqlForException() const { + if(m_sql.length() <= c_maxSqlLenInExceptions) { + return m_sql; + } else { + if(c_maxSqlLenInExceptions >= 3) { + return m_sql.substr(0, c_maxSqlLenInExceptions - 3) + "..."; + } else { + return std::string("..."). substr(0, c_maxSqlLenInExceptions); + } + } +} + //------------------------------------------------------------------------------ // bindBool //------------------------------------------------------------------------------ diff --git a/rdbms/Stmt.hpp b/rdbms/Stmt.hpp index 15dce6e9508f958c287052dafe807e65cd11d268..7683d3789cbe2fea20ef8ebbf3d8147eb9b913a9 100644 --- a/rdbms/Stmt.hpp +++ b/rdbms/Stmt.hpp @@ -45,9 +45,10 @@ public: /** * Constructor. * + * @param sql The SQL statement. * @param autocommitMode The autocommit mode of the statement. */ - Stmt(const AutocommitMode autocommitMode); + Stmt(const std::string &sql, const AutocommitMode autocommitMode); /** * Returns the autocommit mode of teh statement. @@ -91,7 +92,7 @@ public: * * @return The SQL statement. */ - virtual const std::string &getSql() const = 0; + const std::string &getSql() const; /** * Binds an SQL parameter. @@ -172,6 +173,11 @@ public: protected: + /** + * The SQL statement. + */ + std::string m_sql; + /** * The autocommit mode of the statement. */ @@ -182,6 +188,18 @@ protected: */ const uint32_t c_maxSqlLenInExceptions = 80; + /** + * Returns the SQL string to be used in an exception message. The string + * will be clipped at a maxmum of c_maxSqlLenInExceptions characters. If the + * string is actually clipped then the three last characters will be an + * replaced by an ellipsis of three dots, in other word "...". These 3 + * characters will indicate to the reader of the exception message that the + * SQL statement has been clipped. + * + * @return The SQL string to be used in an exception message. + */ + std::string getSqlForException() const; + }; // class Stmt } // namespace rdbms