summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorilotterytea <iltsu@alright.party>2025-07-02 15:24:16 +0500
committerilotterytea <iltsu@alright.party>2025-07-02 15:24:16 +0500
commit4206dd79626773b3f667e9af0ca007aa35a7c6f3 (patch)
treebeda52cd5b7e42ddc67042b4cfc0e1ef7510380a
parent6c002985fddc923f57774c0ca5e7ddd36c629fdc (diff)
feat: lua storage
-rw-r--r--bot/src/commands/lua.cpp116
-rw-r--r--bot/src/commands/lua.hpp9
-rw-r--r--migrations/2025-07-02T10-01-06_luastorage/down.sql3
-rw-r--r--migrations/2025-07-02T10-01-06_luastorage/up.sql18
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