diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 987c6d2be..2098e2dee 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -134,6 +134,7 @@ set (ERESSEA_SRC ${TRIGGERS_SRC} ${ATTRIBUTES_SRC} ${KERNEL_SRC} + ${DB_SRC} ${UTIL_SRC} ) diff --git a/src/eressea.c b/src/eressea.c index e1c81f8db..bc838136a 100755 --- a/src/eressea.c +++ b/src/eressea.c @@ -24,10 +24,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index cbd8a6296..5619092ad 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -11,7 +11,7 @@ command.test.c config.test.c # connection.test.c curse.test.c -db.test.c +database.test.c equipment.test.c faction.test.c group.test.c @@ -36,9 +36,9 @@ jsonconf.test.c # xmlreader.test.c ) -SET(_DBFILES dbtrie.c) +SET(_DBFILES db/critbit.c) IF(SQLITE3_FOUND) -SET(_DBFILES dbsqlite.c) +SET(_DBFILES db/sqlite.c) ENDIF(SQLITE3_FOUND) SET(_FILES @@ -52,6 +52,7 @@ command.c config.c connection.c curse.c +database.c equipment.c faction.c group.c diff --git a/src/kernel/database.c b/src/kernel/database.c new file mode 100644 index 000000000..732f0fc90 --- /dev/null +++ b/src/kernel/database.c @@ -0,0 +1,58 @@ +#include +#include "database.h" + +#include + +#include +#include +#include + +#include + +#ifdef USE_SQLITE +#include "db/sqlite.h" +#else +#include "db/critbit.h" +#endif + +order_data *db_load_order(int id) +{ + if (id > 0) { +#ifdef USE_SQLITE + return db_sqlite_order_load(id); +#else + return db_critbit_order_load(id); +#endif + } + return NULL; +} + +int db_save_order(order_data *od) +{ + if (od->_str) { +#ifdef USE_SQLITE + return db_sqlite_order_save(od); +#else + return db_critbit_order_save(od); +#endif + } + return 0; +} + +void db_open(void) +{ +#ifdef USE_SQLITE + db_sqlite_open(); +#else + db_critbit_open(); +#endif +} + +void db_close(void) +{ +#ifdef USE_SQLITE + db_sqlite_close(); +#else + db_critbit_close(); +#endif +} diff --git a/src/kernel/db.h b/src/kernel/database.h similarity index 100% rename from src/kernel/db.h rename to src/kernel/database.h diff --git a/src/kernel/db.test.c b/src/kernel/database.test.c similarity index 100% rename from src/kernel/db.test.c rename to src/kernel/database.test.c diff --git a/src/kernel/dbtrie.c b/src/kernel/db/critbit.c similarity index 54% rename from src/kernel/dbtrie.c rename to src/kernel/db/critbit.c index 3cca71af8..647c6921b 100644 --- a/src/kernel/dbtrie.c +++ b/src/kernel/db/critbit.c @@ -1,7 +1,7 @@ #include -#include "db.h" -#include "orderdb.h" +#include "critbit.h" +#include #include #include @@ -18,32 +18,30 @@ struct cb_entry { order_data *data; }; -order_data *db_load_order(int id) +order_data *db_critbit_order_load(int id) { void * match; - if (id > 0) { - if (cb_find_prefix(&cb_orders, &id, sizeof(id), &match, 1, 0) > 0) { - struct cb_entry *ent = (struct cb_entry *)match; - order_data * od = ent->data; - ++od->_refcount; - return od; - } + assert(id>0); + if (cb_find_prefix(&cb_orders, &id, sizeof(id), &match, 1, 0) > 0) { + struct cb_entry *ent = (struct cb_entry *)match; + order_data * od = ent->data; + ++od->_refcount; + return od; } return NULL; } -int db_save_order(order_data *od) +int db_critbit_order_save(order_data *od) { - if (od->_str) { - struct cb_entry ent; - ++od->_refcount; - ent.id = ++auto_id; - ent.data = od; - cb_insert(&cb_orders, &ent, sizeof(ent)); - return ent.id; - } - return 0; + struct cb_entry ent; + + assert(od && od->_str); + ++od->_refcount; + ent.id = ++auto_id; + ent.data = od; + cb_insert(&cb_orders, &ent, sizeof(ent)); + return ent.id; } static int free_data_cb(const void *match, const void *key, size_t keylen, @@ -55,13 +53,13 @@ static int free_data_cb(const void *match, const void *key, size_t keylen, return 0; } -void db_open(void) +void db_critbit_open(void) { assert(auto_id == -1); auto_id = 0; } -void db_close(void) +void db_critbit_close(void) { cb_foreach(&cb_orders, NULL, 0, free_data_cb, NULL); cb_clear(&cb_orders); diff --git a/src/kernel/db/critbit.h b/src/kernel/db/critbit.h new file mode 100644 index 000000000..d4140fa08 --- /dev/null +++ b/src/kernel/db/critbit.h @@ -0,0 +1,8 @@ +#pragma once + +struct order_data; + +void db_critbit_open(void); +void db_critbit_close(void); +int db_critbit_order_save(struct order_data *od); +struct order_data *db_critbit_order_load(int id); diff --git a/src/kernel/db/sqlite.c b/src/kernel/db/sqlite.c new file mode 100644 index 000000000..135195ca0 --- /dev/null +++ b/src/kernel/db/sqlite.c @@ -0,0 +1,121 @@ +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +static sqlite3 *g_db; +static sqlite3_stmt * g_stmt_insert; +static sqlite3_stmt * g_stmt_select; + +static int g_order_batchsize; +static int g_order_tx_size; + +order_data *db_sqlite_order_load(int id) +{ + order_data * od = NULL; + int err; + + if (g_order_tx_size > 0) { + g_order_tx_size = 0; + err = sqlite3_exec(g_db, "COMMIT", NULL, NULL, NULL); + assert(err == SQLITE_OK); + } + err = sqlite3_reset(g_stmt_select); + assert(err == SQLITE_OK); + err = sqlite3_bind_int(g_stmt_select, 1, id); + assert(err == SQLITE_OK); + do { + err = sqlite3_step(g_stmt_select); + if (err == SQLITE_ROW) { + const unsigned char *text; + int bytes; + bytes = sqlite3_column_bytes(g_stmt_select, 0); + assert(bytes > 0); + text = sqlite3_column_text(g_stmt_select, 0); + odata_create(&od, 1+(size_t)bytes, (const char *)text); + return od; + } + } while (err == SQLITE_ROW); + assert(err == SQLITE_DONE); + return NULL; +} + +int db_sqlite_order_save(order_data *od) +{ + int err; + sqlite3_int64 id; + + assert(od && od->_str); + + if (g_order_batchsize > 0) { + if (g_order_tx_size == 0) { + err = sqlite3_exec(g_db, "BEGIN TRANSACTION", NULL, NULL, NULL); + assert(err == SQLITE_OK); + } + } + + err = sqlite3_reset(g_stmt_insert); + assert(err == SQLITE_OK); + err = sqlite3_bind_text(g_stmt_insert, 1, od->_str, -1, SQLITE_STATIC); + assert(err == SQLITE_OK); + err = sqlite3_step(g_stmt_insert); + assert(err == SQLITE_DONE); + id = sqlite3_last_insert_rowid(g_db); + assert(id <= INT_MAX); + + if (g_order_batchsize > 0) { + if (++g_order_tx_size >= g_order_batchsize) { + err = sqlite3_exec(g_db, "COMMIT", NULL, NULL, NULL); + assert(err == SQLITE_OK); + g_order_tx_size = 0; + } + } + + return (int)id; +} + +void db_sqlite_open(void) +{ + int err; + const char *dbname; + + g_order_batchsize = config_get_int("game.dbbatch", 100); + dbname = config_get("game.dbname"); + if (!dbname) { + dbname = ""; + } + err = sqlite3_open(dbname, &g_db); + assert(err == SQLITE_OK); + err = sqlite3_exec(g_db, "PRAGMA journal_mode=OFF", NULL, NULL, NULL); + assert(err == SQLITE_OK); + err = sqlite3_exec(g_db, "PRAGMA synchronous=OFF", NULL, NULL, NULL); + assert(err == SQLITE_OK); + err = sqlite3_exec(g_db, "CREATE TABLE IF NOT EXISTS orders (id INTEGER PRIMARY KEY, data TEXT NOT NULL)", NULL, NULL, NULL); + assert(err == SQLITE_OK); + err = sqlite3_prepare_v2(g_db, "INSERT INTO orders (data) VALUES (?)", -1, &g_stmt_insert, NULL); + assert(err == SQLITE_OK); + err = sqlite3_prepare_v2(g_db, "SELECT data FROM orders WHERE id = ?", -1, &g_stmt_select, NULL); + assert(err == SQLITE_OK); +} + +void db_sqlite_close(void) +{ + int err; + + err = sqlite3_finalize(g_stmt_select); + assert(err == SQLITE_OK); + err = sqlite3_finalize(g_stmt_insert); + assert(err == SQLITE_OK); + err = sqlite3_close(g_db); + assert(err == SQLITE_OK); +} diff --git a/src/kernel/db/sqlite.h b/src/kernel/db/sqlite.h new file mode 100644 index 000000000..f0afba6e7 --- /dev/null +++ b/src/kernel/db/sqlite.h @@ -0,0 +1,8 @@ +#pragma once + +struct order_data; + +void db_sqlite_open(void); +void db_sqlite_close(void); +int db_sqlite_order_save(struct order_data *od); +struct order_data *db_sqlite_order_load(int id); diff --git a/src/kernel/dbsqlite.c b/src/kernel/dbsqlite.c deleted file mode 100644 index 055e0f9cf..000000000 --- a/src/kernel/dbsqlite.c +++ /dev/null @@ -1,123 +0,0 @@ -#include -#include "db.h" -#include "orderdb.h" -#include "config.h" - -#include - -#include - -#include -#include -#include -#include - -static sqlite3 *g_db; -static sqlite3_stmt * g_stmt_insert; -static sqlite3_stmt * g_stmt_select; - -static int g_order_batchsize; -static int g_order_tx_size; - -order_data *db_load_order(int id) -{ - if (id > 0) { - order_data * od = NULL; - int err; - - if (g_order_tx_size > 0) { - g_order_tx_size = 0; - err = sqlite3_exec(g_db, "COMMIT", NULL, NULL, NULL); - assert(err == SQLITE_OK); - } - err = sqlite3_reset(g_stmt_select); - assert(err == SQLITE_OK); - err = sqlite3_bind_int(g_stmt_select, 1, id); - assert(err == SQLITE_OK); - do { - err = sqlite3_step(g_stmt_select); - if (err == SQLITE_ROW) { - const unsigned char *text; - int bytes; - bytes = sqlite3_column_bytes(g_stmt_select, 0); - assert(bytes > 0); - text = sqlite3_column_text(g_stmt_select, 0); - odata_create(&od, 1+(size_t)bytes, (const char *)text); - return od; - } - } while (err == SQLITE_ROW); - assert(err == SQLITE_DONE); - } - return NULL; -} - -int db_save_order(order_data *od) -{ - if (od->_str) { - int err; - sqlite3_int64 id; - - if (g_order_batchsize > 0) { - if (g_order_tx_size == 0) { - err = sqlite3_exec(g_db, "BEGIN TRANSACTION", NULL, NULL, NULL); - assert(err == SQLITE_OK); - } - } - - err = sqlite3_reset(g_stmt_insert); - assert(err == SQLITE_OK); - err = sqlite3_bind_text(g_stmt_insert, 1, od->_str, -1, SQLITE_STATIC); - assert(err == SQLITE_OK); - err = sqlite3_step(g_stmt_insert); - assert(err == SQLITE_DONE); - id = sqlite3_last_insert_rowid(g_db); - assert(id <= INT_MAX); - - if (g_order_batchsize > 0) { - if (++g_order_tx_size >= g_order_batchsize) { - err = sqlite3_exec(g_db, "COMMIT", NULL, NULL, NULL); - assert(err == SQLITE_OK); - g_order_tx_size = 0; - } - } - - return (int)id; - } - return 0; -} - -void db_open(void) -{ - int err; - const char *dbname; - - g_order_batchsize = config_get_int("game.dbbatch", 100); - dbname = config_get("game.dbname"); - if (!dbname) { - dbname = ""; - } - err = sqlite3_open(dbname, &g_db); - assert(err == SQLITE_OK); - err = sqlite3_exec(g_db, "PRAGMA journal_mode=OFF", NULL, NULL, NULL); - assert(err == SQLITE_OK); - err = sqlite3_exec(g_db, "PRAGMA synchronous=OFF", NULL, NULL, NULL); - assert(err == SQLITE_OK); - err = sqlite3_exec(g_db, "CREATE TABLE IF NOT EXISTS orders (id INTEGER PRIMARY KEY, data TEXT NOT NULL)", NULL, NULL, NULL); - assert(err == SQLITE_OK); - err = sqlite3_prepare_v2(g_db, "INSERT INTO orders (data) VALUES (?)", -1, &g_stmt_insert, NULL); - assert(err == SQLITE_OK); - err = sqlite3_prepare_v2(g_db, "SELECT data FROM orders WHERE id = ?", -1, &g_stmt_select, NULL); - assert(err == SQLITE_OK); -} - -void db_close(void) -{ - int err; - - err = sqlite3_finalize(g_stmt_select); - assert(err == SQLITE_OK); - err = sqlite3_finalize(g_stmt_insert); - assert(err == SQLITE_OK); - err = sqlite3_close(g_db); - assert(err == SQLITE_OK); -} diff --git a/src/kernel/orderdb.c b/src/kernel/orderdb.c index ee23993e6..e2eed4a0f 100644 --- a/src/kernel/orderdb.c +++ b/src/kernel/orderdb.c @@ -1,5 +1,5 @@ #include -#include "db.h" +#include "database.h" #include "orderdb.h" #include diff --git a/src/main.c b/src/main.c index 215015ed0..ae462c139 100644 --- a/src/main.c +++ b/src/main.c @@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#include +#include #include #include #include diff --git a/src/test_eressea.c b/src/test_eressea.c index c5ba24abb..09d6c2cf4 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include