-- ========================================================================= -- -- SylingTracker -- -- https://www.curseforge.com/wow/addons/sylingtracker -- -- -- -- Repository: -- -- https://github.com/Skamer/SylingTracker -- -- -- -- ========================================================================= -- Syling "SylingTracker.Core.Database" "" -- ========================================================================= -- namespace "SLT" -- ========================================================================= -- DeepCopy = Utils.DeepCopy ShalowCopy = Utils.ShalowCopy class "Database" (function(_ENV) CURRENT_TABLE = nil CURRENT_PARENT_TABLE = nil CURRENT_LEVEL = 0 CURRENT_TABLE_NAME = nil CURRENT_DB = nil __Default__("global") enum "Type" { "global", "char", "spec" } class "Path" (function(_ENV) ----------------------------------------------------------------------------- -- Methods -- ----------------------------------------------------------------------------- __Arguments__ { Database.Type } function SetRelativeDB(self, type) self.relativeDB = type return self end __Arguments__ { Variable.Rest(String + Number )} function Table(self, ...) self.path = { ... } end ----------------------------------------------------------------------------- -- Properties -- ----------------------------------------------------------------------------- property "relativeDB" { TYPE = Database.Type } end) ----------------------------------------------------------------------------- -- Methods -- ----------------------------------------------------------------------------- __Arguments__{ Any, Variable.Optional() } __Static__() function SetValue(index, value) CURRENT_TABLE[index] = value end __Arguments__ { Any } __Static__() function GetValue(index) return CURRENT_TABLE[index] end __Static__() function IterateTable() return pairs(CURRENT_TABLE) end __Static__() function Clean() local function ClearEmptyTables(t) for k,v in pairs(t) do if type(v) == "table" then ClearEmptyTables(v) if next(v) == nil then t[k] = nil end end end end -- NOTE: Important to use 'SylingTrackerDB' else if doesn't work ClearEmptyTables(SylingTrackerDB) end __Arguments__ { String, String } __Static__() function RenameAllTables(sourceName, destName) local function RenameTables(t) for k,v in pairs(t) do if k ~= sourceName and type(v) == "table" then RenameTables(v) elseif k == sourceName then local tb = t[k] t[destName] = tb t[k] = nil end end end RenameTables(EskaTrackerDB) end __Arguments__ { Variable.Rest(String) } __Static__() function MoveTable(self, ...) local copy = DeepCopy(CURRENT_TABLE) local oldTable = CURRENT_TABLE local tables = { ... } local destName = tables[#tables] tables[#tables] = nil Database.SelectRoot() if #tables > 0 then if Database.SelectTable(true, unpack(tables)) then Database.SetValue(destName, copy) wipe(oldTable) end end end __Arguments__ { String, String } __Static__() function RenameTable(sourceName, newName) local table = Database.GetCurrentTable()[sourceName] if table then Database.GetCurrentTable()[newName] = DeepCopy(table) Database.GetCurrentTable()[sourceName] = nil table = nil end end __Arguments__ { Path } __Static__() function GetCopyTable(sourcePath) local sourceDB if not sourcePath.path then if sourcePath.relativeDB == "global" then sourceDB = Database.GetRaw() elseif sourcePath.relativeDB == "char" then sourceDB = Database.GetRawChar() elseif sourcePath.relativeDB == "spec" then sourceDB = Database.GetRawSpec() end else if sourcePath.relativeDB == "GLOBAL" then Database.SelectRoot() elseif sourcePath.relativeDB == "CHAR" then Database.SelectRootChar() elseif sourcePath.relativeDB == "SPEC" then Database.SelectRootSpec() end Database.SelectTable(true, unpack(sourcePath.path)) sourceDB = Database.GetCurrentTable() end return DeepCopy(sourceDB) end __Static__() function DeleteTable() wipe(CURRENT_TABLE) Database.SelectRoot() end __Arguments__{ Variable.Rest(String) } __Static__() function SelectTable(...) return Database.SelectTable(true, ...) end __Arguments__ { Boolean, Variable.Rest(String) } __Static__() function SelectTable(mustCreateTables, ...) local count = select("#", ...) if not CURRENT_TABLE then CURRENT_TABLE = Database.Get() end local tb = CURRENT_TABLE for i = 1, count do local indexTable = select(i, ...) if not tb[indexTable] then if mustCreateTables then tb[indexTable] = {} else return false end end if i > 1 then CURRENT_PARENT_TABLE = tb end tb = tb[indexTable] CURRENT_LEVEL = CURRENT_LEVEL + 1 CURRENT_TABLE_NAME = indexTable end CURRENT_TABLE = tb return true end __Static__() function SelectRoot() CURRENT_TABLE = Database.Get() CURRENT_LEVEL = 0 CURRENT_DB = "global" end __Static__() function SelectRootChar() CURRENT_TABLE = Database.GetChar() CURRENT_LEVEL = 0 CURRENT_DB = "char" end __Static__() function SelectRootSpec() CURRENT_TABLE = Database.GetSpec() CURRENT_LEVEL = 0 CURRENT_DB = "spec" end __Arguments__ { Number } __Static__() function SetVersion(version) if Database.Get() then Database.Get().dbVersion = version end end __Static__() function GetVersion() if Database.Get() then return Database.Get().dbVersion end end __Static__() function Get() return _DB end __Static__() function GetChar() return _DB.Char end __Static__() function GetSpec() return _DB.Char.Spec end __Static__() function GetRaw() return SylingTrackerDB end __Static__() function GetRawChar(self) local name = GetRealmName() .. "-" .. UnitName("player") if Database.GetRaw().__ScorpioChars and Database.GetRaw().__ScorpioChars[name] then return Database.GetRaw().__ScorpioChars[name] end end __Static__() function GetRawSpec(self) local charDB = Database.GetRawChar() if not charDB then return end local spec = GetSpecialization() if charDB.__ScorpioSpecs and charDB.__ScorpioSpecs[spec] then return charDB.__ScorpioSpecs[spec] end end __Static__() function GetCurrentTable(self) if CURRENT_TABLE == 0 then if CURRENT_DB == nil or CURRENT_DB == "global" then return Database.GetRaw() elseif CURRENT_DB == "char" then return Database.GetRawChar() elseif CURRENT_DB == "spec" then return Database.GetRawSpec() end end return CURRENT_TABLE end end)