Jaysyn904 151d074880 Added "Removed Files" folder
Added "Removed Files" folder in case we needed to review any of them.
2022-10-10 10:39:34 -04:00

250 lines
9.8 KiB
Plaintext

#include "nwnx_sql"
#include "nwnx_object"
#include "nwnx_tests"
void cleanup()
{
NWNX_Tests_Report("NWNX_SQL", "Cleanup sql_test", NWNX_SQL_ExecuteQuery("DROP TABLE sql_test"));
NWNX_Tests_Report("NWNX_SQL", "Cleanup stress_test", NWNX_SQL_ExecuteQuery("DROP TABLE stress_test"));
NWNX_Tests_Report("NWNX_SQL", "Cleanup error_test", NWNX_SQL_ExecuteQuery("DROP TABLE error_test"));
}
void main()
{
WriteTimestampedLogEntry("NWNX_SQL unit test begin..");
string db_type = GetStringUpperCase(NWNX_SQL_GetDatabaseType());
WriteTimestampedLogEntry("Testing database " + db_type);
string sCreate = "";
string sInsert = "";
/* MySQL and SQLite version */
if (db_type == "MYSQL" || db_type == "SQLITE")
{
sCreate = "CREATE TABLE sql_test (" +
"colInt INT, colFloat FLOAT, colStr VARCHAR(256)," +
"colObjId INT, colObj TEXT(1000000) );";
sInsert = "INSERT INTO sql_test(colInt, colFloat, colStr, colObjId, colObj) VALUES(?, ?, ?, ?, ?)";
}
/* PostgreSQL version */
if (db_type == "POSTGRESQL")
{
sCreate = "CREATE TABLE sql_test (" +
"colInt INT, colFloat FLOAT, colStr VARCHAR(256)," +
"colObjId INT, colObj TEXT );";
// Even though we're using 0 based parameter numbers, PostgreSQL requires the parameter
// numbers in the actual SQL string to be 1 based (e.g. $1, $2... not $0, $1... )
sInsert = "INSERT INTO sql_test(colInt, colFloat, colStr, colObjId, colObj) VALUES($1, $2, $3, $4, $5)";
}
int b = NWNX_SQL_ExecuteQuery(sCreate);
NWNX_Tests_Report("NWNX_SQL", "Create Table", b);
object o = CreateObject(OBJECT_TYPE_CREATURE, "nw_chicken", GetStartingLocation());
if (!GetIsObjectValid(o))
{
WriteTimestampedLogEntry("NWNX_SQL test: Failed to create creature");
cleanup();
return;
}
vector v = Vector(5.0, 5.0, 0.0); // slightly different location.
b = NWNX_SQL_PrepareQuery(sInsert);
NWNX_Tests_Report("NWNX_SQL", "Complex PrepareQuery", b);
NWNX_Tests_Report("NWNX_SQL", "GetPreparedQueryParamCount", NWNX_SQL_GetPreparedQueryParamCount() == 5);
NWNX_SQL_PreparedInt(0, 42);
NWNX_SQL_PreparedFloat(1, 0.42);
NWNX_SQL_PreparedString(2, "FourtyTwooo");
NWNX_SQL_PreparedObjectId(3, o);
NWNX_SQL_PreparedObjectFull(4, o);
b = NWNX_SQL_ExecutePreparedQuery();
NWNX_Tests_Report("NWNX_SQL", "Complex ExecutePreparedQuery", b);
b = NWNX_SQL_ExecuteQuery("SELECT * FROM sql_test;");
NWNX_Tests_Report("NWNX_SQL", "Select ExecuteQuery", b);
if (b)
{
while (NWNX_SQL_ReadyToReadNextRow())
{
NWNX_SQL_ReadNextRow();
int n = StringToInt(NWNX_SQL_ReadDataInActiveRow(0));
NWNX_Tests_Report("NWNX_SQL", "ReadInt", n == 42);
float f = StringToFloat(NWNX_SQL_ReadDataInActiveRow(1));
NWNX_Tests_Report("NWNX_SQL", "ReadFloat", fabs(f - 0.42) < 0.01);
string s = NWNX_SQL_ReadDataInActiveRow(2);
NWNX_Tests_Report("NWNX_SQL", "ReadString", s == "FourtyTwooo");
string sObjId = NWNX_SQL_ReadDataInActiveRow(3); // In base 10
object o2 = NWNX_Object_StringToObject(IntToHexString(StringToInt(sObjId)));
NWNX_Tests_Report("NWNX_SQL", "ReadObjectId", o == o2);
object o3 = NWNX_SQL_ReadFullObjectInActiveRow(4, GetArea(o), v.x, v.y, v.z);
NWNX_Tests_Report("NWNX_SQL", "ReadFullObject", GetIsObjectValid(o3));
// Alternatively:
// object o3 = NWNX_Object_Deserialize(NWNX_SQL_ReadDataInActiveRow(4));
}
}
object oPlc = CreateObject(OBJECT_TYPE_PLACEABLE, "nw_plc_chestburd", GetStartingLocation());
object oItem = CreateObject(OBJECT_TYPE_ITEM, "x0_it_mring013", GetStartingLocation());
if (!GetIsObjectValid(oPlc) || !GetIsObjectValid(oItem))
{
WriteTimestampedLogEntry("NWNX_SQL test: Failed to create objects..");
}
else
{
object oTmp = GetFirstItemInInventory(oPlc);
while (GetIsObjectValid(oTmp))
{
WriteTimestampedLogEntry("NWNX_SQL Destroying auto created object " + GetTag(oTmp));
DestroyObject(oTmp);
oTmp = GetNextItemInInventory(oPlc);
}
string test2 = "";
if (db_type == "MYSQL" || db_type == "SQLITE")
{
test2="INSERT INTO sql_test(colInt, colFloat, colStr, colObjId, colObj) VALUES(1337,0.0,'xxx',1337,?)";
}
if (db_type == "POSTGRESQL")
{
test2="INSERT INTO sql_test(colInt, colFloat, colStr, colObjId, colObj) VALUES(1337,0.0,'xxx',1337,$1)";
}
NWNX_SQL_PrepareQuery(test2);
NWNX_SQL_PreparedObjectFull(0, oItem);
b = NWNX_SQL_ExecutePreparedQuery();
NWNX_Tests_Report("NWNX_SQL", "Insert item full", b);
b = NWNX_SQL_ExecuteQuery("SELECT colObj FROM sql_test WHERE colInt=1337");
NWNX_Tests_Report("NWNX_SQL", "Select item", b);
if (NWNX_SQL_ReadyToReadNextRow())
{
NWNX_SQL_ReadNextRow();
object oItem2 = NWNX_SQL_ReadFullObjectInActiveRow(0, oPlc);
NWNX_Tests_Report("NWNX_SQL", "ReadFullObject Item", GetIsObjectValid(oItem2));
NWNX_Tests_Report("NWNX_SQL", "Deserialized to placeable's inventory", oItem2 == GetFirstItemInInventory(oPlc));
NWNX_Tests_Report("NWNX_SQL", "Deserialized to placeable's inventory - possessor", GetItemPossessor(oItem2) == oPlc);
object oItem3 = NWNX_SQL_ReadFullObjectInActiveRow(0, GetArea(oPlc), v.x, v.y, v.z);
NWNX_Tests_Report("NWNX_SQL", "Deserialized to area", GetArea(oItem3) == GetArea(oPlc));
object oItem4 = NWNX_SQL_ReadFullObjectInActiveRow(0, o);
NWNX_Tests_Report("NWNX_SQL", "Deserialized to creature's inventory - possessor", GetItemPossessor(oItem4) == o);
}
else
{
WriteTimestampedLogEntry("NWNX_SQL not ready to read item");
}
}
int STRESS_CNT = 10;
WriteTimestampedLogEntry("NWNX_SQL stress test.");
NWNX_SQL_ExecuteQuery("create table stress_test ( i_key int, i_int int, s_text varchar(8))");
int i;
// Brute force some inserts
for ( i=1 ; i<=STRESS_CNT ; i++ ) // Generate 1000 rows.
{
// Simulates the existing NWNX2 ODBC way of generating SQL.
NWNX_SQL_ExecuteQuery("insert into stress_test values ( " + IntToString(i) + ", " + IntToString(i*2) + ", '" + IntToString(i*100) + "')");
}
NWNX_SQL_ExecuteQuery("delete from stress_test where i_key > 0");
int res = NWNX_SQL_GetAffectedRows();
WriteTimestampedLogEntry("Deleted " + IntToString(res) + " rows.");
report ("Delete rows", res == STRESS_CNT);
// now do some elegant inserts
string test3 = "";
if (db_type == "MYSQL" || db_type == "SQLITE")
{
test3 = "insert into stress_test values ( ?, ?, ? )";
}
if (db_type == "POSTGRESQL")
{
test3 = "insert into stress_test values ( $1, $2, $3 )";
}
NWNX_SQL_PrepareQuery(test3);
for ( i = 1 ; i <= STRESS_CNT ; i++ )
{
NWNX_SQL_PreparedInt(0, i);
NWNX_SQL_PreparedInt(1, i*2);
NWNX_SQL_PreparedString(2, IntToString(i*100));
b = NWNX_SQL_ExecutePreparedQuery();
NWNX_Tests_Report("NWNX_SQL", "Elegant Looping ExecutePreparedQuery", b);
}
NWNX_SQL_ExecuteQuery("delete from stress_test where i_key > 0");
res = NWNX_SQL_GetAffectedRows();
WriteTimestampedLogEntry("Deleted " + IntToString(res) + " rows.");
NWNX_Tests_Report("Delete rows", res == STRESS_CNT);
// Test some error output.
b = NWNX_SQL_ExecuteQuery("create table error_test (col varchar(10))");
NWNX_Tests_Report("Test Table Create", b);
b = NWNX_SQL_ExecuteQuery("insert into error_test values('abcdefghij')");
NWNX_Tests_Report("good insert", b);
if (db_type != "SQLITE")
{// SQLite doesn't care about size constraints of columns
b = NWNX_SQL_ExecuteQuery("insert into error_test values('abcde000fghij')");
report ("bad insert", !b);
if (!b) {
WriteTimestampedLogEntry("There should be an error a couple rows up.");
}
}
string test4 = "";
if (db_type == "MYSQL" || db_type == "SQLITE")
{
test3 = "insert into error_test values ( ? )";
}
if (db_type == "POSTGRESQL")
{
test3 = "insert into error_test values ( $1 )";
}
NWNX_SQL_PrepareQuery(test3);
NWNX_SQL_PreparedString(100, "lala"); // out of bounds, must not crash.
NWNX_Tests_Report("NWNX_SQL", "Negative prepare query", NWNX_SQL_PrepareQuery("not a valid query!") == 0);
NWNX_Tests_Report("NWNX_SQL", "GetLastError", NWNX_SQL_GetLastError() != "");
// Test with null values
NWNX_SQL_ExecuteQuery("INSERT INTO sql_test(colInt, colFloat, colStr, colObjId, colObj) VALUES(5121, null, null, null, null)");
NWNX_Tests_Report("NWNX_SQL", "Select null", NWNX_SQL_ExecuteQuery("SELECT * FROM sql_test WHERE colInt=5121"));
if (NWNX_SQL_ReadyToReadNextRow())
{
NWNX_SQL_ReadNextRow();
int n = StringToInt(NWNX_SQL_ReadDataInActiveRow(0));
NWNX_Tests_Report("NWNX_SQL", "ReadInt", n == 5121);
float f = StringToFloat(NWNX_SQL_ReadDataInActiveRow(1));
NWNX_Tests_Report("NWNX_SQL", "ReadFloat", f == 0.0);
string s = NWNX_SQL_ReadDataInActiveRow(2);
NWNX_Tests_Report("NWNX_SQL", "ReadString", s == "");
string sObjId = NWNX_SQL_ReadDataInActiveRow(3); // In base 10
NWNX_Tests_Report("NWNX_SQL", "ReadObjectId", sObjId == "");
object obj = NWNX_SQL_ReadFullObjectInActiveRow(4);
NWNX_Tests_Report("NWNX_SQL", "ReadFullObject", obj == OBJECT_INVALID);
}
cleanup();
WriteTimestampedLogEntry("Testing database " + db_type + " complete.");
WriteTimestampedLogEntry("NWNX_SQL unit tests end.");
}