增加权限、应用程序、角色相关数据表的业务逻辑查看、增加、删除和修改等操作

This commit is contained in:
wanglei 2025-10-27 21:18:16 +08:00
parent 6512b2264c
commit 433260dd16
21 changed files with 536 additions and 1775 deletions

View File

@ -10,14 +10,14 @@ local dao = require("service.system.account")
local resp = require("util.response")
local validator = require("util.validator")
--获取所有账信息
--获取所有账信息
function _M.get_allaccount()
local code,ret = dao.getAllAccount()
local result = resp:json(code, ret)
resp:send(result)
end
--根据账号id获取账号信息
--根据账户id获取账户信息
function _M.get_account(m)
local id = m.id
local code,ret = dao.getAccount(id)
@ -25,7 +25,7 @@ function _M.get_account(m)
resp:send(result)
end
--根据账号id获取账号信息
--根据账户id获取账户信息
function _M.add_account()
--获取请求头并进行校验
if validator.checkReqHeader() == false then
@ -49,7 +49,7 @@ function _M.add_account()
resp:send(result)
end
--根据账号id删除账号信息
--根据账户id删除账户信息
function _M.delete_account(m)
local id = m.id
local code, ret = dao.deleteAccount(id)
@ -57,7 +57,7 @@ function _M.delete_account(m)
resp:send(result)
end
--根据账号id删除账号信息
--根据账户id删除账户信息
function _M.update_account(m)
local id = m.id
--读取请求体的数据

View File

@ -0,0 +1,78 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by admin.
--- DateTime: 2025/9/25 08:19
---
local _M = {}
local dao = require("service.system.application")
local resp = require("util.response")
local validator = require("util.validator")
--获取所有应用程序信息
function _M.get_allapplication()
local code,ret = dao.getAllApplication()
local result = resp:json(code, ret)
resp:send(result)
end
--根据应用id获取应用信息
function _M.get_application(m)
local id = m.id
local code,ret = dao.getApplication(id)
local result = resp:json(code, ret)
resp:send(result)
end
--根据应用id获取应用信息
function _M.add_application()
--获取请求头并进行校验
if validator.checkReqHeader() == false then
local result = resp:json(0x000001)
resp:send(result)
return
end
--读取请求体的数据
ngx.req.read_body()
--获取请求数据
local body_data = ngx.req.get_body_data()
--判断请求体数据是否为空
if body_data == nil then
local result = resp:json(0x000001)
resp:send(result)
return
end
--ngx.say(body_data)
local code, ret = dao.addApplication(body_data)
local result = resp:json(code, ret)
resp:send(result)
end
--根据应用id删除应用信息
function _M.delete_application(m)
local id = m.id
local code, ret = dao.deleteApplication(id)
local result = resp:json(code, ret)
resp:send(result)
end
--根据应用id删除应用信息
function _M.update_application(m)
local id = m.id
--读取请求体的数据
ngx.req.read_body()
--获取请求数据
local body_data = ngx.req.get_body_data()
--判断请求体数据是否为空
if body_data == nil then
local result = resp:json(0x000001)
resp:send(result)
return
end
local code, ret = dao.updateApplication(id, body_data)
local result = resp:json(code, ret)
resp:send(result)
end
return _M

View File

@ -0,0 +1,78 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by admin.
--- DateTime: 2025/9/25 08:19
---
local _M = {}
local dao = require("service.system.permission")
local resp = require("util.response")
local validator = require("util.validator")
--获取所有权限信息
function _M.get_allpermission()
local code,ret = dao.getAllPermission()
local result = resp:json(code, ret)
resp:send(result)
end
--根据权限id获取权限信息
function _M.get_permission(m)
local id = m.id
local code,ret = dao.getPermission(id)
local result = resp:json(code, ret)
resp:send(result)
end
--根据账号id获取账号信息
function _M.add_permission()
--获取请求头并进行校验
if validator.checkReqHeader() == false then
local result = resp:json(0x000001)
resp:send(result)
return
end
--读取请求体的数据
ngx.req.read_body()
--获取请求数据
local body_data = ngx.req.get_body_data()
--判断请求体数据是否为空
if body_data == nil then
local result = resp:json(0x000001)
resp:send(result)
return
end
--ngx.say(body_data)
local code, ret = dao.addPermission(body_data)
local result = resp:json(code, ret)
resp:send(result)
end
--根据账号id删除账号信息
function _M.delete_permission(m)
local id = m.id
local code, ret = dao.deletePermission(id)
local result = resp:json(code, ret)
resp:send(result)
end
--根据账号id删除账号信息
function _M.update_permission(m)
local id = m.id
--读取请求体的数据
ngx.req.read_body()
--获取请求数据
local body_data = ngx.req.get_body_data()
--判断请求体数据是否为空
if body_data == nil then
local result = resp:json(0x000001)
resp:send(result)
return
end
local code, ret = dao.updatePermission(id, body_data)
local result = resp:json(code, ret)
resp:send(result)
end
return _M

78
src/api/system/role.lua Normal file
View File

@ -0,0 +1,78 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by admin.
--- DateTime: 2025/9/25 08:19
---
local _M = {}
local dao = require("service.system.role")
local resp = require("util.response")
local validator = require("util.validator")
--获取所有角色信息
function _M.get_allrole()
local code,ret = dao.getAllRole()
local result = resp:json(code, ret)
resp:send(result)
end
--根据角色id获取角色信息
function _M.get_role(m)
local id = m.id
local code,ret = dao.getRole(id)
local result = resp:json(code, ret)
resp:send(result)
end
--根据角色id获取角色信息
function _M.add_role()
--获取请求头并进行校验
if validator.checkReqHeader() == false then
local result = resp:json(0x000001)
resp:send(result)
return
end
--读取请求体的数据
ngx.req.read_body()
--获取请求数据
local body_data = ngx.req.get_body_data()
--判断请求体数据是否为空
if body_data == nil then
local result = resp:json(0x000001)
resp:send(result)
return
end
--ngx.say(body_data)
local code, ret = dao.addRole(body_data)
local result = resp:json(code, ret)
resp:send(result)
end
--根据角色id删除角色信息
function _M.delete_role(m)
local id = m.id
local code, ret = dao.deleteRole(id)
local result = resp:json(code, ret)
resp:send(result)
end
--根据角色id删除角色信息
function _M.update_role(m)
local id = m.id
--读取请求体的数据
ngx.req.read_body()
--获取请求数据
local body_data = ngx.req.get_body_data()
--判断请求体数据是否为空
if body_data == nil then
local result = resp:json(0x000001)
resp:send(result)
return
end
local code, ret = dao.updateRole(id, body_data)
local result = resp:json(code, ret)
resp:send(result)
end
return _M

