update to schema version 1

- factions table is now faction
- no turn column
- new update logic
This commit is contained in:
Enno Rehling 2019-04-23 13:18:51 +02:00
parent 91e40b7061
commit aab234a3f4
7 changed files with 139 additions and 65 deletions

View file

@ -45,9 +45,7 @@ class EPasswd:
def load_database(self, file): def load_database(self, file):
conn = sqlite3.connect(file) conn = sqlite3.connect(file)
c = conn.cursor() c = conn.cursor()
c.execute('SELECT MAX(turn) FROM factions') for row in c.execute('SELECT `no`, `email`, `password` FROM `faction`'):
args = c.fetchone()
for row in c.execute('SELECT no, email, password FROM factions WHERE turn=?', args):
(no, email, passwd) = row (no, email, passwd) = row
self.set_data(baseconvert(no, 36), email, passwd) self.set_data(baseconvert(no, 36), email, passwd)
conn.close() conn.close()

View file

@ -100,7 +100,7 @@ struct locale *crtag_locale(void) {
static int config; static int config;
if (config_changed(&config)) { if (config_changed(&config)) {
const char *lname = config_get("creport.tags"); const char *lname = config_get("creport.tags");
lang = get_locale(lname ? lname : "de"); lang = lname ? get_locale(lname) : default_locale;
} }
return lang; return lang;
} }

View file

