mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
Upload
This commit is contained in:
191
lua/sam/libs/sql/databases/mysql.lua
Normal file
191
lua/sam/libs/sql/databases/mysql.lua
Normal file
@@ -0,0 +1,191 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
local _SQL = sam.SQL
|
||||
local _error = _SQL.Error
|
||||
local traceback = debug.traceback
|
||||
|
||||
local _mysqloo, database = nil, nil
|
||||
|
||||
local SQL = {}
|
||||
|
||||
function SQL.Connect(callback, failed_callback, config)
|
||||
if database then
|
||||
local status = database:status()
|
||||
if status == _mysqloo.DATABASE_CONNECTING or status == _mysqloo.DATABASE_CONNECTED then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
_SQL.SetConnected(false)
|
||||
|
||||
require("mysqloo")
|
||||
|
||||
if not mysqloo then
|
||||
_error("mysqloo module doesn't exist, get it from https://github.com/FredyH/MySQLOO")
|
||||
return false
|
||||
end
|
||||
|
||||
_mysqloo = mysqloo
|
||||
|
||||
database = _mysqloo.connect(
|
||||
config.Host,
|
||||
config.Username,
|
||||
config.Password,
|
||||
config.Database,
|
||||
config.Port
|
||||
)
|
||||
|
||||
function database.onConnected()
|
||||
callback()
|
||||
end
|
||||
|
||||
function database.onConnectionFailed(_, error_text)
|
||||
failed_callback(error_text)
|
||||
end
|
||||
|
||||
database:connect()
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--
|
||||
--
|
||||
--
|
||||
local transaction
|
||||
|
||||
local add_transaction = function(query)
|
||||
transaction:addQuery(database:query(query))
|
||||
end
|
||||
|
||||
function SQL.Begin()
|
||||
transaction = database:createTransaction()
|
||||
return add_transaction
|
||||
end
|
||||
|
||||
function SQL.Commit(callback)
|
||||
transaction.SQL_traceback = traceback("", 2)
|
||||
|
||||
transaction.onSuccess = callback
|
||||
transaction.onError = transaction_onError
|
||||
|
||||
transaction:start()
|
||||
|
||||
transaction = nil
|
||||
end
|
||||
--
|
||||
--
|
||||
--
|
||||
|
||||
--
|
||||
--
|
||||
--
|
||||
local on_query_success = function(query, data)
|
||||
if query.SQL_first_row then
|
||||
data = data[1]
|
||||
end
|
||||
query.SQL_callback(data, query.SQL_callback_obj)
|
||||
end
|
||||
|
||||
local on_query_fail = function(query, error_text)
|
||||
local status = database:status()
|
||||
|
||||
-- https://github.com/Kamshak/LibK/blob/master/lua/libk/server/sv_libk_database.lua#L129
|
||||
if status == _mysqloo.DATABASE_NOT_CONNECTED or status == _mysqloo.DATABASE_CONNECTING or error_text:find("Lost connection to MySQL server during query", 1, true) then
|
||||
_SQL.SetConnected(false)
|
||||
SQL.Query(query.SQL_query_string, query.SQL_callback, query.SQL_first_row, query.SQL_callback_obj)
|
||||
else
|
||||
-- 3cb9b992975d0cc0ba1b28f92ab5d1b700a08080a59b058f1424736060a73552
|
||||
_error("Query error: " .. error_text, query.SQL_traceback)
|
||||
end
|
||||
end
|
||||
|
||||
function SQL.Query(query, callback, first_row, callback_obj)
|
||||
local status = database:status()
|
||||
if status == _mysqloo.DATABASE_NOT_CONNECTED or status == _mysqloo.DATABASE_INTERNAL_ERROR then
|
||||
_SQL.Connect()
|
||||
database:wait()
|
||||
end
|
||||
|
||||
local query_string = query
|
||||
query = database:query(query)
|
||||
|
||||
query.SQL_query_string = query_string
|
||||
|
||||
if callback then
|
||||
query.onSuccess = on_query_success
|
||||
query.SQL_callback = callback
|
||||
query.SQL_first_row = first_row
|
||||
query.SQL_callback_obj = callback_obj
|
||||
end
|
||||
|
||||
query.SQL_traceback = traceback("", 2)
|
||||
query.onError = on_query_fail
|
||||
|
||||
query:start()
|
||||
|
||||
return query
|
||||
end
|
||||
|
||||
-- local prepared_set_values = function(prepared_query, values)
|
||||
-- for i = 1, #values do
|
||||
-- local v = values[i]
|
||||
-- local value_type = type(v)
|
||||
-- if value_type == "string" then
|
||||
-- prepared_query:setString(i, v)
|
||||
-- elseif value_type == "number" then
|
||||
-- prepared_query:setNumber(i, v)
|
||||
-- else
|
||||
-- error(
|
||||
-- string.format(
|
||||
-- "%s invalid type '%s' was passed to escape '%s'",
|
||||
-- "(" .. SQL.GetAddonName() .. " | MySQL)",
|
||||
-- value_type,
|
||||
-- v
|
||||
-- )
|
||||
-- )
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- function SQL.Prepare(query, callback, first_row, callback_obj)
|
||||
-- local prepared_query = database:prepare(query)
|
||||
-- prepared_query.SetValues = prepared_set_values
|
||||
|
||||
-- if callback then
|
||||
-- prepared_query.onSuccess = on_query_success
|
||||
-- prepared_query.SQL_callback = callback
|
||||
-- prepared_query.SQL_first_row = first_row
|
||||
-- prepared_query.SQL_callback_obj = callback_obj
|
||||
-- end
|
||||
|
||||
-- prepared_query.SQL_traceback = traceback("", 2)
|
||||
-- prepared_query.onError = on_query_fail
|
||||
|
||||
-- return prepared_query
|
||||
-- end
|
||||
|
||||
--
|
||||
--
|
||||
--
|
||||
|
||||
function SQL.EscapeString(value, no_quotes)
|
||||
if no_quotes then
|
||||
return database:escape(value)
|
||||
else
|
||||
return "'" .. database:escape(value) .. "'"
|
||||
end
|
||||
end
|
||||
|
||||
function SQL.TableExistsQuery(name)
|
||||
return "SHOW TABLES LIKE " .. SQL.EscapeString(name)
|
||||
end
|
||||
|
||||
return SQL
|
||||
148
lua/sam/libs/sql/databases/sqlite.lua
Normal file
148
lua/sam/libs/sql/databases/sqlite.lua
Normal file
@@ -0,0 +1,148 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
local _SQL = sam.SQL
|
||||
local _error = sam.SQL.Error
|
||||
local sql_query = sql.Query
|
||||
|
||||
local SQL = {}
|
||||
|
||||
function SQL.Connect(callback)
|
||||
timer.Simple(0, callback)
|
||||
return true
|
||||
end
|
||||
|
||||
--
|
||||
--
|
||||
--
|
||||
local transactions
|
||||
|
||||
local add_transaction = function(query)
|
||||
table.insert(transactions, query)
|
||||
end
|
||||
|
||||
function SQL.Begin()
|
||||
transactions = {}
|
||||
sql_query("BEGIN TRANSACTION")
|
||||
return add_transaction
|
||||
end
|
||||
|
||||
function SQL.Commit(callback)
|
||||
for i = 1, #transactions do
|
||||
if sql_query(transactions[i]) == false then
|
||||
sql_query("ROLLBACK TRANSACTION")
|
||||
transactions = nil
|
||||
_error("Transaction error: " .. sql.LastError())
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
transactions = nil
|
||||
|
||||
sql_query("COMMIT TRANSACTION")
|
||||
|
||||
if callback then
|
||||
callback()
|
||||
end
|
||||
end
|
||||
--
|
||||
--
|
||||
--
|
||||
|
||||
--
|
||||
--
|
||||
--
|
||||
local query_obj = {
|
||||
wait = function() end -- mysqloo has query:wait()
|
||||
}
|
||||
|
||||
function SQL.Query(query, callback, first_row, callback_obj)
|
||||
local data = sql_query(query)
|
||||
if data == false then
|
||||
_error("Query error: " .. sql.LastError())
|
||||
elseif callback then
|
||||
if data == nil then
|
||||
if not first_row then
|
||||
data = {}
|
||||
end
|
||||
elseif first_row then
|
||||
data = data[1]
|
||||
end
|
||||
|
||||
callback(data, callback_obj)
|
||||
end
|
||||
|
||||
return query_obj
|
||||
end
|
||||
|
||||
-- local concat = table.concat
|
||||
-- local prepared_set_values = function(prepared_query, values)
|
||||
-- for i = 1, prepared_query.args_n do
|
||||
-- prepared_query[prepared_query[-i]] = _SQL.Escape(values[i])
|
||||
-- end
|
||||
-- return concat(prepared_query, "", 1, prepared_query.n)
|
||||
-- end
|
||||
|
||||
-- local prepared_start = function()
|
||||
-- end
|
||||
|
||||
-- local sub, find = string.sub, string.find
|
||||
-- function SQL.Prepare(query, callback, first_row, callback_obj)
|
||||
-- local prepared_query = {}
|
||||
-- prepared_query.wait = query_obj.wait
|
||||
-- prepared_query.Start = prepared_start
|
||||
-- prepared_query.SetValues = prepared_set_values
|
||||
|
||||
-- local count, args_n = 0, 0
|
||||
-- local pos, start, _end = 0, nil, 0
|
||||
-- while true do
|
||||
-- start, _end = find(query, "?", _end + 1, true)
|
||||
|
||||
-- if not start then
|
||||
-- break
|
||||
-- end
|
||||
|
||||
-- if pos ~= start then
|
||||
-- count = count + 1; prepared_query[count] = sub(query, pos, start - 1)
|
||||
-- end
|
||||
|
||||
-- count = count + 1; prepared_query[count] = "NULL"
|
||||
-- args_n = args_n - 1; prepared_query[args_n] = count
|
||||
|
||||
-- pos = _end + 1
|
||||
-- end
|
||||
|
||||
-- if pos <= #query then
|
||||
-- count = count + 1; prepared_query[count] = sub(query, pos)
|
||||
-- end
|
||||
|
||||
-- prepared_query.n = count
|
||||
-- prepared_query.args_n = abs(args_n)
|
||||
|
||||
-- return prepared_query
|
||||
-- end
|
||||
--
|
||||
--
|
||||
--
|
||||
|
||||
local SQLStr = SQLStr
|
||||
function SQL.EscapeString(value, no_quotes)
|
||||
return SQLStr(value, no_quotes)
|
||||
end
|
||||
|
||||
function SQL.TableExistsQuery(name)
|
||||
return "SELECT `name` FROM `sqlite_master` WHERE `name` = " .. SQL.EscapeString(name) .. " AND `type` = 'table'"
|
||||
end
|
||||
|
||||
--
|
||||
--
|
||||
--
|
||||
|
||||
return SQL
|
||||
152
lua/sam/libs/sql/sv_init.lua
Normal file
152
lua/sam/libs/sql/sv_init.lua
Normal file
@@ -0,0 +1,152 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
if SAM_LOADED then return end
|
||||
|
||||
local format, isstring, istable, tonumber = string.format, sam.isstring, sam.istable, tonumber
|
||||
|
||||
local config = {}
|
||||
|
||||
local SQL, _SQL = {}, nil
|
||||
|
||||
function SQL.Print(...)
|
||||
MsgC(
|
||||
Color(255, 255, 255), "(",
|
||||
Color(244, 67, 54), SQL.GetAddonName(),
|
||||
Color(255, 255, 255), " | ",
|
||||
Color(244, 67, 54), SQL.IsMySQL() and "MySQL" or "SQLite",
|
||||
Color(255, 255, 255), ") ",
|
||||
...
|
||||
)
|
||||
Msg("\n")
|
||||
end
|
||||
|
||||
function SQL.Error(err, trace)
|
||||
SQL.Print(err, trace or debug.traceback("", 2))
|
||||
end
|
||||
|
||||
function SQL.Connect()
|
||||
return _SQL.Connect(SQL.OnConnected, SQL.OnConnectionFailed, config)
|
||||
end
|
||||
|
||||
do
|
||||
local in_transaction, old_query = false, nil
|
||||
|
||||
function SQL.Begin()
|
||||
if in_transaction then
|
||||
return SQL.Error("transaction on going!")
|
||||
end
|
||||
in_transaction = true
|
||||
|
||||
SQL.Query, old_query = _SQL.Begin(), SQL.Query
|
||||
end
|
||||
|
||||
function SQL.Commit(callback)
|
||||
if not in_transaction then return end
|
||||
|
||||
in_transaction = false
|
||||
SQL.Query, old_query = old_query, nil
|
||||
|
||||
return _SQL.Commit(callback)
|
||||
end
|
||||
end
|
||||
|
||||
local gsub = string.gsub
|
||||
function SQL.FQuery(query, args, callback, first_row, callback_obj)
|
||||
query = gsub(query, "{(%d)(f?)}", function(i, no_escape)
|
||||
return SQL.Escape(args[tonumber(i)], no_escape ~= "")
|
||||
end)
|
||||
|
||||
return SQL.Query(query, callback, first_row, callback_obj)
|
||||
end
|
||||
|
||||
do
|
||||
local table_exists = function(data, callback)
|
||||
callback(data and true or false)
|
||||
end
|
||||
|
||||
function SQL.TableExists(name, callback)
|
||||
return SQL.Query(_SQL.TableExistsQuery(name), table_exists, true, callback)
|
||||
end
|
||||
end
|
||||
|
||||
function SQL.IsMySQL()
|
||||
return config.MySQL == true
|
||||
end
|
||||
|
||||
do
|
||||
local connected = false
|
||||
function SQL.IsConnected()
|
||||
return connected
|
||||
end
|
||||
function SQL.SetConnected(is_connected)
|
||||
connected = is_connected
|
||||
end
|
||||
end
|
||||
|
||||
function SQL.Escape(value, no_quotes)
|
||||
local value_type = type(value)
|
||||
if value_type == "string" then
|
||||
return _SQL.EscapeString(value, no_quotes)
|
||||
elseif value_type == "number" then
|
||||
return value
|
||||
else
|
||||
error(
|
||||
format(
|
||||
"%s invalid type '%s' was passed to escape '%s'",
|
||||
"(" .. SQL.GetAddonName() .. " | " .. (SQL.IsMySQL() and "MySQL" or "SQLite") .. ")",
|
||||
value_type,
|
||||
value
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
function SQL.OnConnected()
|
||||
SQL.SetConnected(true)
|
||||
hook.Call(SQL.GetAddonName() .. ".DatabaseConnected")
|
||||
end
|
||||
|
||||
function SQL.OnConnectionFailed(error_text)
|
||||
SQL.Error("Failed to connect to the server: " .. error_text)
|
||||
hook.Call(SQL.GetAddonName() .. ".DatabaseConnectionFailed", nil, error_text)
|
||||
end
|
||||
|
||||
function SQL.SetConfig(new_config)
|
||||
if not istable(new_config) then return end
|
||||
if new_config.MySQL == true then
|
||||
for _, v in ipairs({"Host", "Username", "Password", "Database"}) do
|
||||
if not isstring(new_config[v]) then
|
||||
return SQL.Error(
|
||||
format("config value for '%s' is invalid '%s' needs to be a string!", v, config[v])
|
||||
)
|
||||
end
|
||||
end
|
||||
new_config.Port = tonumber(new_config.Port) or 3306
|
||||
_SQL = sam.load_file("sam/libs/sql/databases/mysql.lua", "sv_")
|
||||
else
|
||||
_SQL = sam.load_file("sam/libs/sql/databases/sqlite.lua", "sv_")
|
||||
end
|
||||
|
||||
SQL.Query = _SQL.Query
|
||||
config = new_config
|
||||
end
|
||||
|
||||
do
|
||||
local addon_name = "NO NAME"
|
||||
function SQL.SetAddonName(name)
|
||||
addon_name = name
|
||||
end
|
||||
function SQL.GetAddonName()
|
||||
return addon_name
|
||||
end
|
||||
end
|
||||
|
||||
sam.SQL = SQL
|
||||
Reference in New Issue
Block a user