working test
This commit is contained in:
119
thirdparty/SQLiteCpp/tests/Backup_test.cpp
vendored
Normal file
119
thirdparty/SQLiteCpp/tests/Backup_test.cpp
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
/**
|
||||
* @file Backup_test.cpp
|
||||
* @ingroup tests
|
||||
* @brief Test of a SQLite Backup.
|
||||
*
|
||||
* Copyright (c) 2015 Shibao HONG (shibaohong@outlook.com)
|
||||
* Copyright (c) 2015-2019 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <SQLiteCpp/Backup.h>
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
|
||||
#include <sqlite3.h> // for SQLITE_ERROR, SQLITE_RANGE and SQLITE_DONE
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
TEST(Backup, initException)
|
||||
{
|
||||
remove("backup_test.db3");
|
||||
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
|
||||
EXPECT_THROW(SQLite::Backup backup(srcDB, srcDB), SQLite::Exception);
|
||||
EXPECT_THROW(SQLite::Backup backup(srcDB, "main", srcDB, "main"), SQLite::Exception);
|
||||
const std::string name("main");
|
||||
EXPECT_THROW(SQLite::Backup backup(srcDB, name, srcDB, name), SQLite::Exception);
|
||||
remove("backup_test.db3");
|
||||
}
|
||||
|
||||
TEST(Backup, executeStepOne)
|
||||
{
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
|
||||
|
||||
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
SQLite::Backup backup(destDB, "main", srcDB, "main");
|
||||
int res = backup.executeStep(1); // backup only one page at a time
|
||||
ASSERT_EQ(SQLite::OK, res);
|
||||
const int total = backup.getTotalPageCount();
|
||||
ASSERT_EQ(2, total);
|
||||
int remaining = backup.getRemainingPageCount();
|
||||
ASSERT_EQ(1, remaining);
|
||||
res = backup.executeStep(1); // backup the second and last page
|
||||
ASSERT_EQ(SQLITE_DONE, res);
|
||||
remaining = backup.getRemainingPageCount();
|
||||
ASSERT_EQ(0, remaining);
|
||||
|
||||
SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC");
|
||||
ASSERT_TRUE(query.executeStep());
|
||||
EXPECT_EQ(1, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("first", query.getColumn(1));
|
||||
ASSERT_TRUE(query.executeStep());
|
||||
EXPECT_EQ(2, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("second", query.getColumn(1));
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
}
|
||||
|
||||
TEST(Backup, executeStepAll)
|
||||
{
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
|
||||
|
||||
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
SQLite::Backup backup(destDB, srcDB);
|
||||
const int res = backup.executeStep(); // uses default argument "-1" => execute all steps at once
|
||||
ASSERT_EQ(res, SQLITE_DONE);
|
||||
const int total = backup.getTotalPageCount();
|
||||
ASSERT_EQ(2, total);
|
||||
const int remaining = backup.getRemainingPageCount();
|
||||
ASSERT_EQ(0, remaining);
|
||||
|
||||
SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC");
|
||||
ASSERT_TRUE(query.executeStep());
|
||||
EXPECT_EQ(1, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("first", query.getColumn(1));
|
||||
ASSERT_TRUE(query.executeStep());
|
||||
EXPECT_EQ(2, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("second", query.getColumn(1));
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
}
|
||||
|
||||
TEST(Backup, executeStepException)
|
||||
{
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
|
||||
{
|
||||
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
(void)destDB;
|
||||
}
|
||||
{
|
||||
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READONLY);
|
||||
SQLite::Backup backup(destDB, srcDB);
|
||||
EXPECT_THROW(backup.executeStep(), SQLite::Exception);
|
||||
}
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
}
|
241
thirdparty/SQLiteCpp/tests/Column_test.cpp
vendored
Normal file
241
thirdparty/SQLiteCpp/tests/Column_test.cpp
vendored
Normal file
@ -0,0 +1,241 @@
|
||||
/**
|
||||
* @file Column_test.cpp
|
||||
* @ingroup tests
|
||||
* @brief Test of a SQLiteCpp Column.
|
||||
*
|
||||
* Copyright (c) 2012-2019 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
#include <SQLiteCpp/Column.h>
|
||||
|
||||
#include <sqlite3.h> // for sqlite3_int64
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
TEST(Column, basis)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
|
||||
|
||||
// Create a new table
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT, int INTEGER, double REAL, binary BLOB, empty TEXT)"));
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
EXPECT_TRUE(db.tableExists(std::string("test")));
|
||||
EXPECT_EQ(0, db.getLastInsertRowid());
|
||||
|
||||
// Create a first row (autoid: 1) with all kind of data and a null value
|
||||
SQLite::Statement insert(db, "INSERT INTO test VALUES (NULL, \"first\", -123, 0.123, ?, NULL)");
|
||||
// Bind the blob value to the first parameter of the SQL query
|
||||
const char buffer[] = {'b', 'l', '\0', 'b'}; // "bl\0b" : 4 char, with a null byte inside
|
||||
const int size = sizeof(buffer); // size = 4
|
||||
const void* blob = &buffer;
|
||||
insert.bind(1, blob, size);
|
||||
// Execute the one-step query to insert the row
|
||||
EXPECT_EQ(1, insert.exec());
|
||||
EXPECT_EQ(1, db.getLastInsertRowid());
|
||||
EXPECT_EQ(1, db.getTotalChanges());
|
||||
|
||||
EXPECT_THROW(insert.exec(), SQLite::Exception); // exec() shall throw as it needs to be reseted
|
||||
|
||||
// Compile a SQL query
|
||||
SQLite::Statement query(db, "SELECT * FROM test");
|
||||
EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str());
|
||||
EXPECT_EQ(6, query.getColumnCount ());
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
|
||||
// validates every variant of cast operators, and conversions of types
|
||||
{
|
||||
const sqlite3_int64 id1 = query.getColumn(0); // operator long long()
|
||||
const int64_t id2 = query.getColumn(0); // operator long long()
|
||||
const long long id3 = query.getColumn(0); // operator long long()
|
||||
const long id4 = query.getColumn(0); // operator long long() or long() depending on compiler/architecture
|
||||
const char id5 = query.getColumn(0); // operator char()
|
||||
const short id6 = query.getColumn(0); // operator short()
|
||||
const unsigned int uint1 = query.getColumn(0); // operator unsigned int()
|
||||
const uint32_t uint2 = query.getColumn(0); // operator unsigned int()
|
||||
const unsigned char uint3 = query.getColumn(0); // operator unsigned char()
|
||||
const unsigned short uint4 = query.getColumn(0); // operator unsigned short()
|
||||
const char* ptxt = query.getColumn(1); // operator const char*()
|
||||
const std::string msg = query.getColumn(1); // operator std::string() (or const char* with MSVC)
|
||||
const int integer = query.getColumn(2); // operator int()
|
||||
const double real = query.getColumn(3); // operator double()
|
||||
const void* pblob = query.getColumn(4); // operator void*()
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
// This implicit cast should use operator std::string()
|
||||
// but would fallback to const char* with MSVC 2010-2013 (witch does not work with the NULL char in the middle)
|
||||
const std::string sblob = query.getColumn(4); // operator std::string()
|
||||
#endif
|
||||
const void* pempty = query.getColumn(5); // operator void*()
|
||||
EXPECT_EQ(1, id1);
|
||||
EXPECT_EQ(1, id2);
|
||||
EXPECT_EQ(1, id3);
|
||||
EXPECT_EQ(1, id4);
|
||||
EXPECT_EQ(1, id5);
|
||||
EXPECT_EQ(1, id6);
|
||||
EXPECT_EQ(1U, uint1);
|
||||
EXPECT_EQ(1U, uint2);
|
||||
EXPECT_EQ(1U, uint3);
|
||||
EXPECT_EQ(1U, uint4);
|
||||
EXPECT_STREQ("first", ptxt);
|
||||
EXPECT_EQ("first", msg);
|
||||
EXPECT_EQ(-123, integer);
|
||||
EXPECT_EQ(0.123, real);
|
||||
EXPECT_EQ(0, memcmp("bl\0b", pblob, size));
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
EXPECT_EQ((size_t)size, sblob.size());
|
||||
EXPECT_EQ(0, memcmp("bl\0b", &sblob[0], size));
|
||||
#endif
|
||||
EXPECT_EQ(NULL, pempty);
|
||||
}
|
||||
|
||||
// validates every variant of explicit getters
|
||||
{
|
||||
int64_t id = query.getColumn(0).getInt64();
|
||||
const unsigned int uint1 = query.getColumn(0).getUInt();
|
||||
const uint32_t uint2 = query.getColumn(0).getUInt();
|
||||
const char* ptxt = query.getColumn(1).getText();
|
||||
const std::string msg1 = query.getColumn(1).getText();
|
||||
const std::string msg2 = query.getColumn(1).getString();
|
||||
const int integer = query.getColumn(2).getInt();
|
||||
const double real = query.getColumn(3).getDouble();
|
||||
const void* pblob = query.getColumn(4).getBlob();
|
||||
const std::string sblob = query.getColumn(4).getString();
|
||||
EXPECT_EQ(1, id);
|
||||
EXPECT_EQ(1U, uint1);
|
||||
EXPECT_EQ(1U, uint2);
|
||||
EXPECT_STREQ("first", ptxt);
|
||||
EXPECT_EQ("first", msg1);
|
||||
EXPECT_EQ("first", msg2);
|
||||
EXPECT_EQ(-123, integer);
|
||||
EXPECT_EQ(0.123, real);
|
||||
EXPECT_EQ(0, memcmp("bl\0b", pblob, 4));
|
||||
EXPECT_EQ(0, memcmp("bl\0b", &sblob[0], 4));
|
||||
}
|
||||
|
||||
// Validate getBytes(), getType(), isInteger(), isNull()...
|
||||
EXPECT_EQ(SQLite::INTEGER, query.getColumn(0).getType());
|
||||
EXPECT_EQ(true, query.getColumn(0).isInteger());
|
||||
EXPECT_EQ(false, query.getColumn(0).isFloat());
|
||||
EXPECT_EQ(false, query.getColumn(0).isText());
|
||||
EXPECT_EQ(false, query.getColumn(0).isBlob());
|
||||
EXPECT_EQ(false, query.getColumn(0).isNull());
|
||||
EXPECT_STREQ("1", query.getColumn(0).getText()); // convert to string
|
||||
EXPECT_EQ(1, query.getColumn(0).getBytes()); // size of the string "1" without the null terminator
|
||||
EXPECT_EQ(SQLite::TEXT, query.getColumn(1).getType());
|
||||
EXPECT_EQ(false, query.getColumn(1).isInteger());
|
||||
EXPECT_EQ(false, query.getColumn(1).isFloat());
|
||||
EXPECT_EQ(true, query.getColumn(1).isText());
|
||||
EXPECT_EQ(false, query.getColumn(1).isBlob());
|
||||
EXPECT_EQ(false, query.getColumn(1).isNull());
|
||||
EXPECT_STREQ("first", query.getColumn(1).getText()); // convert to string
|
||||
EXPECT_EQ(5, query.getColumn(1).getBytes()); // size of the string "first"
|
||||
EXPECT_EQ(SQLite::INTEGER, query.getColumn(2).getType());
|
||||
EXPECT_EQ(true, query.getColumn(2).isInteger());
|
||||
EXPECT_EQ(false, query.getColumn(2).isFloat());
|
||||
EXPECT_EQ(false, query.getColumn(2).isText());
|
||||
EXPECT_EQ(false, query.getColumn(2).isBlob());
|
||||
EXPECT_EQ(false, query.getColumn(2).isNull());
|
||||
EXPECT_STREQ("-123", query.getColumn(2).getText()); // convert to string
|
||||
EXPECT_EQ(4, query.getColumn(2).getBytes()); // size of the string "-123"
|
||||
EXPECT_EQ(SQLite::FLOAT, query.getColumn(3).getType());
|
||||
EXPECT_EQ(false, query.getColumn(3).isInteger());
|
||||
EXPECT_EQ(true, query.getColumn(3).isFloat());
|
||||
EXPECT_EQ(false, query.getColumn(3).isText());
|
||||
EXPECT_EQ(false, query.getColumn(3).isBlob());
|
||||
EXPECT_EQ(false, query.getColumn(3).isNull());
|
||||
EXPECT_STREQ("0.123", query.getColumn(3).getText()); // convert to string
|
||||
EXPECT_EQ(5, query.getColumn(3).getBytes()); // size of the string "0.123"
|
||||
EXPECT_EQ(SQLite::BLOB, query.getColumn(4).getType());
|
||||
EXPECT_EQ(false, query.getColumn(4).isInteger());
|
||||
EXPECT_EQ(false, query.getColumn(4).isFloat());
|
||||
EXPECT_EQ(false, query.getColumn(4).isText());
|
||||
EXPECT_EQ(true, query.getColumn(4).isBlob());
|
||||
EXPECT_EQ(false, query.getColumn(4).isNull());
|
||||
EXPECT_STREQ("bl\0b", query.getColumn(4).getText()); // convert to string
|
||||
EXPECT_EQ(4, query.getColumn(4).getBytes()); // size of the blob "bl\0b" with the null char
|
||||
EXPECT_EQ(SQLite::Null, query.getColumn(5).getType());
|
||||
EXPECT_EQ(false, query.getColumn(5).isInteger());
|
||||
EXPECT_EQ(false, query.getColumn(5).isFloat());
|
||||
EXPECT_EQ(false, query.getColumn(5).isText());
|
||||
EXPECT_EQ(false, query.getColumn(5).isBlob());
|
||||
EXPECT_EQ(true, query.getColumn(5).isNull());
|
||||
EXPECT_STREQ("", query.getColumn(5).getText()); // convert to string
|
||||
EXPECT_EQ(0, query.getColumn(5).getBytes()); // size of the string "" without the null terminator
|
||||
|
||||
// Use intermediate Column objects (this is not the recommended way to use the API)
|
||||
{
|
||||
const SQLite::Column id = query.getColumn(0);
|
||||
EXPECT_EQ(1, id.getInt64());
|
||||
const SQLite::Column msg = query.getColumn(1);
|
||||
EXPECT_EQ("first", msg.getString());
|
||||
const SQLite::Column integer = query.getColumn(2);
|
||||
EXPECT_EQ(-123, integer.getInt());
|
||||
const SQLite::Column dbl = query.getColumn(3);
|
||||
EXPECT_EQ(0.123, dbl.getDouble());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Column, getName)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT)"));
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\")"));
|
||||
|
||||
// Compile a SQL query, using the "id" column name as-is, but aliasing the "msg" column with new name "value"
|
||||
SQLite::Statement query(db, "SELECT id, msg as value FROM test");
|
||||
query.executeStep();
|
||||
|
||||
// Show how to get the aliased names of the result columns.
|
||||
const std::string name0 = query.getColumn(0).getName();
|
||||
const std::string name1 = query.getColumn(1).getName();
|
||||
EXPECT_EQ("id", name0);
|
||||
EXPECT_EQ("value", name1);
|
||||
|
||||
#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
||||
// Show how to get origin names of the table columns from which theses result columns come from.
|
||||
// Requires the SQLITE_ENABLE_COLUMN_METADATA preprocessor macro to be
|
||||
// also defined at compile times of the SQLite library itself.
|
||||
const std::string oname0 = query.getColumn(0).getOriginName();
|
||||
const std::string oname1 = query.getColumn(1).getOriginName();
|
||||
EXPECT_EQ("id", oname0);
|
||||
EXPECT_EQ("msg", oname1);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Column, stream)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (msg TEXT)"));
|
||||
SQLite::Statement insert(db, "INSERT INTO test VALUES (?)");
|
||||
|
||||
// content to test
|
||||
const char str_[] = "stringwith\0embedded";
|
||||
std::string str(str_, sizeof(str_)-1);
|
||||
|
||||
insert.bind(1, str);
|
||||
// Execute the one-step query to insert the row
|
||||
EXPECT_EQ(1, insert.exec());
|
||||
EXPECT_EQ(1, db.getTotalChanges());
|
||||
|
||||
SQLite::Statement query(db, "SELECT * FROM test");
|
||||
query.executeStep();
|
||||
std::stringstream ss;
|
||||
ss << query.getColumn(0);
|
||||
std::string content = ss.str();
|
||||
EXPECT_EQ(content, str);
|
||||
}
|
364
thirdparty/SQLiteCpp/tests/Database_test.cpp
vendored
Normal file
364
thirdparty/SQLiteCpp/tests/Database_test.cpp
vendored
Normal file
@ -0,0 +1,364 @@
|
||||
/**
|
||||
* @file Database_test.cpp
|
||||
* @ingroup tests
|
||||
* @brief Test of a SQLiteCpp Database.
|
||||
*
|
||||
* Copyright (c) 2012-2019 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <SQLiteCpp/Database.h>
|
||||
|
||||
#include <sqlite3.h> // for SQLITE_ERROR and SQLITE_VERSION_NUMBER
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef SQLITECPP_ENABLE_ASSERT_HANDLER
|
||||
namespace SQLite
|
||||
{
|
||||
/// definition of the assertion handler enabled when SQLITECPP_ENABLE_ASSERT_HANDLER is defined in the project (CMakeList.txt)
|
||||
void assertion_failed(const char* apFile, const long apLine, const char* apFunc, const char* apExpr, const char* apMsg)
|
||||
{
|
||||
// TODO: unit test that this assertion callback get called (already tested manually)
|
||||
std::cout << "assertion_failed(" << apFile << ", " << apLine << ", " << apFunc << ", " << apExpr << ", " << apMsg << ")\n";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(SQLiteCpp, version)
|
||||
{
|
||||
EXPECT_STREQ(SQLITE_VERSION, SQLite::VERSION);
|
||||
EXPECT_EQ (SQLITE_VERSION_NUMBER, SQLite::VERSION_NUMBER);
|
||||
EXPECT_STREQ(SQLITE_VERSION, SQLite::getLibVersion());
|
||||
EXPECT_EQ (SQLITE_VERSION_NUMBER, SQLite::getLibVersionNumber());
|
||||
}
|
||||
|
||||
TEST(Database, ctorExecCreateDropExist)
|
||||
{
|
||||
remove("test.db3");
|
||||
{
|
||||
// Try to open a non-existing database
|
||||
std::string filename = "test.db3";
|
||||
EXPECT_THROW(SQLite::Database not_found(filename), SQLite::Exception);
|
||||
|
||||
// Create a new database
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_STREQ("test.db3", db.getFilename().c_str());
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
EXPECT_FALSE(db.tableExists(std::string("test")));
|
||||
EXPECT_EQ(0, db.getLastInsertRowid());
|
||||
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"));
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
EXPECT_TRUE(db.tableExists(std::string("test")));
|
||||
EXPECT_EQ(0, db.getLastInsertRowid());
|
||||
|
||||
EXPECT_EQ(0, db.exec("DROP TABLE IF EXISTS test"));
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
EXPECT_FALSE(db.tableExists(std::string("test")));
|
||||
EXPECT_EQ(0, db.getLastInsertRowid());
|
||||
} // Close DB test.db3
|
||||
remove("test.db3");
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
|
||||
|
||||
SQLite::Database DatabaseBuilder(const char* apName)
|
||||
{
|
||||
return SQLite::Database(apName, SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
|
||||
}
|
||||
|
||||
TEST(Database, moveConstructor)
|
||||
{
|
||||
remove("test.db3");
|
||||
{
|
||||
// Create a new database, using the move constructor
|
||||
SQLite::Database db = DatabaseBuilder("test.db3");
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
EXPECT_TRUE(db.getHandle() != NULL);
|
||||
SQLite::Database moved = std::move(db);
|
||||
EXPECT_TRUE(db.getHandle() == NULL);
|
||||
EXPECT_TRUE(moved.getHandle() != NULL);
|
||||
EXPECT_FALSE(moved.tableExists("test"));
|
||||
} // Close DB test.db3
|
||||
remove("test.db3");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
TEST(Database, createCloseReopen)
|
||||
{
|
||||
remove("test.db3");
|
||||
{
|
||||
// Try to open the non-existing database
|
||||
EXPECT_THROW(SQLite::Database not_found("test.db3"), SQLite::Exception);
|
||||
|
||||
// Create a new database
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
} // Close DB test.db3
|
||||
{
|
||||
// Reopen the database file
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
} // Close DB test.db3
|
||||
remove("test.db3");
|
||||
}
|
||||
|
||||
TEST(Database, inMemory)
|
||||
{
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE);
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
// Create a new database: not shared with the above db
|
||||
SQLite::Database db2(":memory:");
|
||||
EXPECT_FALSE(db2.tableExists("test"));
|
||||
} // Close an destroy DBs
|
||||
{
|
||||
// Create a new database: no more "test" table
|
||||
SQLite::Database db(":memory:");
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
} // Close an destroy DB
|
||||
}
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3007015 // SQLite v3.7.15 is first version with PRAGMA busy_timeout
|
||||
TEST(Database, busyTimeout)
|
||||
{
|
||||
{
|
||||
// Create a new database with default timeout of 0ms
|
||||
SQLite::Database db(":memory:");
|
||||
// Busy timeout default to 0ms: any contention between threads or process leads to SQLITE_BUSY error
|
||||
EXPECT_EQ(0, db.execAndGet("PRAGMA busy_timeout").getInt());
|
||||
|
||||
// Set a non null busy timeout: any contention between threads will leads to as much retry as possible during the time
|
||||
db.setBusyTimeout(5000);
|
||||
EXPECT_EQ(5000, db.execAndGet("PRAGMA busy_timeout").getInt());
|
||||
|
||||
// Reset timeout to 0
|
||||
db.setBusyTimeout(0);
|
||||
EXPECT_EQ(0, db.execAndGet("PRAGMA busy_timeout").getInt());
|
||||
}
|
||||
{
|
||||
// Create a new database with a non null busy timeout
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE, 5000);
|
||||
EXPECT_EQ(5000, db.execAndGet("PRAGMA busy_timeout").getInt());
|
||||
|
||||
// Reset timeout to null
|
||||
db.setBusyTimeout(0);
|
||||
EXPECT_EQ(0, db.execAndGet("PRAGMA busy_timeout").getInt());
|
||||
}
|
||||
{
|
||||
// Create a new database with a non null busy timeout
|
||||
const std::string memory = ":memory:";
|
||||
SQLite::Database db(memory, SQLite::OPEN_READWRITE, 5000);
|
||||
EXPECT_EQ(5000, db.execAndGet("PRAGMA busy_timeout").getInt());
|
||||
|
||||
// Reset timeout to null
|
||||
db.setBusyTimeout(0);
|
||||
EXPECT_EQ(0, db.execAndGet("PRAGMA busy_timeout").getInt());
|
||||
}
|
||||
}
|
||||
#endif // SQLITE_VERSION_NUMBER >= 3007015
|
||||
|
||||
TEST(Database, exec)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE);
|
||||
|
||||
// Create a new table with an explicit "id" column aliasing the underlying rowid
|
||||
// NOTE: here exec() returns 0 only because it is the first statements since database connexion,
|
||||
// but its return is an undefined value for "CREATE TABLE" statements.
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
EXPECT_EQ(0, db.getLastInsertRowid());
|
||||
EXPECT_EQ(0, db.getTotalChanges());
|
||||
|
||||
// first row : insert the "first" text value into new row of id 1
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\")"));
|
||||
EXPECT_EQ(1, db.getLastInsertRowid());
|
||||
EXPECT_EQ(1, db.getTotalChanges());
|
||||
|
||||
// second row : insert the "second" text value into new row of id 2
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"second\")"));
|
||||
EXPECT_EQ(2, db.getLastInsertRowid());
|
||||
EXPECT_EQ(2, db.getTotalChanges());
|
||||
|
||||
// third row : insert the "third" text value into new row of id 3
|
||||
const std::string insert("INSERT INTO test VALUES (NULL, \"third\")");
|
||||
EXPECT_EQ(1, db.exec(insert));
|
||||
EXPECT_EQ(3, db.getLastInsertRowid());
|
||||
EXPECT_EQ(3, db.getTotalChanges());
|
||||
|
||||
// update the second row : update text value to "second_updated"
|
||||
EXPECT_EQ(1, db.exec("UPDATE test SET value=\"second-updated\" WHERE id='2'"));
|
||||
EXPECT_EQ(3, db.getLastInsertRowid()); // last inserted row ID is still 3
|
||||
EXPECT_EQ(4, db.getTotalChanges());
|
||||
|
||||
// delete the third row
|
||||
EXPECT_EQ(1, db.exec("DELETE FROM test WHERE id='3'"));
|
||||
EXPECT_EQ(3, db.getLastInsertRowid());
|
||||
EXPECT_EQ(5, db.getTotalChanges());
|
||||
|
||||
// drop the whole table, ie the two remaining columns
|
||||
// NOTE: here exec() returns 1, like the last time, as it is an undefined value for "DROP TABLE" statements
|
||||
db.exec("DROP TABLE IF EXISTS test");
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
EXPECT_EQ(5, db.getTotalChanges());
|
||||
|
||||
// Re-Create the same table
|
||||
// NOTE: here exec() returns 1, like the last time, as it is an undefined value for "CREATE TABLE" statements
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
EXPECT_EQ(5, db.getTotalChanges());
|
||||
|
||||
// insert two rows with two *different* statements => returns only 1, ie. for the second INSERT statement
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\");INSERT INTO test VALUES (NULL, \"second\");"));
|
||||
EXPECT_EQ(2, db.getLastInsertRowid());
|
||||
EXPECT_EQ(7, db.getTotalChanges());
|
||||
|
||||
#if (SQLITE_VERSION_NUMBER >= 3007011)
|
||||
// insert two rows with only one statement (starting with SQLite 3.7.11) => returns 2
|
||||
EXPECT_EQ(2, db.exec("INSERT INTO test VALUES (NULL, \"third\"), (NULL, \"fourth\");"));
|
||||
EXPECT_EQ(4, db.getLastInsertRowid());
|
||||
EXPECT_EQ(9, db.getTotalChanges());
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Database, execAndGet)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE);
|
||||
|
||||
// Create a new table with an explicit "id" column aliasing the underlying rowid
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT, weight INTEGER)");
|
||||
|
||||
// insert a few rows
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\", 3)"));
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"second\", 5)"));
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"third\", 7)"));
|
||||
|
||||
// Get a single value result with an easy to use shortcut
|
||||
EXPECT_STREQ("second", db.execAndGet("SELECT value FROM test WHERE id=2"));
|
||||
EXPECT_STREQ("third", db.execAndGet("SELECT value FROM test WHERE weight=7"));
|
||||
EXPECT_EQ(3, db.execAndGet("SELECT weight FROM test WHERE value=\"first\"").getInt());
|
||||
}
|
||||
|
||||
TEST(Database, execException)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE);
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
|
||||
|
||||
// exception with SQL error: "no such table"
|
||||
EXPECT_THROW(db.exec("INSERT INTO test VALUES (NULL, \"first\", 3)"), SQLite::Exception);
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getErrorCode());
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getExtendedErrorCode());
|
||||
EXPECT_STREQ("no such table: test", db.getErrorMsg());
|
||||
|
||||
// Create a new table
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT, weight INTEGER)");
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
|
||||
EXPECT_STREQ("not an error", db.getErrorMsg());
|
||||
|
||||
// exception with SQL error: "table test has 3 columns but 2 values were supplied"
|
||||
EXPECT_THROW(db.exec("INSERT INTO test VALUES (NULL, 3)"), SQLite::Exception);
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getErrorCode());
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getExtendedErrorCode());
|
||||
EXPECT_STREQ("table test has 3 columns but 2 values were supplied", db.getErrorMsg());
|
||||
|
||||
// exception with SQL error: "No row to get a column from"
|
||||
EXPECT_THROW(db.execAndGet("SELECT weight FROM test WHERE value=\"first\""), SQLite::Exception);
|
||||
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\", 3)"));
|
||||
// exception with SQL error: "No row to get a column from"
|
||||
EXPECT_THROW(db.execAndGet("SELECT weight FROM test WHERE value=\"second\""), SQLite::Exception);
|
||||
|
||||
// Add a row with more values than columns in the table: "table test has 3 columns but 4 values were supplied"
|
||||
EXPECT_THROW(db.exec("INSERT INTO test VALUES (NULL, \"first\", 123, 0.123)"), SQLite::Exception);
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getErrorCode());
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getExtendedErrorCode());
|
||||
EXPECT_STREQ("table test has 3 columns but 4 values were supplied", db.getErrorMsg());
|
||||
}
|
||||
|
||||
// TODO: test Database::createFunction()
|
||||
// TODO: test Database::loadExtension()
|
||||
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
TEST(Database, encryptAndDecrypt)
|
||||
{
|
||||
remove("test.db3");
|
||||
{
|
||||
// Try to open the non-existing database
|
||||
EXPECT_THROW(SQLite::Database not_found("test.db3"), SQLite::Exception);
|
||||
|
||||
// Create a new database
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
} // Close DB test.db3
|
||||
{
|
||||
// Reopen the database file and encrypt it
|
||||
EXPECT_TRUE(SQLite::Database::isUnencrypted("test.db3"));
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE);
|
||||
// Encrypt the database
|
||||
db.rekey("123secret");
|
||||
} // Close DB test.db3
|
||||
{
|
||||
// Reopen the database file and try to use it
|
||||
EXPECT_FALSE(SQLite::Database::isUnencrypted("test.db3"));
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READONLY);
|
||||
EXPECT_THROW(db.tableExists("test"), SQLite::Exception);
|
||||
db.key("123secret");
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
} // Close DB test.db3
|
||||
{
|
||||
// Reopen the database file and decrypt it
|
||||
EXPECT_FALSE(SQLite::Database::isUnencrypted("test.db3"));
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE);
|
||||
// Decrypt the database
|
||||
db.key("123secret");
|
||||
db.rekey("");
|
||||
} // Close DB test.db3
|
||||
{
|
||||
// Reopen the database file and use it
|
||||
EXPECT_TRUE(SQLite::Database::isUnencrypted("test.db3"));
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE);
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
} // Close DB test.db3
|
||||
remove("test.db3");
|
||||
}
|
||||
#else // SQLITE_HAS_CODEC
|
||||
TEST(Database, encryptAndDecrypt)
|
||||
{
|
||||
remove("test.db3");
|
||||
{
|
||||
// Try to open the non-existing database
|
||||
EXPECT_THROW(SQLite::Database not_found("test.db3"), SQLite::Exception);
|
||||
|
||||
// Create a new database
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
} // Close DB test.db3
|
||||
{
|
||||
// Reopen the database file and encrypt it
|
||||
EXPECT_TRUE(SQLite::Database::isUnencrypted("test.db3"));
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE);
|
||||
// Encrypt the database
|
||||
EXPECT_THROW(db.key("123secret"), SQLite::Exception);
|
||||
EXPECT_THROW(db.rekey("123secret"), SQLite::Exception);
|
||||
} // Close DB test.db3
|
||||
remove("test.db3");
|
||||
}
|
||||
#endif // SQLITE_HAS_CODEC
|
73
thirdparty/SQLiteCpp/tests/Exception_test.cpp
vendored
Normal file
73
thirdparty/SQLiteCpp/tests/Exception_test.cpp
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @file Transaction_test.cpp
|
||||
* @ingroup tests
|
||||
* @brief Test of a SQLite Transaction.
|
||||
*
|
||||
* Copyright (c) 2012-2019 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
TEST(Exception, copy)
|
||||
{
|
||||
const SQLite::Exception ex1("some error", 2);
|
||||
const SQLite::Exception ex2 = ex1;
|
||||
EXPECT_STREQ(ex1.what(), ex2.what());
|
||||
EXPECT_EQ(ex1.getErrorCode(), ex2.getErrorCode());
|
||||
EXPECT_EQ(ex1.getExtendedErrorCode(), ex2.getExtendedErrorCode());
|
||||
}
|
||||
|
||||
// see http://eel.is/c++draft/exception#2 or http://www.cplusplus.com/reference/exception/exception/operator=/
|
||||
// an assignment operator is expected to be avaiable
|
||||
TEST(Exception, assignment)
|
||||
{
|
||||
const SQLite::Exception ex1("some error", 2);
|
||||
SQLite::Exception ex2("some error2", 3);
|
||||
|
||||
ex2 = ex1;
|
||||
|
||||
EXPECT_STREQ(ex1.what(), ex2.what());
|
||||
EXPECT_EQ(ex1.getErrorCode(), ex2.getErrorCode());
|
||||
EXPECT_EQ(ex1.getExtendedErrorCode(), ex2.getExtendedErrorCode());
|
||||
}
|
||||
|
||||
TEST(Exception, throw_catch)
|
||||
{
|
||||
const char message[] = "some error";
|
||||
try
|
||||
{
|
||||
throw SQLite::Exception(message);
|
||||
}
|
||||
catch (const std::runtime_error& ex)
|
||||
{
|
||||
EXPECT_STREQ(ex.what(), message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(Exception, constructor)
|
||||
{
|
||||
const char msg1[] = "error msg";
|
||||
std::string msg2 = msg1;
|
||||
{
|
||||
const SQLite::Exception ex1(msg1);
|
||||
const SQLite::Exception ex2(msg2);
|
||||
EXPECT_STREQ(ex1.what(), ex2.what());
|
||||
EXPECT_EQ(ex1.getErrorCode(), ex2.getErrorCode());
|
||||
EXPECT_EQ(ex1.getExtendedErrorCode(), ex2.getExtendedErrorCode());
|
||||
}
|
||||
{
|
||||
const SQLite::Exception ex1(msg1, 1);
|
||||
const SQLite::Exception ex2(msg2, 1);
|
||||
EXPECT_STREQ(ex1.what(), ex2.what());
|
||||
EXPECT_EQ(ex1.getErrorCode(), ex2.getErrorCode());
|
||||
EXPECT_EQ(ex1.getExtendedErrorCode(), ex2.getExtendedErrorCode());
|
||||
}
|
||||
}
|
54
thirdparty/SQLiteCpp/tests/ExecuteMany_test.cpp
vendored
Normal file
54
thirdparty/SQLiteCpp/tests/ExecuteMany_test.cpp
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @file VariadicBind_test.cpp
|
||||
* @ingroup tests
|
||||
* @brief Test of variadic bind
|
||||
*
|
||||
* Copyright (c) 2019 Maximilian Bachmann (github@maxbachmann)
|
||||
* Copyright (c) 2019 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
#include <SQLiteCpp/ExecuteMany.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#if (__cplusplus >= 201402L) || ( defined(_MSC_VER) && (_MSC_VER >= 1900) ) // c++14: Visual Studio 2015
|
||||
TEST(ExecuteMany, invalid)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
|
||||
EXPECT_EQ(0, db.exec("DROP TABLE IF EXISTS test"));
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT DEFAULT 'default')"));
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
{
|
||||
execute_many(db, "INSERT INTO test VALUES (?, ?)",
|
||||
std::make_tuple(1),
|
||||
std::make_tuple(2, "two"),
|
||||
std::make_tuple(3, "three")
|
||||
);
|
||||
}
|
||||
// make sure the content is as expected
|
||||
{
|
||||
SQLite::Statement query(db, std::string{"SELECT id, value FROM test ORDER BY id"});
|
||||
std::vector<std::pair<int, std::string> > results;
|
||||
while (query.executeStep())
|
||||
{
|
||||
const int id = query.getColumn(0);
|
||||
std::string value = query.getColumn(1);
|
||||
results.emplace_back( id, std::move(value) );
|
||||
}
|
||||
EXPECT_EQ(std::size_t(3), results.size());
|
||||
|
||||
EXPECT_EQ(std::make_pair(1,std::string{""}), results.at(0));
|
||||
EXPECT_EQ(std::make_pair(2,std::string{"two"}), results.at(1));
|
||||
EXPECT_EQ(std::make_pair(3,std::string{"three"}), results.at(2));
|
||||
}
|
||||
}
|
||||
#endif // c++14
|
864
thirdparty/SQLiteCpp/tests/Statement_test.cpp
vendored
Normal file
864
thirdparty/SQLiteCpp/tests/Statement_test.cpp
vendored
Normal file
@ -0,0 +1,864 @@
|
||||
/**
|
||||
* @file Statement_test.cpp
|
||||
* @ingroup tests
|
||||
* @brief Test of a SQLiteCpp Statement.
|
||||
*
|
||||
* Copyright (c) 2012-2019 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
|
||||
#include <sqlite3.h> // for SQLITE_DONE
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <climits> // For INT_MAX
|
||||
|
||||
TEST(Statement, invalid)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
|
||||
|
||||
// Compile a SQL query, but without any table in the database
|
||||
EXPECT_THROW(SQLite::Statement query(db, "SELECT * FROM test"), SQLite::Exception);
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getErrorCode());
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getExtendedErrorCode());
|
||||
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"));
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
|
||||
|
||||
// Compile a SQL query with no parameter
|
||||
SQLite::Statement query(db, "SELECT * FROM test");
|
||||
EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str());
|
||||
EXPECT_EQ(2, query.getColumnCount ());
|
||||
EXPECT_FALSE(query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_EQ(SQLite::OK, query.getErrorCode());
|
||||
EXPECT_EQ(SQLite::OK, query.getExtendedErrorCode());
|
||||
EXPECT_THROW(query.isColumnNull(-1), SQLite::Exception);
|
||||
EXPECT_THROW(query.isColumnNull(0), SQLite::Exception);
|
||||
EXPECT_THROW(query.isColumnNull(1), SQLite::Exception);
|
||||
EXPECT_THROW(query.isColumnNull(2), SQLite::Exception);
|
||||
EXPECT_THROW(query.getColumn(-1), SQLite::Exception);
|
||||
EXPECT_THROW(query.getColumn(0), SQLite::Exception);
|
||||
EXPECT_THROW(query.getColumn(1), SQLite::Exception);
|
||||
EXPECT_THROW(query.getColumn(2), SQLite::Exception);
|
||||
|
||||
query.reset();
|
||||
EXPECT_FALSE(query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
|
||||
query.executeStep();
|
||||
EXPECT_FALSE(query.hasRow());
|
||||
EXPECT_TRUE( query.isDone());
|
||||
query.reset();
|
||||
EXPECT_FALSE(query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
|
||||
query.reset();
|
||||
EXPECT_THROW(query.bind(-1, 123), SQLite::Exception);
|
||||
EXPECT_THROW(query.bind(0, 123), SQLite::Exception);
|
||||
EXPECT_THROW(query.bind(1, 123), SQLite::Exception);
|
||||
EXPECT_THROW(query.bind(2, 123), SQLite::Exception);
|
||||
EXPECT_THROW(query.bind(0, "abc"), SQLite::Exception);
|
||||
EXPECT_THROW(query.bind(0), SQLite::Exception);
|
||||
EXPECT_EQ(SQLITE_RANGE, db.getErrorCode());
|
||||
EXPECT_EQ(SQLITE_RANGE, db.getExtendedErrorCode());
|
||||
EXPECT_STREQ("column index out of range", db.getErrorMsg());
|
||||
EXPECT_EQ(SQLITE_RANGE, query.getErrorCode());
|
||||
EXPECT_EQ(SQLITE_RANGE, query.getExtendedErrorCode());
|
||||
EXPECT_STREQ("column index out of range", query.getErrorMsg());
|
||||
|
||||
query.exec(); // exec() instead of executeStep() as there is no result
|
||||
EXPECT_THROW(query.isColumnNull(0), SQLite::Exception);
|
||||
EXPECT_THROW(query.getColumn(0), SQLite::Exception);
|
||||
|
||||
EXPECT_THROW(query.exec(), SQLite::Exception); // exec() shall throw as it needs to be reseted
|
||||
|
||||
// Add a first row
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\")"));
|
||||
EXPECT_EQ(1, db.getLastInsertRowid());
|
||||
EXPECT_EQ(1, db.getTotalChanges());
|
||||
|
||||
query.reset();
|
||||
EXPECT_FALSE(query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
|
||||
EXPECT_THROW(query.exec(), SQLite::Exception); // exec() shall throw as it does not expect a result
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
|
||||
|
||||
SQLite::Statement StatementBuilder(SQLite::Database& aDb, const char* apQuery)
|
||||
{
|
||||
return SQLite::Statement(aDb, apQuery);
|
||||
}
|
||||
|
||||
TEST(Statement, moveConstructor)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"));
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\")"));
|
||||
EXPECT_EQ(1, db.getLastInsertRowid());
|
||||
|
||||
SQLite::Statement query = StatementBuilder(db, "SELECT * FROM test");
|
||||
EXPECT_FALSE(query.getQuery().empty());
|
||||
EXPECT_FALSE(query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_EQ(2, query.getColumnCount());
|
||||
SQLite::Statement moved = std::move(query);
|
||||
EXPECT_TRUE(query.getQuery().empty());
|
||||
EXPECT_EQ(0, query.getColumnCount());
|
||||
EXPECT_FALSE(moved.getQuery().empty());
|
||||
EXPECT_EQ(2, moved.getColumnCount());
|
||||
// Execute
|
||||
moved.executeStep();
|
||||
EXPECT_TRUE(moved.hasRow());
|
||||
EXPECT_FALSE(moved.isDone());
|
||||
EXPECT_FALSE(query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
TEST(Statement, executeStep)
|
||||
{
|
||||
// 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
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
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
|
||||
query.executeStep();
|
||||
EXPECT_FALSE(query.hasRow());
|
||||
EXPECT_TRUE (query.isDone()); // "done" is "the end"
|
||||
|
||||
// Step after "the end" throw an exception
|
||||
EXPECT_THROW(query.executeStep(), SQLite::Exception);
|
||||
|
||||
// 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_THROW(insert.executeStep(), SQLite::Exception);
|
||||
// in this case, reset() do throw again the same error
|
||||
EXPECT_THROW(insert.reset(), SQLite::Exception);
|
||||
|
||||
// Try again to insert a new row with the same PRIMARY KEY (with an alternative method): "UNIQUE constraint failed: test.id"
|
||||
SQLite::Statement insert2(db, "INSERT INTO test VALUES (1, \"impossible\", 456, 0.456)");
|
||||
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.hasRow());
|
||||
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.hasRow());
|
||||
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)
|
||||
{
|
||||
// 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());
|
||||
|
||||
// Insertion with bindable parameters
|
||||
SQLite::Statement insert(db, "INSERT INTO test VALUES (NULL, ?, ?, ?)");
|
||||
|
||||
// Compile a SQL query to check the results
|
||||
SQLite::Statement query(db, "SELECT * FROM test");
|
||||
EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str());
|
||||
EXPECT_EQ(4, query.getColumnCount());
|
||||
|
||||
// First row with text/int/double
|
||||
{
|
||||
const char* text = "first";
|
||||
const int integer = -123;
|
||||
const double dbl = 0.123;
|
||||
insert.bind(1, text);
|
||||
insert.bind(2, integer);
|
||||
insert.bind(3, dbl);
|
||||
EXPECT_EQ(insert.getExpandedSQL(), "INSERT INTO test VALUES (NULL, 'first', -123, 0.123)");
|
||||
EXPECT_EQ(1, insert.exec());
|
||||
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
|
||||
|
||||
// Check the result
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_EQ (1, query.getColumn(0).getInt64());
|
||||
EXPECT_STREQ("first", query.getColumn(1).getText());
|
||||
EXPECT_EQ (-123, query.getColumn(2).getInt());
|
||||
EXPECT_EQ (0.123, query.getColumn(3).getDouble());
|
||||
}
|
||||
|
||||
// reset() without clearbindings()
|
||||
insert.reset();
|
||||
|
||||
// Second row with the same exact values because clearbindings() was not called
|
||||
{
|
||||
EXPECT_EQ(1, insert.exec());
|
||||
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
|
||||
|
||||
// Check the result
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_EQ (2, query.getColumn(0).getInt64());
|
||||
EXPECT_STREQ("first", query.getColumn(1).getText());
|
||||
EXPECT_EQ (-123, query.getColumn(2).getInt());
|
||||
EXPECT_EQ (0.123, query.getColumn(3).getDouble());
|
||||
}
|
||||
|
||||
// reset() with clearbindings() and no more bindings
|
||||
insert.reset();
|
||||
insert.clearBindings();
|
||||
|
||||
// Third row with the all null values because clearbindings() was called
|
||||
{
|
||||
EXPECT_EQ(1, insert.exec());
|
||||
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
|
||||
|
||||
// Check the resultw
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_EQ (3, query.getColumn(0).getInt64());
|
||||
EXPECT_TRUE (query.isColumnNull(1));
|
||||
EXPECT_STREQ("", query.getColumn(1).getText());
|
||||
EXPECT_TRUE (query.isColumnNull(2));
|
||||
EXPECT_EQ (0, query.getColumn(2).getInt());
|
||||
EXPECT_TRUE (query.isColumnNull(3));
|
||||
EXPECT_EQ (0.0, query.getColumn(3).getDouble());
|
||||
}
|
||||
|
||||
// reset() with clearbindings() and new bindings
|
||||
insert.reset();
|
||||
insert.clearBindings();
|
||||
|
||||
// Fourth row with string/int64/float
|
||||
{
|
||||
const std::string fourth("fourth");
|
||||
const long long int64 = 12345678900000LL;
|
||||
const float float32 = 0.234f;
|
||||
insert.bind(1, fourth);
|
||||
insert.bind(2, int64);
|
||||
insert.bind(3, float32);
|
||||
EXPECT_EQ(1, insert.exec());
|
||||
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
|
||||
|
||||
// Check the result
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_EQ(4, query.getColumn(0).getInt64());
|
||||
EXPECT_EQ(fourth, query.getColumn(1).getText());
|
||||
EXPECT_EQ(12345678900000LL, query.getColumn(2).getInt64());
|
||||
EXPECT_EQ(0.234f, query.getColumn(3).getDouble());
|
||||
}
|
||||
|
||||
// reset() without clearbindings()
|
||||
insert.reset();
|
||||
|
||||
// Fifth row with binary buffer and a null parameter
|
||||
{
|
||||
const char buffer[] = "binary";
|
||||
insert.bind(1, buffer, sizeof(buffer));
|
||||
insert.bind(2);
|
||||
EXPECT_EQ(1, insert.exec());
|
||||
|
||||
// Check the result
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_EQ(5, query.getColumn(0).getInt64());
|
||||
EXPECT_STREQ(buffer, query.getColumn(1).getText());
|
||||
EXPECT_TRUE (query.isColumnNull(2));
|
||||
EXPECT_EQ(0, query.getColumn(2).getInt());
|
||||
EXPECT_EQ(0.234f, query.getColumn(3).getDouble());
|
||||
}
|
||||
|
||||
|
||||
// reset() without clearbindings()
|
||||
insert.reset();
|
||||
|
||||
// Sixth row with uint32_t unsigned value and a long value (which is either a 32b int or a 64b long long)
|
||||
{
|
||||
const uint32_t uint32 = 4294967295U;
|
||||
const long integer = -123;
|
||||
insert.bind(2, uint32);
|
||||
insert.bind(3, integer);
|
||||
EXPECT_EQ(1, insert.exec());
|
||||
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
|
||||
|
||||
// Check the result
|
||||
query.executeStep();
|
||||
EXPECT_TRUE(query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_EQ(6, query.getColumn(0).getInt64());
|
||||
EXPECT_EQ(4294967295U, query.getColumn(2).getUInt());
|
||||
EXPECT_EQ(-123, query.getColumn(3).getInt());
|
||||
}
|
||||
|
||||
|
||||
// reset() without clearbindings()
|
||||
insert.reset();
|
||||
|
||||
// Seventh row using another variant of int64 type
|
||||
{
|
||||
const int64_t int64 = 12345678900000LL;
|
||||
insert.bind(2, int64);
|
||||
EXPECT_EQ(1, insert.exec());
|
||||
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
|
||||
|
||||
// Check the result
|
||||
query.executeStep();
|
||||
EXPECT_TRUE(query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_EQ(7, query.getColumn(0).getInt64());
|
||||
EXPECT_EQ(12345678900000LL, query.getColumn(2).getInt64());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Statement, bindNoCopy)
|
||||
{
|
||||
// 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, txt1 TEXT, txt2 TEXT, binary BLOB)"));
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
|
||||
// Insertion with bindable parameters
|
||||
SQLite::Statement insert(db, "INSERT INTO test VALUES (NULL, ?, ?, ?)");
|
||||
|
||||
// Compile a SQL query to check the results
|
||||
SQLite::Statement query(db, "SELECT * FROM test");
|
||||
EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str());
|
||||
EXPECT_EQ(4, query.getColumnCount());
|
||||
|
||||
// Insert one row with all variants of bindNoCopy()
|
||||
{
|
||||
const char* txt1 = "first";
|
||||
const std::string txt2 = "sec\0nd";
|
||||
const char blob[] = {'b','l','\0','b'};
|
||||
insert.bindNoCopy(1, txt1);
|
||||
insert.bindNoCopy(2, txt2);
|
||||
insert.bindNoCopy(3, blob, sizeof(blob));
|
||||
EXPECT_EQ(1, insert.exec());
|
||||
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
|
||||
|
||||
// Check the result
|
||||
query.executeStep();
|
||||
EXPECT_TRUE(query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_EQ(1, query.getColumn(0).getInt64());
|
||||
EXPECT_STREQ(txt1, query.getColumn(1).getText());
|
||||
EXPECT_EQ(0, memcmp(&txt2[0], &query.getColumn(2).getString()[0], txt2.size()));
|
||||
EXPECT_EQ(0, memcmp(blob, &query.getColumn(3).getString()[0], sizeof(blob)));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Statement, bindByName)
|
||||
{
|
||||
// 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, long INTEGER)"));
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
|
||||
// Insertion with bindable parameters
|
||||
SQLite::Statement insert(db, "INSERT INTO test VALUES (NULL, @msg, @int, @double, @long)");
|
||||
|
||||
// First row with text/int/double
|
||||
insert.bind("@msg", "first");
|
||||
insert.bind("@int", 123);
|
||||
insert.bind("@long", -123);
|
||||
insert.bind("@double", 0.123);
|
||||
EXPECT_EQ(1, insert.exec());
|
||||
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
|
||||
|
||||
// Compile a SQL query to check the result
|
||||
SQLite::Statement query(db, "SELECT * FROM test");
|
||||
EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str());
|
||||
EXPECT_EQ(5, query.getColumnCount());
|
||||
|
||||
// Check the result
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_EQ (1, query.getColumn(0).getInt64());
|
||||
EXPECT_STREQ("first", query.getColumn(1).getText());
|
||||
EXPECT_EQ (123, query.getColumn(2).getInt());
|
||||
EXPECT_EQ (0.123, query.getColumn(3).getDouble());
|
||||
EXPECT_EQ (-123, query.getColumn(4).getInt());
|
||||
|
||||
// reset() with clearbindings() and new bindings
|
||||
insert.reset();
|
||||
insert.clearBindings();
|
||||
|
||||
// Second row with string/int64/float
|
||||
{
|
||||
const std::string second("second");
|
||||
const long long int64 = 12345678900000LL;
|
||||
const long integer = -123;
|
||||
const float float32 = 0.234f;
|
||||
insert.bind("@msg", second);
|
||||
insert.bind("@int", int64);
|
||||
insert.bind("@double", float32);
|
||||
insert.bind("@long", integer);
|
||||
EXPECT_EQ(1, insert.exec());
|
||||
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
|
||||
|
||||
// Check the result
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_EQ(2, query.getColumn(0).getInt64());
|
||||
EXPECT_EQ(second, query.getColumn(1).getText());
|
||||
EXPECT_EQ(12345678900000LL, query.getColumn(2).getInt64());
|
||||
EXPECT_EQ(0.234f, query.getColumn(3).getDouble());
|
||||
EXPECT_EQ(-123, query.getColumn(4).getInt());
|
||||
}
|
||||
|
||||
// reset() without clearbindings()
|
||||
insert.reset();
|
||||
|
||||
// Third row with binary buffer and a null parameter
|
||||
{
|
||||
const char buffer[] = "binary";
|
||||
insert.bind("@msg", buffer, sizeof(buffer));
|
||||
insert.bind("@int");
|
||||
EXPECT_EQ(1, insert.exec());
|
||||
|
||||
// Check the result
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_EQ(3, query.getColumn(0).getInt64());
|
||||
EXPECT_STREQ(buffer, query.getColumn(1).getText());
|
||||
EXPECT_TRUE (query.isColumnNull(2));
|
||||
EXPECT_EQ(0, query.getColumn(2).getInt());
|
||||
EXPECT_EQ(0.234f, query.getColumn(3).getDouble());
|
||||
}
|
||||
|
||||
// reset() without clearbindings()
|
||||
insert.reset();
|
||||
|
||||
// Fourth row with uint32_t unsigned value and int64_t 64bits value
|
||||
{
|
||||
const uint32_t uint32 = 4294967295U;
|
||||
const int64_t int64 = 12345678900000LL;
|
||||
insert.bind("@int", uint32);
|
||||
insert.bind("@long", int64);
|
||||
EXPECT_EQ(1, insert.exec());
|
||||
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
|
||||
|
||||
// Check the result
|
||||
query.executeStep();
|
||||
EXPECT_TRUE(query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_EQ(4, query.getColumn(0).getInt64());
|
||||
EXPECT_EQ(4294967295U, query.getColumn(2).getUInt());
|
||||
EXPECT_EQ(12345678900000LL, query.getColumn(4).getInt64());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Statement, bindNoCopyByName)
|
||||
{
|
||||
// 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, txt1 TEXT, txt2 TEXT, binary BLOB)"));
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
|
||||
// Insertion with bindable parameters
|
||||
SQLite::Statement insert(db, "INSERT INTO test VALUES (NULL, @txt1, @txt2, @blob)");
|
||||
|
||||
// Compile a SQL query to check the results
|
||||
SQLite::Statement query(db, "SELECT * FROM test");
|
||||
EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str());
|
||||
EXPECT_EQ(4, query.getColumnCount());
|
||||
|
||||
// Insert one row with all variants of bindNoCopy()
|
||||
{
|
||||
const char* txt1 = "first";
|
||||
const std::string txt2 = "sec\0nd";
|
||||
const char blob[] = { 'b','l','\0','b' };
|
||||
insert.bindNoCopy("@txt1", txt1);
|
||||
insert.bindNoCopy("@txt2", txt2);
|
||||
insert.bindNoCopy("@blob", blob, sizeof(blob));
|
||||
EXPECT_EQ(1, insert.exec());
|
||||
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
|
||||
|
||||
// Check the result
|
||||
query.executeStep();
|
||||
EXPECT_TRUE(query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_EQ(1, query.getColumn(0).getInt64());
|
||||
EXPECT_STREQ(txt1, query.getColumn(1).getText());
|
||||
EXPECT_EQ(0, memcmp(&txt2[0], &query.getColumn(2).getString()[0], txt2.size()));
|
||||
EXPECT_EQ(0, memcmp(blob, &query.getColumn(3).getString()[0], sizeof(blob)));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Statement, isColumnNull)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
ASSERT_EQ(SQLite::OK, db.getErrorCode());
|
||||
|
||||
// Create a new table
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (msg TEXT, int INTEGER, double REAL)"));
|
||||
ASSERT_EQ(SQLite::OK, db.getErrorCode());
|
||||
|
||||
// Create a first row with no null values, then other rows with each time a NULL value
|
||||
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", 123, 0.123)"));
|
||||
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, 123, 0.123)"));
|
||||
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", NULL, 0.123)"));
|
||||
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", 123, NULL)"));
|
||||
|
||||
// Compile a SQL query
|
||||
const std::string select("SELECT * FROM test");
|
||||
SQLite::Statement query(db, select);
|
||||
EXPECT_EQ(select, query.getQuery());
|
||||
EXPECT_EQ(3, query.getColumnCount());
|
||||
|
||||
// Get the first non-null row
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_THROW(query.isColumnNull(-1), SQLite::Exception);
|
||||
EXPECT_EQ(false, query.isColumnNull(0));
|
||||
EXPECT_EQ(false, query.isColumnNull(1));
|
||||
EXPECT_EQ(false, query.isColumnNull(2));
|
||||
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
|
||||
|
||||
// Get the second row with null text
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_THROW(query.isColumnNull(-1), SQLite::Exception);
|
||||
EXPECT_EQ(true, query.isColumnNull(0));
|
||||
EXPECT_EQ(false, query.isColumnNull(1));
|
||||
EXPECT_EQ(false, query.isColumnNull(2));
|
||||
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
|
||||
|
||||
// Get the second row with null integer
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_THROW(query.isColumnNull(-1), SQLite::Exception);
|
||||
EXPECT_EQ(false, query.isColumnNull(0));
|
||||
EXPECT_EQ(true, query.isColumnNull(1));
|
||||
EXPECT_EQ(false, query.isColumnNull(2));
|
||||
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
|
||||
|
||||
// Get the third row with null float
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_THROW(query.isColumnNull(-1), SQLite::Exception);
|
||||
EXPECT_EQ(false, query.isColumnNull(0));
|
||||
EXPECT_EQ(false, query.isColumnNull(1));
|
||||
EXPECT_EQ(true, query.isColumnNull(2));
|
||||
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
|
||||
}
|
||||
|
||||
TEST(Statement, isColumnNullByName)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
|
||||
ASSERT_EQ(SQLITE_OK, db.getErrorCode());
|
||||
|
||||
// Create a new table
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (msg TEXT, int INTEGER, double REAL)"));
|
||||
ASSERT_EQ(SQLITE_OK, db.getErrorCode());
|
||||
|
||||
// Create a first row with no null values, then other rows with each time a NULL value
|
||||
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", 123, 0.123)"));
|
||||
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, 123, 0.123)"));
|
||||
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", NULL, 0.123)"));
|
||||
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", 123, NULL)"));
|
||||
|
||||
// Compile a SQL query
|
||||
const std::string select("SELECT * FROM test");
|
||||
SQLite::Statement query(db, select);
|
||||
EXPECT_EQ(select, query.getQuery());
|
||||
EXPECT_EQ(3, query.getColumnCount());
|
||||
|
||||
// Get the first non-null row
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_THROW(query.isColumnNull(""), SQLite::Exception);
|
||||
EXPECT_EQ(false, query.isColumnNull("msg"));
|
||||
EXPECT_EQ(false, query.isColumnNull("int"));
|
||||
EXPECT_EQ(false, query.isColumnNull("double"));
|
||||
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
|
||||
|
||||
// Get the second row with null text
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_THROW(query.isColumnNull(""), SQLite::Exception);
|
||||
EXPECT_EQ(true, query.isColumnNull("msg"));
|
||||
EXPECT_EQ(false, query.isColumnNull(1));
|
||||
EXPECT_EQ(false, query.isColumnNull("double"));
|
||||
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
|
||||
|
||||
// Get the second row with null integer
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_THROW(query.isColumnNull(""), SQLite::Exception);
|
||||
EXPECT_EQ(false, query.isColumnNull("msg"));
|
||||
EXPECT_EQ(true, query.isColumnNull("int"));
|
||||
EXPECT_EQ(false, query.isColumnNull("double"));
|
||||
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
|
||||
|
||||
// Get the third row with null float
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
EXPECT_THROW(query.isColumnNull(""), SQLite::Exception);
|
||||
EXPECT_EQ(false, query.isColumnNull("msg"));
|
||||
EXPECT_EQ(false, query.isColumnNull("int"));
|
||||
EXPECT_EQ(true, query.isColumnNull("double"));
|
||||
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
|
||||
}
|
||||
|
||||
TEST(Statement, getColumnByName)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
|
||||
|
||||
// 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());
|
||||
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
|
||||
|
||||
// Create a first row
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\", 123, 0.123)"));
|
||||
EXPECT_EQ(1, db.getLastInsertRowid());
|
||||
EXPECT_EQ(1, db.getTotalChanges());
|
||||
|
||||
// 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());
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
|
||||
// Look for non-existing columns
|
||||
EXPECT_THROW(query.getColumn("unknown"), SQLite::Exception);
|
||||
EXPECT_THROW(query.getColumn(""), SQLite::Exception);
|
||||
|
||||
const std::string msg = query.getColumn("msg");
|
||||
const int integer = query.getColumn("int");
|
||||
const double real = query.getColumn("double");
|
||||
EXPECT_EQ("first", msg);
|
||||
EXPECT_EQ(123, integer);
|
||||
EXPECT_EQ(0.123, real);
|
||||
}
|
||||
|
||||
TEST(Statement, getName)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT)"));
|
||||
|
||||
// Compile a SQL query, using the "id" column name as-is, but aliasing the "msg" column with new name "value"
|
||||
SQLite::Statement query(db, "SELECT id, msg as value FROM test");
|
||||
query.executeStep();
|
||||
|
||||
const std::string name0 = query.getColumnName(0);
|
||||
const std::string name1 = query.getColumnName(1);
|
||||
EXPECT_EQ("id", name0);
|
||||
EXPECT_EQ("value", name1);
|
||||
|
||||
#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
||||
// Show how to get origin names of the table columns from which theses result columns come from.
|
||||
// Requires the SQLITE_ENABLE_COLUMN_METADATA preprocessor macro to be
|
||||
// also defined at compile times of the SQLite library itself.
|
||||
const std::string oname0 = query.getColumnOriginName(0);
|
||||
const std::string oname1 = query.getColumnOriginName(1);
|
||||
EXPECT_EQ("id", oname0);
|
||||
EXPECT_EQ("msg", oname1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201402L || (defined(_MSC_VER) && _MSC_VER >= 1900)
|
||||
TEST(Statement, getColumns)
|
||||
{
|
||||
struct GetRowTestStruct
|
||||
{
|
||||
int id;
|
||||
std::string msg;
|
||||
int integer;
|
||||
double real;
|
||||
GetRowTestStruct(int _id, std::string _msg, int _integer, double _real)
|
||||
: id(_id), msg(_msg), integer(_integer), real(_real)
|
||||
{}
|
||||
|
||||
GetRowTestStruct(int _id, const std::string& _msg)
|
||||
: id(_id), msg(_msg), integer(-1), real(0.0)
|
||||
{}
|
||||
};
|
||||
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
|
||||
|
||||
// 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());
|
||||
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
|
||||
|
||||
// Create a first row
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\", 123, 0.123)"));
|
||||
EXPECT_EQ(1, db.getLastInsertRowid());
|
||||
EXPECT_EQ(1, db.getTotalChanges());
|
||||
|
||||
// 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());
|
||||
query.executeStep();
|
||||
EXPECT_TRUE(query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
|
||||
// Get all columns
|
||||
auto testStruct = query.getColumns<GetRowTestStruct, 4>();
|
||||
EXPECT_EQ(1, testStruct.id);
|
||||
EXPECT_EQ("first", testStruct.msg);
|
||||
EXPECT_EQ(123, testStruct.integer);
|
||||
EXPECT_EQ(0.123, testStruct.real);
|
||||
|
||||
// Get only the first 2 columns
|
||||
auto testStruct2 = query.getColumns<GetRowTestStruct, 2>();
|
||||
EXPECT_EQ(1, testStruct2.id);
|
||||
EXPECT_EQ("first", testStruct2.msg);
|
||||
EXPECT_EQ(-1, testStruct2.integer);
|
||||
EXPECT_EQ(0.0, testStruct2.real);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (LONG_MAX > INT_MAX) // sizeof(long)==8 means the data model of the system is LP64 (64bits Linux)
|
||||
TEST(Statement, bind64bitsLong)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
|
||||
|
||||
SQLite::Statement query(db, "SELECT ?");
|
||||
query.bind(1, 4294967297L);
|
||||
query.executeStep();
|
||||
EXPECT_EQ(4294967297L, query.getColumn(0).getInt64());
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(Statement, getBindParameterCount)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT)"));
|
||||
|
||||
SQLite::Statement query(db, "SELECT id, msg FROM test where id = ?");
|
||||
EXPECT_EQ(1, query.getBindParameterCount());
|
||||
|
||||
SQLite::Statement query2(db, "SELECT id, msg FROM test where id = ? and msg = ?");
|
||||
EXPECT_EQ(2, query2.getBindParameterCount());
|
||||
|
||||
SQLite::Statement query3(db, "SELECT id, msg FROM test");
|
||||
EXPECT_EQ(0, query3.getBindParameterCount());
|
||||
}
|
104
thirdparty/SQLiteCpp/tests/Transaction_test.cpp
vendored
Normal file
104
thirdparty/SQLiteCpp/tests/Transaction_test.cpp
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
/**
|
||||
* @file Transaction_test.cpp
|
||||
* @ingroup tests
|
||||
* @brief Test of a SQLite Transaction.
|
||||
*
|
||||
* Copyright (c) 2012-2019 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <SQLiteCpp/Transaction.h>
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
TEST(Transaction, commitRollback)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
|
||||
{
|
||||
// Begin transaction
|
||||
SQLite::Transaction transaction(db);
|
||||
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"));
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
|
||||
// Insert a first value
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\")"));
|
||||
EXPECT_EQ(1, db.getLastInsertRowid());
|
||||
|
||||
// Commit transaction
|
||||
transaction.commit();
|
||||
|
||||
// Commit again throw an exception
|
||||
EXPECT_THROW(transaction.commit(), SQLite::Exception);
|
||||
}
|
||||
|
||||
// Auto rollback if no commit() before the end of scope
|
||||
{
|
||||
// Begin transaction
|
||||
SQLite::Transaction transaction(db);
|
||||
|
||||
// Insert a second value (that will be rollbacked)
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"third\")"));
|
||||
EXPECT_EQ(2, db.getLastInsertRowid());
|
||||
|
||||
// end of scope: automatic rollback
|
||||
}
|
||||
|
||||
// Auto rollback of a transaction on error/exception
|
||||
try
|
||||
{
|
||||
// Begin transaction
|
||||
SQLite::Transaction transaction(db);
|
||||
|
||||
// Insert a second value (that will be rollbacked)
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"second\")"));
|
||||
EXPECT_EQ(2, db.getLastInsertRowid());
|
||||
|
||||
// Execute with an error => exception with auto-rollback
|
||||
db.exec("DesiredSyntaxError to raise an exception to rollback the transaction");
|
||||
|
||||
GTEST_FATAL_FAILURE_("we should never get there");
|
||||
transaction.commit(); // We should never get there
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "SQLite exception: " << e.what() << std::endl;
|
||||
// expected error, see above
|
||||
}
|
||||
|
||||
// Double rollback with a manual command before the end of scope
|
||||
{
|
||||
// Begin transaction
|
||||
SQLite::Transaction transaction(db);
|
||||
|
||||
// Insert a second value (that will be rollbacked)
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"third\")"));
|
||||
EXPECT_EQ(2, db.getLastInsertRowid());
|
||||
|
||||
// Execute a manual rollback (no real use case I can think of, so no rollback() method)
|
||||
db.exec("ROLLBACK");
|
||||
|
||||
// end of scope: the automatic rollback should not raise an error because it is harmless
|
||||
}
|
||||
|
||||
// Check the results (expect only one row of result, as all other one have been rollbacked)
|
||||
SQLite::Statement query(db, "SELECT * FROM test");
|
||||
int nbRows = 0;
|
||||
while (query.executeStep())
|
||||
{
|
||||
nbRows++;
|
||||
EXPECT_EQ(1, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("first", query.getColumn(1).getText());
|
||||
}
|
||||
EXPECT_EQ(1, nbRows);
|
||||
}
|
109
thirdparty/SQLiteCpp/tests/VariadicBind_test.cpp
vendored
Normal file
109
thirdparty/SQLiteCpp/tests/VariadicBind_test.cpp
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
/**
|
||||
* @file VariadicBind_test.cpp
|
||||
* @ingroup tests
|
||||
* @brief Test of variadic bind
|
||||
*
|
||||
* Copyright (c) 2016 Paul Dreik (github@pauldreik.se)
|
||||
* Copyright (c) 2016-2019 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
* Copyright (c) 2019 Maximilian Bachmann (github@maxbachmann)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
#include <SQLiteCpp/VariadicBind.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#if (__cplusplus >= 201103L) || ( defined(_MSC_VER) && (_MSC_VER >= 1800) ) // c++11: Visual Studio 2013
|
||||
TEST(VariadicBind, invalid)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
|
||||
EXPECT_EQ(0, db.exec("DROP TABLE IF EXISTS test"));
|
||||
EXPECT_EQ(0,
|
||||
db.exec(
|
||||
"CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT DEFAULT 'default') "));
|
||||
EXPECT_EQ(0,
|
||||
db.exec(
|
||||
"CREATE TABLE test2 (id INTEGER PRIMARY KEY, value TEXT DEFAULT 'default') "));
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
EXPECT_TRUE(db.tableExists("test2"));
|
||||
|
||||
{
|
||||
SQLite::Statement query(db, "INSERT INTO test VALUES (?, ?)");
|
||||
|
||||
// bind one argument less than expected - should be fine.
|
||||
// the unspecified argument should be set to null, not the default.
|
||||
SQLite::bind(query, 1);
|
||||
EXPECT_EQ(1, query.exec());
|
||||
query.reset();
|
||||
|
||||
// bind all arguments - should work just fine
|
||||
SQLite::bind(query, 2, "two");
|
||||
EXPECT_EQ(1, query.exec());
|
||||
query.reset();
|
||||
|
||||
// bind too many arguments - should throw.
|
||||
EXPECT_THROW(SQLite::bind(query, 3, "three", 0), SQLite::Exception);
|
||||
EXPECT_EQ(1, query.exec());
|
||||
}
|
||||
// make sure the content is as expected
|
||||
{
|
||||
SQLite::Statement query(db, std::string{"SELECT id, value FROM test ORDER BY id"});
|
||||
std::vector<std::pair<int, std::string> > results;
|
||||
while (query.executeStep())
|
||||
{
|
||||
const int id = query.getColumn(0);
|
||||
std::string value = query.getColumn(1);
|
||||
results.emplace_back( id, std::move(value) );
|
||||
}
|
||||
EXPECT_EQ(std::size_t(3), results.size());
|
||||
|
||||
EXPECT_EQ(std::make_pair(1,std::string{""}), results.at(0));
|
||||
EXPECT_EQ(std::make_pair(2,std::string{"two"}), results.at(1));
|
||||
EXPECT_EQ(std::make_pair(3,std::string{"three"}), results.at(2));
|
||||
}
|
||||
#if (__cplusplus >= 201402L) || ( defined(_MSC_VER) && (_MSC_VER >= 1900) ) // c++14: Visual Studio 2015
|
||||
{
|
||||
SQLite::Statement query(db, "INSERT INTO test2 VALUES (?, ?)");
|
||||
|
||||
// bind one argument less than expected - should be fine.
|
||||
// the unspecified argument should be set to null, not the default.
|
||||
SQLite::bind(query, std::make_tuple(1));
|
||||
EXPECT_EQ(1, query.exec());
|
||||
query.reset();
|
||||
|
||||
// bind all arguments - should work just fine
|
||||
SQLite::bind(query, std::make_tuple(2, "two"));
|
||||
EXPECT_EQ(1, query.exec());
|
||||
query.reset();
|
||||
|
||||
// bind too many arguments - should throw.
|
||||
EXPECT_THROW(SQLite::bind(query, std::make_tuple(3, "three", 0)), SQLite::Exception);
|
||||
EXPECT_EQ(1, query.exec());
|
||||
}
|
||||
// make sure the content is as expected
|
||||
{
|
||||
SQLite::Statement query(db, std::string{"SELECT id, value FROM test2 ORDER BY id"});
|
||||
std::vector<std::pair<int, std::string> > results;
|
||||
while (query.executeStep())
|
||||
{
|
||||
const int id = query.getColumn(0);
|
||||
std::string value = query.getColumn(1);
|
||||
results.emplace_back( id, std::move(value) );
|
||||
}
|
||||
EXPECT_EQ(std::size_t(3), results.size());
|
||||
|
||||
EXPECT_EQ(std::make_pair(1,std::string{""}), results.at(0));
|
||||
EXPECT_EQ(std::make_pair(2,std::string{"two"}), results.at(1));
|
||||
EXPECT_EQ(std::make_pair(3,std::string{"three"}), results.at(2));
|
||||
}
|
||||
#endif // c++14
|
||||
}
|
||||
#endif // c++11
|
Reference in New Issue
Block a user