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):
conn = sqlite3.connect(file)
c = conn.cursor()
c.execute('SELECT MAX(turn) FROM factions')
args = c.fetchone()
for row in c.execute('SELECT no, email, password FROM factions WHERE turn=?', args):
for row in c.execute('SELECT `no`, `email`, `password` FROM `faction`'):
(no, email, passwd) = row
self.set_data(baseconvert(no, 36), email, passwd)
conn.close()

View File

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

View File

@ -9,9 +9,25 @@
#include "kernel/faction.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)
{
faction *f;
int err;
const char *dbname;
@ -19,14 +35,9 @@ int gamedb_update(void)
err = db_driver_open(DB_GAME, dbname);
if (err == 0) {
for (f = factions; f; f = f->next) {
int uid = db_driver_faction_save(f->uid, f->no, turn,
faction_getemail(f),
faction_getpassword(f));
if (uid > 0) {
f->uid = uid;
}
}
faction *list = factions;
db_driver_update_factions(generate_factions, &list);
db_driver_compact(turn);
db_driver_close(DB_GAME);
}
return err;

View File

@ -47,19 +47,26 @@ static void test_save_load_order(CuTest *tc) {
static void test_update_faction(CuTest *tc) {
faction *f;
int uid;
int err;
dbrow_id id;
test_setup();
db_driver_open(DB_GAME, 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_getpassword(f));
f->uid = uid;
uid = db_driver_faction_save(f->uid, f->no, 0,
CuAssertTrue(tc, 0 != id);
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_getpassword(f));
CuAssertIntEquals(tc, f->uid, uid);
CuAssertIntEquals(tc, f->uid, id);
db_driver_close(DB_GAME);
test_teardown();
}

View File

@ -1,6 +1,7 @@
#pragma once
#include <stddef.h>
#include <stdbool.h>
struct order_data;
@ -17,6 +18,17 @@ int db_driver_open(database_t db, const char *dbname);
void db_driver_close(database_t db);
dbrow_id db_driver_order_save(const char *str);
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);
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;
}
dbrow_id db_driver_faction_save(dbrow_id id, int no, int turn, const char *email, const char *password)
int db_driver_faction_save(dbrow_id * p_id, int no, const char *email, const char *password)
{
sqlite3_int64 row_id;
dbrow_id id = *p_id;
int err;
sqlite3_stmt *stmt = (id > 0) ? g_stmt_update_faction : g_stmt_insert_faction;
assert(g_game_db);
if (id != 0) {
int rows;
err = sqlite3_reset(g_stmt_update_faction);
assert(err == SQLITE_OK);
err = sqlite3_bind_int(g_stmt_update_faction, 1, no);
assert(err == SQLITE_OK);
err = sqlite3_bind_int(g_stmt_update_faction, 2, turn);
assert(err == SQLITE_OK);
err = sqlite3_bind_text(g_stmt_update_faction, 3, email, -1, SQLITE_STATIC);
assert(err == SQLITE_OK);
err = sqlite3_bind_text(g_stmt_update_faction, 4, password, -1, SQLITE_STATIC);
assert(err == SQLITE_OK);
err = sqlite3_bind_int(g_stmt_update_faction, 5, id);
assert(err == SQLITE_OK);
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(stmt);
if (err != SQLITE_OK) return err;
err = sqlite3_bind_int(stmt, 1, no);
if (err != SQLITE_OK) return err;
err = sqlite3_bind_text(stmt, 2, email, -1, SQLITE_STATIC);
if (err != SQLITE_OK) return err;
err = sqlite3_bind_text(stmt, 3, password, -1, SQLITE_STATIC);
if (err != SQLITE_OK) return err;
if (id > 0) {
err = sqlite3_bind_int(stmt, 4, id);
if (err != SQLITE_OK) return err;
}
err = sqlite3_reset(g_stmt_insert_faction);
assert(err == SQLITE_OK);
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);
err = sqlite3_step(stmt);
if (err != SQLITE_DONE) return err;
ERRNO_CHECK();
row_id = sqlite3_last_insert_rowid(g_game_db);
assert(row_id>0 && row_id <= UINT_MAX);
return (dbrow_id)row_id;
if (id <= 0) {
sqlite3_int64 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) {
int err;
int err, version = 0;
err = sqlite3_open(dbname, &g_game_db);
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);
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);
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);
ERRNO_CHECK();
return 0;
return err;
}
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();
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
%BUILD%\test_eressea.exe
%SERVER% ..\scripts\run-tests.lua
%SERVER% -re2 ..\scripts\run-tests-e2.lua
%SERVER% -re3 ..\scripts\run-tests-e3.lua
%SERVER% -v1 ..\scripts\run-tests.lua
%SERVER% -v1 -re2 ..\scripts\run-tests-e2.lua
%SERVER% -v1 -re3 ..\scripts\run-tests-e3.lua
%SERVER% --version
PAUSE
RMDIR /s /q reports