initial commit
This commit is contained in:
198
LibTSM/Util/DatabaseClasses/Schema.lua
Normal file
198
LibTSM/Util/DatabaseClasses/Schema.lua
Normal file
@@ -0,0 +1,198 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Schema = TSM.Init("Util.DatabaseClasses.Schema")
|
||||
local Constants = TSM.Include("Util.DatabaseClasses.Constants")
|
||||
local DBTable = TSM.Include("Util.DatabaseClasses.DBTable")
|
||||
local ObjectPool = TSM.Include("Util.ObjectPool")
|
||||
local LibTSMClass = TSM.Include("LibTSMClass")
|
||||
local DatabaseSchema = LibTSMClass.DefineClass("DatabaseSchema")
|
||||
local private = {
|
||||
objectPool = nil,
|
||||
}
|
||||
local FIELD_TYPE_IS_VALID = {
|
||||
string = true,
|
||||
number = true,
|
||||
boolean = true,
|
||||
}
|
||||
local MAX_MULTI_FIELD_INDEX_PARTS = 2
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Modules Functions
|
||||
-- ============================================================================
|
||||
|
||||
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
|
||||
|
||||
function Schema.IsClass(obj)
|
||||
return obj:__isa(DatabaseSchema)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Class Method Methods
|
||||
-- ============================================================================
|
||||
|
||||
function DatabaseSchema.__init(self)
|
||||
self._name = nil
|
||||
self._fieldList = {}
|
||||
self._fieldTypeLookup = {}
|
||||
self._isIndex = {}
|
||||
self._isUnique = {}
|
||||
self._smartMapLookup = {}
|
||||
self._smartMapInputLookup = {}
|
||||
self._trigramIndexField = nil
|
||||
end
|
||||
|
||||
function DatabaseSchema._Acquire(self, name)
|
||||
assert(type(name) == "string")
|
||||
self._name = name
|
||||
end
|
||||
|
||||
function DatabaseSchema._Release(self)
|
||||
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
|
||||
-- ============================================================================
|
||||
|
||||
function DatabaseSchema.Release(self)
|
||||
self:_Release()
|
||||
private.objectPool:Recycle(self)
|
||||
end
|
||||
|
||||
function DatabaseSchema.AddStringField(self, fieldName)
|
||||
self:_AddField("string", fieldName)
|
||||
return self
|
||||
end
|
||||
|
||||
function DatabaseSchema.AddNumberField(self, fieldName)
|
||||
self:_AddField("number", fieldName)
|
||||
return self
|
||||
end
|
||||
|
||||
function DatabaseSchema.AddBooleanField(self, fieldName)
|
||||
self:_AddField("boolean", fieldName)
|
||||
return self
|
||||
end
|
||||
|
||||
function DatabaseSchema.AddUniqueStringField(self, fieldName)
|
||||
self:_AddField("string", fieldName, true)
|
||||
self._isUnique[fieldName] = true
|
||||
return self
|
||||
end
|
||||
|
||||
function DatabaseSchema.AddUniqueNumberField(self, fieldName)
|
||||
self:_AddField("number", fieldName, true)
|
||||
return self
|
||||
end
|
||||
|
||||
function DatabaseSchema.AddSmartMapField(self, fieldName, map, inputFieldName)
|
||||
assert(self._fieldTypeLookup[inputFieldName] == map:GetKeyType())
|
||||
self:_AddField(map:GetValueType(), fieldName)
|
||||
self._smartMapLookup[fieldName] = map
|
||||
self._smartMapInputLookup[fieldName] = inputFieldName
|
||||
return self
|
||||
end
|
||||
|
||||
function DatabaseSchema.AddIndex(self, ...)
|
||||
local numFields = select("#", ...)
|
||||
assert(numFields > 0)
|
||||
assert(numFields <= MAX_MULTI_FIELD_INDEX_PARTS, "Unsupported number of fields in index")
|
||||
for i = 1, numFields do
|
||||
local fieldName = select(i, ...)
|
||||
assert(self._fieldTypeLookup[fieldName])
|
||||
end
|
||||
self._isIndex[strjoin(Constants.DB_INDEX_FIELD_SEP, ...)] = true
|
||||
return self
|
||||
end
|
||||
|
||||
function DatabaseSchema.AddTrigramIndex(self, fieldName)
|
||||
assert(not self._trigramIndexField)
|
||||
self._trigramIndexField = fieldName
|
||||
return self
|
||||
end
|
||||
|
||||
function DatabaseSchema.Commit(self)
|
||||
local db = DBTable.Create(self)
|
||||
self:Release()
|
||||
return db
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Private Class Method
|
||||
-- ============================================================================
|
||||
|
||||
function DatabaseSchema._GetName(self)
|
||||
return self._name
|
||||
end
|
||||
|
||||
function DatabaseSchema._AddField(self, fieldType, fieldName, isUnique)
|
||||
assert(FIELD_TYPE_IS_VALID[fieldType])
|
||||
assert(type(fieldName) == "string" and strsub(fieldName, 1, 1) ~= "_" and not strmatch(fieldName, Constants.DB_INDEX_FIELD_SEP))
|
||||
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(self)
|
||||
return private.FieldIterator, self, 0
|
||||
end
|
||||
|
||||
function DatabaseSchema._MultiFieldIndexIterator(self)
|
||||
return private.MultiFieldIndexIterator, self, nil
|
||||
end
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Private Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.FieldIterator(self, index)
|
||||
index = index + 1
|
||||
if index > #self._fieldList then
|
||||
return
|
||||
end
|
||||
local fieldName = self._fieldList[index]
|
||||
return index, fieldName, self._fieldTypeLookup[fieldName], self._isIndex[fieldName], self._isUnique[fieldName], self._smartMapLookup[fieldName], self._smartMapInputLookup[fieldName]
|
||||
end
|
||||
|
||||
function private.MultiFieldIndexIterator(self, fieldName)
|
||||
while true do
|
||||
fieldName = next(self._isIndex, fieldName)
|
||||
if not fieldName then
|
||||
return
|
||||
end
|
||||
if strmatch(fieldName, Constants.DB_INDEX_FIELD_SEP) then
|
||||
return fieldName
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user