12
src/model/application.lua Normal file
View File

@ -0,0 +1,12 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by admin.
--- DateTime: 2025/10/25 16:36
--- 数据表模型文件
--引用使用的库文件
local Model = require("util.model")
--创建一个数据表相关的模型
local Application = Model:new('tbl_application')
return Application

12
src/model/permission.lua Normal file
View File

@ -0,0 +1,12 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by admin.
--- DateTime: 2025/10/25 16:36
--- 数据表模型文件
--引用使用的库文件
local Model = require("util.model")
--创建一个数据表相关的模型
local Permission = Model:new('tbl_permission')
return Permission

12
src/model/role.lua Normal file
View File

@ -0,0 +1,12 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by admin.
--- DateTime: 2025/10/25 16:36
--- 数据表模型文件
--引用使用的库文件
local Model = require("util.model")
--创建一个数据表相关的模型
local Role = Model:new('tbl_role')
return Role

View File

@ -0,0 +1,87 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by .
--- DateTime: 2025/9/27 16:02
--- 业务逻辑 对应用数据表进行数据表业务处理
local validator = require("util.validator")
local helpers = require("util.helpers")
local application = require("model.application")
local _M = {}
-- 查询数据表中的所有应用信息
function _M.getAllApplication()
return application:all()
end
--根据应用id获取应用信息
function _M.getApplication(id)
return application.find(id)
end
--增加应用信息到数据表
function _M.addApplication(jsonData)
--验证数据的正确性,错误时返回
local success, result = validator.checkJson(jsonData)
if success == false then
return 0x000001, result
end
--解析json中的键和数据值
local name = ""
for key, value in pairs(result) do
if key == "name" then name = value end
end
--根据应用进行验证是否存在
local code, res = application:where("name", "=", name):get()
if code ~= 0 then
return 0x000001, res
end
local num = 0
for _, row in ipairs(res) do
for key, value in pairs(row) do
num = num + 1
end
end
--应用存在时返回应用已经存在
if num <= 0 then
return 0x01000C, nil
end
--键值为id产生uuid数据值增加到json中
result.id = helpers.getUuid()
local ret = helpers.convert_json(result)
-- 创建一个应用
return application:create('{'..ret..'}')
end
--增加应用信息到数据表
function _M.deleteApplication(id)
return application:delete(id)
end
--更新应用信息到数据表
function _M.updateApplication(id, jsonData)
--根据应用id进行验证应用是否存在
local code, res = application:find(id)
if code ~= 0 then
return 0x000001, res
end
local num = 0
for _, row in ipairs(res) do
for key, value in pairs(row) do
num = num + 1
end
end
--应用不存在返回错误
if num <= 0 then
return 0x01000C, nil
end
--验证数据的正确性,错误时返回
local success, result = validator.checkJson(jsonData)
if success == false then
return 0x000001, result
end
--对数据内容进行更新
return application:where('id', '=', id):update(jsonData)
end
return _M

View File

@ -0,0 +1,87 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by .
--- DateTime: 2025/9/27 17:06
--- 业务逻辑 对权限数据表进行数据表业务处理
local validator = require("util.validator")
local helpers = require("util.helpers")
local permission = require("model.permission")
local _M = {}
-- 查询数据表中的所有权限信息
function _M.getAllPermission()
return permission:all()
end
--根据权限id获取权限信息
function _M.getPermission(id)
return permission.find(id)
end
--增加权限信息到数据表
function _M.addPermission(jsonData)
--验证数据的正确性,错误时返回
local success, result = validator.checkJson(jsonData)
if success == false then
return 0x000001, result
end
--解析json中的键和数据值
local name = ""
for key, value in pairs(result) do
if key == "name" then name = value end
end
--根据权限进行验证是否存在
local code, res = permission:where("name", "=", name):get()
if code ~= 0 then
return 0x000001, res
end
local num = 0
for _, row in ipairs(res) do
for key, value in pairs(row) do
num = num + 1
end
end
--权限存在时返回权限已经存在
if num <= 0 then
return 0x01000C, nil
end
--键值为id产生uuid数据值增加到json中
result.id = helpers.getUuid()
local ret = helpers.convert_json(result)
-- 创建一个权限
return permission:create('{'..ret..'}')
end
--增加权限信息到数据表
function _M.deletePermission(id)
return permission:delete(id)
end
--更新权限信息到数据表
function _M.updatePermission(id, jsonData)
--根据权限id进行验证权限是否存在
local code, res = permission:find(id)
if code ~= 0 then
return 0x000001, res
end
local num = 0
for _, row in ipairs(res) do
for key, value in pairs(row) do
num = num + 1
end
end
--权限不存在返回错误
if num <= 0 then
return 0x01000C, nil
end
--验证数据的正确性,错误时返回
local success, result = validator.checkJson(jsonData)
if success == false then
return 0x000001, result
end
--对数据内容进行更新
return permission:where('id', '=', id):update(jsonData)
end
return _M

View File

@ -0,0 +1,87 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by .
--- DateTime: 2025/9/27 15:19
--- 业务逻辑 对用户数据表进行数据表业务处理
local validator = require("util.validator")
local helpers = require("util.helpers")
local role = require("model.role")
local _M = {}
-- 查询数据表中的所有角色信息
function _M.getAllRole()
return role:all()
end
--根据角色id获取角色信息
function _M.getRole(id)
return role.find(id)
end
--增加角色信息到数据表
function _M.addRole(jsonData)
--验证数据的正确性,错误时返回
local success, result = validator.checkJson(jsonData)
if success == false then
return 0x000001, result
end
--解析json中的键和数据值
local name = ""
for key, value in pairs(result) do
if key == "name" then name = value end
end
--根据角色进行验证是否存在
local code, res = role:where("name", "=", name):get()
if code ~= 0 then
return 0x000001, res
end
local num = 0
for _, row in ipairs(res) do
for key, value in pairs(row) do
num = num + 1
end
end
--角色存在时返回账号已经存在
if num <= 0 then
return 0x01000C, nil
end
--键值为id产生uuid数据值增加到json中
result.id = helpers.getUuid()
local ret = helpers.convert_json(result)
-- 创建一个角色
return role:create('{'..ret..'}')
end
--增加角色信息到数据表
function _M.deleteRole(id)
return role:delete(id)
end
--更新角色信息到数据表
function _M.updateRole(id, jsonData)
--根据角色id进行验证角色是否存在
local code, res = role:find(id)
if code ~= 0 then
return 0x000001, res
end
local num = 0
for _, row in ipairs(res) do
for key, value in pairs(row) do
num = num + 1
end
end
--角色不存在返回错误
if num <= 0 then
return 0x01000C, nil
end
--验证数据的正确性,错误时返回
local success, result = validator.checkJson(jsonData)
if success == false then
return 0x000001, result
end
--对数据内容进行更新
return role:where('id', '=', id):update(jsonData)
end
return _M