@ -9,9 +9,25 @@
#include "kernel/faction.h" #include "kernel/faction.h"
#include "kernel/db/driver.h" #include "kernel/db/driver.h"
#include "util/strings.h"
static int generate_factions(void *data, db_faction *results, int nresults)
{
int i;
faction **iter = (faction **)data;
for (i = 0; *iter && i != nresults; ++i) {
faction *f = *iter;
results[i].p_uid = &f->uid;
results[i].no = f->no;
results[i].email = faction_getemail(f);
str_strlcpy(results[i].pwhash, faction_getpassword(f), sizeof(results[i].pwhash));
*iter = f->next;
}
return i;
}
int gamedb_update(void) int gamedb_update(void)
{ {
faction *f;
int err; int err;
const char *dbname; const char *dbname;
@ -19,14 +35,9 @@ int gamedb_update(void)
err = db_driver_open(DB_GAME, dbname); err = db_driver_open(DB_GAME, dbname);
if (err == 0) { if (err == 0) {
for (f = factions; f; f = f->next) { faction *list = factions;
int uid = db_driver_faction_save(f->uid, f->no, turn, db_driver_update_factions(generate_factions, &list);
faction_getemail(f), db_driver_compact(turn);
faction_getpassword(f));
if (uid > 0) {
f->uid = uid;
}
}
db_driver_close(DB_GAME); db_driver_close(DB_GAME);
} }
return err; return err;

View file

@ -47,19 +47,26 @@ static void test_save_load_order(CuTest *tc) {
static void test_update_faction(CuTest *tc) { static void test_update_faction(CuTest *tc) {
faction *f; faction *f;
int uid; int err;
dbrow_id id;
test_setup(); test_setup();
db_driver_open(DB_GAME, NULL); db_driver_open(DB_GAME, NULL);
f = test_create_faction(NULL); f = test_create_faction(NULL);
uid = db_driver_faction_save(f->uid, f->no, 0, CuAssertIntEquals(tc, 0, f->uid);
id = 0;
err = db_driver_faction_save(&id, f->no,
faction_getemail(f), faction_getemail(f),
faction_getpassword(f)); faction_getpassword(f));
f->uid = uid; CuAssertTrue(tc, 0 != id);
uid = db_driver_faction_save(f->uid, f->no, 0, f->uid = (int)id;
db_driver_close(DB_GAME);
db_driver_open(DB_GAME, NULL);
db_driver_faction_save(&id, f->no,
faction_getemail(f), faction_getemail(f),
faction_getpassword(f)); faction_getpassword(f));
CuAssertIntEquals(tc, f->uid, uid); CuAssertIntEquals(tc, f->uid, id);
db_driver_close(DB_GAME); db_driver_close(DB_GAME);
test_teardown(); test_teardown();
} }

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <stddef.h> #include <stddef.h>
#include <stdbool.h>
struct order_data; struct order_data;
@ -17,6 +18,17 @@ int db_driver_open(database_t db, const char *dbname);
void db_driver_close(database_t db); void db_driver_close(database_t db);
dbrow_id db_driver_order_save(const char *str); dbrow_id db_driver_order_save(const char *str);
struct order_data *db_driver_order_load(dbrow_id id); struct order_data *db_driver_order_load(dbrow_id id);
dbrow_id db_driver_faction_save(dbrow_id id, int no, int turn, const char *email, const char *password);
dbrow_id db_driver_string_save(const char *s); dbrow_id db_driver_string_save(const char *s);
const char *db_driver_string_load(dbrow_id id, size_t *size); const char *db_driver_string_load(dbrow_id id, size_t *size);
void db_driver_compact(int turn);
typedef struct db_faction {
int *p_uid;
int no;
const char *email;
char pwhash[128];
} db_faction;
typedef int (*db_faction_generator)(void *, db_faction *, int);
int db_driver_update_factions(db_faction_generator gen, void *data);
int db_driver_faction_save(dbrow_id * p_id, int no, const char *email, const char *password);

View file

@ -95,68 +95,104 @@ dbrow_id db_driver_order_save(const char *str) {
return (dbrow_id)id; return (dbrow_id)id;
} }
int db_driver_faction_save(dbrow_id * p_id, int no, const char *email, const char *password)
dbrow_id db_driver_faction_save(dbrow_id id, int no, int turn, const char *email, const char *password)
{ {
sqlite3_int64 row_id; dbrow_id id = *p_id;
int err; int err;
sqlite3_stmt *stmt = (id > 0) ? g_stmt_update_faction : g_stmt_insert_faction;
assert(g_game_db); assert(g_game_db);
if (id != 0) {
int rows;
err = sqlite3_reset(g_stmt_update_faction); err = sqlite3_reset(stmt);
assert(err == SQLITE_OK); if (err != SQLITE_OK) return err;
err = sqlite3_bind_int(g_stmt_update_faction, 1, no); err = sqlite3_bind_int(stmt, 1, no);
assert(err == SQLITE_OK); if (err != SQLITE_OK) return err;
err = sqlite3_bind_int(g_stmt_update_faction, 2, turn); err = sqlite3_bind_text(stmt, 2, email, -1, SQLITE_STATIC);
assert(err == SQLITE_OK); if (err != SQLITE_OK) return err;
err = sqlite3_bind_text(g_stmt_update_faction, 3, email, -1, SQLITE_STATIC); err = sqlite3_bind_text(stmt, 3, password, -1, SQLITE_STATIC);
assert(err == SQLITE_OK); if (err != SQLITE_OK) return err;
err = sqlite3_bind_text(g_stmt_update_faction, 4, password, -1, SQLITE_STATIC);
assert(err == SQLITE_OK); if (id > 0) {
err = sqlite3_bind_int(g_stmt_update_faction, 5, id); err = sqlite3_bind_int(stmt, 4, id);
assert(err == SQLITE_OK); if (err != SQLITE_OK) return err;
err = sqlite3_step(g_stmt_update_faction);
assert(err == SQLITE_DONE);
rows = sqlite3_changes(g_game_db);
if (rows != 0) {
return id;
}
} }
err = sqlite3_reset(g_stmt_insert_faction); err = sqlite3_step(stmt);
assert(err == SQLITE_OK); if (err != SQLITE_DONE) return err;
err = sqlite3_bind_int(g_stmt_insert_faction, 1, no);
assert(err == SQLITE_OK);
err = sqlite3_bind_int(g_stmt_insert_faction, 2, turn);
assert(err == SQLITE_OK);
err = sqlite3_bind_text(g_stmt_insert_faction, 3, email, -1, SQLITE_STATIC);
assert(err == SQLITE_OK);
err = sqlite3_bind_text(g_stmt_insert_faction, 4, password, -1, SQLITE_STATIC);
assert(err == SQLITE_OK);
err = sqlite3_step(g_stmt_insert_faction);
assert(err == SQLITE_DONE);
ERRNO_CHECK(); ERRNO_CHECK();
row_id = sqlite3_last_insert_rowid(g_game_db); if (id <= 0) {
assert(row_id>0 && row_id <= UINT_MAX); sqlite3_int64 row_id;
return (dbrow_id)row_id; row_id = sqlite3_last_insert_rowid(g_game_db);
assert(row_id > 0 && row_id <= UINT_MAX);
*p_id = (dbrow_id)row_id;
}
return SQLITE_OK;
}
int db_driver_update_factions(db_faction_generator gen, void *data)
{
db_faction results[32];
int num, err;
err = sqlite3_exec(g_game_db, "BEGIN TRANSACTION", NULL, NULL, NULL);
assert(err == SQLITE_OK);
err = sqlite3_exec(g_game_db, "DELETE FROM `faction`", NULL, NULL, NULL);
if (err != SQLITE_OK) {
sqlite3_exec(g_game_db, "ROLLBACK", NULL, NULL, NULL);
return err;
}
num = gen(data, results, 32);
while (num > 0) {
int i;
for (i = 0; i != num; ++i) {
db_faction *dbf = results + i;
dbrow_id id = (dbrow_id)*dbf->p_uid;
err = db_driver_faction_save(&id, dbf->no, dbf->email, dbf->pwhash);
if (err != SQLITE_OK) {
sqlite3_exec(g_game_db, "ROLLBACK", NULL, NULL, NULL);
return err;
}
assert(id > 0 && id <= INT_MAX);
*dbf->p_uid = (int)id;
}
num = gen(data, results, 32);
}
err = sqlite3_exec(g_game_db, "COMMIT", NULL, NULL, NULL);
return err;
}
static int cb_int_col(void *data, int ncols, char **text, char **name) {
int *p_int = (int *)data;
*p_int = atoi(text[0]);
return SQLITE_OK;
} }
static int db_open_game(const char *dbname) { static int db_open_game(const char *dbname) {
int err; int err, version = 0;
err = sqlite3_open(dbname, &g_game_db); err = sqlite3_open(dbname, &g_game_db);
assert(err == SQLITE_OK); assert(err == SQLITE_OK);
err = sqlite3_exec(g_game_db, "CREATE TABLE IF NOT EXISTS factions (id INTEGER PRIMARY KEY, no INTEGER NOT NULL, email VARCHAR(128), password VARCHAR(128), turn INTEGER NOT NULL)", NULL, NULL, NULL);
err = sqlite3_exec(g_game_db, "PRAGMA user_version", cb_int_col, &version, NULL);
assert(err == SQLITE_OK); assert(err == SQLITE_OK);
err = sqlite3_prepare_v2(g_game_db, "UPDATE factions SET no=?, turn=?, email=?, password=? WHERE id=?", -1, &g_stmt_update_faction, NULL); if (version < 1) {
/* drop deprecated table */
err = sqlite3_exec(g_game_db, "DROP TABLE IF EXISTS `factions`", NULL, NULL, NULL);
assert(err == SQLITE_OK);
/* install schema version 1: */
err = sqlite3_exec(g_game_db, "CREATE TABLE IF NOT EXISTS `faction` (`id` INTEGER PRIMARY KEY, `no` INTEGER NOT NULL UNIQUE, `email` VARCHAR(128), `password` VARCHAR(128))", NULL, NULL, NULL);
assert(err == SQLITE_OK);
err = sqlite3_exec(g_game_db, "PRAGMA user_version = 1", NULL, NULL, NULL);
assert(err == SQLITE_OK);
}
/* create prepared statments: */
err = sqlite3_prepare_v2(g_game_db, "INSERT INTO `faction` (`no`, `email`, `password`, `id`) VALUES (?,?,?,?)", -1, &g_stmt_update_faction, NULL);
assert(err == SQLITE_OK); assert(err == SQLITE_OK);
err = sqlite3_prepare_v2(g_game_db, "INSERT INTO factions (no, turn, email, password) VALUES (?,?,?,?)", -1, &g_stmt_insert_faction, NULL); err = sqlite3_prepare_v2(g_game_db, "INSERT INTO `faction` (`no`, `email`, `password`) VALUES (?,?,?)", -1, &g_stmt_insert_faction, NULL);
assert(err == SQLITE_OK); assert(err == SQLITE_OK);
ERRNO_CHECK(); ERRNO_CHECK();
return 0; return err;
} }
static int db_open_swap(const char *dbname) { static int db_open_swap(const char *dbname) {
@ -303,3 +339,13 @@ const char *db_driver_string_load(dbrow_id id, size_t *size) {
ERRNO_CHECK(); ERRNO_CHECK();
return NULL; return NULL;
} }
void db_driver_compact(int turn)
{
int err;
/* repack database: */
err = sqlite3_exec(g_game_db, "VACUUM", 0, 0, 0);
assert(err == SQLITE_OK);
}

View file

@ -7,9 +7,9 @@ IF EXIST ..\build-vs15 SET BUILD=..\build-vs15\eressea\Debug
SET SERVER=%BUILD%\eressea.exe SET SERVER=%BUILD%\eressea.exe
%BUILD%\test_eressea.exe %BUILD%\test_eressea.exe
%SERVER% ..\scripts\run-tests.lua %SERVER% -v1 ..\scripts\run-tests.lua
%SERVER% -re2 ..\scripts\run-tests-e2.lua %SERVER% -v1 -re2 ..\scripts\run-tests-e2.lua
%SERVER% -re3 ..\scripts\run-tests-e3.lua %SERVER% -v1 -re3 ..\scripts\run-tests-e3.lua
%SERVER% --version %SERVER% --version
PAUSE PAUSE
RMDIR /s /q reports RMDIR /s /q reports