Revert "remove sqlite3 code and dependency"

This reverts commit 7b55a57610.
This commit is contained in:
Enno Rehling 2017-01-22 12:57:25 +01:00
parent 59916d1d5c
commit f86d86d4c6
7 changed files with 322 additions and 0 deletions

View File

@ -9,6 +9,7 @@ project (eressea-server C)
enable_testing()
find_package (LibXml2)
find_package (SQLite3)
find_package (Curses)
find_package (Lua REQUIRED)
find_package (ToLua REQUIRED)

View File

@ -39,3 +39,9 @@ fi
source ${FACTION}.sh $EMAIL || reply "Unbekannte Partei $FACTION"
if [ -e $ERESSEA/game-$GAME/eressea.db ]; then
SQL="select email from faction f left join faction_data fd on fd.faction_id=f.id where f.game_id=$GAME AND fd.code='$FACTION' and fd.turn=(select max(turn) from faction_data fx where fx.faction_id=f.id)"
OWNER=$(sqlite3 $ERESSEA/game-$GAME/eressea.db "$SQL")
echo "Der Report Deiner Partei wurde an ${EMAIL} gesandt." \
| mutt -s "Reportnachforderung Partei ${FACTION}" $OWNER
fi

View File

@ -155,6 +155,13 @@ set(SERVER_SRC
bind_unit.c
)
if (SQLITE3_FOUND)
set (SERVER_SRC ${SERVER_SRC}
sqlite.c
bind_sqlite.c
)
endif (SQLITE3_FOUND)
if (CURSES_FOUND)
set (SERVER_SRC ${SERVER_SRC}
gmtool.c
@ -244,6 +251,11 @@ add_test(server test_eressea)
install(TARGETS eressea DESTINATION "bin")
if (SQLITE3_FOUND)
target_link_libraries(eressea ${SQLITE3_LIBRARIES})
add_definitions(-DUSE_SQLITE)
endif(SQLITE3_FOUND)
if (CURSES_FOUND)
include_directories (${CURSES_INCLUDE_DIR})
target_link_libraries(eressea ${CURSES_LIBRARIES})

95
src/bind_sqlite.c Normal file
View File

@ -0,0 +1,95 @@
/*
+-------------------+
| | Enno Rehling <enno@eressea.de>
| Eressea PBEM host | Christian Schlittchen <corwin@amber.kn-bremen.de>
| (c) 1998 - 2008 | Katja Zedel <katze@felidae.kn-bremen.de>
| | Henning Peters <faroul@beyond.kn-bremen.de>
+-------------------+
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
*/
#include <platform.h>
#include "bind_unit.h"
#include "bindings.h"
#include <kernel/config.h>
#include <sqlite3.h>
#include <tolua.h>
#define LTYPE_DB TOLUA_CAST "db"
extern int db_update_factions(sqlite3 * db, bool force, int game);
static int tolua_db_update_factions(lua_State * L)
{
sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0);
db_update_factions(db, tolua_toboolean(L, 2, 0), game_id());
return 0;
}
extern int db_update_scores(sqlite3 * db, bool force);
static int tolua_db_update_scores(lua_State * L)
{
sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0);
db_update_scores(db, tolua_toboolean(L, 2, 0));
return 0;
}
static int tolua_db_execute(lua_State * L)
{
sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0);
const char *sql = tolua_tostring(L, 2, 0);
int res = sqlite3_exec(db, sql, 0, 0, 0);
lua_pushinteger(L, res);
return 1;
}
static int tolua_db_close(lua_State * L)
{
sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0);
sqlite3_close(db);
return 0;
}
static int tolua_db_create(lua_State * L)
{
sqlite3 *db;
const char *dbname = tolua_tostring(L, 1, 0);
int result = sqlite3_open_v2(dbname, &db, SQLITE_OPEN_READWRITE, 0);
if (result == SQLITE_OK) {
tolua_pushusertype(L, (void *)db, LTYPE_DB);
return 1;
}
return 0;
}
int tolua_sqlite_open(lua_State * L)
{
/* register user types */
tolua_usertype(L, LTYPE_DB);
tolua_module(L, NULL, 0);
tolua_beginmodule(L, NULL);
{
tolua_cclass(L, LTYPE_DB, LTYPE_DB, TOLUA_CAST "", NULL);
tolua_beginmodule(L, LTYPE_DB);
{
tolua_function(L, TOLUA_CAST "open", &tolua_db_create);
tolua_function(L, TOLUA_CAST "close", &tolua_db_close);
tolua_function(L, TOLUA_CAST "update_factions",
&tolua_db_update_factions);
tolua_function(L, TOLUA_CAST "update_scores", &tolua_db_update_scores);
tolua_function(L, TOLUA_CAST "execute", &tolua_db_execute);
}
tolua_endmodule(L);
}
tolua_endmodule(L);
return 0;
}

