|
|
|
|
-- ------------------------------------------------------------------------------ --
|
|
|
|
|
-- TradeSkillMaster --
|
|
|
|
|
-- https://tradeskillmaster.com --
|
|
|
|
|
-- All Rights Reserved - Detailed license information included with addon. --
|
|
|
|
|
-- ------------------------------------------------------------------------------ --
|
|
|
|
|
|
|
|
|
|
local TSM = select(2, ...) ---@type TSM
|
|
|
|
|
local Schema = TSM.Init("Util.DatabaseClasses.Schema") ---@class Util.DatabaseClasses.Schema
|
|
|
|
|
local DBTable = TSM.Include("Util.DatabaseClasses.DBTable")
|
|
|
|
|
local ObjectPool = TSM.Include("Util.ObjectPool")
|
|
|
|
|
local LibTSMClass = TSM.Include("LibTSMClass")
|
|
|
|
|
local DatabaseSchema = LibTSMClass.DefineClass("DatabaseSchema") ---@class DatabaseSchema
|
|
|
|
|
local private = {
|
|
|
|
|
objectPool = nil,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
|
|
|
-- Modules Functions
|
|
|
|
|
-- ============================================================================
|
|
|
|
|
|
|
|
|
|
---Gets a new DB schema object.
|
|
|
|
|
---@param name string The name of the schema
|
|
|
|
|
---@return DatabaseSchema @The schema object
|
|
|
|
|
function Schema.Get(name)
|
|
|
|
|
if not private.objectPool then
|
|
|
|
|
private.objectPool = ObjectPool.New("DATABASE_SCHEMAS", DatabaseSchema, 2)
|
|
|
|
|
end
|
|
|
|
|
local schema = private.objectPool:Get()
|
|
|
|
|
schema:_Acquire(name)
|
|
|
|
|
return schema
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
|
|
|
-- Class Method Methods
|
|
|
|
|
-- ============================================================================
|
|
|
|
|
|
|
|
|
|
function DatabaseSchema:__init()
|
|
|
|
|
self._name = nil
|
|
|
|
|
self._fieldList = {}
|
|
|
|
|
self._fieldTypeLookup = {}
|
|
|
|
|
self._isIndex = {}
|
|
|
|
|
self._isUnique = {}
|
|
|
|
|
self._smartMapLookup = {}
|
|
|
|
|
self._smartMapInputLookup = {}
|
|
|
|
|
self._trigramIndexField = nil
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function DatabaseSchema:_Acquire(name)
|
|
|
|
|
assert(type(name) == "string")
|
|
|
|
|
self._name = name
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function DatabaseSchema:_Release()
|
|
|
|
|
self._name = nil
|
|
|
|
|
wipe(self._fieldList)
|
|
|
|
|
wipe(self._fieldTypeLookup)
|
|
|
|
|
wipe(self._isIndex)
|
|
|
|
|
wipe(self._isUnique)
|
|
|
|
|
wipe(self._smartMapLookup)
|
|
|
|
|
wipe(self._smartMapInputLookup)
|
|
|
|
|
self._trigramIndexField = nil
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
|
|
|
-- Public Class Method
|
|
|
|
|
-- ============================================================================
|
|
|
|
|
|
|
|
|
|
---Adds a string field to the DB schema.
|
|
|
|
|
---@param fieldName string The name of the field
|
|
|
|
|
---@return DatabaseSchema
|
|
|
|
|
function DatabaseSchema:AddStringField(fieldName)
|
|
|
|
|
self:_AddField("string", fieldName)
|
|
|
|
|
return self
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
---Adds a number field to the DB schema.
|
|
|
|
|
---@param fieldName string The name of the field
|
|
|
|
|
---@return DatabaseSchema
|
|
|
|
|
function DatabaseSchema:AddNumberField(fieldName)
|
|
|
|
|
self:_AddField("number", fieldName)
|
|
|
|
|
return self
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
---Adds a boolean field to the DB schema.
|
|
|
|
|
---@param fieldName string The name of the field
|
|
|
|
|
---@return DatabaseSchema
|
|
|
|
|
function DatabaseSchema:AddBooleanField(fieldName)
|
|
|
|
|
self:_AddField("boolean", fieldName)
|
|
|
|
|
return self
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
---Adds a string field with a unique index to the DB schema.
|
|
|
|
|
---@param fieldName string The name of the field
|
|
|
|
|
---@return DatabaseSchema
|
|
|
|
|
function DatabaseSchema:AddUniqueStringField(fieldName)
|
|
|
|
|
self:_AddField("string", fieldName, true)
|
|
|
|
|
return self
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
---Adds a number field with a unique index to the DB schema.
|
|
|
|
|
---@param fieldName string The name of the field
|
|
|
|
|
---@return DatabaseSchema
|
|
|
|
|
function DatabaseSchema:AddUniqueNumberField(fieldName)
|
|
|
|
|
self:_AddField("number", fieldName, true)
|
|
|
|
|
return self
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
---Adds a string list field to the DB schema.
|
|
|
|
|
---@param fieldName string The name of the field
|
|
|
|
|
---@return DatabaseSchema
|
|
|
|
|
function DatabaseSchema:AddStringListField(fieldName)
|
|
|
|
|
self:_AddField("STRING_LIST", fieldName)
|
|
|
|
|
return self
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
---Adds a number list field to the DB schema.
|
|
|
|
|
---@param fieldName string The name of the field
|
|
|
|
|
---@return DatabaseSchema
|
|
|
|
|
function DatabaseSchema:AddNumberListField(fieldName)
|
|
|
|
|
self:_AddField("NUMBER_LIST", fieldName)
|
|
|
|
|
return self
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
---Adds a smart map field to the DB schema.
|
|
|
|
|
---@param fieldName string The name of the field
|
|
|
|
|
---@param map SmartMapObject The smart map object
|
|
|
|
|
---@param inputFieldName string The name of the field which is used as an input to the smart map
|
|
|
|
|
---@return DatabaseSchema
|
|
|
|
|
function DatabaseSchema:AddSmartMapField(fieldName, map, inputFieldName)
|
|
|
|
|
assert(self._fieldTypeLookup[inputFieldName] == map:GetKeyType())
|
|
|
|
|
local fieldType = map:GetValueType()
|
|
|
|
|
assert(fieldType == "string" or fieldType == "number" or fieldType == "boolean")
|
|
|
|
|
self:_AddField(fieldType, fieldName)
|
|
|
|
|
self._smartMapLookup[fieldName] = map
|
|
|
|
|
self._smartMapInputLookup[fieldName] = inputFieldName
|
|
|
|
|
return self
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
---Adds an index which speeds up querying for the field.
|
|
|
|
|
---@param fieldName string The name of the field to index
|
|
|
|
|
---@return DatabaseSchema
|
|
|
|
|
function DatabaseSchema:AddIndex(fieldName)
|
|
|
|
|
local fieldType = self._fieldTypeLookup[fieldName]
|
|
|
|
|
assert(fieldType and fieldType ~= "STRING_LIST" and fieldType ~= "NUMBER_LIST" and not self._isIndex[fieldName])
|
|
|
|
|
self._isIndex[fieldName] = true
|
|
|
|
|
return self
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
---Adds a trigram index which speeds up text searching.
|
|
|
|
|
---@param fieldName string The name of the field to index
|
|
|
|
|
---@return DatabaseSchema
|
|
|
|
|
function DatabaseSchema:AddTrigramIndex(fieldName)
|
|
|
|
|
local fieldType = self._fieldTypeLookup[fieldName]
|
|
|
|
|
assert(fieldType and fieldType ~= "STRING_LIST" and fieldType ~= "NUMBER_LIST" and not self._trigramIndexField)
|
|
|
|
|
self._trigramIndexField = fieldName
|
|
|
|
|
return self
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
---Commits the schema and creates a DB table.
|
|
|
|
|
---@return DatabaseTable @The new DB table
|
|
|
|
|
function DatabaseSchema:Commit()
|
|
|
|
|
local db = DBTable.Create(self)
|
|
|
|
|
self:_Release()
|
|
|
|
|
private.objectPool:Recycle(self)
|
|
|
|
|
return db
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
|
|
|
-- Private Class Method
|
|
|
|
|
-- ============================================================================
|
|
|
|
|
|
|
|
|
|
function DatabaseSchema:_GetName()
|
|
|
|
|
return self._name
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function DatabaseSchema:_AddField(fieldType, fieldName, isUnique)
|
|
|
|
|
assert(type(fieldName) == "string" and strsub(fieldName, 1, 1) ~= "_")
|
|
|
|
|
assert(not self._fieldTypeLookup[fieldName])
|
|
|
|
|
tinsert(self._fieldList, fieldName)
|
|
|
|
|
self._fieldTypeLookup[fieldName] = fieldType
|
|
|
|
|
if isUnique then
|
|
|
|
|
self._isUnique[fieldName] = true
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function DatabaseSchema:_FieldIterator()
|
|
|
|
|
return private.FieldIterator, self, 0
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
|
|
|
-- Private Helper Functions
|
|
|
|
|
-- ============================================================================
|
|
|
|
|
|
|
|
|
|
function private.FieldIterator(schema, index)
|
|
|
|
|
index = index + 1
|
|
|
|
|
if index > #schema._fieldList then
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
local fieldName = schema._fieldList[index]
|
|
|
|
|
return index, fieldName, schema._fieldTypeLookup[fieldName], schema._isIndex[fieldName], schema._isUnique[fieldName], schema._trigramIndexField == fieldName, schema._smartMapLookup[fieldName], schema._smartMapInputLookup[fieldName]
|
|
|
|
|
end
|