View File

@ -1,141 +0,0 @@
------------------------------------------------------------------------------
-- Class --
------------------------------------------------------------------------------
local Field = {
-- Table column type
__type__ = "varchar",
-- Validator handler
validator = function (self, value)
return true
end,
-- Default parser
as = function (value)
return value
end,
to_type = Type.to.str,
-- Call when create new field in some table
register = function (self, args)
if not args then
args = {}
end
-- New field type
-------------------------------------------
-- @args {table}
-- Table can have parametrs:
-- @args.__type__ {string} some sql valid type
-- @args.validator {function} type validator
-- @args.as {function} return parse value
-------------------------------------------
new_field_type = {
-- some sql valid type
__type__ = args.__type__ or self.__type__,
-- Validator handler
validator = args.validator or self.validator,
-- Parse variable for equation
as = args.as or self.as,
-- Cast values to correct type
to_type = args.to_type or self.to_type,
-- Default settings for type
settings = args.settings or {},
-- Get new table column instance
new = function (this, args)
if not args then
args = {}
end
local new_self = {
-- link to field instance
field = this,
-- Column name
name = nil,
-- Parent table
__table__ = nil,
-- table column settings
settings = {
default = nil,
null = false,
unique = false,
max_length = nil,
primary_key = false,
escape_value = false
},
-- Return string for column type create
_create_type = function (this)
local _type = this.field.__type__
if this.settings.max_length and this.settings.max_length > 0 then
_type = _type .. "(" .. this.settings.max_length .. ")"
end
if this.settings.primary_key then
_type = _type .. " PRIMARY KEY"
end
if this.settings.auto_increment and DB.type ~= SQLITE then
_type = _type .. " AUTO_INCREMENT"
end
if this.settings.unique then
_type = _type .. " UNIQUE"
end
_type = _type .. (this.settings.null and " NULL"
or " NOT NULL")
return _type
end
}
-- Set Default settings
--
-- The content of the settings table must be copied because trying to copy a table
-- directly will result in a reference to the original table, thus all
-- instances of the same field type would have the same settings table.
--
for index, setting in pairs(new_self.field.settings) do
new_self.settings[index] = setting
end
-- Set settings for column
if args.max_length then
new_self.settings.max_length = args.max_length
end
if args.null ~= nil then
new_self.settings.null = args.null
end
if new_self.settings.foreign_key and args.to then
new_self.settings.to = args.to
end
if args.escape_value then
new_self.settings.escape_value = true
end
return new_self
end
}
setmetatable(new_field_type, {__call = new_field_type.new})
return new_field_type
end
}
return Field

View File

