Further file organization
Further file organization
This commit is contained in:
306
nwn/nwnprc/trunk/include/inc_sql.nss
Normal file
306
nwn/nwnprc/trunk/include/inc_sql.nss
Normal file
@@ -0,0 +1,306 @@
|
||||
/**
|
||||
* @file
|
||||
* All the functions dealing with the NWNx database. Based on the APS include
|
||||
* with optimisations, renamed to avoid naming clashes with the APS system.
|
||||
* @author Primogenitor, motu99, fluffyamoeba
|
||||
* @date created on 2009-01-25
|
||||
*/
|
||||
|
||||
const int PRC_SQL_ERROR = 0;
|
||||
const int PRC_SQL_SUCCESS = 1;
|
||||
const string XCHST_DB = "xchst_db";
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Function prototypes */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
// creates and stores a 1024 Byte string for database-fetches on the module
|
||||
void PRC_SQLInit();
|
||||
|
||||
// executes an SQL command direclty
|
||||
void PRC_SQLExecDirect(string sSQL);
|
||||
|
||||
// fetches data from a previous SQL fetch request; returns TRUE is fetch was successful
|
||||
int PRC_SQLFetch();
|
||||
|
||||
// gets the actual data from a fetch; if a table with more than 1 column was requested, return the table element at column iCol
|
||||
string PRC_SQLGetData(int iCol);
|
||||
|
||||
// SQLite and MYSQL use different syntaxes
|
||||
string PRC_SQLGetTick();
|
||||
|
||||
// Problems can arise with SQL commands if variables or values have single quotes
|
||||
// in their names. These functions are a replace these quote with the tilde character
|
||||
string ReplaceSingleChars(string sString, string sTarget, string sReplace);
|
||||
|
||||
// only needed for SQLite; commits (actually stores) the changed to the database
|
||||
void PRC_SQLiteCommit();
|
||||
// starts the pseudo heartbeat for committing SQLite DB
|
||||
void StartSQLiteCommitHB();
|
||||
// pseudo heartbeat for committing SQLite DB; interval given in switch PRC_DB_SQLITE_INTERVAL
|
||||
// default is 600 seconds (= 10 min)
|
||||
void SQLiteCommitHB();
|
||||
|
||||
// Set oObject's persistent object with sVarName to sValue
|
||||
// Optional parameters:
|
||||
// iExpiration: Number of days the persistent variable should be kept in database (default: 0=forever)
|
||||
// sTable: Name of the table where variable should be stored (default: pwobjdata)
|
||||
void PRC_SetPersistentObject(object oObject, string sVarName, object oObject2, int iExpiration = 0, string sTable = "pwobjdata");
|
||||
|
||||
// Get oObject's persistent object sVarName
|
||||
// Optional parameters:
|
||||
// sTable: Name of the table where object is stored (default: pwobjdata)
|
||||
// * Return value on error: 0
|
||||
object PRC_GetPersistentObject(object oObject, string sVarName, object oOwner = OBJECT_INVALID, string sTable = "pwobjdata");
|
||||
|
||||
// Portable presistent chest system (X-Chest) nwnx database support
|
||||
//
|
||||
void CreateXChestDB_SQLite();
|
||||
void CreateXChestDB_MySQL();
|
||||
void DeleteXChestDB();
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Function definitions */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
void PRC_SQLInit()
|
||||
{
|
||||
int i;
|
||||
|
||||
// Placeholder for ODBC persistence
|
||||
string sMemory;
|
||||
|
||||
for (i = 0; i < 8; i++) // reserve 8*128 bytes
|
||||
sMemory +=
|
||||
"................................................................................................................................";
|
||||
|
||||
SetLocalString(GetModule(), "NWNX!ODBC!SPACER", sMemory);
|
||||
}
|
||||
|
||||
void PRC_SQLExecDirect(string sSQL)
|
||||
{
|
||||
SetLocalString(GetModule(), "NWNX!ODBC!EXEC", sSQL);
|
||||
}
|
||||
|
||||
int PRC_SQLFetch()
|
||||
{
|
||||
string sRow;
|
||||
object oModule = GetModule();
|
||||
|
||||
// initialize the fetch string to a large 1024 Byte string; this will also trigger the fetch operation in NWNX
|
||||
SetLocalString(oModule, "NWNX!ODBC!FETCH", GetLocalString(oModule, "NWNX!ODBC!SPACER"));
|
||||
|
||||
// get the result from the fetch
|
||||
sRow = GetLocalString(oModule, "NWNX!ODBC!FETCH");
|
||||
if (GetStringLength(sRow) > 0)
|
||||
{
|
||||
// store the result on the module and signal success
|
||||
SetLocalString(oModule, "NWNX_ODBC_CurrentRow", sRow);
|
||||
return PRC_SQL_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
// set the result string on the module to empty and signal failure
|
||||
SetLocalString(oModule, "NWNX_ODBC_CurrentRow", "");
|
||||
return PRC_SQL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/** @todo check mySQL manual, not sure if this is needed - fluffyamoeba */
|
||||
string PRC_SQLGetTick()
|
||||
{
|
||||
if(GetPRCSwitch(PRC_DB_SQLITE)) return "";
|
||||
else return "`";
|
||||
}
|
||||
|
||||
string PRC_SQLGetData(int iCol)
|
||||
{
|
||||
string sResultSet = GetLocalString(GetModule(), "NWNX_ODBC_CurrentRow");
|
||||
int iPos = FindSubString(sResultSet, "<22>");
|
||||
if (iCol == 1)
|
||||
{
|
||||
// only one column returned ? Then we are finished
|
||||
if (iPos == -1) return sResultSet;
|
||||
// more than one column returned ? Then return first column
|
||||
else return GetStringLeft(sResultSet, iPos);
|
||||
}
|
||||
// more than one column requested, but only one returned ? Something went wrong; return empty string
|
||||
else if (iPos == -1) return "";
|
||||
|
||||
// find column in current row
|
||||
int iCount = 0;
|
||||
int nLength = GetStringLength(sResultSet);
|
||||
|
||||
// loop through columns until found
|
||||
while (iCount++ != iCol)
|
||||
{
|
||||
if (iCount == iCol)
|
||||
return GetStringLeft(sResultSet, iPos);
|
||||
|
||||
// pull off the previous column and find new column marker
|
||||
nLength -= (iPos + 1);
|
||||
sResultSet = GetStringRight(sResultSet, nLength);
|
||||
iPos = FindSubString(sResultSet, "<22>");
|
||||
|
||||
// special case: last column in row
|
||||
if (iPos == -1) return sResultSet;
|
||||
}
|
||||
|
||||
return sResultSet;
|
||||
}
|
||||
|
||||
string ReplaceSingleChars(string sString, string sTarget, string sReplace)
|
||||
{
|
||||
if (FindSubString(sString, sTarget) == -1) // not found
|
||||
return sString;
|
||||
|
||||
int i;
|
||||
string sReturn = "";
|
||||
string sChar;
|
||||
|
||||
// Loop over every character and replace special characters
|
||||
for (i = 0; i < GetStringLength(sString); i++)
|
||||
{
|
||||
sChar = GetSubString(sString, i, 1);
|
||||
if (sChar == sTarget)
|
||||
sReturn += sReplace;
|
||||
else
|
||||
sReturn += sChar;
|
||||
}
|
||||
return sReturn;
|
||||
}
|
||||
|
||||
// only needed for SQLite; commits (actually stores) the changed to the database
|
||||
void PRC_SQLiteCommit()
|
||||
{
|
||||
PRC_SQLExecDirect("COMMIT");
|
||||
PRC_SQLExecDirect("BEGIN IMMEDIATE");
|
||||
}
|
||||
|
||||
// starts the pseudo heartbeat for committing SQLite DB
|
||||
void StartSQLiteCommitHB()
|
||||
{
|
||||
if (GetPRCSwitch(PRC_DB_SQLITE))
|
||||
{
|
||||
int nInterval = GetPRCSwitch(PRC_DB_SQLITE_INTERVAL);
|
||||
DelayCommand(nInterval ? IntToFloat(nInterval) : 600.0f, SQLiteCommitHB());
|
||||
}
|
||||
}
|
||||
|
||||
// pseudo heartbeat for committing SQLite DB; interval given in switch PRC_DB_SQLITE_INTERVAL
|
||||
// default is 600 seconds (= 10 min)
|
||||
void SQLiteCommitHB()
|
||||
{
|
||||
// check if we are still using SQLite
|
||||
if (GetPRCSwitch(PRC_DB_SQLITE))
|
||||
{
|
||||
// do the commit
|
||||
PRC_SQLExecDirect("COMMIT");
|
||||
PRC_SQLExecDirect("BEGIN IMMEDIATE");
|
||||
|
||||
// continue pseudo heartbeat
|
||||
int nInterval = GetPRCSwitch(PRC_DB_SQLITE_INTERVAL);
|
||||
DelayCommand(nInterval ? IntToFloat(nInterval) : 600.0f, SQLiteCommitHB());
|
||||
}
|
||||
}
|
||||
|
||||
void PRC_SetPersistentObject(object oOwner, string sVarName, object oObject, int iExpiration = 0, string sTable = "pwobjdata")
|
||||
{
|
||||
string sPlayer;
|
||||
string sTag;
|
||||
|
||||
if (GetIsPC(oOwner))
|
||||
{
|
||||
sPlayer = ReplaceSingleChars(GetPCPlayerName(oOwner), "'", "~");
|
||||
sTag = ReplaceSingleChars(GetName(oOwner), "'", "~");
|
||||
}
|
||||
else
|
||||
{
|
||||
sPlayer = "~";
|
||||
sTag = GetTag(oOwner);
|
||||
}
|
||||
sVarName = ReplaceSingleChars(sVarName, "'", "~");
|
||||
|
||||
string sSQL = "SELECT player FROM " + sTable + " WHERE player='" + sPlayer +
|
||||
"' AND tag='" + sTag + "' AND name='" + sVarName + "'";
|
||||
PRC_SQLExecDirect(sSQL);
|
||||
|
||||
if (PRC_SQLFetch() == PRC_SQL_SUCCESS)
|
||||
{
|
||||
// row exists
|
||||
sSQL = "UPDATE " + sTable + " SET val=%s,expire=" + IntToString(iExpiration) +
|
||||
" WHERE player='" + sPlayer + "' AND tag='" + sTag + "' AND name='" + sVarName + "'";
|
||||
SetLocalString(GetModule(), "NWNX!ODBC!SETSCORCOSQL", sSQL);
|
||||
StoreCampaignObject ("NWNX", "-", oObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
// row doesn't exist
|
||||
sSQL = "INSERT INTO " + sTable + " (player,tag,name,val,expire) VALUES" +
|
||||
"('" + sPlayer + "','" + sTag + "','" + sVarName + "',%s," + IntToString(iExpiration) + ")";
|
||||
SetLocalString(GetModule(), "NWNX!ODBC!SETSCORCOSQL", sSQL);
|
||||
StoreCampaignObject ("NWNX", "-", oObject);
|
||||
}
|
||||
}
|
||||
|
||||
object PRC_GetPersistentObject(object oObject, string sVarName, object oOwner = OBJECT_INVALID, string sTable = "pwobjdata")
|
||||
{
|
||||
string sPlayer;
|
||||
string sTag;
|
||||
object oModule;
|
||||
|
||||
if (GetIsPC(oObject))
|
||||
{
|
||||
sPlayer = ReplaceSingleChars(GetPCPlayerName(oObject), "'", "~");
|
||||
sTag = ReplaceSingleChars(GetName(oObject), "'", "~");
|
||||
}
|
||||
else
|
||||
{
|
||||
sPlayer = "~";
|
||||
sTag = GetTag(oObject);
|
||||
}
|
||||
sVarName = ReplaceSingleChars(sVarName, "'", "~");
|
||||
|
||||
string sSQL = "SELECT val FROM " + sTable + " WHERE player='" + sPlayer +
|
||||
"' AND tag='" + sTag + "' AND name='" + sVarName + "'";
|
||||
SetLocalString(GetModule(), "NWNX!ODBC!SETSCORCOSQL", sSQL);
|
||||
|
||||
if (!GetIsObjectValid(oOwner))
|
||||
oOwner = oObject;
|
||||
return RetrieveCampaignObject ("NWNX", "-", GetLocation(oOwner), oOwner);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Functions for portable persistent chest */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
void DeleteXChestDB()
|
||||
{
|
||||
PRC_SQLExecDirect("DROP TABLE "+XCHST_DB);
|
||||
}
|
||||
|
||||
void CreateXChestDB_SQLite()
|
||||
{
|
||||
PRC_SQLExecDirect("CREATE TABLE "+XCHST_DB+" (" +
|
||||
"player varchar(64) NOT NULL default '~'," +
|
||||
"tag varchar(64) NOT NULL default '~'," +
|
||||
"name varchar(64) NOT NULL default '~'," +
|
||||
"val blob," +
|
||||
"expire int(11) default NULL," +
|
||||
"last timestamp NOT NULL default current_timestamp," +
|
||||
"PRIMARY KEY (player,tag,name)" +
|
||||
")");
|
||||
}
|
||||
|
||||
void CreateXChestDB_MySQL()
|
||||
{
|
||||
PRC_SQLExecDirect("CREATE TABLE "+XCHST_DB+" (" +
|
||||
"player varchar(64) NOT NULL default '~'," +
|
||||
"tag varchar(64) NOT NULL default '~'," +
|
||||
"name varchar(64) NOT NULL default '~'," +
|
||||
"val blob," +
|
||||
"expire int(11) default NULL," +
|
||||
"last timestamp NOT NULL default CURRENT_TIMESTAMP," +
|
||||
"PRIMARY KEY (player,tag,name)" +
|
||||
") ENGINE=MyISAM DEFAULT CHARSET=latin1;");
|
||||
}
|
Reference in New Issue
Block a user