我设法创建了一个库来帮助我向 SqlLite 库发出请求,特别是那些与 BLOB 文件相关的库。
问题来了,因为我觉得实现可以改进,但是我没有足够的知识来实现它。对这两个问题的任何帮助:
可以使用 SQL 语句作为 c-pure 字符串或 std::string 调用某些函数。他们俩最终都调用了相同的函数最终实现。如果我尝试删除函数声明和调用的“_”(请参阅源代码),则问题来自对模板函数的明确调用。我知道这是一个小问题,但我想知道是否有任何方法可以实现它。
我尝试对使用文件在数据库中加载 BLOB 的请求以及不使用 BLOBS 的请求使用相同的代码。区别在于第一个使用文件流作为参数,第二个没有任何流参数。SqlLite 强制调用特定函数来执行 sql 语句,因此我需要使用“if consexpr ...”条件子句将 0 个参数的情况与 1 个或多个流参数的情况分开。
源代码在前面介绍:
#include <string>
#include <sstream>
#include <utility>
class sqlite3 {};
class sqlite3_stmt {};
void sqlite3_step(sqlite3_stmt*) {}
sqlite3* db;
//Auxiliary BLOB functions
template<typename T>
bool sqlite3_blob(sqlite3_stmt*, const T& data, int col);
template<>
bool sqlite3_blob<std::ostringstream>(sqlite3_stmt* statement, const std::ostringstream& data, int col)
{
//std::string buffer{ data.str() };
return true;
}
//sqlite3 automatization request
template<typename... Args, std::size_t... Is>
constexpr bool sqlite3_request_(sqlite3* db, const char* sql, Args&&... args, std::index_sequence<Is...>)
{
sqlite3_stmt* statement{};
(sqlite3_blob(statement, std::forward<Args>(args), Is + 1), ...);
if constexpr (sizeof...(Args) == 0) sqlite3_step(statement);//Horrible conditional statement. Is there any way of getting rid of it???
return true;
}
template<typename... Args>
constexpr bool sqlite3_request(sqlite3* db, const char* sql, Args&&... args)
{
return sqlite3_request_<Args...>(db, sql, std::forward<Args>(args)..., std::make_index_sequence<sizeof...(Args)>{});//Need to change the name because calling function is not able to unambiguosly called the right on
}
//For std::string arguments:
template<typename... Args>
constexpr bool sqlite3_request(sqlite3* db, const std::string& sql, Args&&... args)//args contain loading data for blobs, if any
{
return sqlite3_request_<Args...>(db, sql.c_str(), std::forward<Args>(args)..., std::make_index_sequence<sizeof...(Args)>{});// Possible to improve? Unambiguos calling to function if '_' eliminated in function calling and declaration
}
int main()
{
const std::ostringstream data;
std::string sql = "INSERT INTO scenarios(file) VALUES(?);";//file is a BLOB field
sqlite3_request(db, sql, data);
}
请注意,我已经清理并模拟了所有 SqlLite 函数。这不是关于 SqlLite 的问题,而是关于改进模板样式的问题。
此外,这是一个指向http://coliru.stacked-crooked.com/a/ec8e8bf65f451b20
所述源代码的 coliru 链接。