Skip to content

Commit f409a4b

Browse files
committed
Add parseDateType config option
1 parent 500047b commit f409a4b

4 files changed

Lines changed: 179 additions & 8 deletions

File tree

docs/intro/config-file.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ The InterceptDB Config file
3030
3131
global:
3232
enableDynamicQueries: true #Allow queries to be created from SQF, if false only statements from config are allowed
33+
parseDateType: string #This is a enum, one of the below values is allowed
34+
#string: default. Return Date/DateTime as "2018-12-24 13:45:11"
35+
#stringMS: Return Date/DateTime as "2018-12-24 13:45:11.123"
36+
#array: Return Date/DateTime as [year,month,day,hour,minute,second,millisecond] (yes both have time too, date will be 0 hours) in dbResultTo(Parsed)Array
37+
#timestamp: Return Date/DateTime as a timestamp as a number (this can incur precision loss)
38+
#timestampString: Return Date/DateTime as a unix timestamp in a string
39+
#timestampStringMS: Return Date/DateTime as a millisecond unix timestamp in a string
3340
3441
schemas:
3542
test: schema.sql #Filename relative to config.yaml to be used in dbLoadSchema

src/config.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,21 @@ namespace YAML {
2424
}
2525

2626

27+
ConfigDateType dateTypeFromString(std::string_view str) {
28+
if (str == "string")
29+
return ConfigDateType::humanString;
30+
if (str == "stringMS")
31+
return ConfigDateType::humanStringMS;
32+
if (str == "array")
33+
return ConfigDateType::array;
34+
if (str == "timestamp")
35+
return ConfigDateType::timestamp;
36+
if (str == "timestampString")
37+
return ConfigDateType::timestampString;
38+
if (str == "timestampStringMS")
39+
return ConfigDateType::timestampStringMS;
40+
throw std::invalid_argument("Invalid value passed as parseDateTime entry");
41+
}
2742

