我正在围绕Sqlite C函数编写一个简单的包装器类。环境是Ubuntu 14_04,是gcc 4.8.4的版本,我通过apt-get安装了libsqlite-dev,我相信这是版本3.8.2。
问题是这样的:如果我调用多个函数(c'tor
和exec
),则测试将失败。如果我将代码包装的sqlite函数(_open
和_exec
)函数放在一个函数中(我在构造函数中尝试过),则它会通过。失败是
而失败的单元测试是这样的:
TEST_FIXTURE(DatabaseFixture, TryToCreateATable)
{
database db(test);
REQUIRE CHECK(db);
CHECK(db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"));
std::cout << db.error() << std::endl;
}
包装器类如下。
database(const std::string& filename)
: connected_(false), database_(nullptr)
{
if (sqlite3_open(filename.c_str(), &database_) != SQLITE_OK)
{
const std::runtime_error ex(error());
sqlite3_close(database_);
throw ex;
}
connected_ = true;
}
bool exec(const std::string& query)
{
assert(connected_ != false && "The connected is false");
assert(database_ != nullptr && "The db_ is null");
assert(!query.empty() && "The string is empty");
sql_statement call;
assert(call.statement == nullptr && "The call is not null");
int result = sqlite3_exec(database_, query.c_str(), NULL, NULL, NULL);
// int result = sqlite3_prepare_v2(database_, query.c_str(), -1, &call.statement, nullptr);
if (result != SQLITE_OK)
{
std::cout << "err: " << result << " msg: " << error() << std::endl;
return false;
}
return true;
}
sql_statement
是_stmt
的小型包装,它将指针初始化为null并在析构函数中调用_finalize
。 'error()' returns the string from
_errmsg`。如您所见,我尝试使用
_prepare_v2
,但失败并出现相同的错误。不同的libsqlite版本会有所不同-我希望它无法编译吗?如何检查libsqlite与安装的版本匹配?它应该有什么区别吗-我认为应该没有什么不同?更新:我创建了一个新的VM,并从全新安装Ubuntu 14_04开始。通过apt-get按以下顺序获得了所需的一切:Git,CMake,g++,sqlite3,libsqlite3-dev。仍然表现出相同的问题。
UPDATE2 :我使用16_04创建了一个新的VM。以相同的顺序安装了除g++(已安装)以外我之前所做的所有操作。仍然表现出相同的问题。由于SQL的版本号不同,我认为可以排除吗?
最佳答案
CHECK(db)
宏调用扩展为UnitTest::Check(db)
-声明为:
template< typename Value >
bool Check(Value const value)
{
return !!value; // doing double negative to avoid silly VS warnings
}
这意味着
db
被复制以便按值传递。如果您具有默认的复制构造函数,并且析构函数使用其数据库指针关闭数据库连接,那么我很确定这会产生您所看到的效果。
编辑添加:https://github.com/unittest-cpp/unittest-cpp/issues/7