A Wyrmkin Dreamwalker
Join Date: Jul 2013
Posts: 54
|
AceDB help
Hi all. I'm wondering if anyone can explain the proper way to handle database restructures when using AceDB. I'm wanting to release an alpha version of an add-on I'm working on but I want to make sure stable databases are not lost. In my current development version I've restructured the database.
I am not ready to convert stable DBs into the new one yet, so the plan is to save a backup of the stable db when someone uses the alpha. However I want to be able to restore the stable db if they decide they don't wanna deal with the alpha and revert back to stable.
I've managed to save a backup of the stable db fine but I'm having issues restoring it in the stable version.
I was able to have it write the user saved data, but I get errors until a reload. I think it's because I'm using "**" in my defaults DB and when I manually add the saved data it's not linked to that. I then tried to set it as a metatable but it didn't work. Then my lunch break was over so that was all I could see from there.
Anyway this whole process has just seemed way too complicated for something that was so easy before I used AceDB (save a backup and just rewrite). I'm wondering if there's something I'm missing that would make this process a lot simpler?
Or is it just because am doing the metatables wrong?
As I'm on my phone now I can't really show the code and I didn't commit it before I left but if it's needed I can show when I get home.
Issue is with the char DB. I have a table inside it called bars and then a table nested in that with the "**" key and another table inside that with another "**".
So I tried after writing the saved data to set it like
setmetatable(barrable, defaultbartable["**"])
That just being pseudocode but that was what didn't work. And I did the same with the nested "**"
Edit: this is what I've got so far, and the problem with it is that it's only saving the values for items that are in the default and not also the ones in the saved. I don't know if I'm just missing something because I'm tired or what.
Lua Code:
local defaults = { char = { numBars = 1, bars = { ["**"] = { enabled = false, desc = "", movable = true, hidden = false, mouseover = false, anchorMouseover = false, showEmpties = true, muteAlerts = false, trackProgress = false, trackCompletedObjectives = true, visibleButtons = 6, direction = 2, -- 1: Up, 2: Right, 3: Down, 4: Left buttonsPerRow = 12, rowDirection = 1, -- 1: Normal (Right/Down), 2: Reverse (Left/Up) alpha = 1, scale = 1, position = {"TOP"}, buttonSize = 35, buttonPadding = 2, font = { face = false, outline = false, size = false, }, count = { anchor = "BOTTOM", xOffset = 1, yOffset = 6, }, objective = { anchor = "TOPLEFT", xOffset = 6, yOffset = -4, }, objectives = { ["**"] = { objective = false, }, }, }, }, }, global = { autoLootItems = false, alerts = { barChat = true, barScreen = true, barSound = true, chat = true, screen = true, sound = true, }, alertFormats = { objectivePreview = 200, newCountPreview = 25, oldCountPreview = 20, barCountPreview = 1, barTotalPreview = 5, barTitlePreview = true, barProgress = self.barProgress, hasObjective = self.hasObjective, noObjective = self.noObjective, }, commands = { farmbar = true, farm = true, fbar = true, fb = false, }, sounds = { barProgress = "Auction Open", barComplete = "Auction Close", farmingProgress = "Loot Coin", objectiveComplete = "Quest Complete", objectiveSet = "Quest Activate", objectiveCleared = "Quest Failed", }, template = { includeData = false, includeDataPrompt = false, saveOrder = false, saveOrderPrompt = false, }, tooltips = { bar = true, barTips = true, button = true, buttonTips = true, enableMod = true, mod = "Alt", }, skins = {}, templates = {}, version = 2, }, profile = { style = { font = { face = "Friz Quadrata TT", outline = "OUTLINE", size = 11, }, skin = { type = "builtin", name = "default", }, layers = { AutoCastable = true, -- bank overlay Border = false, -- oGlow Cooldown = false, CooldownEdge = false, }, count = { type = "custom", -- "includeBank", "oGlow", "custom" color = {1, 1, 1, 1}, }, }, }, } local backup = {} local version3 = FarmingBarDB and FarmingBarDB.global.version == 3 if version3 then for k, v in pairs(FarmingBarDB) do backup[k] = v end wipe(FarmingBarDB) end self.db = LibStub("AceDB-3.0"):New(addonName .. "DB", defaults, true) if version3 then local version2 = backup.global.version2 if version2 then if version2.global then for k, v in pairs(version2.global) do self.db.global[k] = v end end if version2.profile then for k, v in pairs(version2.profile) do self.db.profile[k] = v end end if version2.char then local realmKey = GetRealmName() local charKey = UnitName("player").." - "..realmKey local defaultBar = defaults.char.bars["**"] if version2.char[charKey] then local char = version2.char[charKey] self.db.char.numBars = char.numBars or defaults.char.numBars for k, v in pairs(defaultBar) do for barID, bar in pairs(char.bars) do if k == "objectives" then for objectiveID, objective in pairs(bar.objectives) do for K, V in pairs(defaultBar.objectives["**"]) do C_Timer.After(5, function() print(K, V) end) self.db.char.bars[barID].objectives[objectiveID][K] = (objective[K] ~= nil and objective[K]) or V end end else self.db.char.bars[barID][k] = (bar[k] ~= nil and bar[k]) or v end end end end end end end
Seeing as I've had no responses so far and I've come up with something that... works, I'll post it here in case it helps anyone else. But I still wonder if there's a better way to do this. I feel like this solution is a bit messy (but also it's just a quick fix to a temporary problem anyway so I'm not that concerned).
Lua Code:
local defaults = { char = { numBars = 1, bars = { ["**"] = { enabled = false, desc = "", movable = true, hidden = false, mouseover = false, anchorMouseover = false, showEmpties = true, muteAlerts = false, trackProgress = false, trackCompletedObjectives = true, visibleButtons = 6, direction = 2, -- 1: Up, 2: Right, 3: Down, 4: Left buttonsPerRow = 12, rowDirection = 1, -- 1: Normal (Right/Down), 2: Reverse (Left/Up) alpha = 1, scale = 1, position = {"TOP"}, buttonSize = 35, buttonPadding = 2, font = { face = false, outline = false, size = false, }, count = { anchor = "BOTTOM", xOffset = 1, yOffset = 6, }, objective = { anchor = "TOPLEFT", xOffset = 6, yOffset = -4, }, objectives = { ["**"] = { objective = false, }, }, }, }, }, global = { autoLootItems = false, alerts = { barChat = true, barScreen = true, barSound = true, chat = true, screen = true, sound = true, }, alertFormats = { objectivePreview = 200, newCountPreview = 25, oldCountPreview = 20, barCountPreview = 1, barTotalPreview = 5, barTitlePreview = true, barProgress = self.barProgress, hasObjective = self.hasObjective, noObjective = self.noObjective, }, commands = { farmbar = true, farm = true, fbar = true, fb = false, }, sounds = { barProgress = "Auction Open", barComplete = "Auction Close", farmingProgress = "Loot Coin", objectiveComplete = "Quest Complete", objectiveSet = "Quest Activate", objectiveCleared = "Quest Failed", }, template = { includeData = false, includeDataPrompt = false, saveOrder = false, saveOrderPrompt = false, }, tooltips = { bar = true, barTips = true, button = true, buttonTips = true, enableMod = true, mod = "Alt", }, skins = {}, templates = {}, version = 2, }, profile = { style = { font = { face = "Friz Quadrata TT", outline = "OUTLINE", size = 11, }, skin = { type = "builtin", name = "default", }, layers = { AutoCastable = true, -- bank overlay Border = false, -- oGlow Cooldown = false, CooldownEdge = false, }, count = { type = "custom", -- "includeBank", "oGlow", "custom" color = {1, 1, 1, 1}, }, }, }, } ------------------------------------------------------------ -- If coming back from version 3, save data to backup and wipe FarmingBarDB to prevent lua errors from changed k/v -- Don't wipe the whole DB as it'll wipe profiles and profileKeys local backup, version2 = {} if FarmingBarDB then version2 = FarmingBarDB.global and FarmingBarDB.global.version2 if version2 then for k, v in pairs(version2) do backup[k] = v end FarmingBarDB.char = nil FarmingBarDB.global = nil FarmingBarDB.profile = nil end end ------------------------------------------------------------ self.db = LibStub("AceDB-3.0"):New(addonName .. "DB", defaults, true) ------------------------------------------------------------ -- Save the backup to the database, so we can still access multiple characters' saved data -- We'll delete as we go below if version2 then self.db.global.version2_2 = backup end local version2_2 = self.db.global.version2_2 if version2_2 then -- Copy profiles and delete; no use for this after the first time if version2_2.profiles then for k, v in pairs(version2_2.profiles) do self.db.profiles[k] = v end self.db.global.version2_2.profiles = nil end -- Copy global and delete; no use for this after the first time if version2_2.global then for k, v in pairs(version2_2.global) do self.db.global[k] = v end self.db.global.version2_2.global = nil end if version2_2.profile then for k, v in pairs(version2_2.profile) do self.db.profile[k] = v end self.db.global.version2_2.profile = nil end ------------------------------------------------------------ -- If there's a saved char db for the current toon, copy and delete local realmKey = GetRealmName() local charKey = UnitName("player").." - "..realmKey if version2_2.char then local char = version2_2.char[charKey] if char then -- Set the data self.db.char.numBars = char.numBars for k, v in pairs(char.bars) do tinsert(self.db.char.bars, v) end -- Remove from the backup self.db.global.version2_2.char[charKey] = nil if U.tcount(version2_2.char) == 0 then self.db.global.version2_2.char = nil end -- Calling this ensures the new bars have the correct metatables set self:OnInitialize() return end end -- If we have backup profileKeys for this character, change the profile to the correct profile and remove if version2_2.profileKeys and version2_2.profileKeys[charKey] then self.db:SetProfile(version2_2.profileKeys[charKey]) version2_2.profileKeys[charKey] = nil if U.tcount(version2_2.profileKeys) == 0 then self.db.global.version2_2.profileKeys = nil end end ------------------------------------------------------------ -- If there are no more items in the backup, remove the backup if U.tcount(version2_2) == 0 then self.db.global.version2_2 = nil end end
Last edited by Niketa : 11-12-20 at 09:30 AM.
Reason: Added "solution"
|