diff options
| author | ilotterytea <iltsu@alright.party> | 2025-07-02 15:24:16 +0500 |
|---|---|---|
| committer | ilotterytea <iltsu@alright.party> | 2025-07-02 15:24:16 +0500 |
| commit | 4206dd79626773b3f667e9af0ca007aa35a7c6f3 (patch) | |
| tree | beda52cd5b7e42ddc67042b4cfc0e1ef7510380a | |
| parent | 6c002985fddc923f57774c0ca5e7ddd36c629fdc (diff) | |
feat: lua storage
| -rw-r--r-- | bot/src/commands/lua.cpp | 116 | ||||
| -rw-r--r-- | bot/src/commands/lua.hpp | 9 | ||||
| -rw-r--r-- | migrations/2025-07-02T10-01-06_luastorage/down.sql | 3 | ||||
| -rw-r--r-- | migrations/2025-07-02T10-01-06_luastorage/up.sql | 18 |
4 files changed, 143 insertions, 3 deletions
diff --git a/bot/src/commands/lua.cpp b/bot/src/commands/lua.cpp index 2c1b176..a67bd17 100644 --- a/bot/src/commands/lua.cpp +++ b/bot/src/commands/lua.cpp @@ -728,6 +728,114 @@ namespace bot::command::lua { return o; }); } + + void add_storage_library(std::shared_ptr<sol::state> state, + const Request &request, const Configuration &cfg, + const std::string &lua_id) { + state->set_function("storage_get", [state, &request, &cfg, &lua_id]() { + std::unique_ptr<db::BaseDatabase> conn = db::create_connection(cfg); + std::vector<std::string> params{std::to_string(request.user.get_id()), + lua_id}; + + db::DatabaseRows rows = conn->exec( + "SELECT value FROM lua_user_storage WHERE user_id = $1 AND " + "lua_id = $2", + params); + + std::string value = ""; + + if (rows.empty()) { + conn->exec( + "INSERT INTO lua_user_storage(user_id, lua_id) VALUES ($1, " + "$2)", + params); + } else { + value = rows[0].at("value"); + } + + return value; + }); + + state->set_function("storage_put", [state, &request, &cfg, + &lua_id](const std::string &value) { + std::unique_ptr<db::BaseDatabase> conn = db::create_connection(cfg); + std::vector<std::string> params{std::to_string(request.user.get_id()), + lua_id}; + + db::DatabaseRows rows = conn->exec( + "SELECT id FROM lua_user_storage WHERE user_id = $1 AND " + "lua_id = $2", + params); + + if (rows.empty()) { + params.push_back(value); + conn->exec( + "INSERT INTO lua_user_storage(user_id, lua_id, value) VALUES " + "($1, " + "$2, $3)", + params); + } else { + conn->exec("UPDATE lua_user_storage SET value = $1 WHERE id = $2", + {value, rows[0].at("id")}); + } + + return true; + }); + + state->set_function("storage_channel_get", [state, &request, &cfg, + &lua_id]() { + std::unique_ptr<db::BaseDatabase> conn = db::create_connection(cfg); + std::vector<std::string> params{ + std::to_string(request.channel.get_id()), lua_id}; + + db::DatabaseRows rows = conn->exec( + "SELECT value FROM lua_channel_storage WHERE channel_id = $1 AND " + "lua_id = $2", + params); + + std::string value = ""; + + if (rows.empty()) { + conn->exec( + "INSERT INTO lua_channel_storage(channel_id, lua_id) VALUES ($1, " + "$2)", + params); + } else { + value = rows[0].at("value"); + } + + return value; + }); + + state->set_function( + "storage_channel_put", + [state, &request, &cfg, &lua_id](const std::string &value) { + std::unique_ptr<db::BaseDatabase> conn = db::create_connection(cfg); + std::vector<std::string> params{ + std::to_string(request.channel.get_id()), lua_id}; + + db::DatabaseRows rows = conn->exec( + "SELECT id FROM lua_channel_storage WHERE channel_id = $1 AND " + "lua_id = $2", + params); + + if (rows.empty()) { + params.push_back(value); + conn->exec( + "INSERT INTO lua_channel_storage(channel_id, lua_id, value) " + "VALUES " + "($1, " + "$2, $3)", + params); + } else { + conn->exec( + "UPDATE lua_channel_storage SET value = $1 WHERE id = $2", + {value, rows[0].at("id")}); + } + + return true; + }); + } } Response parse_lua_response(const sol::table &r, sol::object &res, @@ -761,13 +869,19 @@ namespace bot::command::lua { command::Response run_safe_lua_script(const Request &request, const InstanceBundle &bundle, - const std::string &script) { + const std::string &script, + std::string lua_id) { // shared_ptr is unnecessary here, but my library needs it. std::shared_ptr<sol::state> state = std::make_shared<sol::state>(); state->open_libraries(sol::lib::base, sol::lib::table, sol::lib::string); library::add_base_libraries(state); + if (!lua_id.empty()) { + library::add_storage_library(state, request, bundle.configuration, + lua_id); + } + sol::load_result s = state->load("return " + script); if (!s.valid()) { s = state->load(script); diff --git a/bot/src/commands/lua.hpp b/bot/src/commands/lua.hpp index bde317b..422f79e 100644 --- a/bot/src/commands/lua.hpp +++ b/bot/src/commands/lua.hpp @@ -37,6 +37,9 @@ namespace bot::command::lua { const InstanceBundle &bundle); void add_l10n_library(std::shared_ptr<sol::state> state, const InstanceBundle &bundle); + void add_storage_library(std::shared_ptr<sol::state> state, + const Request &request, const Configuration &cfg, + const std::string &lua_id); void add_base_libraries(std::shared_ptr<sol::state> state); void add_chat_libraries(std::shared_ptr<sol::state> state, @@ -46,7 +49,8 @@ namespace bot::command::lua { command::Response run_safe_lua_script(const Request &request, const InstanceBundle &bundle, - const std::string &script); + const std::string &script, + std::string lua_id = ""); class LuaCommand : public Command { public: @@ -133,7 +137,8 @@ namespace bot::command::lua { std::string script = response.text; - return command::lua::run_safe_lua_script(request, bundle, script); + return command::lua::run_safe_lua_script(request, bundle, script, + url); } }; } diff --git a/migrations/2025-07-02T10-01-06_luastorage/down.sql b/migrations/2025-07-02T10-01-06_luastorage/down.sql new file mode 100644 index 0000000..4711155 --- /dev/null +++ b/migrations/2025-07-02T10-01-06_luastorage/down.sql @@ -0,0 +1,3 @@ +-- This file should undo anything in 'up.sql' +DROP TABLE lua_user_storage; +DROP TABLE lua_channel_storage;
\ No newline at end of file diff --git a/migrations/2025-07-02T10-01-06_luastorage/up.sql b/migrations/2025-07-02T10-01-06_luastorage/up.sql new file mode 100644 index 0000000..dd61116 --- /dev/null +++ b/migrations/2025-07-02T10-01-06_luastorage/up.sql @@ -0,0 +1,18 @@ +-- Your SQL goes here +CREATE TABLE IF NOT EXISTS lua_channel_storage( + id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, + channel_id INTEGER NOT NULL REFERENCES channels(id) ON DELETE CASCADE, + lua_id TEXT NOT NULL, + value TEXT NOT NULL DEFAULT '', + + CONSTRAINT unique_lua_script_per_channel UNIQUE (channel_id, lua_id) +); + +CREATE TABLE IF NOT EXISTS lua_user_storage( + id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, + user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, + lua_id TEXT NOT NULL, + value TEXT NOT NULL DEFAULT '', + + CONSTRAINT unique_lua_script_per_channel UNIQUE (user_id, lua_id) +);
\ No newline at end of file |
