Update ArmaRAMDb with new features and improvements, including logging enhancements, support for ARDB file format, and various function updates. Added config.xml to project inclusion and modified function includes for better compatibility. Updated build files for both Windows and Linux platforms.

This commit is contained in:
Jacob Schmidt 2025-03-21 23:01:39 -05:00
parent 95e5f86a48
commit 6e4bd093ee
36 changed files with 474 additions and 373 deletions

View File

@ -8,6 +8,7 @@ include = [
"*.dll",
"*.so",
"*.json",
"config.xml",
"mod.cpp",
"README.md",
"LICENSE",

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,25 @@
PREP(addTask);
PREP(delete);
PREP(fetch);
PREP(get);
PREP(handler);
PREP(hashGet);
PREP(hashGetAll);
PREP(hashGetAllId);
PREP(hashSet);
PREP(hashSetBulk);
PREP(hashSetId);
PREP(hashSetIdBulk);
PREP(init);
PREP(listAdd);
PREP(listGet);
PREP(listLoad);
PREP(listRemove);
PREP(listSet);
PREP(load);
PREP(printAddonName);
PREP(processQueue);
PREP(save);
PREP(scheduler);
PREP(set);
PREP(test);

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_addTask

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_delete

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
@file Title: ArmaRAMDb Framework by Creedcoder, J.Schmidt
@ -20,21 +20,14 @@
["uniqueID", "function", "index", "indextotal", "datachunk", "call", "netId"]
*/
diag_log _this;
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_fetch' Input: %1", _this];
params ["_uniqueID", "_function", "_index", "_total", "_datachunk", "_call", "_netId"];
private _dataString = "";
private _index_array = [];
private _count_total = -1;
// _uniqueID = parseNumber _uniqueID;
// _function
// _index = parseNumber _index;
// _total = parseNumber _total;
// _datachunk
// _call
// _netId
ramdb_db_fetch_array pushBackUnique [_uniqueID, _function, _index, _total, _datachunk, _call, _netId];
_count_total = {
@ -52,12 +45,7 @@ if (_count_total == _total) then {
_dataString = _dataString + ((_index_array select _i) select 1);
};
diag_log _dataString;
// Old direct execution
// (parseSimpleArray _dataString) call (missionNamespace getVariable [_function, {
// hint "Function does not exist!";
// }]);
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_fetch' DataString: %1", _dataString];
[_uniqueID, _function, _call, (parseSimpleArray _dataString), _netId] call FUNC(handler);

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_get
@ -31,19 +31,31 @@
* Public: Yes
*/
params [["_key", "", [""]], ["_function", "", [""]], ["_call", false, [false]], ["_netId", nil, [""]]];
params [["_key", "", [""]], ["_function", "", [""]], ["_call", false, [false]], ["_netId", "", [""]]];
if (_key == "" || _function == "") exitWith { diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_get' Invalid Input for Key '%1' or Function '%2'", _key, _function]; };
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_get' Key: '%1', Function: '%2', Call: '%3', NetId: '%4'", _key, _function, _call, _netId];
if ((!isNil "_netId") and (_netId isNotEqualTo "")) then {
if (_key == "" || _function == "") exitWith {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_get' Invalid Input for Key '%1' or Function '%2'", _key, _function];
};
private _return = "";
if (_netId != "") then {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_get' Using NetId: '%1'", _netId];
if (_call) then {
_return = "ArmaRAMDb" callExtension ["get", [_key, _function, _netId, _call]];
[(_return select 0)] call FUNC(scheduler);
} else {
_return = "ArmaRAMDb" callExtension ["get", [_key, _function, _netId]];
[(_return select 0)] call FUNC(scheduler);
};
} else {
_return = "ArmaRAMDb" callExtension ["get", [_key, _function]];
[(_return select 0)] call FUNC(scheduler);
diag_log text "ArmaRAMDb: 'ramdb_db_fnc_get' Using current player";
if (_call) then {
_return = "ArmaRAMDb" callExtension ["get", [_key, _function, _call]];
} else {
_return = "ArmaRAMDb" callExtension ["get", [_key, _function]];
};
};
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_get' Return: '%1'", _return];
[(_return select 0)] call FUNC(scheduler);

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_handler
@ -34,7 +34,11 @@
params [["_uniqueID", "", [""]], ["_function", "", [""]], ["_call", false, [false]], ["_data", [], [[]]], ["_netId", nil, [""]]];
if (_function == "" || count _data == 0) exitWith { diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_handler' Invalid Input for Function '%1' or Data '%2'", _function, _data]; };
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_handler' UniqueID: '%1', Function: '%2', Call: '%3', Data: '%4', NetId: '%5'", _uniqueID, _function, _call, _data, _netId];
if (_function == "" || count _data == 0) exitWith {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_handler' Invalid Input for Function '%1' or Data '%2'", _function, _data];
};
private _func = call compile format ["%1", _function];

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_hashGet
@ -31,19 +31,31 @@
* Public: Yes
*/
params [["_keyField", "", [""]], ["_function", "", [""]], ["_call", false, [false]], ["_netId", nil, [""]]];
params [["_keyField", "", [""]], ["_function", "", [""]], ["_call", false, [false]], ["_netId", "", [""]]];
if (_keyField == "" || _function == "") exitWith { diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGet' Invalid Input for KeyField '%1' or Function '%2'", _keyField, _function]; };
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGet' KeyField: '%1', Function: '%2', Call: '%3', NetId: '%4'", _keyField, _function, _call, _netId];
if ((!isNil "_netId") and (_netId isNotEqualTo "")) then {
if (_keyField == "" || _function == "") exitWith {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGet' Invalid Input for KeyField '%1' or Function '%2'", _keyField, _function];
};
private _return = "";
if (_netId != "") then {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGet' Using NetId: '%1'", _netId];
if (_call) then {
_return = "ArmaRAMDb" callExtension ["hget", [_keyField, _function, _netId, _call]];
[(_return select 0)] call FUNC(scheduler);
} else {
_return = "ArmaRAMDb" callExtension ["hget", [_keyField, _function, _netId]];
[(_return select 0)] call FUNC(scheduler);
};
} else {
_return = "ArmaRAMDb" callExtension ["hget", [_keyField, _function]];
[(_return select 0)] call FUNC(scheduler);
diag_log text "ArmaRAMDb: 'ramdb_db_fnc_hashGet' Using current player";
if (_call) then {
_return = "ArmaRAMDb" callExtension ["hget", [_keyField, _function, _call]];
} else {
_return = "ArmaRAMDb" callExtension ["hget", [_keyField, _function]];
};
};
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGet' Return: '%1'", _return];
[(_return select 0)] call FUNC(scheduler);

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_hashGetAll
@ -30,19 +30,31 @@
* Public: Yes
*/
params [["_function", "", [""]], ["_call", false, [false]], ["_netId", nil, [""]]];
params [["_function", "", [""]], ["_call", false, [false]], ["_netId", "", [""]]];
if (_function isEqualTo "") exitWith { diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGetAll' Invalid Input for Function '%1'", _function]; };
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGetAll' Function: '%1', Call: '%2', NetId: '%3'", _function, _call, _netId];
if ((!isNil "_netId") and (_netId isNotEqualTo "")) then {
if (_function isEqualTo "") exitWith {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGetAll' Invalid Input for Function '%1'", _function];
};
private _return = "";
if (_netId != "") then {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGetAll' Using NetId: '%1'", _netId];
if (_call) then {
_return = "ArmaRAMDb" callExtension ["hgetall", [_function, _netId, _call]];
[(_return select 0)] call FUNC(scheduler);
} else {
_return = "ArmaRAMDb" callExtension ["hgetall", [_function, _netId]];
[(_return select 0)] call FUNC(scheduler);
};
} else {
_return = "ArmaRAMDb" callExtension ["hgetall", [_function]];
[(_return select 0)] call FUNC(scheduler);
diag_log text "ArmaRAMDb: 'ramdb_db_fnc_hashGetAll' Using current player";
if (_call) then {
_return = "ArmaRAMDb" callExtension ["hgetall", [_function, _call]];
} else {
_return = "ArmaRAMDb" callExtension ["hgetall", [_function]];
};
};
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGetAll' Return: '%1'", _return];
[(_return select 0)] call FUNC(scheduler);

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_hashGetAllId
@ -31,19 +31,31 @@
* Public: Yes
*/
params [["_key", "", [""]], ["_function", "", [""]], ["_call", false, [false]], ["_netId", nil, [""]]];
params [["_key", "", [""]], ["_function", "", [""]], ["_call", false, [false]], ["_netId", "", [""]]];
if (_key == "" || _function == "") exitWith { diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGetAllId' Invalid Input for Key '%1' or Function '%2'", _key, _function]; };
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGetAllId' Key: '%1', Function: '%2', Call: '%3', NetId: '%4'", _key, _function, _call, _netId];
if ((!isNil "_netId") and (_netId isNotEqualTo "")) then {
if (_key == "" || _function == "") exitWith {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGetAllId' Invalid Input for Key '%1' or Function '%2'", _key, _function];
};
private _return = "";
if (_netId != "") then {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGetAllId' Using NetId: '%1'", _netId];
if (_call) then {
_return = "ArmaRAMDb" callExtension ["hgetallid", [_key, _function, _netId, _call]];
[(_return select 0)] call FUNC(scheduler);
} else {
_return = "ArmaRAMDb" callExtension ["hgetallid", [_key, _function, _netId]];
[(_return select 0)] call FUNC(scheduler);
};
} else {
_return = "ArmaRAMDb" callExtension ["hgetallid", [_key, _function]];
[(_return select 0)] call FUNC(scheduler);
diag_log text "ArmaRAMDb: 'ramdb_db_fnc_hashGetAllId' Using current player";
if (_call) then {
_return = "ArmaRAMDb" callExtension ["hgetallid", [_key, _function, _call]];
} else {
_return = "ArmaRAMDb" callExtension ["hgetallid", [_key, _function]];
};
};
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGetAllId' Return: '%1'", _return];
[(_return select 0)] call FUNC(scheduler);

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_hashGetId
@ -32,19 +32,31 @@
* Public: Yes
*/
params [["_key", "", [""]], ["_keyField", "", [""]], ["_function", "", [""]], ["_call", false, [false]], ["_netId", nil, [""]]];
params [["_key", "", [""]], ["_keyField", "", [""]], ["_function", "", [""]], ["_call", false, [false]], ["_netId", "", [""]]];
if (_key == "" || _keyField == "" || _function == "") exitWith { diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGetId' Invalid Input for Key '%1', KeyField '%2' or Function '%3'", _key, _keyField, _function]; };
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGetId' Key: '%1', KeyField: '%2', Function: '%3', Call: '%4', NetId: '%5'", _key, _keyField, _function, _call, _netId];
if ((!isNil "_netId") and (_netId isNotEqualTo "")) then {
if (_key == "" || _keyField == "" || _function == "") exitWith {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGetId' Invalid Input for Key '%1', KeyField '%2' or Function '%3'", _key, _keyField, _function];
};
private _return = "";
if (_netId != "") then {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGetId' Using NetId: '%1'", _netId];
if (_call) then {
_return = "ArmaRAMDb" callExtension ["hgetid", [_key, _keyField, _function, _netId, _call]];
[(_return select 0)] call FUNC(scheduler);
} else {
_return = "ArmaRAMDb" callExtension ["hgetid", [_key, _keyField, _function, _netId]];
[(_return select 0)] call FUNC(scheduler);
};
} else {
_return = "ArmaRAMDb" callExtension ["hgetid", [_key, _keyField, _function]];
[(_return select 0)] call FUNC(scheduler);
diag_log text "ArmaRAMDb: 'ramdb_db_fnc_hashGetId' Using current player";
if (_call) then {
_return = "ArmaRAMDb" callExtension ["hgetid", [_key, _keyField, _function, _call]];
} else {
_return = "ArmaRAMDb" callExtension ["hgetid", [_key, _keyField, _function]];
};
};
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashGetId' Return: '%1'", _return];
[(_return select 0)] call FUNC(scheduler);

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_hashSet
@ -29,8 +29,12 @@
* Public: Yes
*/
params [["_keyField", "", [""]], ["_data", [], [[]]]];
params [["_keyField", "", [""]], ["_data", [], [[], "", 0, false, objNull, grpNull]]];
if (_keyField == "" || count _data == 0) exitWith { diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashSet' Invalid Input for KeyField '%1' or Data '%2'", _keyField, _data]; };
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashSet' KeyField: '%1', Data: '%2'", _keyField, _data];
if (_keyField == "" || isNil "_data") exitWith {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashSet' Invalid Input for KeyField '%1' or Data '%2'", _keyField, _data];
};
"ArmaRAMDb" callExtension ["hset", [_keyField, _data]];

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_hashSetBulk
@ -28,8 +28,12 @@
* Public: Yes
*/
params [["_data", [], [[]]]];
params [["_data", [], [[], "", 0, false, objNull, grpNull]]];
if (count _data == 0) exitWith { diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashSetBulk' Invalid Input for Data '%1'", _data]; };
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashSetBulk' Data: %1", _data];
if (isNil "_data") exitWith {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashSetBulk' Invalid Input for Data '%1'", _data];
};
"ArmaRAMDb" callExtension ["hset", _data];

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_hashSetId
@ -30,8 +30,12 @@
* Public: Yes
*/
params [["_key", "", [""]], ["_keyField", "", [""]], ["_data", [], [[]]]];
params [["_key", "", [""]], ["_keyField", "", [""]], ["_data", [], [[], "", 0, false, objNull, grpNull]]];
if (_key == "" || _keyField == "" || count _data == 0) exitWith { diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashSetId' Invalid Input for Key '%1', KeyField '%2' or Data '%3'", _key, _keyField, _data]; };
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashSetId' Key: '%1', KeyField: '%2', Data: '%3'", _key, _keyField, _data];
if (_key == "" || _keyField == "" || isNil "_data") exitWith {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashSetId' Invalid Input for Key '%1', KeyField '%2' or Data '%3'", _key, _keyField, _data];
};
"ArmaRAMDb" callExtension ["hsetid", [_key, _keyField, _data]];

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_hashSetIdBulk
@ -28,8 +28,12 @@
* Public: Yes
*/
params [["_data", [], [[]]]];
params [["_data", [], [[], "", 0, false, objNull, grpNull]]];
if (count _data == 0) exitWith { diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashSetIdBulk' Invalid Input for Data '%1'", _data]; };
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashSetIdBulk' Data: %1", _data];
if (isNil "_data") exitWith {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_hashSetIdBulk' Invalid Input for Data '%1'", _data];
};
"ArmaRAMDb" callExtension ["hsetid", _data];

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_init

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_listAdd
@ -29,8 +29,12 @@
* Public: Yes
*/
params [["_key", "", [""]], ["_data", [], [[]]]];
params [["_key", "", [""]], ["_data", [], [[], "", 0, false, objNull, grpNull]]];
if (_key == "" || count _data == 0) exitWith { diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listAdd' Invalid Input for Key '%1' or Data '%2'", _key, _data]; };
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listAdd' Key: '%1', Data: '%2'", _key, _data];
if (_key == "" || isNil "_data") exitWith {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listAdd' Invalid Input for Key '%1' or Data '%2'", _key, _data];
};
"ArmaRAMDb" callExtension ["listadd", [_key, _data]];

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_listGet
@ -32,19 +32,31 @@
* Public: Yes
*/
params [["_key", "", [""]], ["_index", -1, [0]], ["_function", "", [""]], ["_call", false, [false]], ["_netId", nil, [""]]];
params [["_key", "", [""]], ["_index", -1, [0]], ["_function", "", [""]], ["_call", false, [false]], ["_netId", "", [""]]];
if (_key == "" || _function == "") exitWith { diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listGet' Invalid Input for Key '%1' or Function '%2'", _key, _function]; };
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listGet' Key: '%1', Index: '%2', Function: '%3', Call: '%4', NetId: '%5'", _key, _index, _function, _call, _netId];
if ((!isNil "_netId") and (_netId isNotEqualTo "")) then {
if (_key == "" || _function == "") exitWith {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listGet' Invalid Input for Key '%1' or Function '%2'", _key, _function];
};
private _return = "";
if (_netId != "") then {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listGet' Using NetId: '%1'", _netId];
if (_call) then {
_return = "ArmaRAMDb" callExtension ["listidx", [_key, _index, _function, _netId, _call]];
[(_return select 0)] call FUNC(scheduler);
} else {
_return = "ArmaRAMDb" callExtension ["listidx", [_key, _index, _function, _netId]];
[(_return select 0)] call FUNC(scheduler);
};
} else {
_return = "ArmaRAMDb" callExtension ["listidx", [_key, _index, _function]];
[(_return select 0)] call FUNC(scheduler);
diag_log text "ArmaRAMDb: 'ramdb_db_fnc_listGet' Using current player";
if (_call) then {
_return = "ArmaRAMDb" callExtension ["listidx", [_key, _index, _function, _call]];
} else {
_return = "ArmaRAMDb" callExtension ["listidx", [_key, _index, _function]];
};
};
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listGet' Return: '%1'", _return];
[(_return select 0)] call FUNC(scheduler);

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_listLoad
@ -31,19 +31,31 @@
* Public: Yes
*/
params [["_key", "", [""]], ["_function", "", [""]], ["_call", false, [false]], ["_netId", nil, [""]]];
params [["_key", "", [""]], ["_function", "", [""]], ["_call", false, [false]], ["_netId", "", [""]]];
if (_key == "" || _function == "") exitWith { diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listLoad' Invalid Input for Key '%1' or Function '%2'", _key, _function]; };
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listLoad' Key: '%1', Function: '%2', Call: '%3', NetId: '%4'", _key, _function, _call, _netId];
if ((!isNil "_netId") and (_netId isNotEqualTo "")) then {
if (_key == "" || _function == "") exitWith {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listLoad' Invalid Input for Key '%1' or Function '%2'", _key, _function];
};
private _return = "";
if (_netId != "") then {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listLoad' Using NetId: '%1'", _netId];
if (_call) then {
_return = "ArmaRAMDb" callExtension ["listrng", [_key, 0, -1, _function, _netId, _call]];
[(_return select 0)] call FUNC(scheduler);
} else {
_return = "ArmaRAMDb" callExtension ["listrng", [_key, 0, -1, _function, _netId]];
[(_return select 0)] call FUNC(scheduler);
};
} else {
_return = "ArmaRAMDb" callExtension ["listrng", [_key, 0, -1, _function]];
[(_return select 0)] call FUNC(scheduler);
diag_log text "ArmaRAMDb: 'ramdb_db_fnc_listLoad' Using current player";
if (_call) then {
_return = "ArmaRAMDb" callExtension ["listrng", [_key, 0, -1, _function, _call]];
} else {
_return = "ArmaRAMDb" callExtension ["listrng", [_key, 0, -1, _function]];
};
};
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listLoad' Return: '%1'", _return];
[(_return select 0)] call FUNC(scheduler);

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_listRemove
@ -31,6 +31,10 @@
params [["_key", "", [""]], ["_index", -1, [0]]];
if (_key == "") exitWith { diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listRemove' Invalid Input for Key '%1'", _key]; };
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listRemove' Key: '%1', Index: '%2'", _key, _index];
if (_key == "") exitWith {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listRemove' Invalid Input for Key '%1'", _key];
};
"ArmaRAMDb" callExtension ["listrem", [_key, _index]];

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_listSet
@ -30,8 +30,12 @@
* Public: Yes
*/
params [["_key", "", [""]], ["_index", -1, [0]], ["_data", [], [[]]]];
params [["_key", "", [""]], ["_index", -1, [0]], ["_data", [], [[], "", 0, false, objNull, grpNull]]];
if (_key == "" || count _data == 0) exitWith { diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listSet' Invalid Input for Key '%1' or Data '%2'", _key, _data]; };
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listSet' Key: '%1', Index: '%2', Data: '%3'", _key, _index, _data];
if (_key == "" || isNil "_data") exitWith {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_listSet' Invalid Input for Key '%1' or Data '%2'", _key, _data];
};
"ArmaRAMDb" callExtension ["listset", [_key, _index, _data]];

View File

@ -0,0 +1,31 @@
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_load
* Author: Creedcoder, J.Schmidt
* Edit: 07.15.2024
* Copyright © 2024 Creedcoder, J.Schmidt, All rights reserved
*
* Do not edit without permission!
*
* This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
* To view a copy of this license, vist https://creativecommons.org/licenses/by-nc-sa/4.0/ or send a letter to Creative Commons,
* PO Box 1866, Mountain View, CA 94042
*
* [Description]
* Load from disc.
*
* Arguments:
* N/A
*
* Return Value:
* N/A
*
* Examples:
* [] call ramdb_db_fnc_load (Server or Singleplayer Only)
* [] remoteExecCall ["ramdb_db_fnc_load", 2, false] (Multiplayer Only)
*
* Public: Yes
*/
"ArmaRAMDb" callExtension ["load", []];

View File

@ -1,3 +1,3 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
systemChat format ["Thank you for using the %1", 'ADDON'];

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_processQueue

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_save
@ -16,25 +16,20 @@
* Save to disc.
*
* Arguments:
* 0: Type of save <STRING> (default: "xml")
* 1: Create backup <BOOL> (default: false)
* 0: Create backup <BOOL> (default: false)
*
* Return Value:
* N/A
*
* Examples:
* [] call ramdb_db_fnc_save (Server or Singleplayer Only)
* ["rdb", true] call ramdb_db_fnc_save (Server or Singleplayer Only)
* [true] call ramdb_db_fnc_save (Server or Singleplayer Only)
* [] remoteExecCall ["ramdb_db_fnc_save", 2, false] (Multiplayer Only)
* ["rdb", true] remoteExecCall ["ramdb_db_fnc_save", 2, false] (Multiplayer Only)
* [true] remoteExecCall ["ramdb_db_fnc_save", 2, false] (Multiplayer Only)
*
* Public: Yes
*/
params [["_type", "xml", [""]], ["_createBackup", false, [false]]];
params [["_createBackup", false, [false]]];
if (_type == "xml") then {
"ArmaRAMDb" callExtension ["save", []];
} else {
"ArmaRAMDb" callExtension ["saverdb", [_createBackup]];
};
"ArmaRAMDb" callExtension ["save", []];

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_scheduler

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_set
@ -29,8 +29,12 @@
* Public: Yes
*/
params [["_key", "", [""]], ["_data", "", [[]]]];
params [["_key", "", [""]], ["_data", "", [[], "", 0, false, objNull, grpNull]]];
if (_key == "" || _data == "") exitWith { diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_set' Invalid Input for Key '%1' or Data '%2'", _key, _data]; };
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_set' Key: '%1', Data: '%2'", _key, _data];
if (_key == "" || isNil "_data") exitWith {
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_set' Invalid Input for Key '%1' or Data '%2'", _key, _data];
};
"ArmaRAMDb" callExtension ["set", [_key, _data]];

View File

@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Function: ramdb_db_fnc_test
@ -32,3 +32,4 @@ _res = _this;
ramdb_db_test = _res;
hint format ["%1", _res];
diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_test' Return: '%1'", _res];

View File

@ -1 +0,0 @@
#include "..\script_component.hpp"

View File

@ -1,5 +1,5 @@
#define MAINPREFIX z
#define PREFIX dragonfly
#define PREFIX ramdb
#include "script_version.hpp"
@ -9,7 +9,7 @@
#define REQUIRED_VERSION 2.12
#ifdef COMPONENT_BEAUTIFIED
#define COMPONENT_NAME QUOTE(DRAGONFLY - COMPONENT_BEAUTIFIED)
#define COMPONENT_NAME QUOTE(RAMDB - COMPONENT_BEAUTIFIED)
#else
#define COMPONENT_NAME QUOTE(DRAGONFLY - COMPONENT)
#define COMPONENT_NAME QUOTE(RAMDB - COMPONENT)
#endif

View File

@ -54,7 +54,7 @@ namespace ArmaRAMDb
try
{
var configXml = XElement.Load(Environment.CurrentDirectory + "\\" + str);
List<string> settings = configXml.Elements().Select(element => (string)element).ToList();
List<string> settings = [.. configXml.Elements().Select(element => (string)element)];
// Parse existing settings
if (settings.Count >= 2)
@ -81,7 +81,16 @@ namespace ArmaRAMDb
Log($"Config file found! Context Mode: {ARDB_CONTEXTLOG}! Debug Mode: {ARDB_DEBUG}! " +
$"Auto Backup: {RAMDb.AutoBackupEnabled} (every {RAMDb.BackupFrequencyMinutes} min, keep {RAMDb.MaxBackupsToKeep})", "action");
// Initialize automatic backup if enabled
// First, load any existing RDB file
var db = new RAMDb();
if (File.Exists(Path.Combine(Environment.CurrentDirectory, RAMDb.DEFAULT_ARDB_PATH)))
{
db.ImportFromArdb();
ARDB_ISLOADED = true;
Log("Existing ARDB data loaded during initialization", "action");
}
// Then initialize automatic backup if enabled
if (RAMDb.AutoBackupEnabled)
{
RAMDb.InitializeAutoBackup();
@ -227,7 +236,7 @@ namespace ArmaRAMDb
var _id = DateTimeOffset.Now.ToUnixTimeMilliseconds();
var func = GetString(function);
List<string> args = Enumerable.Range(0, argc).Select(i => GetString(argv[i])).ToList();
List<string> args = [.. Enumerable.Range(0, argc).Select(i => GetString(argv[i]))];
switch (func.ToLower())
{
@ -302,20 +311,12 @@ namespace ArmaRAMDb
HandleListSetOperation(args, argc);
WriteOutput(output, "Async");
return 200;
case "loadrdb":
LoadRdb();
WriteOutput(output, "Data loaded");
return 100;
case "saverdb":
SaveRdb(args);
WriteOutput(output, "Data saved");
return 100;
case "load":
LoadData();
Load();
WriteOutput(output, "Data loaded");
return 100;
case "save":
SaveData();
Save(args);
WriteOutput(output, "Data saved");
return 100;
case "set":
@ -378,7 +379,7 @@ namespace ArmaRAMDb
Marshal.Copy(bytes, 0, (nint)output, bytes.Length);
}
private static void SaveRdb(List<string> args)
private static void Save(List<string> args)
{
var db = new RAMDb();
@ -386,34 +387,17 @@ namespace ArmaRAMDb
bool createBackup = args.Count > 0 &&
(args[0].Trim('"').Equals("true", StringComparison.CurrentCultureIgnoreCase) || args[0].Trim('"') == "1");
db.ExportToRdb(createBackup);
Log($"Data saved to RDB{(createBackup ? " with backup" : "")}", "action");
db.ExportToArdb(createBackup);
Log($"Data saved to ARDB{(createBackup ? " with backup" : "")}", "action");
}
private static void LoadRdb()
private static void Load()
{
var db = new RAMDb();
db.ImportFromRdb();
db.ImportFromArdb();
ARDB_ISLOADED = true;
Log("Data loaded from RDB", "action");
}
private static void SaveData()
{
var db = new RAMDb();
db.ExportToXml();
Log("Data saved to XML", "action");
}
private static void LoadData()
{
var db = new RAMDb();
db.ImportFromXml();
ARDB_ISLOADED = true;
Log("Data loaded from XML", "action");
Log("Data loaded from ARDB", "action");
}
#pragma warning disable IDE0060 // Remove unused parameter
@ -441,12 +425,21 @@ namespace ArmaRAMDb
Task.Run(async () =>
{
string _uniqueID = $"{_id}_hget";
if (argc == 2)
await HashStore.HashGet(STEAMID, args[0].Trim('"'), args[1].Trim('"'), _uniqueID);
if (argc == 3)
await HashStore.HashGet(STEAMID, args[0].Trim('"'), args[1].Trim('"'), _uniqueID, args[2].Trim('"'));
if (argc == 4)
await HashStore.HashGet(STEAMID, args[0].Trim('"'), args[1].Trim('"'), _uniqueID, args[2].Trim('"'), args[3].Trim('"'));
switch (argc)
{
case 2:
await HashStore.HashGet(STEAMID, args[0].Trim('"'), args[1].Trim('"'), _uniqueID);
break;
case 3:
await HashStore.HashGet(STEAMID, args[0].Trim('"'), args[1].Trim('"'), _uniqueID, args[2].Trim('"'));
break;
case 4:
await HashStore.HashGet(STEAMID, args[0].Trim('"'), args[1].Trim('"'), _uniqueID, args[2].Trim('"'), args[3].Trim('"'));
break;
default:
Main.Log($"Unexpected argument count: {argc} for HashGet operation", "warning");
break;
}
});
}
@ -455,12 +448,21 @@ namespace ArmaRAMDb
Task.Run(async () =>
{
string _uniqueID = $"{_id}_hgetid";
if (argc == 3)
await HashStore.HashGet(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), _uniqueID);
if (argc == 4)
await HashStore.HashGet(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), _uniqueID, args[3].Trim('"'));
if (argc == 5)
await HashStore.HashGet(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), _uniqueID, args[3].Trim('"'), args[4].Trim('"'));
switch (argc)
{
case 3:
await HashStore.HashGet(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), _uniqueID);
break;
case 4:
await HashStore.HashGet(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), _uniqueID, args[3].Trim('"'));
break;
case 5:
await HashStore.HashGet(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), _uniqueID, args[3].Trim('"'), args[4].Trim('"'));
break;
default:
Main.Log($"Unexpected argument count: {argc} for HashGetId operation", "warning");
break;
}
});
}
@ -469,12 +471,21 @@ namespace ArmaRAMDb
Task.Run(async () =>
{
string _uniqueID = $"{_id}_hgetall";
if (argc == 1)
await HashStore.HashGetAllAsync(STEAMID, args[0].Trim('"'), _uniqueID);
if (argc == 2)
await HashStore.HashGetAllAsync(STEAMID, args[0].Trim('"'), _uniqueID, args[1].Trim('"'));
if (argc == 3)
await HashStore.HashGetAllAsync(STEAMID, args[0].Trim('"'), _uniqueID, args[1].Trim('"'), args[2].Trim('"'));
switch (argc)
{
case 1:
await HashStore.HashGetAllAsync(STEAMID, args[0].Trim('"'), _uniqueID);
break;
case 2:
await HashStore.HashGetAllAsync(STEAMID, args[0].Trim('"'), _uniqueID, args[1].Trim('"'));
break;
case 3:
await HashStore.HashGetAllAsync(STEAMID, args[0].Trim('"'), _uniqueID, args[1].Trim('"'), args[2].Trim('"'));
break;
default:
Main.Log($"Unexpected argument count: {argc} for HashGetAll operation", "warning");
break;
}
});
}
@ -483,12 +494,21 @@ namespace ArmaRAMDb
Task.Run(async () =>
{
string _uniqueID = $"{_id}_hgetallid";
if (argc == 2)
await HashStore.HashGetAllAsync(args[0].Trim('"'), args[1].Trim('"'), _uniqueID);
if (argc == 3)
await HashStore.HashGetAllAsync(args[0].Trim('"'), args[1].Trim('"'), _uniqueID, args[2].Trim('"'));
if (argc == 4)
await HashStore.HashGetAllAsync(args[0].Trim('"'), args[1].Trim('"'), _uniqueID, args[2], args[3].Trim('"'));
switch (argc)
{
case 2:
await HashStore.HashGetAllAsync(args[0].Trim('"'), args[1].Trim('"'), _uniqueID);
break;
case 3:
await HashStore.HashGetAllAsync(args[0].Trim('"'), args[1].Trim('"'), _uniqueID, args[2].Trim('"'));
break;
case 4:
await HashStore.HashGetAllAsync(args[0].Trim('"'), args[1].Trim('"'), _uniqueID, args[2], args[3].Trim('"'));
break;
default:
Main.Log($"Unexpected argument count: {argc} for HashGetAllId operation", "warning");
break;
}
});
}
@ -516,18 +536,22 @@ namespace ArmaRAMDb
{
Task.Run(async () =>
{
if (argc > 2)
switch (argc)
{
var bulkValues = new Dictionary<string, string>();
for (var i = 0; i < argc; i += 2)
{
bulkValues[args[i].Trim('"')] = args[i + 1];
}
await HashStore.HashSetBulkAsync(STEAMID, bulkValues);
}
else
{
await HashStore.HashSetAsync(STEAMID, args[0].Trim('"'), args[1].Trim('"'));
case > 2: // For bulk operations
var bulkValues = new Dictionary<string, string>();
for (var i = 0; i < argc; i += 2)
{
bulkValues[args[i].Trim('"')] = args[i + 1];
}
await HashStore.HashSetBulkAsync(STEAMID, bulkValues);
break;
case 2: // For single key-value pair
await HashStore.HashSetAsync(STEAMID, args[0].Trim('"'), args[1].Trim('"'));
break;
default:
Main.Log($"Invalid argument count: {argc} for HashSet operation", "warning");
break;
}
});
}
@ -536,18 +560,22 @@ namespace ArmaRAMDb
{
Task.Run(async () =>
{
if (argc > 4)
switch (argc)
{
var bulkValues = new Dictionary<string, string>();
for (var i = 1; i < argc; i += 2)
{
bulkValues[args[i].Trim('"')] = args[i + 1];
}
await HashStore.HashSetBulkAsync(args[0].Trim('"'), bulkValues);
}
else
{
await HashStore.HashSetAsync(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'));
case > 4: // For bulk operations
var bulkValues = new Dictionary<string, string>();
for (var i = 1; i < argc; i += 2)
{
bulkValues[args[i].Trim('"')] = args[i + 1];
}
await HashStore.HashSetBulkAsync(args[0].Trim('"'), bulkValues);
break;
case 3: // For single key-value pair
await HashStore.HashSetAsync(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'));
break;
default:
Main.Log($"Invalid argument count: {argc} for HashSetId operation", "warning");
break;
}
});
}
@ -559,14 +587,17 @@ namespace ArmaRAMDb
switch (argc)
{
case > 2:
for (var i = 0; i < argc; i++)
for (var i = 1; i < argc; i++) // Fixed: start from index 1 to skip list name
{
await ListStore.ListAddAsync(args[0].Trim('"'), args[i]);
}
break;
default:
case 2:
await ListStore.ListAddAsync(args[0].Trim('"'), args[1].Trim('"'));
break;
default:
Main.Log($"Invalid argument count: {argc} for ListAdd operation", "warning");
break;
}
});
}
@ -587,12 +618,21 @@ namespace ArmaRAMDb
Task.Run(async () =>
{
string _uniqueID = $"{_id}_listidx";
if (argc == 3)
await ListStore.ListIndexAsync(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), _uniqueID);
if (argc == 4)
await ListStore.ListIndexAsync(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), _uniqueID, args[3].Trim('"'));
if (argc == 5)
await ListStore.ListIndexAsync(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), _uniqueID, args[3].Trim('"'), args[4].Trim('"'));
switch (argc)
{
case 3:
await ListStore.ListIndexAsync(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), _uniqueID);
break;
case 4:
await ListStore.ListIndexAsync(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), _uniqueID, args[3].Trim('"'));
break;
case 5:
await ListStore.ListIndexAsync(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), _uniqueID, args[3].Trim('"'), args[4].Trim('"'));
break;
default:
Main.Log($"Unexpected argument count: {argc} for ListIdx operation", "warning");
break;
}
});
}
@ -601,12 +641,21 @@ namespace ArmaRAMDb
Task.Run(async () =>
{
string _uniqueID = $"{_id}_listrng";
if (argc == 4)
await ListStore.ListRangeAsync(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), args[3].Trim('"'), _uniqueID);
if (argc == 5)
await ListStore.ListRangeAsync(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), args[3].Trim('"'), _uniqueID, args[4].Trim('"'));
if (argc == 6)
await ListStore.ListRangeAsync(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), args[3].Trim('"'), _uniqueID, args[4].Trim('"'), args[5].Trim('"'));
switch (argc)
{
case 4:
await ListStore.ListRangeAsync(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), args[3].Trim('"'), _uniqueID);
break;
case 5:
await ListStore.ListRangeAsync(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), args[3].Trim('"'), _uniqueID, args[4].Trim('"'));
break;
case 6:
await ListStore.ListRangeAsync(args[0].Trim('"'), args[1].Trim('"'), args[2].Trim('"'), args[3].Trim('"'), _uniqueID, args[4].Trim('"'), args[5].Trim('"'));
break;
default:
Main.Log($"Unexpected argument count: {argc} for ListRng operation", "warning");
break;
}
});
}
@ -635,12 +684,21 @@ namespace ArmaRAMDb
Task.Run(async () =>
{
string _uniqueID = $"{_id}_get";
if (argc == 2)
await KeyValueStore.GetAsync(args[0].Trim('"'), args[1].Trim('"'), _uniqueID);
if (argc == 3)
await KeyValueStore.GetAsync(args[0].Trim('"'), args[1].Trim('"'), _uniqueID, args[2].Trim('"'));
if (argc == 4)
await KeyValueStore.GetAsync(args[0].Trim('"'), args[1].Trim('"'), _uniqueID, args[2].Trim('"'), args[3].Trim('"'));
switch (argc)
{
case 2:
await KeyValueStore.GetAsync(args[0].Trim('"'), args[1].Trim('"'), _uniqueID);
break;
case 3:
await KeyValueStore.GetAsync(args[0].Trim('"'), args[1].Trim('"'), _uniqueID, args[2].Trim('"'));
break;
case 4:
await KeyValueStore.GetAsync(args[0].Trim('"'), args[1].Trim('"'), _uniqueID, args[2].Trim('"'), args[3].Trim('"'));
break;
default:
Main.Log($"Unexpected argument count: {argc} for Get operation", "warning");
break;
}
});
}

View File

@ -1,45 +1,38 @@
using System.Xml.Linq;
using System.Collections.Concurrent;
#pragma warning disable IDE0130 // Namespace does not match folder structure
namespace ArmaRAMDb
#pragma warning restore IDE0130 // Namespace does not match folder structure
{
internal class RAMDb(string path = RAMDb.DEFAULT_XML_PATH, string rdbPath = RAMDb.DEFAULT_RDB_PATH) : IDisposable
internal class RAMDb(string ardbPath = RAMDb.DEFAULT_ARDB_PATH) : IDisposable
{
private const string DEFAULT_XML_PATH = "@ramdb\\ArmaRAMDb.xml";
private const string DEFAULT_RDB_PATH = "@ramdb\\ArmaRAMDb.rdb";
private readonly string _xmlPath = Path.Combine(Environment.CurrentDirectory, path);
private readonly string _rdbPath = Path.Combine(Environment.CurrentDirectory, rdbPath);
private XDocument _document;
public const string DEFAULT_ARDB_PATH = "@ramdb\\ArmaRAMDb.ardb";
private readonly string _ardbPath = Path.Combine(Environment.CurrentDirectory, ardbPath);
public static readonly ConcurrentDictionary<string, string> _keyValues = new();
public static readonly ConcurrentDictionary<string, ConcurrentDictionary<string, string>> _hashTables = new();
public static readonly ConcurrentDictionary<string, List<string>> _lists = new();
// Add these properties to the RAMDb class
public static bool AutoBackupEnabled { get; set; } = false;
public static int BackupFrequencyMinutes { get; set; } = 60; // Default 1 hour
public static int BackupFrequencyMinutes { get; set; } = 60;
public static int MaxBackupsToKeep { get; set; } = 10;
private static Timer _backupTimer;
public void ImportFromRdb()
public void ImportFromArdb()
{
try
{
if (File.Exists(_rdbPath))
if (File.Exists(_ardbPath))
{
using var stream = new FileStream(_rdbPath, FileMode.Open);
using var stream = new FileStream(_ardbPath, FileMode.Open);
using var reader = new BinaryReader(stream);
// Read version (for future compatibility)
int version = reader.ReadInt32();
if (version != 1)
{
Main.Log($"Unsupported RDB format version: {version}", "warning");
Main.Log($"Unsupported ARDB format version: {version}", "warning");
return;
}
// Clear existing collections
_keyValues.Clear();
_hashTables.Clear();
_lists.Clear();
@ -95,38 +88,34 @@ namespace ArmaRAMDb
_lists.TryAdd(listName, items);
}
Main.Log("RDB import complete", "debug");
Main.Log("ARDB import complete", "debug");
}
}
catch (Exception ex)
{
Main.Log($"Error during RDB import: {ex.Message}", "error");
Main.Log($"Error during ARDB import: {ex.Message}", "error");
}
}
public void ExportToRdb(bool createBackup = false)
public void ExportToArdb(bool createBackup = false)
{
try
{
// Save to the standard location
Directory.CreateDirectory(Path.GetDirectoryName(_rdbPath));
Directory.CreateDirectory(Path.GetDirectoryName(_ardbPath));
using (var stream = new FileStream(_rdbPath, FileMode.Create))
using (var stream = new FileStream(_ardbPath, FileMode.Create))
using (var writer = new BinaryWriter(stream))
{
// Add version number
writer.Write(1); // Version 1 of format
writer.Write(1);
// Write data as before
WriteDataToBinaryWriter(writer);
}
// Create a backup copy with timestamp if requested
if (createBackup)
{
string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
string backupDirectory = Path.Combine(Path.GetDirectoryName(_rdbPath), "backups");
string backupFileName = Path.GetFileNameWithoutExtension(_rdbPath) + "_" + timestamp + Path.GetExtension(_rdbPath);
string backupDirectory = Path.Combine(Path.GetDirectoryName(_ardbPath), "backups");
string backupFileName = Path.GetFileNameWithoutExtension(_ardbPath) + "_" + timestamp + Path.GetExtension(_ardbPath);
string backupPath = Path.Combine(backupDirectory, backupFileName);
Directory.CreateDirectory(backupDirectory);
@ -134,22 +123,20 @@ namespace ArmaRAMDb
using (var stream = new FileStream(backupPath, FileMode.Create))
using (var writer = new BinaryWriter(stream))
{
// Write the same data to the backup file
WriteDataToBinaryWriter(writer);
}
Main.Log($"Created backup at: {backupPath}", "debug");
}
Main.Log("RDB export complete", "debug");
Main.Log("ARDB export complete", "debug");
}
catch (Exception ex)
{
Main.Log($"Error during RDB export: {ex.Message}", "error");
Main.Log($"Error during ARDB export: {ex.Message}", "error");
}
}
// Extract the data writing logic to a separate method to avoid code duplication
private static void WriteDataToBinaryWriter(BinaryWriter writer)
{
// Write KeyValues
@ -188,21 +175,19 @@ namespace ArmaRAMDb
}
}
// Add a method to list available backups
public List<string> ListBackups()
{
string backupDirectory = Path.Combine(Path.GetDirectoryName(_rdbPath), "backups");
string backupDirectory = Path.Combine(Path.GetDirectoryName(_ardbPath), "backups");
List<string> backups = [];
if (Directory.Exists(backupDirectory))
{
backups = [.. Directory.GetFiles(backupDirectory, "*.rdb").OrderByDescending(file => file)];
backups = [.. Directory.GetFiles(backupDirectory, "*.ardb").OrderByDescending(file => file)];
}
return backups;
}
// Add a method to restore from a specific backup
public static bool RestoreFromBackup(string backupPath)
{
if (File.Exists(backupPath))
@ -212,20 +197,17 @@ namespace ArmaRAMDb
using var stream = new FileStream(backupPath, FileMode.Open);
using var reader = new BinaryReader(stream);
// Read version (for future compatibility)
int version = reader.ReadInt32();
if (version != 1)
{
Main.Log($"Unsupported RDB format version in backup: {version}", "warning");
Main.Log($"Unsupported ARDB format version in backup: {version}", "warning");
return false;
}
// Clear existing collections
_keyValues.Clear();
_hashTables.Clear();
_lists.Clear();
// Call a shared method for reading data
ReadDataFromBinaryReader(reader);
Main.Log($"Restored from backup: {backupPath}", "info");
@ -240,7 +222,6 @@ namespace ArmaRAMDb
return false;
}
// Add a shared method for reading data (similar to WriteDataToBinaryWriter)
private static void ReadDataFromBinaryReader(BinaryReader reader)
{
// Read KeyValues
@ -294,101 +275,9 @@ namespace ArmaRAMDb
_lists.TryAdd(listName, items);
}
Main.Log("RDB import complete", "debug");
Main.Log("ARDB import complete", "debug");
}
public void ImportFromXml()
{
if (File.Exists(_xmlPath))
{
_document = XDocument.Load(_xmlPath);
LoadIntoMemory();
}
}
public void ExportToXml()
{
_document = new XDocument(
new XElement("ArmaRAMDb",
new XElement("KeyValues",
from pair in _keyValues
select new XElement("Entry",
new XAttribute("Key", pair.Key),
new XAttribute("Value", pair.Value))),
new XElement("HashTables",
from table in _hashTables
select new XElement("Table",
new XAttribute("Name", table.Key),
from entry in table.Value
select new XElement("Entry",
new XAttribute("Key", entry.Key),
new XAttribute("Value", entry.Value)))),
new XElement("Lists",
from list in _lists
select new XElement("List",
new XAttribute("Name", list.Key),
from item in list.Value
select new XElement("Item", item)))
));
SaveDocument();
}
private void LoadIntoMemory()
{
Main.Log("Starting XML import", "debug");
foreach (var entry in _document.Root.Element("KeyValues").Elements("Entry"))
{
var key = entry.Attribute("Key").Value;
var value = entry.Attribute("Value").Value;
_keyValues.TryAdd(key, value);
Main.Log($"Loaded key-value: {key} = {value[..Math.Min(50, value.Length)]}...", "debug");
}
foreach (var table in _document.Root.Element("HashTables").Elements("Table"))
{
var tableName = table.Attribute("Name").Value;
Main.Log($"Loading table: {tableName}", "debug");
var concurrentDict = new ConcurrentDictionary<string, string>();
foreach (var entry in table.Elements("Entry"))
{
var key = entry.Attribute("Key").Value;
var value = entry.Attribute("Value").Value;
concurrentDict.TryAdd(key, value);
Main.Log($"Loaded entry: {key} = {value[..Math.Min(50, value.Length)]}...", "debug");
}
_hashTables.TryAdd(tableName, concurrentDict);
}
foreach (var list in _document.Root.Element("Lists").Elements("List"))
{
var listName = list.Attribute("Name").Value;
Main.Log($"Loading list: {listName}", "debug");
var items = new List<string>();
foreach (var item in list.Elements("Item"))
{
var value = item.Value;
items.Add(value);
Main.Log($"Loaded item: {value[..Math.Min(50, value.Length)]}...", "debug");
}
_lists.TryAdd(listName, items);
}
Main.Log("XML import complete", "debug");
}
private void SaveDocument()
{
Directory.CreateDirectory(Path.GetDirectoryName(_xmlPath));
_document.Save(_xmlPath);
}
// Add a method to start the automatic backup timer
public static void InitializeAutoBackup()
{
if (AutoBackupEnabled)
@ -396,23 +285,20 @@ namespace ArmaRAMDb
_backupTimer?.Dispose();
_backupTimer = new Timer(BackupTimerCallback, null,
TimeSpan.Zero,
TimeSpan.FromMinutes(BackupFrequencyMinutes),
TimeSpan.FromMinutes(BackupFrequencyMinutes));
Main.Log($"Automatic backup initialized (every {BackupFrequencyMinutes} minutes)", "info");
}
}
// Timer callback method
private static void BackupTimerCallback(object state)
{
try
{
// Create a new instance to perform the backup
var db = new RAMDb();
db.ExportToRdb(true);
db.ExportToArdb(true);
// Manage backup rotation
ManageBackupRotation();
Main.Log($"Automatic backup created at {DateTime.Now}", "info");
@ -423,7 +309,6 @@ namespace ArmaRAMDb
}
}
// Method to clean up old backups
private static void ManageBackupRotation()
{
try
@ -431,7 +316,6 @@ namespace ArmaRAMDb
var db = new RAMDb();
var backups = db.ListBackups();
// Keep only the number of backups specified in config
if (backups.Count > MaxBackupsToKeep)
{
for (int i = MaxBackupsToKeep; i < backups.Count; i++)
@ -450,8 +334,7 @@ namespace ArmaRAMDb
public void Dispose()
{
_backupTimer?.Dispose();
ExportToXml();
ExportToRdb(createBackup: true); // Create a backup on normal shutdown
ExportToArdb(createBackup: true);
}
}
}