summaryrefslogtreecommitdiff
path: root/src/map/mapreg_sql.c
diff options
context:
space:
mode:
authorultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2008-08-15 11:14:45 +0000
committerultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2008-08-15 11:14:45 +0000
commit0d67a194537e8e69426c8f55ced61b0a8701e90a (patch)
treea0dffc2e7af02443e1189e6b4e724414625eb43b /src/map/mapreg_sql.c
parentf16b914ef2bf3f75e1ee42f2277927660acd0116 (diff)
downloadhercules-0d67a194537e8e69426c8f55ced61b0a8701e90a.tar.gz
hercules-0d67a194537e8e69426c8f55ced61b0a8701e90a.tar.bz2
hercules-0d67a194537e8e69426c8f55ced61b0a8701e90a.tar.xz
hercules-0d67a194537e8e69426c8f55ced61b0a8701e90a.zip
Split off mapreg code from script.c
* new mapserver files, mapreg.h, mapreg_txt.c, mapreg_sql.c * removed MAPREGSQL from project files / makefiles * mapreg storage engine is now fully dependent on the server type * added config settings mapreg_txt and mapreg_db to inter config * added get_str() function to complement add_str() * fixed txt mapreg code allowing too long variable names git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@13081 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/mapreg_sql.c')
-rw-r--r--src/map/mapreg_sql.c242
1 files changed, 242 insertions, 0 deletions
diff --git a/src/map/mapreg_sql.c b/src/map/mapreg_sql.c
new file mode 100644
index 000000000..401367611
--- /dev/null
+++ b/src/map/mapreg_sql.c
@@ -0,0 +1,242 @@
+// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
+// For more information, see LICENCE in the main folder
+
+#include "../common/cbasetypes.h"
+#include "../common/db.h"
+#include "../common/malloc.h"
+#include "../common/showmsg.h"
+#include "../common/sql.h"
+#include "../common/strlib.h"
+#include "../common/timer.h"
+#include "map.h" // mmysql_handle
+#include "script.h"
+#include <stdlib.h>
+#include <string.h>
+
+static DBMap* mapreg_db = NULL; // int var_id -> int value
+static DBMap* mapregstr_db = NULL; // int var_id -> char* value
+
+static char mapreg_table[32] = "mapreg";
+static bool mapreg_dirty = false;
+#define MAPREG_AUTOSAVE_INTERVAL (300*1000)
+
+
+/// Looks up the value of an integer variable using its uid.
+int mapreg_readreg(int uid)
+{
+ return (int)idb_get(mapreg_db, uid);
+}
+
+/// Looks up the value of a string variable using its uid.
+char* mapreg_readregstr(int uid)
+{
+ return (char*)idb_get(mapregstr_db, uid);
+}
+
+/// Modifies the value of an integer variable.
+bool mapreg_setreg(int uid, int val)
+{
+ int num = uid & 0x00ffffff;
+ int i = uid & 0xff000000 >> 24;
+ const char* name = get_str(num);
+
+ if( val != 0 )
+ {
+ if( idb_put(mapreg_db,uid,(void*)val) )
+ ; // already exists, delay write
+ else
+ if( name[1] == '@' )
+ ; // nothing more to do
+ else
+ {// write new wariable to database
+ char tmp_str[32*2+1];
+ Sql_EscapeStringLen(mmysql_handle, tmp_str, name, strnlen(name, 32));
+ if( SQL_ERROR == Sql_Query(mmysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%d')", mapreg_table, tmp_str, i, val) )
+ Sql_ShowDebug(mmysql_handle);
+ }
+ }
+ else // val == 0
+ {
+ idb_remove(mapreg_db,uid);
+
+ if( name[1] == '@' )
+ ; // nothing more to do
+ else
+ {// Remove from database because it is unused.
+ if( SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%d'", mapreg_table, name, i) )
+ Sql_ShowDebug(mmysql_handle);
+ }
+ }
+
+ mapreg_dirty = true;
+ return true;
+}
+
+/// Modifies the value of a string variable.
+bool mapreg_setregstr(int uid, const char* str)
+{
+ int num = uid & 0x00ffffff;
+ int i = uid & 0xff000000 >> 24;
+ const char* name = get_str(num);
+
+ if( str == NULL || *str == 0 )
+ {
+ if(name[1] != '@') {
+ if( SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%d'", mapreg_table, name, i) )
+ Sql_ShowDebug(mmysql_handle);
+ }
+ idb_remove(mapregstr_db,uid);
+ }
+ else
+ {
+ if (idb_put(mapregstr_db,uid, aStrdup(str)))
+ ;
+ else if(name[1] != '@') { //put returned null, so we must insert.
+ // Someone is causing a database size infinite increase here without name[1] != '@' [Lance]
+ char tmp_str[32*2+1];
+ char tmp_str2[255*2+1];
+ Sql_EscapeStringLen(mmysql_handle, tmp_str, name, strnlen(name, 32));
+ Sql_EscapeStringLen(mmysql_handle, tmp_str2, str, strnlen(str, 255));
+ if( SQL_ERROR == Sql_Query(mmysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%s')", mapreg_table, tmp_str, i, tmp_str2) )
+ Sql_ShowDebug(mmysql_handle);
+ }
+ }
+
+ mapreg_dirty = true;
+ return true;
+}
+
+/// Loads permanent variables from database
+static void script_load_mapreg(void)
+{
+ /*
+ 0 1 2
+ +-------------------------+
+ | varname | index | value |
+ +-------------------------+
+ */
+ SqlStmt* stmt = SqlStmt_Malloc(mmysql_handle);
+ char varname[32+1];
+ int index;
+ char value[255+1];
+ uint32 length;
+
+ if ( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `varname`, `index`, `value` FROM `%s`", mapreg_table)
+ || SQL_ERROR == SqlStmt_Execute(stmt)
+ ) {
+ SqlStmt_ShowDebug(stmt);
+ SqlStmt_Free(stmt);
+ return;
+ }
+
+ SqlStmt_BindColumn(stmt, 0, SQLDT_STRING, &varname[0], 32, &length, NULL);
+ SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &index, 0, NULL, NULL);
+ SqlStmt_BindColumn(stmt, 2, SQLDT_STRING, &value[0], 255, NULL, NULL);
+
+ while ( SQL_SUCCESS == SqlStmt_NextRow(stmt) )
+ {
+ int s = add_str(varname);
+ int i = index;
+
+ if( varname[length-1] == '$' )
+ idb_put(mapregstr_db, (i<<24)|s, aStrdup(value));
+ else
+ idb_put(mapreg_db, (i<<24)|s, (void *)atoi(value));
+ }
+
+ SqlStmt_Free(stmt);
+
+ mapreg_dirty = false;
+}
+
+/// Saves permanent variables to database
+static void script_save_mapreg(void)
+{
+ DBIterator* iter;
+ void* data;
+ DBKey key;
+
+ iter = mapreg_db->iterator(mapreg_db);
+ for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) )
+ {
+ int num = key.i & 0x00ffffff;
+ int i = key.i & 0xff000000 >> 24;
+ const char* name = get_str(num);
+
+ if( name[1] == '@' )
+ continue;
+
+ if( SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `value`='%d' WHERE `varname`='%s' AND `index`='%d'", mapreg_table, (int)data, name, i) )
+ Sql_ShowDebug(mmysql_handle);
+ }
+ iter->destroy(iter);
+
+ iter = mapregstr_db->iterator(mapregstr_db);
+ for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) )
+ {
+ int num = key.i & 0x00ffffff;
+ int i = key.i & 0xff000000 >> 24;
+ const char* name = get_str(num);
+ char tmp_str2[2*255+1];
+
+ if( name[1] == '@' )
+ continue;
+
+ Sql_EscapeStringLen(mmysql_handle, tmp_str2, (char*)data, safestrnlen((char*)data, 255));
+ if( SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `value`='%s' WHERE `varname`='%s' AND `index`='%d'", mapreg_table, tmp_str2, name, i) )
+ Sql_ShowDebug(mmysql_handle);
+ }
+ iter->destroy(iter);
+
+ mapreg_dirty = false;
+}
+
+static int script_autosave_mapreg(int tid, unsigned int tick, int id, intptr data)
+{
+ if( mapreg_dirty )
+ script_save_mapreg();
+
+ return 0;
+}
+
+
+void mapreg_reload(void)
+{
+ if( mapreg_dirty )
+ script_save_mapreg();
+
+ mapreg_db->clear(mapreg_db, NULL);
+ mapregstr_db->clear(mapregstr_db, NULL);
+
+ script_load_mapreg();
+}
+
+void mapreg_final(void)
+{
+ if( mapreg_dirty )
+ script_save_mapreg();
+
+ mapreg_db->destroy(mapreg_db,NULL);
+ mapregstr_db->destroy(mapregstr_db,NULL);
+}
+
+void mapreg_init(void)
+{
+ mapreg_db = idb_alloc(DB_OPT_BASE);
+ mapregstr_db = idb_alloc(DB_OPT_RELEASE_DATA);
+
+ script_load_mapreg();
+
+ add_timer_func_list(script_autosave_mapreg, "script_autosave_mapreg");
+ add_timer_interval(gettick() + MAPREG_AUTOSAVE_INTERVAL, script_autosave_mapreg, 0, 0, MAPREG_AUTOSAVE_INTERVAL);
+}
+
+bool mapreg_config_read(const char* w1, const char* w2)
+{
+ if(!strcmpi(w1, "mapreg_db"))
+ safestrncpy(mapreg_table, w2, sizeof(mapreg_table));
+ else
+ return false;
+
+ return true;
+}