View File

@ -1149,6 +1149,9 @@ lua_State *lua_init(const dictionary *inifile) {
register_tolua_helpers();
tolua_bindings_open(L, inifile);
tolua_eressea_open(L);
#ifdef USE_SQLITE
tolua_sqlite_open(L);
#endif
tolua_unit_open(L);
tolua_building_open(L);
tolua_ship_open(L);

View File

@ -18,6 +18,7 @@ extern "C" {
struct selist;
struct _dictionary_;
int tolua_sqlite_open(struct lua_State *L);
int tolua_bindings_open(struct lua_State *L, const struct _dictionary_ *d);
int tolua_itemlist_next(struct lua_State *L);
int tolua_orderlist_next(struct lua_State *L);

204
src/sqlite.c Normal file
View File

@ -0,0 +1,204 @@
#include <platform.h>
#include <kernel/config.h>
#include <kernel/faction.h>
#include <kernel/race.h>
#include <util/language.h>
#include <util/log.h>
#include <util/base36.h>
#include <util/log.h>
#include <quicklist.h>
#include <sqlite3.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
faction *get_faction_by_id(int uid)
{
faction *f;
for (f = factions; f; f = f->next) {
if (f->subscription == uid) {
return f;
}
}
return NULL;
}
/*
typedef struct stmt_cache {
sqlite3 *db;
sqlite3_stmt *stmt;
const char *sql;
int inuse;
} stmt_cache;
#define MAX_STMT_CACHE 64
static stmt_cache cache[MAX_STMT_CACHE];
static int cache_insert;
static sqlite3_stmt *stmt_cache_get(sqlite3 * db, const char *sql)
{
int i;
sqlite3_stmt *stmt;
for (i = 0; i != MAX_STMT_CACHE && cache[i].db; ++i) {
if (cache[i].sql == sql && cache[i].db == db) {
cache[i].inuse = 1;
stmt = cache[i].stmt;
sqlite3_reset(stmt);
sqlite3_clear_bindings(stmt);
return stmt;
}
}
if (i == MAX_STMT_CACHE) {
while (cache[cache_insert].inuse) {
cache[cache_insert].inuse = 0;
cache_insert = (cache_insert + 1) & (MAX_STMT_CACHE - 1);
}
i = cache_insert;
stmt = cache[i].stmt;
sqlite3_finalize(stmt);
}
cache[i].inuse = 1;
cache[i].db = db;
cache[i].sql = sql;
sqlite3_prepare_v2(db, sql, -1, &cache[i].stmt, NULL);
return cache[i].stmt;
}
*/
typedef struct db_faction {
int uid;
int no;
char *email;
char *name;
} db_faction;
static struct quicklist *
read_factions(sqlite3 * db, int game_id) {
int res;
quicklist *result = 0;
const char * sql =
"SELECT f.id, fd.code, fd.name, fd.email FROM faction f"
" LEFT OUTER JOIN faction_data fd"
" WHERE f.id=fd.faction_id AND f.game_id=? AND"
" fd.turn=(SELECT MAX(turn) FROM faction_data fx WHERE fx.faction_id=f.id)"
" ORDER BY f.id";
sqlite3_stmt *stmt = 0;
sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
sqlite3_bind_int(stmt, 1, game_id);
res = sqlite3_step(stmt);
while (res == SQLITE_ROW) {
const char * text;
db_faction * dbf = (db_faction*)calloc(1, sizeof(db_faction));
dbf->uid = (int)sqlite3_column_int64(stmt, 0);
text = (const char *)sqlite3_column_text(stmt, 1);
if (text) dbf->no = atoi36(text);
text = (const char *)sqlite3_column_text(stmt, 2);
if (text) dbf->name = strdup(text);
text = (const char *)sqlite3_column_text(stmt, 3);
if (text) dbf->email = strdup(text);
ql_push(&result, dbf);
res = sqlite3_step(stmt);
}
sqlite3_finalize(stmt);
return result;
}
static int insert_faction(sqlite3 *db, int game_id, faction *f) {
const char *sql = "INSERT INTO faction (game_id, race) VALUES (?, ?)";
sqlite3_stmt *stmt = 0;
sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
sqlite3_bind_int(stmt, 1, game_id);
sqlite3_bind_text(stmt, 2, f->race->_name, -1, SQLITE_STATIC);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
return (int)sqlite3_last_insert_rowid(db);
}
static void update_faction(sqlite3 *db, const faction *f) {
char code[5];
const char *sql =
"INSERT INTO faction_data (faction_id, code, name, email, lang, turn)"
" VALUES (?, ?, ?, ?, ?, ?)";
sqlite3_stmt *stmt = 0;
strcpy(code, itoa36(f->no));
sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
sqlite3_bind_int(stmt, 1, f->subscription);
sqlite3_bind_text(stmt, 2, code, -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 3, f->name, -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 4, f->email, -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 5, locale_name(f->locale), -1, SQLITE_STATIC);
sqlite3_bind_int(stmt, 6, turn);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
}
int db_update_factions(sqlite3 * db, bool force, int game_id) {
quicklist *ql = read_factions(db, game_id);
faction *f;
sqlite3_exec(db, "BEGIN", 0, 0, 0);
for (f = factions; f; f = f->next) {
bool update = force;
db_faction *dbf = 0;
ql_iter it = qli_init(&ql);
while (qli_more(it)) {
db_faction *df = (db_faction*)qli_next(&it);
if (f->no == df->no || strcmp(f->email, df->email) == 0 || strcmp(f->name, df->name) == 0) {
dbf = df;
}
if (f->subscription == df->uid) {
dbf = df;
break;
}
}
if (dbf) {
if (dbf->uid != f->subscription) {
log_warning("faction %s(%d) not found in database, but matches %d\n", itoa36(f->no), f->subscription, dbf->uid);
f->subscription = dbf->uid;
}
update = (dbf->no != f->no) || (strcmp(f->email, dbf->email) != 0) || (strcmp(f->name, dbf->name) != 0);
}
else {
f->subscription = insert_faction(db, game_id, f);
log_warning("faction %s not found in database, created as %d\n", itoa36(f->no), f->subscription);
update = true;
}
if (update) {
update_faction(db, f);
log_debug("faction %s updated\n", itoa36(f->no));
}
}
sqlite3_exec(db, "COMMIT", 0, 0, 0);
return SQLITE_OK;
}
int db_update_scores(sqlite3 * db, bool force)
{
/*
const char *sql_ins =
"INSERT OR FAIL INTO score (value,faction_id,turn) VALUES (?,?,?)";
sqlite3_stmt *stmt_ins = stmt_cache_get(db, sql_ins);
const char *sql_upd =
"UPDATE score set value=? WHERE faction_id=? AND turn=?";
sqlite3_stmt *stmt_upd = stmt_cache_get(db, sql_upd);
faction *f;
sqlite3_exec(db, "BEGIN", 0, 0, 0);
for (f = factions; f; f = f->next) {
int res;
sqlite3_bind_int(stmt_ins, 1, f->score);
sqlite3_bind_int64(stmt_ins, 2, f->subscription);
sqlite3_bind_int(stmt_ins, 3, turn);
res = sqlite3_step(stmt_ins);
if (res == SQLITE_CONSTRAINT) {
sqlite3_bind_int(stmt_upd, 1, f->score);
sqlite3_bind_int64(stmt_upd, 2, f->subscription);
sqlite3_bind_int(stmt_upd, 3, turn);
res = sqlite3_step(stmt_upd);
sqlite3_reset(stmt_upd);
}
sqlite3_reset(stmt_ins);
}
sqlite3_exec(db, "COMMIT", 0, 0, 0);
*/
return SQLITE_OK;
}