@ -1,103 +0,0 @@
------------------------------------------------------------------------------
-- Constants --
------------------------------------------------------------------------------
-- Backtrace types
ERROR = 'e'
WARNING = 'w'
INFO = 'i'
DEBUG = 'd'
All_Tables = {}
------------------------------------------------------------------------------
-- Helping functions --
------------------------------------------------------------------------------
local _pairs = pairs
function pairs(Table)
if Table.__classname__ == QUERY_LIST then
return Table()
else
return _pairs(Table)
end
end
function BACKTRACE(tracetype, message)
if DB.backtrace then
if tracetype == ERROR then
print("[SQL:Error] " .. message)
os.exit()
elseif tracetype == WARNING then
print("[SQL:Warning] " .. message)
elseif tracetype == INFO then
print("[SQL:Info] " .. message)
end
end
if DB.DEBUG and tracetype == DEBUG then
print("[SQL:Debug] " .. message)
end
end
function string.endswith(String, End)
return End == '' or string.sub(String, -string.len(End)) == End
end
function string.cutend(String, End)
return End == '' and String or string.sub(String, 0, -#End - 1)
end
function string.divided_into(String, separator)
local separator_pos = string.find(String, separator)
return string.sub(String, 0, separator_pos - 1),
string.sub(String, separator_pos + 1, #String)
end
function table.has_key(array, key)
if Type.is.table(key) and key.colname then
key = key.colname
end
for array_key, _ in pairs(array) do
if array_key == key then
return true
end
end
end
function table.has_value(array, value)
if Type.is.table(value) and value.colname then
value = value.colname
end
for _, array_value in pairs(array) do
if array_value == value then
return true
end
end
end
function table.join(array, separator)
local result = ""
local counter = 0
if not separator then
separator = ","
end
for _, value in pairs(array) do
if counter ~= 0 then
value = separator .. value
end
result = result .. value
counter = counter + 1
end
return result
end

View File

@ -1,25 +0,0 @@
-- Function for create column functions
local function Property(args)
return function (colname)
local column_func = {
-- class type
__classtype__ = AGGREGATOR,
-- Asc column name
colname = colname,
-- concatenate methods
__concat = function (left_part, right_part)
return tostring(left_part) .. tostring(right_part)
end,
__tostring = args.parse or self.parse
}
setmetatable(column_func, {__tostring = column_func.__tostring,
__concat = column_func.__concat})
return column_func
end
end
return Property

View File

@ -1,231 +0,0 @@
------------------------------------------------------------------------------
-- query.lua --
------------------------------------------------------------------------------
-- Creates an instance to retrieve and manage a
-- string table with the database
---------------------------------------------------
-- @own_table {table} parent table instace
-- @data {table} data returned by the query to the database
--
-- @return {table} database query instance
---------------------------------------------------
function Query(own_table, data)
local query = {
------------------------------------------------
-- Table info varibles --
------------------------------------------------
-- Table instance
own_table = own_table,
-- Column data
-- Structure example of one column
-- fieldname = {
-- old = nil,
-- new = nil
-- }
_data = {},
-- Data only for read mode
_readonly = {},
------------------------------------------------
-- Metamethods --
------------------------------------------------
-- Get column value
-----------------------------------------
-- @colname {string} column name in table
--
-- @return {string|boolean|number|nil} column value
-----------------------------------------
_get_col = function (self, colname)
if self._data[colname] and self._data[colname].new then
return self._data[colname].new
elseif self._readonly[colname] then
return self._readonly[colname]
end
end,
-- Set column new value
-----------------------------------------
-- @colname {string} column name in table
-- @colvalue {string|number|boolean} new column value
-----------------------------------------
_set_col = function (self, colname, colvalue)
local coltype
if self._data[colname] and self._data[colname].new and colname ~= ID then
coltype = self.own_table:get_column(colname)
if coltype and coltype.field.validator(colvalue) then
self._data[colname].old = self._data[colname].new
self._data[colname].new = colvalue
else
BACKTRACE(WARNING, "Not valid column value for update")
end
end
end,
------------------------------------------------
-- Private methods --
------------------------------------------------
-- Add new row to table
_add = function (self)
local insert = "INSERT INTO `" .. self.own_table.__tablename__ .. "` ("
local counter = 0
local values = ""
local _connect
local value
local colname
for _, table_column in pairs(self.own_table.__colnames) do
colname = table_column.name
if colname ~= ID then
-- If value exist correct value
if self[colname] ~= nil then
value = self[colname]
if table_column.field.validator(value) then
value = _G.escapeValue(self.own_table, colname, value)
value = table_column.field.as(value)
else
BACKTRACE(WARNING, "Wrong type for table '" ..
self.own_table.__tablename__ ..
"' in column '" .. tostring(colname) .. "'")
return false
end
-- Set default value
elseif table_column.settings.default then
value = table_column.field.as(table_column.settings.default)
else
value = "NULL"
end
colname = "`" .. colname .. "`"
-- TODO: save in correct type
if counter ~= 0 then
colname = ", " .. colname
value = ", " .. value
end
values = values .. value
insert = insert .. colname
counter = counter + 1
end
end
insert = insert .. ") \n\t VALUES (" .. values .. ")"
print(insert)
-- TODO: return valid ID
_connect = db:insert(insert)
self._data.id = {new = _connect}
end,
-- Update data in database
_update = function (self)
local update = "UPDATE `" .. self.own_table.__tablename__ .. "` "
local equation_for_set = {}
local set, coltype
for colname, colinfo in pairs(self._data) do
if colinfo.old ~= colinfo.new and colname ~= ID then
coltype = self.own_table:get_column(colname)
if coltype and coltype.field.validator(colinfo.new) then
local colvalue = _G.escapeValue(self.own_table, colname, colinfo.new)
set = " `" .. colname .. "` = " .. coltype.field.as(colvalue)
table.insert(equation_for_set, set)
else
BACKTRACE(WARNING, "Can't update value for column `" ..
Type.to.str(colname) .. "`")
end
end
end
set = table.join(equation_for_set, ",")
if set ~= "" then
update = update .. " SET " .. set .. "\n\t WHERE `" .. ID .. "` = " .. self.id
db:execute(update)
end
end,
------------------------------------------------
-- User methods --
------------------------------------------------
-- save row
save = function (self)
if self.id then
self:_update()
else
self:_add()
end
end,
-- delete row
delete = function (self)
local delete, result
if self.id then
delete = "DELETE FROM `" .. self.own_table.__tablename__ .. "` "
delete = delete .. "WHERE `" .. ID .. "` = " .. self.id
db:execute(delete)
end
self._data = {}
end
}
if data then
local current_table
for colname, colvalue in pairs(data) do
if query.own_table:has_column(colname) then
colvalue = query.own_table:get_column(colname)
.field.to_type(colvalue)
query._data[colname] = {
new = colvalue,
old = colvalue
}
else
if _G.All_Tables[colname] then
current_table = _G.All_Tables[colname]
colvalue = Query(current_table, colvalue)
query._readonly[colname .. "_all"] = QueryList(current_table, {})
query._readonly[colname .. "_all"]:add(colvalue)
end
query._readonly[colname] = colvalue
end
end
else
BACKTRACE(INFO, "Create empty row instance for table '" ..
self.own_table.__tablename__ .. "'")
end
setmetatable(query, {__index = query._get_col,
__newindex = query._set_col})
return query
end
local QueryList = require('orm.class.query_list')
return Query, QueryList

View File

@ -1,109 +0,0 @@
------------------------------------------------------------------------------
-- query_list.lua --
------------------------------------------------------------------------------
function QueryList(own_table, rows)
local current_query
local _query_list = {
------------------------------------------------
-- Table info varibles --
------------------------------------------------
--class name
__classname__ = QUERY_LIST,
-- Own Table
own_table = own_table,
-- Stack of data rows
_stack = {},
------------------------------------------------
-- Metamethods --
------------------------------------------------
-- Get n-th position value from Query stack
------------------------------------------------
-- @position {integer} position element is stack
--
-- @return {Query Instance} Table row instance
-- in n-th position
------------------------------------------------
__index = function (self, position)
if Type.is.int(position) and position >= 1 then
return self._stack[position]
end
end,
__call = function (self)
return pairs(self._stack)
end,
------------------------------------------------
-- User methods --
------------------------------------------------
-- Get Query instance by id
------------------------------------------------
-- @id {integer} table data row identifier
--
-- @return {table/nil} get Query instance or nil if
-- instance is not exists
------------------------------------------------
with_id = function (self, id)
if Type.is.int(id) then
for _, query in pairs(self) do
if query.id == id then
return query
end
end
else
BACKTRACE(WARNING, "ID `" .. id .. "` is not integer value")
end
end,
-- Add new Query Instance to stack
add = function (self, QueryInstance)
table.insert(self._stack, QueryInstance)
end,
-- Get count of values in stack
count = function (self)
return #self._stack
end,
-- Remove from database all elements from stack
delete = function (self)
for _, query in pairs(self._stack) do
query:delete()
end
self._stack = {}
end
}
setmetatable(_query_list, {__index = _query_list.__index,
__len = _query_list.__len,
__call = _query_list.__call})
for _, row in pairs(rows) do
current_query = _query_list:with_id(Type.to.number(row.id))
if current_query then
for key, value in pairs(row) do
if Type.is.table(value)
and current_query._readonly[key .. "_all"] then
current_query._readonly[key .. "_all"]:add(
Query(_G.All_Tables[key], value)
)
end
end
else
_query_list:add(Query(own_table, row))
end
end
return _query_list
end
return QueryList

View File

@ -1,610 +0,0 @@
------------------------------------------------------------------------------
-- Constants --
------------------------------------------------------------------------------
-- For WHERE equations ends
local LESS_THEN = "__lt"
local EQ_OR_LESS_THEN = "__lte"
local MORE_THEN = "__gt"
local EQ_OR_MORE_THEN = "__gte"
local IN = "__in"
local NOT_IN = "__notin"
local IS_NULL = '__null'
-- Joining types
local JOIN = {
INNER = 'i',
LEFT = 'l',
RIGHT = 'r',
FULL = 'f'
}
------------------------------------------------------------------------------
-- Class --
------------------------------------------------------------------------------
local Select = function(own_table)
return {
------------------------------------------------
-- Table info varibles --
------------------------------------------------
-- Link for table instance
own_table = own_table,
-- Create select rules
_rules = {
-- Where equation rules
where = {},
-- Having equation rules
having = {},
-- limit
limit = nil,
-- offset
offset = nil,
-- order columns list
order = {},
-- group columns list
group = {},
--Columns rules
columns = {
-- Joining tables rules
join = {},
-- including columns list
include = {},
}
},
------------------------------------------------
-- Private methods --
------------------------------------------------
-- Build correctly equation for SQL searching
_build_equation = function (self, colname, value)
local result = ""
local table_column
local rule
local _in
-- Special conditions that need no value escaping
if colname:endswith(IS_NULL) then
colname = string.cutend(colname, IS_NULL)
if value then
result = " IS NULL"
else
result = " NOT NULL"
end
elseif colname:endswith(IN) or colname:endswith(NOT_IN) then
rule = colname:endswith(IN) and IN or NOT_IN
if type(value) == "table" and #value > 0 then
colname = string.cutend(colname, rule)
table_column = self.own_table:get_column(colname)
_in = {}
for counter, val in pairs(value) do
table.insert(_in, table_column.field.as(val))
end
if rule == IN then
result = " IN (" .. table.join(_in) .. ")"
elseif rule == NOT_IN then
result = " NOT IN (" .. table.join(_in) .. ")"
end
end
else
-- Conditions that need value escaping when it's enabled
local conditionPrepend = ""
if colname:endswith(LESS_THEN) and Type.is.number(value) then
colname = string.cutend(colname, LESS_THEN)
conditionPrepend = " < "
elseif colname:endswith(MORE_THEN) and Type.is.number(value) then
colname = string.cutend(colname, MORE_THEN)
conditionPrepend = " > "
elseif colname:endswith(EQ_OR_LESS_THEN) and Type.is.number(value) then
colname = string.cutend(colname, EQ_OR_LESS_THEN)
conditionPrepend = " <= "
elseif colname:endswith(EQ_OR_MORE_THEN) and Type.is.number(value) then
colname = string.cutend(colname, EQ_OR_MORE_THEN)
conditionPrepend = " >= "
else
conditionPrepend = " = "
end
value = _G.escapeValue(self.own_table, colname, value)
table_column = self.own_table:get_column(colname)
result = conditionPrepend .. table_column.field.as(value)
end
if self.own_table:has_column(colname) then
local parse_column, _ = self.own_table:column(colname)
result = parse_column .. result
end
return result
end,
-- Need for ASC and DESC columns
_update_col_names = function (self, list_of_cols)
local tablename = self.own_table.__tablename__
local result = {}
local parsed_column
for _, col in pairs(list_of_cols) do
if Type.is.table(col) and col.__classtype__ == AGGREGATOR then
col.__table__ = self.own_table.__tablename__
table.insert(result, col)
else
parsed_column, _ = self.own_table:column(col)
table.insert(result, parsed_column)
end
end
return result
end,
-- Build condition for equation rules
---------------------------------------------------
-- @rules {table} list of columns
-- @start_with {string} WHERE or HAVING
--
-- @retrun {string} parsed string for select equation
---------------------------------------------------
_condition = function (self, rules, start_with)
local counter = 0
local condition = ""
local _equation
condition = condition .. start_with
-- TODO: add OR
for colname, value in pairs(rules) do
_equation = self:_build_equation(colname, value)
if counter ~= 0 then
_equation = "AND " .. _equation
end
condition = condition .. " " .. _equation
counter = counter + 1
end
return condition
end,
_has_foreign_key_table = function (self, left_table, right_table)
for _, key in pairs(left_table.__foreign_keys) do
if key.settings.to == right_table then
return true
end
end
end,
-- Build join tables rules
_build_join = function (self)
local result_join = ""
local unique_tables = {}
local left_table, right_table, mode
local join_mode, colname
local parsed_column, _
local tablename
for _, value in pairs(self._rules.columns.join) do
left_table = value[1]
right_table = value[2]
mode = value[3]
tablename = left_table.__tablename__
if mode == JOIN.INNER then
join_mode = "INNER JOIN"
elseif mode == JOIN.LEFT then
join_mode = "LEFT OUTER JOIN"
elseif mode == JOIN.RIGHT then
join_mode = "RIGHT OUTER JOIN"
elseif mode == JOIN.FULL then
join_mode = "FULL OUTER JOIN"
else
BACKTRACE(WARNING, "Not valid join mode " .. mode)
end
if self:_has_foreign_key_table(right_table, left_table) then
left_table, right_table = right_table, left_table
tablename = right_table.__tablename__
elseif not self:_has_foreign_key_table(right_table, left_table) then
BACKTRACE(WARNING, "Not valid tables links")
end
for _, key in pairs(left_table.__foreign_keys) do
if key.settings.to == right_table then
colname = key.name
result_join = result_join .. " \n" .. join_mode .. " `" ..
tablename .. "` ON "
parsed_column, _ = left_table:column(colname)
result_join = result_join .. parsed_column
parsed_column, _ = right_table:column(ID)
result_join = result_join .. " = " .. parsed_column
break
end
end
end
return result_join
end,
-- String with including data in select
--------------------------------------------
-- @own_table {table|nil} Table instance
--
-- @return {string} comma separated fields
--------------------------------------------
_build_including = function (self, own_table)
local include = {}
local colname_as, colname
if not own_table then
own_table = self.own_table
end
-- get current column
for _, column in pairs(own_table.__colnames) do
colname, colname_as = own_table:column(column.name)
table.insert(include, colname .. " AS " .. colname_as)
end
include = table.join(include)
return include
end,
-- Method for build select with rules
_select = function (self)
local including = self:_build_including()
local joining = ""
local _select
local tablename
local condition
local where
local rule
local join
--------------------- Include Columns To Select ------------------
_select = "SELECT " .. including
-- Add join rules
if #self._rules.columns.join > 0 then
local unique_tables = { self.own_table }
local join_tables = {}
local left_table, right_table
for _, values in pairs(self._rules.columns.join) do
left_table = values[1]
right_table = values[2]
if not table.has_value(unique_tables, left_table) then
table.insert(unique_tables, left_table)
_select = _select .. ", " .. self:_build_including(left_table)
end
if not table.has_value(unique_tables, right_table) then
table.insert(unique_tables, right_table)
_select = _select .. ", " .. self:_build_including(right_table)
end
end
join = self:_build_join()
end
-- Check aggregators in select
if #self._rules.columns.include > 0 then
local aggregators = {}
local aggregator, as
for _, value in pairs(self._rules.columns.include) do
_, as = own_table:column(value.as)
table.insert(aggregators, value[1] .. " AS " .. as)
end
_select = _select .. ", " .. table.join(aggregators)
end
------------------- End Include Columns To Select ----------------
_select = _select .. " FROM `" .. self.own_table.__tablename__ .. "`"
if join then
_select = _select .. " " .. join
end
-- Build WHERE
if next(self._rules.where) then
condition = self:_condition(self._rules.where, "\nWHERE")
_select = _select .. " " .. condition
end
-- Build GROUP BY
if #self._rules.group > 0 then
rule = self:_update_col_names(self._rules.group)
rule = table.join(rule)
_select = _select .. " \nGROUP BY " .. rule
end
-- Build HAVING
if next(self._rules.having) and self._rules.group then
condition = self:_condition(self._rules.having, "\nHAVING")
_select = _select .. " " .. condition
end
-- Build ORDER BY
if #self._rules.order > 0 then
rule = self:_update_col_names(self._rules.order)
rule = table.join(rule)
_select = _select .. " \nORDER BY " .. rule
end
-- Build LIMIT
if self._rules.limit then
_select = _select .. " \nLIMIT " .. self._rules.limit
end
-- Build OFFSET
if self._rules.offset then
_select = _select .. " \nOFFSET " .. self._rules.offset
end
return db:rows(_select, self.own_table)
end,
-- Add column to table
-------------------------------------------------
-- @col_table {table} table with column names
-- @colname {string/table} column name or list of column names
-------------------------------------------------
_add_col_to_table = function (self, col_table, colname)
if Type.is.str(colname) and self.own_table:has_column(colname) then
table.insert(col_table, colname)
elseif Type.is.table(colname) then
for _, column in pairs(colname) do
if (Type.is.table(column) and column.__classtype__ == AGGREGATOR
and self.own_table:has_column(column.colname))
or self.own_table:has_column(column) then
table.insert(col_table, column)
end
end
else
BACKTRACE(WARNING, "Not a string and not a table (" ..
tostring(colname) .. ")")
end
end,
--------------------------------------------------------
-- Column filters --
--------------------------------------------------------
-- Including columns to select query
include = function (self, column_list)
if Type.is.table(column_list) then
for _, value in pairs(column_list) do
if Type.is.table(value) and value.as and value[1]
and value[1].__classtype__ == AGGREGATOR then
table.insert(self._rules.columns.include, value)
else
BACKTRACE(WARNING, "Not valid aggregator syntax")
end
end
else
BACKTRACE(WARNING, "You can include only table type data")
end
return self
end,
--------------------------------------------------------
-- Joining tables methods --
--------------------------------------------------------
-- By default, join is INNER JOIN command
_join = function (self, left_table, MODE, right_table)
if not right_table then
right_table = self.own_table
end
if left_table.__tablename__ then
table.insert(self._rules.columns.join,
{left_table, right_table, MODE})
else
BACKTRACE(WARNING, "Not table in join")
end
return self
end,
join = function (self, left_table, right_table)
self:_join(left_table, JOIN.INNER, right_table)
return self
end,
-- left outer joining command
left_join = function (self, left_table, right_table)
self:_join(left_table, JOIN.LEFT, right_table)
return self
end,
-- right outer joining command
right_join = function (self, left_table, right_table)
self:_join(left_table, JOIN.RIGHT, right_table)
return self
end,
-- full outer joining command
full_join = function (self, left_table, right_table)
self:_join(left_table, JOIN.FULL, right_table)
return self
end,
--------------------------------------------------------
-- Select building methods --
--------------------------------------------------------
-- SQL Where query rules
where = function (self, args)
for col, value in pairs(args) do
self._rules.where[col] = value
end
return self
end,
-- Set returned data limit
limit = function (self, count)
if Type.is.int(count) then
self._rules.limit = count
else
BACKTRACE(WARNING, "You try set limit to not integer value")
end
return self
end,
-- From which position start get data
offset = function (self, count)
if Type.is.int(count) then
self._rules.offset = count
else
BACKTRACE(WARNING, "You try set offset to not integer value")
end
return self
end,
-- Order table
order_by = function (self, colname)
self:_add_col_to_table(self._rules.order, colname)
return self
end,
-- Group table
group_by = function (self, colname)
self:_add_col_to_table(self._rules.group, colname)
return self
end,
-- Having
having = function (self, args)
for col, value in pairs(args) do
self._rules.having[col] = value
end
return self
end,
--------------------------------------------------------
-- Update data methods --
--------------------------------------------------------
update = function (self, data)
if Type.is.table(data) then
local _update = "UPDATE `" .. self.own_table.__tablename__ .. "`"
local _set = ""
local coltype
local _set_tbl = {}
local i=1
for colname, new_value in pairs(data) do
coltype = self.own_table:get_column(colname)
if coltype and coltype.field.validator(new_value) then
_set = _set .. " `" .. colname .. "` = " ..
coltype.field.as(new_value)
_set_tbl[i] = " `" .. colname .. "` = " ..
coltype.field.as(new_value)
i=i+1
else
BACKTRACE(WARNING, "Can't update value for column `" ..
Type.to.str(colname) .. "`")
end
end
-- Build WHERE
if next(self._rules.where) then
_where = self:_condition(self._rules.where, "\nWHERE")
else
BACKTRACE(INFO, "No 'where' statement. All data update!")
end
if _set ~= "" then
if #_set_tbl<2 then
_update = _update .. " SET " .. _set .. " " .. _where
else
_update = _update .. " SET " .. table.concat(_set_tbl,",") .. " " .. _where
end
db:execute(_update)
else
BACKTRACE(WARNING, "No table columns for update")
end
else
BACKTRACE(WARNING, "No data for global update")
end
end,
--------------------------------------------------------
-- Delete data methods --
--------------------------------------------------------
delete = function (self)
local _delete = "DELETE FROM `" .. self.own_table.__tablename__ .. "` "
-- Build WHERE
if next(self._rules.where) then
_delete = _delete .. self:_condition(self._rules.where, "\nWHERE")
else
BACKTRACE(WARNING, "Try delete all values")
end
db:execute(_delete)
end,
--------------------------------------------------------
-- Get select data methods --
--------------------------------------------------------
-- Return one value
first = function (self)
self._rules.limit = 1
local data = self:all()
if data:count() == 1 then
return data[1]
end
end,
-- Return list of values
all = function (self)
local data = self:_select()
return QueryList(self.own_table, data)
end
}
end
return Select

View File

@ -1,236 +0,0 @@
------------------------------------------------------------------------------
-- Required classes --
------------------------------------------------------------------------------
local Select = require('orm.class.select')
local Query, QueryList = require('orm.class.query')
local fields = require('orm.tools.fields')
------------------------------------------------------------------------------
-- Table --
------------------------------------------------------------------------------
Table = {
-- database table name
__tablename__ = nil,
-- Foreign Keys list
foreign_keys = {},
}
-- This method create new table
-------------------------------------------
-- @table_instance {table} class Table instance
--
-- @table_instance.__tablename__ {string} table name
-- @table_instance.__colnames {table} list of column instances
-- @table_instance.__foreign_keys {table} list of foreign key
-- column instances
-------------------------------------------
function Table:create_table(table_instance)
-- table information
local tablename = table_instance.__tablename__
local columns = table_instance.__colnames
local foreign_keys = table_instance.__foreign_keys
BACKTRACE(INFO, "Start create table: " .. tablename)
-- other variables
local create_query = "CREATE TABLE IF NOT EXISTS `" .. tablename .. "` \n("
local counter = 0
local column_query
local result
for _, coltype in pairs(columns) do
column_query = "\n `" .. coltype.name .. "` " .. coltype:_create_type()
if counter ~= 0 then
column_query = "," .. column_query
end
create_query = create_query .. column_query
counter = counter + 1
end
for _, coltype in pairs(foreign_keys) do
create_query = create_query .. ",\n FOREIGN KEY(`" ..
coltype.name .. "`)" .. " REFERENCES `" ..
coltype.settings.to.__tablename__ ..
"`(`id`)"
end
create_query = create_query .. "\n)"
db:execute(create_query)
end
-- Create new table instance
--------------------------------------
-- @args {table} must have __tablename__ key
-- and other must be a column names
--------------------------------------
function Table.new(self, args)
local colnames = {}
local create_query
self.__tablename__ = args.__tablename__
args.__tablename__ = nil
-- Determine the column creation order
-- This is necessary because tables in lua have no order
self.__columnCreateOrder__ = { "id" };
local customColumnCreateOrder = args.__columnCreateOrder__;
args.__columnCreateOrder__ = nil;
if (customColumnCreateOrder) then
for _, colname in ipairs(customColumnCreateOrder) do
-- Add only existing columns to the column create order
if (args[colname]) then
table.insert(self.__columnCreateOrder__, colname);
end
end
end
for colname, coltype in pairs(args) do
-- Add the columns that are defined but missing from the column create order
if (not table.has_value(self.__columnCreateOrder__, colname)) then
table.insert(self.__columnCreateOrder__, colname);
end
end
local Table_instance = {
------------------------------------------------
-- Table info variables --
------------------------------------------------
-- SQL table name
__tablename__ = self.__tablename__,
-- list of column names
__colnames = {},
-- Foreign keys list
__foreign_keys = {},
------------------------------------------------
-- Metamethods --
------------------------------------------------
-- If try get value by name "get" it return Select class instance
__index = function (self, key)
if key == "get" then
return Select(self)
end
local old_index = self.__index
setmetatable(self, {__index = nil})
key = self[key]
setmetatable(self, {__index = old_index, __call = self.create})
return key
end,
-- Create new row instance
-----------------------------------------
-- @data {table} parsed query answer data
--
-- @retrun {table} Query instance
-----------------------------------------
create = function (self, data)
return Query(self, data)
end,
------------------------------------------------
-- Methods which using --
------------------------------------------------
-- parse column in correct types
column = function (self, column)
local tablename = self.__tablename__
if Type.is.table(column) and column.__classtype__ == AGGREGATOR then
column.colname = tablename .. column.colname
column = column .. ""
end
return "`" .. tablename .. "`.`" .. column .. "`",
tablename .. "_" .. column
end,
-- Check column in table
-----------------------------------------
-- @colname {string} column name
--
-- @return {boolean} get true if column exist
-----------------------------------------
has_column = function (self, colname)
for _, table_column in pairs(self.__colnames) do
if table_column.name == colname then
return true
end
end
BACKTRACE(WARNING, "Can't find column '" .. tostring(colname) ..
"' in table '" .. self.__tablename__ .. "'")
end,
-- get column instance by name
-----------------------------------------
-- @colname {string} column name
--
-- @return {table} get column instance if column exist
-----------------------------------------
get_column = function (self, colname)
for _, table_column in pairs(self.__colnames) do
if table_column.name == colname then
return table_column
end
end
BACKTRACE(WARNING, "Can't find column '" .. tostring(column) ..
"' in table '" .. self.__tablename__ .. "'")
end
}
-- Add default column 'id'
args.id = fields.PrimaryField({auto_increment = true})
-- copy column arguments to new table instance
for _, colname in ipairs(self.__columnCreateOrder__) do
local coltype = args[colname];
coltype.name = colname
coltype.__table__ = Table_instance
table.insert(Table_instance.__colnames, coltype)
if coltype.settings.foreign_key then
table.insert(Table_instance.__foreign_keys, coltype)
end
end
setmetatable(Table_instance, {
__call = Table_instance.create,
__index = Table_instance.__index
})
_G.All_Tables[self.__tablename__] = Table_instance
-- Create new table if needed
if DB.new then
self:create_table(Table_instance)
end
return Table_instance
end
setmetatable(Table, {__call = Table.new})
return Table

View File

@ -1,44 +0,0 @@
------------------------------------------------------------------------------
-- type.lua --
------------------------------------------------------------------------------
local Type = {
-- Check value for correct type
----------------------------------
-- @value {any type} checked value
--
-- @return {boolean} get true if type is correct
----------------------------------
is = {
int = function (value)
if type(value) == "number" then
integer, fractional = math.modf(value)
return fractional == 0
end
end,
number = function (value)
return type(value) == "number"
end,
str = function (value)
return type(value) == "string"
end,
table = function (value)
return type(value) == "table"
end,
},
to = {
number = function (value)
return tonumber(value)
end,
str = function (value)
return tostring(value)
end
}
}
return Type

View File

@ -1,124 +0,0 @@
------------------------------------------------------------------------------
-- Require --
------------------------------------------------------------------------------
require('orm.class.global')
require("orm.tools.func")
local Table = require('orm.class.table')
------------------------------------------------------------------------------
-- Constants --
------------------------------------------------------------------------------
-- Global
ID = "id"
AGGREGATOR = "aggregator"
QUERY_LIST = "query_list"
------------------------------------------------------------------------------
-- Model Settings --
------------------------------------------------------------------------------
if not DB then
print("[SQL:Startup] Can't find global database settings variable 'DB'. Creating empty one.")
DB = {}
end
DB = {
-- ORM settings
new = (DB.new == true),
DEBUG = (DB.DEBUG == true),
backtrace = (DB.backtrace == true),
name = DB.name,
host = DB.host,
port = DB.port,
username = DB.username,
password = DB.password,
}
print(DB)
local sql, _connect
-- Get database by settings
--local luasql = require("luasql.postgres")
--sql = luasql.postgres()
--print(DB.name, DB.username, DB.password, DB.host, DB.port)
--_connect = sql:connect(DB.name, DB.username, DB.password, DB.host, DB.port)
luasql = require "luasql.postgres"
env = luasql.postgres()
-- database user pwd host port
_connect = env:connect("postgres","postgres","1qaz2wsx",'127.0.0.1',5432)
if not _connect then
BACKTRACE(DEBUG, "Connect error!")
end
------------------------------------------------------------------------------
-- Database --
------------------------------------------------------------------------------
-- Database settings
db = {
-- Database connect instance
connect = _connect,
-- Execute SQL query
execute = function (self, query)
BACKTRACE(DEBUG, query)
BACKTRACE(INFO, query)
local result = self.connect:execute(query)
if result then
return result
else
BACKTRACE(WARNING, "Wrong SQL query")
end
end,
-- Return insert query id
insert = function (self, query)
local _cursor = self:execute(query)
return 1
end,
-- get parced data
rows = function (self, query, own_table)
local _cursor = self:execute(query)
local data = {}
local current_row = {}
local current_table
local row
if _cursor then
row = _cursor:fetch({}, "a")
while row do
for colname, value in pairs(row) do
current_table, colname = string.divided_into(colname, "_")
if current_table == own_table.__tablename__ then
current_row[colname] = value
else
if not current_row[current_table] then
current_row[current_table] = {}
end
current_row[current_table][colname] = value
end
end
table.insert(data, current_row)
current_row = {}
row = _cursor:fetch({}, "a")
end
end
return data
end
}
return Table

View File

@ -1,83 +0,0 @@
------------------------------------------------------------------------------
-- Libs --
------------------------------------------------------------------------------
Type = require('orm.class.type')
Field = require('orm.class.fields')
------------------------------------------------------------------------------
-- Field Types --
------------------------------------------------------------------------------
local function save_as_str(str)
return "'" .. str .. "'"
end
local field = {}
-- The "Field" class will be used to search a table index that the "field" class doesn't have.
-- This way field:register() will call the same function like Field:register() and the register
-- function has access to the default values for the field configuration.
setmetatable(field, {__index = Field});
field.PrimaryField = Field:register({
__type__ = "integer",
validator = Type.is.int,
settings = {
null = true,
primary_key = true,
auto_increment = true
},
to_type = Type.to.number
})
field.IntegerField = Field:register({
__type__ = "integer",
validator = Type.is.int,
to_type = Type.to.number
})
field.CharField = Field:register({
__type__ = "varchar",
validator = Type.is.str,
as = save_as_str
})
field.TextField = Field:register({
__type__ = "text",
validator = Type.is.str,
as = save_as_str
})
field.BooleandField = Field:register({
__type__ = "bool"
})
field.DateTimeField = Field:register({
__type__ = "integer",
validator = function (value)
if (Type.is.table(value) and value.isdst ~= nil)
or Type.is.int(value) then
return true
end
end,
as = function (value)
return Type.is.int(value) and value or os.time(value)
end,
to_type = function (value)
return os.date("*t", Type.to.number(value))
end
})
field.ForeignKey = Field:register({
__type__ = "integer",
settings = {
null = true,
foreign_key = true
},
to_type = Type.to.number
})
return field

View File

@ -1,64 +0,0 @@
local Property = require('orm.class.property')
_G.asc = Property({
parse = function (self)
return "`" .. self.__table__ .. "`.`" .. self.colname .. "` ASC"
end
})
_G.desc = Property({
parse = function (self)
return "`" .. self.__table__ .. "`.`" .. self.colname .. "` DESC"
end
})
_G.MAX = Property({
parse = function (self)
return "MAX(`" .. self.__table__ .. "`.`" .. self.colname .. "`)"
end
})
_G.MIN = Property({
parse = function (self)
return "MIN(`" .. self.__table__ .. "`.`" .. self.colname .. "`)"
end
})
_G.COUNT = Property({
parse = function (self)
return "COUNT(`" .. self.__table__ .. "`.`" .. self.colname .. "`)"
end
})
_G.SUM = Property({
parse = function (self)
return "SUM(" .. self.colname .. ")"
end
})
-- Escape text values to prevent sql injection
function _G.escapeValue(own_table, colname, colvalue)
local coltype = own_table:get_column(colname)
if coltype and coltype.settings.escape_value then
local fieldtype = coltype.field.__type__
if fieldtype:find("text") or fieldtype:find("char") then
if (DB.type == "sqlite3" or DB.type == "mysql" or DB.type == "postgresql") then
-- See https://keplerproject.github.io/luasql/manual.html for a list of
-- database drivers that support this method
colvalue = db.connect:escape(colvalue)
elseif (DB.type == "oracle") then
BACKTRACE(WARNING, "Can't autoescape values for oracle databases (Tried to escape field `" .. colname .. "`)");
end
end
end
return colvalue;
end