mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-25 14:25:02 +00:00
132 lines
3.6 KiB
Lua
132 lines
3.6 KiB
Lua
-- packages/shared/seed/scripts/db/prefix.lua
|
|
-- Entity name prefixing helpers for DBAL operations
|
|
-- Ensures package entities don't clash with each other
|
|
-- @module shared.db.prefix
|
|
|
|
local M = {}
|
|
|
|
---Convert snake_case to PascalCase
|
|
---@param str string
|
|
---@return string
|
|
function M.toPascalCase(str)
|
|
local result = ''
|
|
for word in string.gmatch(str, '[^_]+') do
|
|
result = result .. word:sub(1, 1):upper() .. word:sub(2):lower()
|
|
end
|
|
return result
|
|
end
|
|
|
|
---Generate prefixed entity name
|
|
---Format: Pkg_{PascalPackageName}_{EntityName}
|
|
---@param packageId string Package identifier (e.g., 'forum_forge')
|
|
---@param entityName string Original entity name (e.g., 'Post')
|
|
---@return string Prefixed name (e.g., 'Pkg_ForumForge_Post')
|
|
function M.getPrefixedName(packageId, entityName)
|
|
local prefix = M.toPascalCase(packageId)
|
|
return 'Pkg_' .. prefix .. '_' .. entityName
|
|
end
|
|
|
|
---Get table name from package and entity
|
|
---Format: {packageId}_{lowercaseEntityName}
|
|
---@param packageId string
|
|
---@param entityName string
|
|
---@return string Table name
|
|
function M.getTableName(packageId, entityName)
|
|
return packageId .. '_' .. entityName:lower()
|
|
end
|
|
|
|
---Check if an entity name is prefixed
|
|
---@param name string
|
|
---@return boolean
|
|
function M.isPrefixed(name)
|
|
return name:sub(1, 4) == 'Pkg_'
|
|
end
|
|
|
|
---Extract package ID from prefixed entity name
|
|
---@param prefixedName string e.g., 'Pkg_ForumForge_Post'
|
|
---@return string|nil Package ID (e.g., 'forum_forge')
|
|
function M.extractPackage(prefixedName)
|
|
if not M.isPrefixed(prefixedName) then
|
|
return nil
|
|
end
|
|
|
|
local match = prefixedName:match('^Pkg_([A-Z][a-zA-Z]*)_')
|
|
if not match then
|
|
return nil
|
|
end
|
|
|
|
-- Convert PascalCase back to snake_case
|
|
local result = match:gsub('([a-z])([A-Z])', '%1_%2'):lower()
|
|
return result
|
|
end
|
|
|
|
---Extract original entity name from prefixed name
|
|
---@param prefixedName string e.g., 'Pkg_ForumForge_Post'
|
|
---@return string|nil Entity name (e.g., 'Post')
|
|
function M.extractEntity(prefixedName)
|
|
if not M.isPrefixed(prefixedName) then
|
|
return nil
|
|
end
|
|
|
|
-- Find the position after the second underscore
|
|
local count = 0
|
|
local pos = 0
|
|
for i = 1, #prefixedName do
|
|
if prefixedName:sub(i, i) == '_' then
|
|
count = count + 1
|
|
if count == 2 then
|
|
pos = i
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
if pos == 0 then
|
|
return nil
|
|
end
|
|
|
|
return prefixedName:sub(pos + 1)
|
|
end
|
|
|
|
---Create a package-aware DBAL wrapper
|
|
---All entity names are automatically prefixed
|
|
---@param dbal table DBAL client instance
|
|
---@param packageId string Package identifier
|
|
---@return table Wrapped DBAL with auto-prefixing
|
|
function M.createPackageDb(dbal, packageId)
|
|
local wrapper = {}
|
|
|
|
-- Wrap all DBAL methods to auto-prefix entity names
|
|
function wrapper:create(entity, data)
|
|
return dbal:create(M.getPrefixedName(packageId, entity), data)
|
|
end
|
|
|
|
function wrapper:read(entity, id)
|
|
return dbal:read(M.getPrefixedName(packageId, entity), id)
|
|
end
|
|
|
|
function wrapper:update(entity, id, data)
|
|
return dbal:update(M.getPrefixedName(packageId, entity), id, data)
|
|
end
|
|
|
|
function wrapper:delete(entity, id)
|
|
return dbal:delete(M.getPrefixedName(packageId, entity), id)
|
|
end
|
|
|
|
function wrapper:list(entity, options)
|
|
return dbal:list(M.getPrefixedName(packageId, entity), options)
|
|
end
|
|
|
|
function wrapper:findFirst(entity, options)
|
|
return dbal:findFirst(M.getPrefixedName(packageId, entity), options)
|
|
end
|
|
|
|
-- Allow access to raw DBAL for cross-package queries
|
|
wrapper.raw = dbal
|
|
wrapper.packageId = packageId
|
|
|
|
return wrapper
|
|
end
|
|
|
|
return M
|