Use argument binding for query

This commit is contained in:
topjohnwu
2025-01-02 01:04:44 -08:00
committed by John Wu
parent 2722875190
commit 8e1a44e7eb
6 changed files with 115 additions and 115 deletions

View File

@@ -88,23 +88,41 @@ struct db_strings {
********************/
using db_exec_callback = std::function<void(StringSlice, DbValues&)>;
using db_bind_callback = std::function<void(int, DbStatement&)>;
int get_db_settings(db_settings &cfg, int key = -1);
int set_db_settings(int key, int value);
int get_db_strings(db_strings &str, int key = -1);
void rm_db_strings(int key);
struct DbArg {
enum {
INT,
TEXT,
} type;
union {
int64_t int_val;
rust::Str str_val;
};
DbArg(int64_t v) : type(INT), int_val(v) {}
DbArg(const char *v) : type(TEXT), str_val(v) {}
};
struct DbArgs {
DbArgs() : curr(0) {}
DbArgs(std::initializer_list<DbArg> list) : args(list), curr(0) {}
int operator()(int index, DbStatement &stmt);
bool empty() const { return args.empty(); }
private:
std::vector<DbArg> args;
size_t curr;
};
bool get_db_settings(db_settings &cfg, int key = -1);
bool set_db_settings(int key, int value);
bool get_db_strings(db_strings &str, int key = -1);
bool rm_db_strings(int key);
void exec_sql(owned_fd client);
bool db_exec(const char *sql, db_bind_callback bind_fn = {}, db_exec_callback exec_fn = {});
static inline bool db_exec(const char *sql, db_exec_callback exec_fn) {
return db_exec(sql, {}, std::move(exec_fn));
}
bool db_exec(const char *sql, DbArgs args = {}, db_exec_callback exec_fn = {});
template<typename T>
concept DbData = requires(T t, StringSlice s, DbValues &v) { t(s, v); };
template<DbData T>
bool db_exec(const char *sql, T &data) {
return db_exec(sql, (db_exec_callback) std::ref(data));
bool db_exec(const char *sql, DbArgs args, T &data) {
return db_exec(sql, std::move(args), (db_exec_callback) std::ref(data));
}

View File

@@ -17,27 +17,24 @@ extern int (*sqlite3_open_v2)(const char *filename, sqlite3 **ppDb, int flags, c
extern int (*sqlite3_close)(sqlite3 *db);
extern const char *(*sqlite3_errstr)(int);
// Transparent wrapper of sqlite3_stmt
// Transparent wrappers of sqlite3_stmt
struct DbValues {
const char *get_text(int index);
int get_int(int index);
~DbValues() = delete;
};
struct DbStatement {
int bind_text(int index, const char *val);
int bind_text(int index, rust::Str val);
int bind_int64(int index, int64_t val);
~DbStatement() = delete;
};
using StringSlice = rust::Slice<rust::String>;
using sql_bind_callback = void(*)(void*, int, DbStatement&);
using sql_bind_callback = int(*)(void*, int, DbStatement&);
using sql_exec_callback = void(*)(void*, StringSlice, DbValues&);
#define fn_run_ret(fn, ...) if (int rc = fn(__VA_ARGS__); rc != SQLITE_OK) return rc
bool load_sqlite();
sqlite3 *open_and_init_db();
int sql_exec(sqlite3 *db, rust::Str zSql,
sql_bind_callback bind_cb, void *bind_cookie,
sql_exec_callback exec_cb, void *exec_cookie);
sql_bind_callback bind_cb = nullptr, void *bind_cookie = nullptr,
sql_exec_callback exec_cb = nullptr, void *exec_cookie = nullptr);