From 273c4d9b6cc727977a822dfa78c30e3da46b7e9e Mon Sep 17 00:00:00 2001 From: Sky Johnson Date: Fri, 1 Aug 2025 19:06:02 -0500 Subject: [PATCH] lots of string fixes --- modules/registry.go | 2 + modules/sqlite/sqlite.lua | 135 +++++++++++++++++++------------------ modules/string+/string.lua | 2 +- 3 files changed, 72 insertions(+), 67 deletions(-) diff --git a/modules/registry.go b/modules/registry.go index 2d67137..972d1a5 100644 --- a/modules/registry.go +++ b/modules/registry.go @@ -118,6 +118,7 @@ func (r *Registry) InstallInState(state *luajit.State) error { return s.PushError("require: failed to load module '%s': %v", moduleName, err) } if err := s.Call(0, 1); err != nil { + s.Pop(1) return s.PushError("require: failed to execute module '%s': %v", moduleName, err) } return 1 @@ -133,6 +134,7 @@ func (r *Registry) InstallInState(state *luajit.State) error { return 1 } + s.Pop(1) return s.PushError("require: module '%s' not found", moduleName) }) } diff --git a/modules/sqlite/sqlite.lua b/modules/sqlite/sqlite.lua index 94aac27..1bb4972 100644 --- a/modules/sqlite/sqlite.lua +++ b/modules/sqlite/sqlite.lua @@ -23,14 +23,14 @@ function Connection:query(query_str, ...) if not self._id then error("Connection is closed") end - return moonshark.sql_query(self._id, query_str:normalize_whitespace(), ...) + return moonshark.sql_query(self._id, string.normalize_whitespace(query_str), ...) end function Connection:exec(query_str, ...) if not self._id then error("Connection is closed") end - return moonshark.sql_exec(self._id, query_str:normalize_whitespace(), ...) + return moonshark.sql_exec(self._id, string.normalize_whitespace(query_str), ...) end function Connection:query_row(query_str, ...) @@ -90,17 +90,17 @@ function Connection:begin() end function Connection:insert(table_name, data) - if table_name:is_blank() then + if string.is_blank(table_name) then error("Table name cannot be empty") end local keys = table.keys(data) local values = table.values(data) - local placeholders = string.repeat_("?, ", #keys):trim_right(", ") + local placeholders = string.trim_right(string.rep("?, ", #keys), ", ") - local query = "INSERT INTO {{table}} ({{columns}}) VALUES ({{placeholders}})":parse({ + local query = string.parse("INSERT INTO {{table}} ({{columns}}) VALUES ({{placeholders}})", { table = table_name, - columns = keys:join(", "), + columns = table.concat(keys, ", "), placeholders = placeholders }) @@ -108,14 +108,16 @@ function Connection:insert(table_name, data) end function Connection:upsert(table_name, data, conflict_columns) - if table_name:is_blank() then + if string.is_blank(table_name) then error("Table name cannot be empty") end local keys = table.keys(data) local values = table.values(data) - local placeholders = string.repeat_("?, ", #keys):trim_right(", ") - local updates = table.map(keys, function(key) return key .. " = excluded." .. key end):join(", ") + local placeholders = string.trim_right(string.rep("?, ", #keys), ", ") + + local updates = table.map(keys, function(key) return key .. " = excluded." .. key end) + local updates_str = table.concat(updates, ", ") local conflict_clause = "" if conflict_columns then @@ -126,32 +128,33 @@ function Connection:upsert(table_name, data, conflict_columns) end end - local query = "INSERT INTO {{table}} ({{columns}}) VALUES ({{placeholders}}) ON CONFLICT {{conflict}} DO UPDATE SET {{updates}}":parse({ + local query = string.parse("INSERT INTO {{table}} ({{columns}}) VALUES ({{placeholders}}) ON CONFLICT {{conflict}} DO UPDATE SET {{updates}}", { table = table_name, - columns = keys:join(", "), + columns = table.concat(keys, ", "), placeholders = placeholders, conflict = conflict_clause, - updates = updates + updates = updates_str }) return self:exec(query, unpack(values)) end function Connection:update(table_name, data, where_clause, ...) - if table_name:is_blank() then + if string.is_blank(table_name) then error("Table name cannot be empty") end - if where_clause:is_blank() then + if string.is_blank(where_clause) then error("WHERE clause cannot be empty for UPDATE") end local keys = table.keys(data) local values = table.values(data) - local sets = table.map(keys, function(key) return key .. " = ?" end):join(", ") + local sets = table.map(keys, function(key) return key .. " = ?" end) + local sets_str = table.concat(sets, ", ") - local query = "UPDATE {{table}} SET {{sets}} WHERE {{where}}":parse({ + local query = string.parse("UPDATE {{table}} SET {{sets}} WHERE {{where}}", { table = table_name, - sets = sets, + sets = sets_str, where = where_clause }) @@ -160,14 +163,14 @@ function Connection:update(table_name, data, where_clause, ...) end function Connection:delete(table_name, where_clause, ...) - if table_name:is_blank() then + if string.is_blank(table_name) then error("Table name cannot be empty") end - if where_clause:is_blank() then + if string.is_blank(where_clause) then error("WHERE clause cannot be empty for DELETE") end - local query = "DELETE FROM {{table}} WHERE {{where}}":parse({ + local query = string.parse("DELETE FROM {{table}} WHERE {{where}}", { table = table_name, where = where_clause }) @@ -175,7 +178,7 @@ function Connection:delete(table_name, where_clause, ...) end function Connection:select(table_name, columns, where_clause, ...) - if table_name:is_blank() then + if string.is_blank(table_name) then error("Table name cannot be empty") end @@ -184,15 +187,15 @@ function Connection:select(table_name, columns, where_clause, ...) columns = table.concat(columns, ", ") end - if where_clause and not where_clause:is_blank() then - local query = "SELECT {{columns}} FROM {{table}} WHERE {{where}}":parse({ + if where_clause and not string.is_blank(where_clause) then + local query = string.parse("SELECT {{columns}} FROM {{table}} WHERE {{where}}", { columns = columns, table = table_name, where = where_clause }) return self:query(query, ...) else - local query = "SELECT {{columns}} FROM {{table}}":parse({ + local query = string.parse("SELECT {{columns}} FROM {{table}}", { columns = columns, table = table_name }) @@ -201,62 +204,62 @@ function Connection:select(table_name, columns, where_clause, ...) end function Connection:table_exists(table_name) - if table_name:is_blank() then return false end - return self:query_value("SELECT name FROM sqlite_master WHERE type='table' AND name=?", table_name:trim()) ~= nil + if string.is_blank(table_name) then return false end + return self:query_value("SELECT name FROM sqlite_master WHERE type='table' AND name=?", string.trim(table_name)) ~= nil end function Connection:column_exists(table_name, column_name) - if table_name:is_blank() or column_name:is_blank() then return false end + if string.is_blank(table_name) or string.is_blank(column_name) then return false end - local result = self:query("PRAGMA table_info({{table}})":parse({table = table_name})) + local result = self:query(string.parse("PRAGMA table_info({{table}})", {table = table_name})) if result then return table.any(result, function(row) - return row.name:iequals(column_name:trim()) + return string.iequals(row.name, string.trim(column_name)) end) end return false end function Connection:create_table(table_name, schema) - if table_name:is_blank() or schema:is_blank() then + if string.is_blank(table_name) or string.is_blank(schema) then error("Table name and schema cannot be empty") end - local query = "CREATE TABLE IF NOT EXISTS {{table}} ({{schema}})":parse({ + local query = string.parse("CREATE TABLE IF NOT EXISTS {{table}} ({{schema}})", { table = table_name, - schema = schema:trim() + schema = string.trim(schema) }) return self:exec(query) end function Connection:drop_table(table_name) - if table_name:is_blank() then + if string.is_blank(table_name) then error("Table name cannot be empty") end - return self:exec("DROP TABLE IF EXISTS {{table}}":parse({table = table_name})) + return self:exec(string.parse("DROP TABLE IF EXISTS {{table}}", {table = table_name})) end function Connection:add_column(table_name, column_def) - if table_name:is_blank() or column_def:is_blank() then + if string.is_blank(table_name) or string.is_blank(column_def) then error("Table name and column definition cannot be empty") end - local query = "ALTER TABLE {{table}} ADD COLUMN {{column}}":parse({ + local query = string.parse("ALTER TABLE {{table}} ADD COLUMN {{column}}", { table = table_name, - column = column_def:trim() + column = string.trim(column_def) }) return self:exec(query) end function Connection:create_index(index_name, table_name, columns, unique) - if index_name:is_blank() or table_name:is_blank() then + if string.is_blank(index_name) or string.is_blank(table_name) then error("Index name and table name cannot be empty") end local unique_clause = unique and "UNIQUE " or "" local columns_str = type(columns) == "table" and table.concat(columns, ", ") or tostring(columns) - local query = "CREATE {{unique}}INDEX IF NOT EXISTS {{index}} ON {{table}} ({{columns}})":parse({ + local query = string.parse("CREATE {{unique}}INDEX IF NOT EXISTS {{index}} ON {{table}} ({{columns}})", { unique = unique_clause, index = index_name, table = table_name, @@ -266,10 +269,10 @@ function Connection:create_index(index_name, table_name, columns, unique) end function Connection:drop_index(index_name) - if index_name:is_blank() then + if string.is_blank(index_name) then error("Index name cannot be empty") end - return self:exec("DROP INDEX IF EXISTS {{index}}":parse({index = index_name})) + return self:exec(string.parse("DROP INDEX IF EXISTS {{index}}", {index = index_name})) end -- SQLite-specific functions @@ -287,29 +290,29 @@ end function Connection:foreign_keys(enabled) local value = enabled and "ON" or "OFF" - return self:exec("PRAGMA foreign_keys = {{value}}":parse({value = value})) + return self:exec(string.parse("PRAGMA foreign_keys = {{value}}", {value = value})) end function Connection:journal_mode(mode) - mode = (mode or "WAL"):upper() + mode = string.upper(mode or "WAL") local valid_modes = {"DELETE", "TRUNCATE", "PERSIST", "MEMORY", "WAL", "OFF"} if not table.contains(valid_modes, mode) then error("Invalid journal mode: " .. mode) end - return self:query("PRAGMA journal_mode = {{mode}}":parse({mode = mode})) + return self:query(string.parse("PRAGMA journal_mode = {{mode}}", {mode = mode})) end function Connection:synchronous(level) - level = (level or "NORMAL"):upper() + level = string.upper(level or "NORMAL") local valid_levels = {"OFF", "NORMAL", "FULL", "EXTRA"} if not table.contains(valid_levels, level) then error("Invalid synchronous level: " .. level) end - return self:exec("PRAGMA synchronous = {{level}}":parse({level = level})) + return self:exec(string.parse("PRAGMA synchronous = {{level}}", {level = level})) end function Connection:cache_size(size) @@ -317,28 +320,28 @@ function Connection:cache_size(size) if type(size) ~= "number" then error("Cache size must be a number") end - return self:exec("PRAGMA cache_size = {{size}}":parse({size = tostring(size)})) + return self:exec(string.parse("PRAGMA cache_size = {{size}}", {size = tostring(size)})) end function Connection:temp_store(mode) - mode = (mode or "MEMORY"):upper() + mode = string.upper(mode or "MEMORY") local valid_modes = {"DEFAULT", "FILE", "MEMORY"} if not table.contains(valid_modes, mode) then error("Invalid temp_store mode: " .. mode) end - return self:exec("PRAGMA temp_store = {{mode}}":parse({mode = mode})) + return self:exec(string.parse("PRAGMA temp_store = {{mode}}", {mode = mode})) end -- Connection management function sqlite.open(database_path) database_path = database_path or ":memory:" - if database_path ~= ":memory:" and database_path:is_blank() then + if database_path ~= ":memory:" and string.is_blank(database_path) then database_path = ":memory:" end - local conn_id = moonshark.sql_connect("sqlite", database_path:trim()) + local conn_id = moonshark.sql_connect("sqlite", string.trim(database_path)) if conn_id then return setmetatable({_id = conn_id}, Connection) end @@ -351,7 +354,7 @@ sqlite.connect = sqlite.open function sqlite.query(database_path, query_str, ...) local conn = sqlite.open(database_path) if not conn then - error("Failed to open SQLite database: {{path}}":parse({path = database_path or ":memory:"})) + error(string.parse("Failed to open SQLite database: {{path}}", {path = database_path or ":memory:"})) end local results = conn:query(query_str, ...) @@ -362,7 +365,7 @@ end function sqlite.exec(database_path, query_str, ...) local conn = sqlite.open(database_path) if not conn then - error("Failed to open SQLite database: {{path}}":parse({path = database_path or ":memory:"})) + error(string.parse("Failed to open SQLite database: {{path}}", {path = database_path or ":memory:"})) end local result = conn:exec(query_str, ...) @@ -401,13 +404,13 @@ function sqlite.migrate(database_path, migrations) end for _, migration in ipairs(migrations) do - if not migration.name or migration.name:is_blank() then + if not migration.name or string.is_blank(migration.name) then tx:rollback() conn:close() error("Migration must have a non-empty name") end - local existing = conn:query_value("SELECT id FROM _migrations WHERE name = ?", migration.name:trim()) + local existing = conn:query_value("SELECT id FROM _migrations WHERE name = ?", string.trim(migration.name)) if not existing then local ok, err = pcall(function() if type(migration.up) == "string" then @@ -420,12 +423,12 @@ function sqlite.migrate(database_path, migrations) end) if ok then - conn:exec("INSERT INTO _migrations (name) VALUES (?)", migration.name:trim()) - print("Applied migration: {{name}}":parse({name = migration.name})) + conn:exec("INSERT INTO _migrations (name) VALUES (?)", string.trim(migration.name)) + print(string.parse("Applied migration: {{name}}", {name = migration.name})) else tx:rollback() conn:close() - error("Migration '{{name}}' failed: {{error}}":parse({ + error(string.parse("Migration '{{name}}' failed: {{error}}", { name = migration.name, error = err or "unknown error" })) @@ -441,13 +444,13 @@ end -- Result processing utilities function sqlite.to_array(results, column_name) if not results or table.is_empty(results) then return {} end - if column_name:is_blank() then error("Column name cannot be empty") end + if string.is_blank(column_name) then error("Column name cannot be empty") end return table.map(results, function(row) return row[column_name] end) end function sqlite.to_map(results, key_column, value_column) if not results or table.is_empty(results) then return {} end - if key_column:is_blank() then error("Key column name cannot be empty") end + if string.is_blank(key_column) then error("Key column name cannot be empty") end local map = {} for _, row in ipairs(results) do @@ -459,7 +462,7 @@ end function sqlite.group_by(results, column_name) if not results or table.is_empty(results) then return {} end - if column_name:is_blank() then error("Column name cannot be empty") end + if string.is_blank(column_name) then error("Column name cannot be empty") end return table.group_by(results, function(row) return row[column_name] end) end @@ -475,16 +478,16 @@ function sqlite.print_results(results) -- Calculate column widths local widths = {} for _, col in ipairs(columns) do - widths[col] = col:length() + widths[col] = string.length(col) for _, row in ipairs(results) do local value = tostring(row[col] or "") - widths[col] = math.max(widths[col], value:length()) + widths[col] = math.max(widths[col], string.length(value)) end end -- Print header and separator - local header_parts = table.map(columns, function(col) return col:pad_right(widths[col]) end) - local separator_parts = table.map(columns, function(col) return string.repeat_("-", widths[col]) end) + local header_parts = table.map(columns, function(col) return string.pad_right(col, widths[col]) end) + local separator_parts = table.map(columns, function(col) return string.rep("-", widths[col]) end) print(table.concat(header_parts, " | ")) print(table.concat(separator_parts, "-+-")) @@ -493,7 +496,7 @@ function sqlite.print_results(results) for _, row in ipairs(results) do local value_parts = table.map(columns, function(col) local value = tostring(row[col] or "") - return value:pad_right(widths[col]) + return string.pad_right(value, widths[col]) end) print(table.concat(value_parts, " | ")) end diff --git a/modules/string+/string.lua b/modules/string+/string.lua index 0667757..ae9815e 100644 --- a/modules/string+/string.lua +++ b/modules/string+/string.lua @@ -861,7 +861,7 @@ function string.iparse(template_str, values) local value = values[value_index] local str = tostring(value or "") if escaped then - str:html_special_chars() + str = str:html_special_chars() end table.insert(output, str)