2843
void Config::reloadConfig() {
2944
std::filesystem::path configFilePath("@InterceptDB/config.yaml");
@@ -34,6 +49,8 @@ void Config::reloadConfig() {
3449
auto stringpath = configFilePath.string();
3550
YAML::Node config = YAML::LoadFile(configFilePath.string());
3651

52+
#pragma region accounts
53+
3754
if (!config["accounts"].IsMap()) throw std::runtime_error("Config Accounts entry is not a map");
3855

3956
for (auto& it : config["accounts"]) {
@@ -60,15 +77,25 @@ void Config::reloadConfig() {
6077
accounts[accountName] = acc;
6178
}
6279

80+
#pragma endregion accounts
81+
82+
#pragma region statements
83+
6384
for (auto& it : config["statements"]) {
6485
r_string stmtName = it.first.as<r_string>();
6586
statements[stmtName] = it.second.as<r_string>();
6687
}
6788

89+
#pragma endregion statements
90+
91+
#pragma region global
92+
6893
if (!config["global"].IsMap()) throw std::runtime_error("Config Global entry is not a map");
6994

7095
dynamicQueriesEnabled = config["global"]["enableDynamicQueries"].as<bool>(true);
96+
dateType = dateTypeFromString(config["global"]["parseDateType"].as<r_string>("string"sv));
7197

98+
#pragma endregion global
7299

73100
if (config["schemas"].IsMap())
74101
for (auto& it : config["schemas"]) {

src/config.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,18 @@
55
#include "mariadb++/account.hpp"
66
#include "../intercept/src/client/headers/shared/containers.hpp"
77

8+
enum class ConfigDateType {
9+
humanString,
10+
humanStringMS,
11+
array,
12+
timestamp,
13+
timestampString,
14+
timestampStringMS
15+
};
16+
17+
ConfigDateType dateTypeFromString(std::string_view str);
18+
19+
820
class Config : public intercept::singleton<Config> {
921

1022
public:
@@ -32,6 +44,10 @@ class Config : public intercept::singleton<Config> {
3244
return dynamicQueriesEnabled;
3345
}
3446

47+
ConfigDateType getDateType() const {
48+
return dateType;
49+
}
50+
3551
static void initCommands();
3652
static inline registered_sqf_function handle_cmd_reloadConfig;
3753
static inline registered_sqf_function handle_cmd_version;
@@ -42,6 +58,6 @@ class Config : public intercept::singleton<Config> {
4258
std::map<intercept::types::r_string, std::filesystem::path> schemas;
4359
bool dynamicQueriesEnabled = true;
4460

45-
61+
ConfigDateType dateType = ConfigDateType::humanString;
4662

4763
};

src/res.cpp

Lines changed: 128 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,128 @@
11
#include "res.h"
22
#include <mariadb++/result_set.hpp>
33
#include "threading.h"
4+
#include "config.h"
45

56
using namespace intercept::client;
67

8+
9+
10+
/// date, datetime
11+
std::tuple<std::function<game_value(const mariadb::date_time&)>,
12+
std::function<game_value(const mariadb::date_time&)>,
13+
std::function<game_value(const mariadb::time&)>
14+
> getDateParser(ConfigDateType type) {
15+
switch (type) {
16+
17+
18+
case ConfigDateType::humanString:
19+
return {
20+
[](const mariadb::date_time& date) -> game_value {
21+
return date.str();
22+
},
23+
[](const mariadb::date_time& dateTime) -> game_value {
24+
return dateTime.str();
25+
},
26+
[](const mariadb::time& time) -> game_value {
27+
return time.str_time();
28+
}
29+
};
30+
case ConfigDateType::humanStringMS:
31+
return {
32+
[](const mariadb::date_time& date) -> game_value {
33+
return date.str(true);
34+
},
35+
[](const mariadb::date_time& dateTime) -> game_value {
36+
return dateTime.str(true);
37+
},
38+
[](const mariadb::time& time) -> game_value {
39+
return time.str_time(true);
40+
}
41+
};
42+
case ConfigDateType::array:
43+
return {
44+
[](const mariadb::date_time& date) -> game_value {
45+
auto_array<game_value> res;
46+
res.reserve(7);
47+
48+
res.emplace_back(date.year());
49+
res.emplace_back(date.month());
50+
res.emplace_back(date.day());
51+
res.emplace_back(date.hour()); //Probably don't need to return this on a date
52+
res.emplace_back(date.minute());
53+
res.emplace_back(date.second());
54+
res.emplace_back(date.millisecond());
55+
56+
return res;
57+
},
58+
[](const mariadb::date_time& dateTime) -> game_value {
59+
auto_array<game_value> res;
60+
res.reserve(7);
61+
62+
res.emplace_back(dateTime.year());
63+
res.emplace_back(dateTime.month());
64+
res.emplace_back(dateTime.day());
65+
res.emplace_back(dateTime.hour());
66+
res.emplace_back(dateTime.minute());
67+
res.emplace_back(dateTime.second());
68+
res.emplace_back(dateTime.millisecond());
69+
70+
return res;
71+
},
72+
[](const mariadb::time& time) -> game_value {
73+
auto_array<game_value> res;
74+
res.reserve(4);
75+
res.emplace_back(time.hour());
76+
res.emplace_back(time.minute());
77+
res.emplace_back(time.second());
78+
res.emplace_back(time.millisecond());
79+
80+
return res;
81+
}
82+
};
83+
case ConfigDateType::timestamp:
84+
return {
85+
[](const mariadb::date_time& date) -> game_value {
86+
return static_cast<float>(date.mktime());
87+
},
88+
[](const mariadb::date_time& dateTime) -> game_value {
89+
return static_cast<float>(dateTime.mktime());
90+
},
91+
[](const mariadb::time& time) -> game_value {
92+
return static_cast<float>(time.mktime());
93+
}
94+
};
95+
case ConfigDateType::timestampString:
96+
return {
97+
[](const mariadb::date_time& date) -> game_value {
98+
return std::to_string(date.mktime());
99+
},
100+
[](const mariadb::date_time& dateTime) -> game_value {
101+
return std::to_string(dateTime.mktime());
102+
},
103+
[](const mariadb::time& time) -> game_value {
104+
return std::to_string(time.mktime());
105+
}
106+
};
107+
case ConfigDateType::timestampStringMS:
108+
return {
109+
[](const mariadb::date_time& date) -> game_value {
110+
return std::to_string(date.mktime()*1000 + date.millisecond());
111+
},
112+
[](const mariadb::date_time& dateTime) -> game_value {
113+
return std::to_string(dateTime.mktime()*1000 + dateTime.millisecond());
114+
},
115+
[](const mariadb::time& time) -> game_value {
116+
return std::to_string(time.mktime()*1000 + time.millisecond());
117+
}
118+
};
119+
120+
}
121+
}
122+
123+
124+
125+
7126
game_data* createGameDataDBResult(param_archive* ar) {
8127
auto x = new GameDataDBResult();
9128
if (ar)
@@ -35,16 +154,17 @@ game_value Result::cmd_toArray(game_state&, game_value_parameter right) {
35154
if (!res) return auto_array<game_value>();
36155
auto_array<game_value> result;
37156

157+
const auto [dateParser, dateTimeParser, timeParser] = getDateParser(Config::get().getDateType());
38158
while (res->next()) {
39159
auto_array<game_value> row;
40160

41161
for (mariadb::u32 i = 0u; i < res->column_count(); ++i) {
42162
try {
43163
switch (res->column_type(i)) {
44164
case mariadb::value::null: row.emplace_back(game_value{}); break;
45-
case mariadb::value::date: row.emplace_back(res->get_date(i).str()); break;
46-
case mariadb::value::date_time: row.emplace_back(res->get_date_time(i).str()); break;
47-
case mariadb::value::time: row.emplace_back(res->get_time(i).str_time()); break;
165+
case mariadb::value::date: row.emplace_back(dateParser(res->get_date(i))); break;
166+
case mariadb::value::date_time: row.emplace_back(dateTimeParser(res->get_date_time(i))); break;
167+
case mariadb::value::time: row.emplace_back(timeParser(res->get_time(i))); break;
48168
case mariadb::value::string: row.emplace_back(res->get_string(i)); break;
49169
case mariadb::value::boolean: row.emplace_back(res->get_boolean(i)); break;
50170
case mariadb::value::decimal: row.emplace_back(res->get_decimal(i).float32()); break;
@@ -76,6 +196,8 @@ game_value Result::cmd_toParsedArray(game_state& state, game_value_parameter rig
76196
if (!res) return auto_array<game_value>();
77197
auto_array<game_value> result;
78198

199+
const auto [dateParser, dateTimeParser, timeParser] = getDateParser(Config::get().getDateType());
200+
79201
while (res->next()) {
80202
auto_array<game_value> row;
81203

@@ -116,14 +238,13 @@ game_value Result::cmd_toParsedArray(game_state& state, game_value_parameter rig
116238
}
117239
};
118240

119-
120241
for (size_t i = 0u; i < res->column_count(); ++i) {
121242

122243
switch (res->column_type(i)) {
123244
case mariadb::value::null: row.emplace_back(game_value{}); break;
124-
case mariadb::value::date: row.emplace_back(res->get_date(i).str()); break;
125-
case mariadb::value::date_time: row.emplace_back(res->get_date_time(i).str()); break;
126-
case mariadb::value::time: row.emplace_back(res->get_time(i).str_time()); break;
245+
case mariadb::value::date: row.emplace_back(dateParser(res->get_date(i))); break;
246+
case mariadb::value::date_time: row.emplace_back(dateTimeParser(res->get_date_time(i))); break;
247+
case mariadb::value::time: row.emplace_back(timeParser(res->get_time(i))); break;
127248
case mariadb::value::string: addParsedString(res->get_string(i)); break;
128249
case mariadb::value::blob: addParsedString(res->get_blobString(i)); break;
129250
case mariadb::value::boolean: row.emplace_back(res->get_boolean(i)); break;

0 commit comments

Comments
 (0)