mirror of
https://github.com/cuberite/SQLiteCpp.git
synced 2025-08-04 09:46:02 -04:00
Merge branch 'try_execute'
This commit is contained in:
commit
473a307b6d
@ -75,9 +75,12 @@ public:
|
|||||||
/// Finalize and unregister the SQL query from the SQLite Database Connection.
|
/// Finalize and unregister the SQL query from the SQLite Database Connection.
|
||||||
~Statement();
|
~Statement();
|
||||||
|
|
||||||
/// Reset the statement to make it ready for a new execution.
|
/// Reset the statement to make it ready for a new execution. Throws an exception on error.
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
/// Reset the statement. Returns the sqlite result code instead of throwing an exception on error.
|
||||||
|
int tryReset() noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Clears away all the bindings of a prepared statement.
|
* @brief Clears away all the bindings of a prepared statement.
|
||||||
*
|
*
|
||||||
@ -335,6 +338,7 @@ public:
|
|||||||
* thru the getColumn() method
|
* thru the getColumn() method
|
||||||
*
|
*
|
||||||
* @see exec() execute a one-step prepared statement with no expected result
|
* @see exec() execute a one-step prepared statement with no expected result
|
||||||
|
* @see tryExecuteStep() try to execute a step of the prepared query to fetch one row of results, returning the sqlite result code.
|
||||||
* @see Database::exec() is a shortcut to execute one or multiple statements without results
|
* @see Database::exec() is a shortcut to execute one or multiple statements without results
|
||||||
*
|
*
|
||||||
* @return - true (SQLITE_ROW) if there is another row ready : you can call getColumn(N) to get it
|
* @return - true (SQLITE_ROW) if there is another row ready : you can call getColumn(N) to get it
|
||||||
@ -346,6 +350,19 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool executeStep();
|
bool executeStep();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Try to execute a step of the prepared query to fetch one row of results, returning the sqlite result code.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @see exec() execute a one-step prepared statement with no expected result
|
||||||
|
* @see executeStep() execute a step of the prepared query to fetch one row of results
|
||||||
|
* @see Database::exec() is a shortcut to execute one or multiple statements without results
|
||||||
|
*
|
||||||
|
* @return the sqlite result code.
|
||||||
|
*/
|
||||||
|
int tryExecuteStep() noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Execute a one-step query with no expected result.
|
* @brief Execute a one-step query with no expected result.
|
||||||
*
|
*
|
||||||
@ -359,6 +376,7 @@ public:
|
|||||||
* - reusing it allows for better performances (efficient for multiple insertion).
|
* - reusing it allows for better performances (efficient for multiple insertion).
|
||||||
*
|
*
|
||||||
* @see executeStep() execute a step of the prepared query to fetch one row of results
|
* @see executeStep() execute a step of the prepared query to fetch one row of results
|
||||||
|
* @see tryExecuteStep() try to execute a step of the prepared query to fetch one row of results, returning the sqlite result code.
|
||||||
* @see Database::exec() is a shortcut to execute one or multiple statements without results
|
* @see Database::exec() is a shortcut to execute one or multiple statements without results
|
||||||
*
|
*
|
||||||
* @return number of row modified by this SQL statement (INSERT, UPDATE or DELETE)
|
* @return number of row modified by this SQL statement (INSERT, UPDATE or DELETE)
|
||||||
@ -610,7 +628,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check if there is a row of result returnes by executeStep(), else throw a SQLite::Exception.
|
* @brief Check if there is a row of result returned by executeStep(), else throw a SQLite::Exception.
|
||||||
*/
|
*/
|
||||||
inline void checkRow() const
|
inline void checkRow() const
|
||||||
{
|
{
|
||||||
|
@ -51,11 +51,16 @@ Statement::~Statement()
|
|||||||
|
|
||||||
// Reset the statement to make it ready for a new execution (see also #clearBindings() bellow)
|
// Reset the statement to make it ready for a new execution (see also #clearBindings() bellow)
|
||||||
void Statement::reset()
|
void Statement::reset()
|
||||||
|
{
|
||||||
|
const int ret = tryReset();
|
||||||
|
check(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Statement::tryReset() noexcept
|
||||||
{
|
{
|
||||||
mbOk = false;
|
mbOk = false;
|
||||||
mbDone = false;
|
mbDone = false;
|
||||||
const int ret = sqlite3_reset(mStmtPtr);
|
return sqlite3_reset(mStmtPtr);
|
||||||
check(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clears away all the bindings of a prepared statement (can be associated with #reset() above).
|
// Clears away all the bindings of a prepared statement (can be associated with #reset() above).
|
||||||
@ -238,6 +243,37 @@ void Statement::bind(const char* apName)
|
|||||||
|
|
||||||
// Execute a step of the query to fetch one row of results
|
// Execute a step of the query to fetch one row of results
|
||||||
bool Statement::executeStep()
|
bool Statement::executeStep()
|
||||||
|
{
|
||||||
|
const int ret = tryExecuteStep();
|
||||||
|
if ((SQLITE_ROW != ret) && (SQLITE_DONE != ret)) // on row or no (more) row ready, else it's a problem
|
||||||
|
{
|
||||||
|
throw SQLite::Exception(mStmtPtr, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mbOk; // true only if one row is accessible by getColumn(N)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute a one-step query with no expected result
|
||||||
|
int Statement::exec()
|
||||||
|
{
|
||||||
|
const int ret = tryExecuteStep();
|
||||||
|
if (SQLITE_DONE != ret) // the statement has finished executing successfully
|
||||||
|
{
|
||||||
|
if (SQLITE_ROW == ret)
|
||||||
|
{
|
||||||
|
throw SQLite::Exception("exec() does not expect results. Use executeStep.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw SQLite::Exception(mStmtPtr, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the number of rows modified by those SQL statements (INSERT, UPDATE or DELETE)
|
||||||
|
return sqlite3_changes(mStmtPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Statement::tryExecuteStep() noexcept
|
||||||
{
|
{
|
||||||
if (false == mbDone)
|
if (false == mbDone)
|
||||||
{
|
{
|
||||||
@ -255,49 +291,17 @@ bool Statement::executeStep()
|
|||||||
{
|
{
|
||||||
mbOk = false;
|
mbOk = false;
|
||||||
mbDone = false;
|
mbDone = false;
|
||||||
throw SQLite::Exception(mStmtPtr, ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw SQLite::Exception("Statement needs to be reseted.");
|
// Statement needs to be reseted !
|
||||||
|
return SQLITE_MISUSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mbOk; // true only if one row is accessible by getColumn(N)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute a one-step query with no expected result
|
|
||||||
int Statement::exec()
|
|
||||||
{
|
|
||||||
if (false == mbDone)
|
|
||||||
{
|
|
||||||
const int ret = sqlite3_step(mStmtPtr);
|
|
||||||
if (SQLITE_DONE == ret) // the statement has finished executing successfully
|
|
||||||
{
|
|
||||||
mbOk = false;
|
|
||||||
mbDone = true;
|
|
||||||
}
|
|
||||||
else if (SQLITE_ROW == ret)
|
|
||||||
{
|
|
||||||
mbOk = false;
|
|
||||||
mbDone = false;
|
|
||||||
throw SQLite::Exception("exec() does not expect results. Use executeStep.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mbOk = false;
|
|
||||||
mbDone = false;
|
|
||||||
throw SQLite::Exception(mStmtPtr, ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw SQLite::Exception("Statement need to be reseted.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the number of rows modified by those SQL statements (INSERT, UPDATE or DELETE)
|
|
||||||
return sqlite3_changes(mStmtPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a copy of the column data specified by its index starting at 0
|
// Return a copy of the column data specified by its index starting at 0
|
||||||
// (use the Column copy-constructor)
|
// (use the Column copy-constructor)
|
||||||
|
@ -147,6 +147,51 @@ TEST(Statement, executeStep) {
|
|||||||
EXPECT_THROW(insert2.exec(), SQLite::Exception);
|
EXPECT_THROW(insert2.exec(), SQLite::Exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Statement, tryExecuteStep) {
|
||||||
|
// Create a new database
|
||||||
|
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||||
|
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||||
|
|
||||||
|
// Create a new table
|
||||||
|
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT, int INTEGER, double REAL)"));
|
||||||
|
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||||
|
|
||||||
|
// Create a first row
|
||||||
|
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\", 123, 0.123)"));
|
||||||
|
EXPECT_EQ(1, db.getLastInsertRowid());
|
||||||
|
|
||||||
|
// Compile a SQL query
|
||||||
|
SQLite::Statement query(db, "SELECT * FROM test");
|
||||||
|
EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str());
|
||||||
|
EXPECT_EQ(4, query.getColumnCount());
|
||||||
|
|
||||||
|
// Get the first row
|
||||||
|
EXPECT_EQ(query.tryExecuteStep(), SQLITE_ROW);
|
||||||
|
EXPECT_TRUE (query.isOk());
|
||||||
|
EXPECT_FALSE(query.isDone());
|
||||||
|
const int64_t id = query.getColumn(0);
|
||||||
|
const std::string msg = query.getColumn(1);
|
||||||
|
const int integer = query.getColumn(2);
|
||||||
|
const long integer2= query.getColumn(2);
|
||||||
|
const double real = query.getColumn(3);
|
||||||
|
EXPECT_EQ(1, id);
|
||||||
|
EXPECT_EQ("first", msg);
|
||||||
|
EXPECT_EQ(123, integer);
|
||||||
|
EXPECT_EQ(123, integer2);
|
||||||
|
EXPECT_EQ(0.123, real);
|
||||||
|
|
||||||
|
// Step one more time to discover there is nothing more
|
||||||
|
EXPECT_EQ(query.tryExecuteStep(), SQLITE_DONE);
|
||||||
|
EXPECT_FALSE(query.isOk());
|
||||||
|
EXPECT_TRUE (query.isDone()); // "done" is "the end"
|
||||||
|
|
||||||
|
// Try to insert a new row with the same PRIMARY KEY: "UNIQUE constraint failed: test.id"
|
||||||
|
SQLite::Statement insert(db, "INSERT INTO test VALUES (1, \"impossible\", 456, 0.456)");
|
||||||
|
EXPECT_EQ(insert.tryExecuteStep(), SQLITE_CONSTRAINT);
|
||||||
|
// in this case, reset() do throw again the same error
|
||||||
|
EXPECT_EQ(insert.tryReset(), SQLITE_CONSTRAINT);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Statement, bindings) {
|
TEST(Statement, bindings) {
|
||||||
// Create a new database
|
// Create a new database
|
||||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user