From 433260dd16f5424054f9420cd6f0d323087aa255 Mon Sep 17 00:00:00 2001 From: wanglei <34475144@qqcom> Date: Mon, 27 Oct 2025 21:18:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9D=83=E9=99=90=E3=80=81?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E7=A8=8B=E5=BA=8F=E3=80=81=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=95=B0=E6=8D=AE=E8=A1=A8=E7=9A=84=E4=B8=9A?= =?UTF-8?q?=E5=8A=A1=E9=80=BB=E8=BE=91=E6=9F=A5=E7=9C=8B=E3=80=81=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E3=80=81=E5=88=A0=E9=99=A4=E5=92=8C=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E7=AD=89=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/system/account.lua | 10 +- src/api/system/application.lua | 78 ++++ src/api/system/permission.lua | 78 ++++ src/api/system/role.lua | 78 ++++ src/model/application.lua | 12 + src/model/permission.lua | 12 + src/model/role.lua | 12 + src/service/system/application.lua | 87 ++++ src/service/system/permission.lua | 87 ++++ src/service/system/role.lua | 87 ++++ src/share/orm/class/fields.lua | 141 ------- src/share/orm/class/global.lua | 103 ----- src/share/orm/class/property.lua | 25 -- src/share/orm/class/query.lua | 231 ----------- src/share/orm/class/query_list.lua | 109 ------ src/share/orm/class/select.lua | 610 ----------------------------- src/share/orm/class/table.lua | 236 ----------- src/share/orm/class/type.lua | 44 --- src/share/orm/model.lua | 124 ------ src/share/orm/tools/fields.lua | 83 ---- src/share/orm/tools/func.lua | 64 --- 21 files changed, 536 insertions(+), 1775 deletions(-) create mode 100644 src/api/system/application.lua create mode 100644 src/api/system/permission.lua create mode 100644 src/api/system/role.lua create mode 100644 src/model/application.lua create mode 100644 src/model/permission.lua create mode 100644 src/model/role.lua create mode 100644 src/service/system/application.lua create mode 100644 src/service/system/permission.lua create mode 100644 src/service/system/role.lua delete mode 100644 src/share/orm/class/fields.lua delete mode 100644 src/share/orm/class/global.lua delete mode 100644 src/share/orm/class/property.lua delete mode 100644 src/share/orm/class/query.lua delete mode 100644 src/share/orm/class/query_list.lua delete mode 100644 src/share/orm/class/select.lua delete mode 100644 src/share/orm/class/table.lua delete mode 100644 src/share/orm/class/type.lua delete mode 100644 src/share/orm/model.lua delete mode 100644 src/share/orm/tools/fields.lua delete mode 100644 src/share/orm/tools/func.lua diff --git a/src/api/system/account.lua b/src/api/system/account.lua index c20d7eb..2e591fd 100644 --- a/src/api/system/account.lua +++ b/src/api/system/account.lua @@ -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 --读取请求体的数据 diff --git a/src/api/system/application.lua b/src/api/system/application.lua new file mode 100644 index 0000000..75ef23a --- /dev/null +++ b/src/api/system/application.lua @@ -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 \ No newline at end of file diff --git a/src/api/system/permission.lua b/src/api/system/permission.lua new file mode 100644 index 0000000..0c0e0bf --- /dev/null +++ b/src/api/system/permission.lua @@ -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 \ No newline at end of file diff --git a/src/api/system/role.lua b/src/api/system/role.lua new file mode 100644 index 0000000..aef901c --- /dev/null +++ b/src/api/system/role.lua @@ -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 \ No newline at end of file diff --git a/src/model/application.lua b/src/model/application.lua new file mode 100644 index 0000000..3bc1414 --- /dev/null +++ b/src/model/application.lua @@ -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 \ No newline at end of file diff --git a/src/model/permission.lua b/src/model/permission.lua new file mode 100644 index 0000000..0d96ade --- /dev/null +++ b/src/model/permission.lua @@ -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 \ No newline at end of file diff --git a/src/model/role.lua b/src/model/role.lua new file mode 100644 index 0000000..194899d --- /dev/null +++ b/src/model/role.lua @@ -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 \ No newline at end of file diff --git a/src/service/system/application.lua b/src/service/system/application.lua new file mode 100644 index 0000000..bd31f6f --- /dev/null +++ b/src/service/system/application.lua @@ -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 diff --git a/src/service/system/permission.lua b/src/service/system/permission.lua new file mode 100644 index 0000000..202e6bf --- /dev/null +++ b/src/service/system/permission.lua @@ -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 diff --git a/src/service/system/role.lua b/src/service/system/role.lua new file mode 100644 index 0000000..4ac1f46 --- /dev/null +++ b/src/service/system/role.lua @@ -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 diff --git a/src/share/orm/class/fields.lua b/src/share/orm/class/fields.lua deleted file mode 100644 index 2426977..0000000 --- a/src/share/orm/class/fields.lua +++ /dev/null @@ -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 \ No newline at end of file diff --git a/src/share/orm/class/global.lua b/src/share/orm/class/global.lua deleted file mode 100644 index 93b8e16..0000000 --- a/src/share/orm/class/global.lua +++ /dev/null @@ -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 \ No newline at end of file diff --git a/src/share/orm/class/property.lua b/src/share/orm/class/property.lua deleted file mode 100644 index a5b47bf..0000000 --- a/src/share/orm/class/property.lua +++ /dev/null @@ -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 \ No newline at end of file diff --git a/src/share/orm/class/query.lua b/src/share/orm/class/query.lua deleted file mode 100644 index a144c1c..0000000 --- a/src/share/orm/class/query.lua +++ /dev/null @@ -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 \ No newline at end of file diff --git a/src/share/orm/class/query_list.lua b/src/share/orm/class/query_list.lua deleted file mode 100644 index 97b1e6c..0000000 --- a/src/share/orm/class/query_list.lua +++ /dev/null @@ -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 \ No newline at end of file diff --git a/src/share/orm/class/select.lua b/src/share/orm/class/select.lua deleted file mode 100644 index 977225d..0000000 --- a/src/share/orm/class/select.lua +++ /dev/null @@ -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 \ No newline at end of file diff --git a/src/share/orm/class/table.lua b/src/share/orm/class/table.lua deleted file mode 100644 index afcb343..0000000 --- a/src/share/orm/class/table.lua +++ /dev/null @@ -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 \ No newline at end of file diff --git a/src/share/orm/class/type.lua b/src/share/orm/class/type.lua deleted file mode 100644 index 13637fa..0000000 --- a/src/share/orm/class/type.lua +++ /dev/null @@ -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 \ No newline at end of file diff --git a/src/share/orm/model.lua b/src/share/orm/model.lua deleted file mode 100644 index ee6a995..0000000 --- a/src/share/orm/model.lua +++ /dev/null @@ -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 diff --git a/src/share/orm/tools/fields.lua b/src/share/orm/tools/fields.lua deleted file mode 100644 index 91e253b..0000000 --- a/src/share/orm/tools/fields.lua +++ /dev/null @@ -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 \ No newline at end of file diff --git a/src/share/orm/tools/func.lua b/src/share/orm/tools/func.lua deleted file mode 100644 index b3bbaeb..0000000 --- a/src/share/orm/tools/func.lua +++ /dev/null @@ -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