flickerstreak@28
|
1 --[[ $Id: AceDB-3.0.lua 63886 2008-03-08 12:43:31Z nevcairiel $ ]]
|
flickerstreak@28
|
2 local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 5
|
flickerstreak@28
|
3 local AceDB, oldminor = LibStub:NewLibrary(ACEDB_MAJOR, ACEDB_MINOR)
|
flickerstreak@28
|
4
|
flickerstreak@28
|
5 if not AceDB then return end -- No upgrade needed
|
flickerstreak@28
|
6
|
flickerstreak@28
|
7 local type = type
|
flickerstreak@28
|
8 local pairs, next = pairs, next
|
flickerstreak@28
|
9 local rawget, rawset = rawget, rawset
|
flickerstreak@28
|
10 local setmetatable = setmetatable
|
flickerstreak@28
|
11
|
flickerstreak@28
|
12 AceDB.db_registry = AceDB.db_registry or {}
|
flickerstreak@28
|
13 AceDB.frame = AceDB.frame or CreateFrame("Frame")
|
flickerstreak@28
|
14
|
flickerstreak@28
|
15 local CallbackHandler
|
flickerstreak@28
|
16 local CallbackDummy = { Fire = function() end }
|
flickerstreak@28
|
17
|
flickerstreak@28
|
18 local DBObjectLib = {}
|
flickerstreak@28
|
19
|
flickerstreak@28
|
20 --[[-------------------------------------------------------------------------
|
flickerstreak@28
|
21 AceDB Utility Functions
|
flickerstreak@28
|
22 ---------------------------------------------------------------------------]]
|
flickerstreak@28
|
23
|
flickerstreak@28
|
24 -- Simple shallow copy for copying defaults
|
flickerstreak@28
|
25 local function copyTable(src, dest)
|
flickerstreak@28
|
26 if type(dest) ~= "table" then dest = {} end
|
flickerstreak@28
|
27 if type(src) == "table" then
|
flickerstreak@28
|
28 for k,v in pairs(src) do
|
flickerstreak@28
|
29 if type(v) == "table" then
|
flickerstreak@28
|
30 -- try to index the key first so that the metatable creates the defaults, if set, and use that table
|
flickerstreak@28
|
31 v = copyTable(v, dest[k])
|
flickerstreak@28
|
32 end
|
flickerstreak@28
|
33 dest[k] = v
|
flickerstreak@28
|
34 end
|
flickerstreak@28
|
35 end
|
flickerstreak@28
|
36 return dest
|
flickerstreak@28
|
37 end
|
flickerstreak@28
|
38
|
flickerstreak@28
|
39 -- Called to add defaults to a section of the database
|
flickerstreak@28
|
40 --
|
flickerstreak@28
|
41 -- When a ["*"] default section is indexed with a new key, a table is returned
|
flickerstreak@28
|
42 -- and set in the host table. These tables must be cleaned up by removeDefaults
|
flickerstreak@28
|
43 -- in order to ensure we don't write empty default tables.
|
flickerstreak@28
|
44 local function copyDefaults(dest, src)
|
flickerstreak@28
|
45 -- this happens if some value in the SV overwrites our default value with a non-table
|
flickerstreak@28
|
46 --if type(dest) ~= "table" then return end
|
flickerstreak@28
|
47 for k, v in pairs(src) do
|
flickerstreak@28
|
48 if k == "*" or k == "**" then
|
flickerstreak@28
|
49 if type(v) == "table" then
|
flickerstreak@28
|
50 -- This is a metatable used for table defaults
|
flickerstreak@28
|
51 local mt = {
|
flickerstreak@28
|
52 -- This handles the lookup and creation of new subtables
|
flickerstreak@28
|
53 __index = function(t,k)
|
flickerstreak@28
|
54 if k == nil then return nil end
|
flickerstreak@28
|
55 local tbl = {}
|
flickerstreak@28
|
56 copyDefaults(tbl, v)
|
flickerstreak@28
|
57 rawset(t, k, tbl)
|
flickerstreak@28
|
58 return tbl
|
flickerstreak@28
|
59 end,
|
flickerstreak@28
|
60 }
|
flickerstreak@28
|
61 setmetatable(dest, mt)
|
flickerstreak@28
|
62 -- handle already existing tables in the SV
|
flickerstreak@28
|
63 for dk, dv in pairs(dest) do
|
flickerstreak@28
|
64 if not rawget(src, dk) and type(dv) == "table" then
|
flickerstreak@28
|
65 copyDefaults(dv, v)
|
flickerstreak@28
|
66 end
|
flickerstreak@28
|
67 end
|
flickerstreak@28
|
68 else
|
flickerstreak@28
|
69 -- Values are not tables, so this is just a simple return
|
flickerstreak@28
|
70 local mt = {__index = function(t,k) return k~=nil and v or nil end}
|
flickerstreak@28
|
71 setmetatable(dest, mt)
|
flickerstreak@28
|
72 end
|
flickerstreak@28
|
73 elseif type(v) == "table" then
|
flickerstreak@28
|
74 if not rawget(dest, k) then rawset(dest, k, {}) end
|
flickerstreak@28
|
75 if type(dest[k]) == "table" then
|
flickerstreak@28
|
76 copyDefaults(dest[k], v)
|
flickerstreak@28
|
77 if src['**'] then
|
flickerstreak@28
|
78 copyDefaults(dest[k], src['**'])
|
flickerstreak@28
|
79 end
|
flickerstreak@28
|
80 end
|
flickerstreak@28
|
81 else
|
flickerstreak@28
|
82 if rawget(dest, k) == nil then
|
flickerstreak@28
|
83 rawset(dest, k, v)
|
flickerstreak@28
|
84 end
|
flickerstreak@28
|
85 end
|
flickerstreak@28
|
86 end
|
flickerstreak@28
|
87 end
|
flickerstreak@28
|
88
|
flickerstreak@28
|
89 -- Called to remove all defaults in the default table from the database
|
flickerstreak@28
|
90 local function removeDefaults(db, defaults, blocker)
|
flickerstreak@28
|
91 for k,v in pairs(defaults) do
|
flickerstreak@28
|
92 if k == "*" or k == "**" then
|
flickerstreak@28
|
93 if type(v) == "table" then
|
flickerstreak@28
|
94 -- Loop through all the actual k,v pairs and remove
|
flickerstreak@28
|
95 for key, value in pairs(db) do
|
flickerstreak@28
|
96 if type(value) == "table" then
|
flickerstreak@28
|
97 -- if the key was not explicitly specified in the defaults table, just strip everything from * and ** tables
|
flickerstreak@28
|
98 if defaults[key] == nil then
|
flickerstreak@28
|
99 removeDefaults(value, v)
|
flickerstreak@28
|
100 -- if the table is empty afterwards, remove it
|
flickerstreak@28
|
101 if not next(value) then
|
flickerstreak@28
|
102 db[key] = nil
|
flickerstreak@28
|
103 end
|
flickerstreak@28
|
104 -- if it was specified, only strip ** content, but block values which were set in the key table
|
flickerstreak@28
|
105 elseif k == "**" then
|
flickerstreak@28
|
106 removeDefaults(value, v, defaults[key])
|
flickerstreak@28
|
107 end
|
flickerstreak@28
|
108 end
|
flickerstreak@28
|
109 end
|
flickerstreak@28
|
110 elseif k == "*" then
|
flickerstreak@28
|
111 -- check for non-table default
|
flickerstreak@28
|
112 for key, value in pairs(db) do
|
flickerstreak@28
|
113 if defaults[key] == nil and v == value then
|
flickerstreak@28
|
114 db[key] = nil
|
flickerstreak@28
|
115 end
|
flickerstreak@28
|
116 end
|
flickerstreak@28
|
117 end
|
flickerstreak@28
|
118 elseif type(v) == "table" and type(db[k]) == "table" then
|
flickerstreak@28
|
119 -- if a blocker was set, dive into it, to allow multi-level defaults
|
flickerstreak@28
|
120 removeDefaults(db[k], v, blocker and blocker[k])
|
flickerstreak@28
|
121 if not next(db[k]) then
|
flickerstreak@28
|
122 db[k] = nil
|
flickerstreak@28
|
123 end
|
flickerstreak@28
|
124 else
|
flickerstreak@28
|
125 -- check if the current value matches the default, and that its not blocked by another defaults table
|
flickerstreak@28
|
126 if db[k] == defaults[k] and (not blocker or blocker[k] == nil) then
|
flickerstreak@28
|
127 db[k] = nil
|
flickerstreak@28
|
128 end
|
flickerstreak@28
|
129 end
|
flickerstreak@28
|
130 end
|
flickerstreak@28
|
131 -- remove all metatables from the db
|
flickerstreak@28
|
132 setmetatable(db, nil)
|
flickerstreak@28
|
133 end
|
flickerstreak@28
|
134
|
flickerstreak@28
|
135 -- This is called when a table section is first accessed, to set up the defaults
|
flickerstreak@28
|
136 local function initSection(db, section, svstore, key, defaults)
|
flickerstreak@28
|
137 local sv = rawget(db, "sv")
|
flickerstreak@28
|
138
|
flickerstreak@28
|
139 local tableCreated
|
flickerstreak@28
|
140 if not sv[svstore] then sv[svstore] = {} end
|
flickerstreak@28
|
141 if not sv[svstore][key] then
|
flickerstreak@28
|
142 sv[svstore][key] = {}
|
flickerstreak@28
|
143 tableCreated = true
|
flickerstreak@28
|
144 end
|
flickerstreak@28
|
145
|
flickerstreak@28
|
146 local tbl = sv[svstore][key]
|
flickerstreak@28
|
147
|
flickerstreak@28
|
148 if defaults then
|
flickerstreak@28
|
149 copyDefaults(tbl, defaults)
|
flickerstreak@28
|
150 end
|
flickerstreak@28
|
151 rawset(db, section, tbl)
|
flickerstreak@28
|
152
|
flickerstreak@28
|
153 return tableCreated, tbl
|
flickerstreak@28
|
154 end
|
flickerstreak@28
|
155
|
flickerstreak@28
|
156 -- Metatable to handle the dynamic creation of sections and copying of sections.
|
flickerstreak@28
|
157 local dbmt = {
|
flickerstreak@28
|
158 __index = function(t, section)
|
flickerstreak@28
|
159 local keys = rawget(t, "keys")
|
flickerstreak@28
|
160 local key = keys[section]
|
flickerstreak@28
|
161 if key then
|
flickerstreak@28
|
162 local defaultTbl = rawget(t, "defaults")
|
flickerstreak@28
|
163 local defaults = defaultTbl and defaultTbl[section]
|
flickerstreak@28
|
164
|
flickerstreak@28
|
165 if section == "profile" then
|
flickerstreak@28
|
166 local new = initSection(t, section, "profiles", key, defaults)
|
flickerstreak@28
|
167 if new then
|
flickerstreak@28
|
168 -- Callback: OnNewProfile, database, newProfileKey
|
flickerstreak@28
|
169 t.callbacks:Fire("OnNewProfile", t, key)
|
flickerstreak@28
|
170 end
|
flickerstreak@28
|
171 elseif section == "profiles" then
|
flickerstreak@28
|
172 local sv = rawget(t, "sv")
|
flickerstreak@28
|
173 if not sv.profiles then sv.profiles = {} end
|
flickerstreak@28
|
174 rawset(t, "profiles", sv.profiles)
|
flickerstreak@28
|
175 elseif section == "global" then
|
flickerstreak@28
|
176 local sv = rawget(t, "sv")
|
flickerstreak@28
|
177 if not sv.global then sv.global = {} end
|
flickerstreak@28
|
178 if defaults then
|
flickerstreak@28
|
179 copyDefaults(sv.global, defaults)
|
flickerstreak@28
|
180 end
|
flickerstreak@28
|
181 rawset(t, section, sv.global)
|
flickerstreak@28
|
182 else
|
flickerstreak@28
|
183 initSection(t, section, section, key, defaults)
|
flickerstreak@28
|
184 end
|
flickerstreak@28
|
185 end
|
flickerstreak@28
|
186
|
flickerstreak@28
|
187 return rawget(t, section)
|
flickerstreak@28
|
188 end
|
flickerstreak@28
|
189 }
|
flickerstreak@28
|
190
|
flickerstreak@28
|
191 local function validateDefaults(defaults, keyTbl, offset)
|
flickerstreak@28
|
192 if not defaults then return end
|
flickerstreak@28
|
193 offset = offset or 0
|
flickerstreak@28
|
194 for k in pairs(defaults) do
|
flickerstreak@28
|
195 if not keyTbl[k] or k == "profiles" then
|
flickerstreak@28
|
196 error(("Usage: AceDBObject:RegisterDefaults(defaults): '%s' is not a valid datatype."):format(k), 3 + offset)
|
flickerstreak@28
|
197 end
|
flickerstreak@28
|
198 end
|
flickerstreak@28
|
199 end
|
flickerstreak@28
|
200
|
flickerstreak@28
|
201 local preserve_keys = {
|
flickerstreak@28
|
202 ["callbacks"] = true,
|
flickerstreak@28
|
203 ["RegisterCallback"] = true,
|
flickerstreak@28
|
204 ["UnregisterCallback"] = true,
|
flickerstreak@28
|
205 ["UnregisterAllCallbacks"] = true,
|
flickerstreak@28
|
206 ["children"] = true,
|
flickerstreak@28
|
207 }
|
flickerstreak@28
|
208
|
flickerstreak@28
|
209 local realmKey = GetRealmName()
|
flickerstreak@28
|
210 local charKey = UnitName("player") .. " - " .. realmKey
|
flickerstreak@28
|
211 local _, classKey = UnitClass("player")
|
flickerstreak@28
|
212 local _, raceKey = UnitRace("player")
|
flickerstreak@28
|
213 local factionKey = UnitFactionGroup("player")
|
flickerstreak@28
|
214 local factionrealmKey = factionKey .. " - " .. realmKey
|
flickerstreak@28
|
215 -- Actual database initialization function
|
flickerstreak@28
|
216 local function initdb(sv, defaults, defaultProfile, olddb, parent)
|
flickerstreak@28
|
217 -- Generate the database keys for each section
|
flickerstreak@28
|
218
|
flickerstreak@28
|
219 -- Make a container for profile keys
|
flickerstreak@28
|
220 if not sv.profileKeys then sv.profileKeys = {} end
|
flickerstreak@28
|
221
|
flickerstreak@28
|
222 -- Try to get the profile selected from the char db
|
flickerstreak@28
|
223 local profileKey = sv.profileKeys[charKey] or defaultProfile or charKey
|
flickerstreak@28
|
224 sv.profileKeys[charKey] = profileKey
|
flickerstreak@28
|
225
|
flickerstreak@28
|
226 -- This table contains keys that enable the dynamic creation
|
flickerstreak@28
|
227 -- of each section of the table. The 'global' and 'profiles'
|
flickerstreak@28
|
228 -- have a key of true, since they are handled in a special case
|
flickerstreak@28
|
229 local keyTbl= {
|
flickerstreak@28
|
230 ["char"] = charKey,
|
flickerstreak@28
|
231 ["realm"] = realmKey,
|
flickerstreak@28
|
232 ["class"] = classKey,
|
flickerstreak@28
|
233 ["race"] = raceKey,
|
flickerstreak@28
|
234 ["faction"] = factionKey,
|
flickerstreak@28
|
235 ["factionrealm"] = factionrealmKey,
|
flickerstreak@28
|
236 ["profile"] = profileKey,
|
flickerstreak@28
|
237 ["global"] = true,
|
flickerstreak@28
|
238 ["profiles"] = true,
|
flickerstreak@28
|
239 }
|
flickerstreak@28
|
240
|
flickerstreak@28
|
241 validateDefaults(defaults, keyTbl, 1)
|
flickerstreak@28
|
242
|
flickerstreak@28
|
243 -- This allows us to use this function to reset an entire database
|
flickerstreak@28
|
244 -- Clear out the old database
|
flickerstreak@28
|
245 if olddb then
|
flickerstreak@28
|
246 for k,v in pairs(olddb) do if not preserve_keys[k] then olddb[k] = nil end end
|
flickerstreak@28
|
247 end
|
flickerstreak@28
|
248
|
flickerstreak@28
|
249 -- Give this database the metatable so it initializes dynamically
|
flickerstreak@28
|
250 local db = setmetatable(olddb or {}, dbmt)
|
flickerstreak@28
|
251
|
flickerstreak@28
|
252 if not rawget(db, "callbacks") then
|
flickerstreak@28
|
253 -- try to load CallbackHandler-1.0 if it loaded after our library
|
flickerstreak@28
|
254 if not CallbackHandler then CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0", true) end
|
flickerstreak@28
|
255 db.callbacks = CallbackHandler and CallbackHandler:New(db) or CallbackDummy
|
flickerstreak@28
|
256 end
|
flickerstreak@28
|
257
|
flickerstreak@28
|
258 -- Copy methods locally into the database object, to avoid hitting
|
flickerstreak@28
|
259 -- the metatable when calling methods
|
flickerstreak@28
|
260
|
flickerstreak@28
|
261 if not parent then
|
flickerstreak@28
|
262 for name, func in pairs(DBObjectLib) do
|
flickerstreak@28
|
263 db[name] = func
|
flickerstreak@28
|
264 end
|
flickerstreak@28
|
265 else
|
flickerstreak@28
|
266 -- hack this one in
|
flickerstreak@28
|
267 db.RegisterDefaults = DBObjectLib.RegisterDefaults
|
flickerstreak@28
|
268 end
|
flickerstreak@28
|
269
|
flickerstreak@28
|
270 -- Set some properties in the database object
|
flickerstreak@28
|
271 db.profiles = sv.profiles
|
flickerstreak@28
|
272 db.keys = keyTbl
|
flickerstreak@28
|
273 db.sv = sv
|
flickerstreak@28
|
274 --db.sv_name = name
|
flickerstreak@28
|
275 db.defaults = defaults
|
flickerstreak@28
|
276 db.parent = parent
|
flickerstreak@28
|
277
|
flickerstreak@28
|
278 -- store the DB in the registry
|
flickerstreak@28
|
279 AceDB.db_registry[db] = true
|
flickerstreak@28
|
280
|
flickerstreak@28
|
281 return db
|
flickerstreak@28
|
282 end
|
flickerstreak@28
|
283
|
flickerstreak@28
|
284 -- handle PLAYER_LOGOUT
|
flickerstreak@28
|
285 -- strip all defaults from all databases
|
flickerstreak@28
|
286 local function logoutHandler(frame, event)
|
flickerstreak@28
|
287 if event == "PLAYER_LOGOUT" then
|
flickerstreak@28
|
288 for db in pairs(AceDB.db_registry) do
|
flickerstreak@28
|
289 db.callbacks:Fire("OnDatabaseShutdown", db)
|
flickerstreak@28
|
290 for section, key in pairs(db.keys) do
|
flickerstreak@28
|
291 if db.defaults and db.defaults[section] and rawget(db, section) then
|
flickerstreak@28
|
292 removeDefaults(db[section], db.defaults[section])
|
flickerstreak@28
|
293 end
|
flickerstreak@28
|
294 end
|
flickerstreak@28
|
295 end
|
flickerstreak@28
|
296 end
|
flickerstreak@28
|
297 end
|
flickerstreak@28
|
298
|
flickerstreak@28
|
299 AceDB.frame:RegisterEvent("PLAYER_LOGOUT")
|
flickerstreak@28
|
300 AceDB.frame:SetScript("OnEvent", logoutHandler)
|
flickerstreak@28
|
301
|
flickerstreak@28
|
302
|
flickerstreak@28
|
303 --[[-------------------------------------------------------------------------
|
flickerstreak@28
|
304 AceDB Object Method Definitions
|
flickerstreak@28
|
305 ---------------------------------------------------------------------------]]
|
flickerstreak@28
|
306
|
flickerstreak@28
|
307 -- DBObject:RegisterDefaults(defaults)
|
flickerstreak@28
|
308 -- defaults (table) - A table of defaults for this database
|
flickerstreak@28
|
309 --
|
flickerstreak@28
|
310 -- Sets the defaults table for the given database object by clearing any
|
flickerstreak@28
|
311 -- that are currently set, and then setting the new defaults.
|
flickerstreak@28
|
312 function DBObjectLib:RegisterDefaults(defaults)
|
flickerstreak@28
|
313 if defaults and type(defaults) ~= "table" then
|
flickerstreak@28
|
314 error("Usage: AceDBObject:RegisterDefaults(defaults): 'defaults' - table or nil expected.", 2)
|
flickerstreak@28
|
315 end
|
flickerstreak@28
|
316
|
flickerstreak@28
|
317 validateDefaults(defaults, self.keys)
|
flickerstreak@28
|
318
|
flickerstreak@28
|
319 -- Remove any currently set defaults
|
flickerstreak@28
|
320 if self.defaults then
|
flickerstreak@28
|
321 for section,key in pairs(self.keys) do
|
flickerstreak@28
|
322 if self.defaults[section] and rawget(self, section) then
|
flickerstreak@28
|
323 removeDefaults(self[section], self.defaults[section])
|
flickerstreak@28
|
324 end
|
flickerstreak@28
|
325 end
|
flickerstreak@28
|
326 end
|
flickerstreak@28
|
327
|
flickerstreak@28
|
328 -- Set the DBObject.defaults table
|
flickerstreak@28
|
329 self.defaults = defaults
|
flickerstreak@28
|
330
|
flickerstreak@28
|
331 -- Copy in any defaults, only touching those sections already created
|
flickerstreak@28
|
332 if defaults then
|
flickerstreak@28
|
333 for section,key in pairs(self.keys) do
|
flickerstreak@28
|
334 if defaults[section] and rawget(self, section) then
|
flickerstreak@28
|
335 copyDefaults(self[section], defaults[section])
|
flickerstreak@28
|
336 end
|
flickerstreak@28
|
337 end
|
flickerstreak@28
|
338 end
|
flickerstreak@28
|
339 end
|
flickerstreak@28
|
340
|
flickerstreak@28
|
341 -- DBObject:SetProfile(name)
|
flickerstreak@28
|
342 -- name (string) - The name of the profile to set as the current profile
|
flickerstreak@28
|
343 --
|
flickerstreak@28
|
344 -- Changes the profile of the database and all of it's namespaces to the
|
flickerstreak@28
|
345 -- supplied named profile
|
flickerstreak@28
|
346 function DBObjectLib:SetProfile(name)
|
flickerstreak@28
|
347 if type(name) ~= "string" then
|
flickerstreak@28
|
348 error("Usage: AceDBObject:SetProfile(name): 'name' - string expected.", 2)
|
flickerstreak@28
|
349 end
|
flickerstreak@28
|
350
|
flickerstreak@28
|
351 -- changing to the same profile, dont do anything
|
flickerstreak@28
|
352 if name == self.keys.profile then return end
|
flickerstreak@28
|
353
|
flickerstreak@28
|
354 local oldProfile = self.profile
|
flickerstreak@28
|
355 local defaults = self.defaults and self.defaults.profile
|
flickerstreak@28
|
356
|
flickerstreak@28
|
357 if oldProfile and defaults then
|
flickerstreak@28
|
358 -- Remove the defaults from the old profile
|
flickerstreak@28
|
359 removeDefaults(oldProfile, defaults)
|
flickerstreak@28
|
360 end
|
flickerstreak@28
|
361
|
flickerstreak@28
|
362 self.profile = nil
|
flickerstreak@28
|
363 self.keys["profile"] = name
|
flickerstreak@28
|
364 self.sv.profileKeys[charKey] = name
|
flickerstreak@28
|
365
|
flickerstreak@28
|
366 -- Callback: OnProfileChanged, database, newProfileKey
|
flickerstreak@28
|
367 self.callbacks:Fire("OnProfileChanged", self, name)
|
flickerstreak@28
|
368
|
flickerstreak@28
|
369 -- populate to child namespaces
|
flickerstreak@28
|
370 if self.children then
|
flickerstreak@28
|
371 for _, db in pairs(self.children) do
|
flickerstreak@28
|
372 DBObjectLib.SetProfile(db, name)
|
flickerstreak@28
|
373 end
|
flickerstreak@28
|
374 end
|
flickerstreak@28
|
375 end
|
flickerstreak@28
|
376
|
flickerstreak@28
|
377 -- DBObject:GetProfiles(tbl)
|
flickerstreak@28
|
378 -- tbl (table) - A table to store the profile names in (optional)
|
flickerstreak@28
|
379 --
|
flickerstreak@28
|
380 -- Returns a table with the names of the existing profiles in the database.
|
flickerstreak@28
|
381 -- You can optionally supply a table to re-use for this purpose.
|
flickerstreak@28
|
382 function DBObjectLib:GetProfiles(tbl)
|
flickerstreak@28
|
383 if tbl and type(tbl) ~= "table" then
|
flickerstreak@28
|
384 error("Usage: AceDBObject:GetProfiles(tbl): 'tbl' - table or nil expected.", 2)
|
flickerstreak@28
|
385 end
|
flickerstreak@28
|
386
|
flickerstreak@28
|
387 -- Clear the container table
|
flickerstreak@28
|
388 if tbl then
|
flickerstreak@28
|
389 for k,v in pairs(tbl) do tbl[k] = nil end
|
flickerstreak@28
|
390 else
|
flickerstreak@28
|
391 tbl = {}
|
flickerstreak@28
|
392 end
|
flickerstreak@28
|
393
|
flickerstreak@28
|
394 local curProfile = self.keys.profile
|
flickerstreak@28
|
395
|
flickerstreak@28
|
396 local i = 0
|
flickerstreak@28
|
397 for profileKey in pairs(self.profiles) do
|
flickerstreak@28
|
398 i = i + 1
|
flickerstreak@28
|
399 tbl[i] = profileKey
|
flickerstreak@28
|
400 if curProfile and profileKey == curProfile then curProfile = nil end
|
flickerstreak@28
|
401 end
|
flickerstreak@28
|
402
|
flickerstreak@28
|
403 -- Add the current profile, if it hasn't been created yet
|
flickerstreak@28
|
404 if curProfile then
|
flickerstreak@28
|
405 i = i + 1
|
flickerstreak@28
|
406 tbl[i] = curProfile
|
flickerstreak@28
|
407 end
|
flickerstreak@28
|
408
|
flickerstreak@28
|
409 return tbl, i
|
flickerstreak@28
|
410 end
|
flickerstreak@28
|
411
|
flickerstreak@28
|
412 -- DBObject:GetCurrentProfile()
|
flickerstreak@28
|
413 --
|
flickerstreak@28
|
414 -- Returns the current profile name used by the database
|
flickerstreak@28
|
415 function DBObjectLib:GetCurrentProfile()
|
flickerstreak@28
|
416 return self.keys.profile
|
flickerstreak@28
|
417 end
|
flickerstreak@28
|
418
|
flickerstreak@28
|
419 -- DBObject:DeleteProfile(name)
|
flickerstreak@28
|
420 -- name (string) - The name of the profile to be deleted
|
flickerstreak@28
|
421 --
|
flickerstreak@28
|
422 -- Deletes a named profile. This profile must not be the active profile.
|
flickerstreak@28
|
423 function DBObjectLib:DeleteProfile(name, silent)
|
flickerstreak@28
|
424 if type(name) ~= "string" then
|
flickerstreak@28
|
425 error("Usage: AceDBObject:DeleteProfile(name): 'name' - string expected.", 2)
|
flickerstreak@28
|
426 end
|
flickerstreak@28
|
427
|
flickerstreak@28
|
428 if self.keys.profile == name then
|
flickerstreak@28
|
429 error("Cannot delete the active profile in an AceDBObject.", 2)
|
flickerstreak@28
|
430 end
|
flickerstreak@28
|
431
|
flickerstreak@28
|
432 if not rawget(self.sv.profiles, name) and not silent then
|
flickerstreak@28
|
433 error("Cannot delete profile '" .. name .. "'. It does not exist.", 2)
|
flickerstreak@28
|
434 end
|
flickerstreak@28
|
435
|
flickerstreak@28
|
436 self.sv.profiles[name] = nil
|
flickerstreak@28
|
437 -- Callback: OnProfileDeleted, database, profileKey
|
flickerstreak@28
|
438 self.callbacks:Fire("OnProfileDeleted", self, name)
|
flickerstreak@28
|
439
|
flickerstreak@28
|
440 -- populate to child namespaces
|
flickerstreak@28
|
441 if self.children then
|
flickerstreak@28
|
442 for _, db in pairs(self.children) do
|
flickerstreak@28
|
443 DBObjectLib.DeleteProfile(db, name, true)
|
flickerstreak@28
|
444 end
|
flickerstreak@28
|
445 end
|
flickerstreak@28
|
446 end
|
flickerstreak@28
|
447
|
flickerstreak@28
|
448 -- DBObject:CopyProfile(name)
|
flickerstreak@28
|
449 -- name (string) - The name of the profile to be copied into the current profile
|
flickerstreak@28
|
450 --
|
flickerstreak@28
|
451 -- Copies a named profile into the current profile, overwriting any conflicting
|
flickerstreak@28
|
452 -- settings.
|
flickerstreak@28
|
453 function DBObjectLib:CopyProfile(name, silent)
|
flickerstreak@28
|
454 if type(name) ~= "string" then
|
flickerstreak@28
|
455 error("Usage: AceDBObject:CopyProfile(name): 'name' - string expected.", 2)
|
flickerstreak@28
|
456 end
|
flickerstreak@28
|
457
|
flickerstreak@28
|
458 if name == self.keys.profile then
|
flickerstreak@28
|
459 error("Cannot have the same source and destination profiles.", 2)
|
flickerstreak@28
|
460 end
|
flickerstreak@28
|
461
|
flickerstreak@28
|
462 if not rawget(self.sv.profiles, name) and not silent then
|
flickerstreak@28
|
463 error("Cannot copy profile '" .. name .. "'. It does not exist.", 2)
|
flickerstreak@28
|
464 end
|
flickerstreak@28
|
465
|
flickerstreak@28
|
466 -- Reset the profile before copying
|
flickerstreak@28
|
467 DBObjectLib.ResetProfile(self)
|
flickerstreak@28
|
468
|
flickerstreak@28
|
469 local profile = self.profile
|
flickerstreak@28
|
470 local source = self.sv.profiles[name]
|
flickerstreak@28
|
471
|
flickerstreak@28
|
472 copyTable(source, profile)
|
flickerstreak@28
|
473
|
flickerstreak@28
|
474 -- Callback: OnProfileCopied, database, sourceProfileKey
|
flickerstreak@28
|
475 self.callbacks:Fire("OnProfileCopied", self, name)
|
flickerstreak@28
|
476
|
flickerstreak@28
|
477 -- populate to child namespaces
|
flickerstreak@28
|
478 if self.children then
|
flickerstreak@28
|
479 for _, db in pairs(self.children) do
|
flickerstreak@28
|
480 DBObjectLib.CopyProfile(db, name, true)
|
flickerstreak@28
|
481 end
|
flickerstreak@28
|
482 end
|
flickerstreak@28
|
483 end
|
flickerstreak@28
|
484
|
flickerstreak@28
|
485 -- DBObject:ResetProfile()
|
flickerstreak@28
|
486 --
|
flickerstreak@28
|
487 -- Resets the current profile
|
flickerstreak@28
|
488 function DBObjectLib:ResetProfile()
|
flickerstreak@28
|
489 local profile = self.profile
|
flickerstreak@28
|
490
|
flickerstreak@28
|
491 for k,v in pairs(profile) do
|
flickerstreak@28
|
492 profile[k] = nil
|
flickerstreak@28
|
493 end
|
flickerstreak@28
|
494
|
flickerstreak@28
|
495 local defaults = self.defaults and self.defaults.profile
|
flickerstreak@28
|
496 if defaults then
|
flickerstreak@28
|
497 copyDefaults(profile, defaults)
|
flickerstreak@28
|
498 end
|
flickerstreak@28
|
499
|
flickerstreak@28
|
500 -- Callback: OnProfileReset, database
|
flickerstreak@28
|
501 self.callbacks:Fire("OnProfileReset", self)
|
flickerstreak@28
|
502
|
flickerstreak@28
|
503 -- populate to child namespaces
|
flickerstreak@28
|
504 if self.children then
|
flickerstreak@28
|
505 for _, db in pairs(self.children) do
|
flickerstreak@28
|
506 DBObjectLib.ResetProfile(db)
|
flickerstreak@28
|
507 end
|
flickerstreak@28
|
508 end
|
flickerstreak@28
|
509 end
|
flickerstreak@28
|
510
|
flickerstreak@28
|
511 -- DBObject:ResetDB(defaultProfile)
|
flickerstreak@28
|
512 -- defaultProfile (string) - The profile name to use as the default
|
flickerstreak@28
|
513 --
|
flickerstreak@28
|
514 -- Resets the entire database, using the string defaultProfile as the default
|
flickerstreak@28
|
515 -- profile.
|
flickerstreak@28
|
516 function DBObjectLib:ResetDB(defaultProfile)
|
flickerstreak@28
|
517 if defaultProfile and type(defaultProfile) ~= "string" then
|
flickerstreak@28
|
518 error("Usage: AceDBObject:ResetDB(defaultProfile): 'defaultProfile' - string or nil expected.", 2)
|
flickerstreak@28
|
519 end
|
flickerstreak@28
|
520
|
flickerstreak@28
|
521 local sv = self.sv
|
flickerstreak@28
|
522 for k,v in pairs(sv) do
|
flickerstreak@28
|
523 sv[k] = nil
|
flickerstreak@28
|
524 end
|
flickerstreak@28
|
525
|
flickerstreak@28
|
526 local parent = self.parent
|
flickerstreak@28
|
527
|
flickerstreak@28
|
528 initdb(sv, self.defaults, defaultProfile, self)
|
flickerstreak@28
|
529
|
flickerstreak@28
|
530 -- Callback: OnDatabaseReset, database
|
flickerstreak@28
|
531 self.callbacks:Fire("OnDatabaseReset", self)
|
flickerstreak@28
|
532 -- Callback: OnProfileChanged, database, profileKey
|
flickerstreak@28
|
533 self.callbacks:Fire("OnProfileChanged", self, self.keys["profile"])
|
flickerstreak@28
|
534
|
flickerstreak@28
|
535 -- fix the child namespaces
|
flickerstreak@28
|
536 if self.children then
|
flickerstreak@28
|
537 if not sv.namespaces then sv.namespaces = {} end
|
flickerstreak@28
|
538 for name, db in pairs(self.children) do
|
flickerstreak@28
|
539 if not sv.namespaces[name] then sv.namespaces[name] = {} end
|
flickerstreak@28
|
540 initdb(sv.namespaces[name], db.defaults, self.keys.profile, db, self)
|
flickerstreak@28
|
541 end
|
flickerstreak@28
|
542 end
|
flickerstreak@28
|
543
|
flickerstreak@28
|
544 return self
|
flickerstreak@28
|
545 end
|
flickerstreak@28
|
546
|
flickerstreak@28
|
547 -- DBObject:RegisterNamespace(name [, defaults])
|
flickerstreak@28
|
548 -- name (string) - The name of the new namespace
|
flickerstreak@28
|
549 -- defaults (table) - A table of values to use as defaults
|
flickerstreak@28
|
550 --
|
flickerstreak@28
|
551 -- Creates a new database namespace, directly tied to the database. This
|
flickerstreak@28
|
552 -- is a full scale database in it's own rights other than the fact that
|
flickerstreak@28
|
553 -- it cannot control its profile individually
|
flickerstreak@28
|
554 function DBObjectLib:RegisterNamespace(name, defaults)
|
flickerstreak@28
|
555 if type(name) ~= "string" then
|
flickerstreak@28
|
556 error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - string expected.", 2)
|
flickerstreak@28
|
557 end
|
flickerstreak@28
|
558 if defaults and type(defaults) ~= "table" then
|
flickerstreak@28
|
559 error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'defaults' - table or nil expected.", 2)
|
flickerstreak@28
|
560 end
|
flickerstreak@28
|
561 if self.children and self.children[name] then
|
flickerstreak@28
|
562 error ("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - a namespace with that name already exists.", 2)
|
flickerstreak@28
|
563 end
|
flickerstreak@28
|
564
|
flickerstreak@28
|
565 local sv = self.sv
|
flickerstreak@28
|
566 if not sv.namespaces then sv.namespaces = {} end
|
flickerstreak@28
|
567 if not sv.namespaces[name] then
|
flickerstreak@28
|
568 sv.namespaces[name] = {}
|
flickerstreak@28
|
569 end
|
flickerstreak@28
|
570
|
flickerstreak@28
|
571 local newDB = initdb(sv.namespaces[name], defaults, self.keys.profile, nil, self)
|
flickerstreak@28
|
572
|
flickerstreak@28
|
573 if not self.children then self.children = {} end
|
flickerstreak@28
|
574 self.children[name] = newDB
|
flickerstreak@28
|
575 return newDB
|
flickerstreak@28
|
576 end
|
flickerstreak@28
|
577
|
flickerstreak@28
|
578 --[[-------------------------------------------------------------------------
|
flickerstreak@28
|
579 AceDB Exposed Methods
|
flickerstreak@28
|
580 ---------------------------------------------------------------------------]]
|
flickerstreak@28
|
581
|
flickerstreak@28
|
582 -- AceDB:New(name, defaults, defaultProfile)
|
flickerstreak@28
|
583 -- name (table or string) - The name of variable, or table to use for the database
|
flickerstreak@28
|
584 -- defaults (table) - A table of database defaults
|
flickerstreak@28
|
585 -- defaultProfile (string) - The name of the default profile
|
flickerstreak@28
|
586 --
|
flickerstreak@28
|
587 -- Creates a new database object that can be used to handle database settings
|
flickerstreak@28
|
588 -- and profiles.
|
flickerstreak@28
|
589 function AceDB:New(tbl, defaults, defaultProfile)
|
flickerstreak@28
|
590 if type(tbl) == "string" then
|
flickerstreak@28
|
591 local name = tbl
|
flickerstreak@28
|
592 tbl = getglobal(name)
|
flickerstreak@28
|
593 if not tbl then
|
flickerstreak@28
|
594 tbl = {}
|
flickerstreak@28
|
595 setglobal(name, tbl)
|
flickerstreak@28
|
596 end
|
flickerstreak@28
|
597 end
|
flickerstreak@28
|
598
|
flickerstreak@28
|
599 if type(tbl) ~= "table" then
|
flickerstreak@28
|
600 error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'tbl' - table expected.", 2)
|
flickerstreak@28
|
601 end
|
flickerstreak@28
|
602
|
flickerstreak@28
|
603 if defaults and type(defaults) ~= "table" then
|
flickerstreak@28
|
604 error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaults' - table expected.", 2)
|
flickerstreak@28
|
605 end
|
flickerstreak@28
|
606
|
flickerstreak@28
|
607 if defaultProfile and type(defaultProfile) ~= "string" then
|
flickerstreak@28
|
608 error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaultProfile' - string expected.", 2)
|
flickerstreak@28
|
609 end
|
flickerstreak@28
|
610
|
flickerstreak@28
|
611 return initdb(tbl, defaults, defaultProfile)
|
flickerstreak@28
|
612 end
|
flickerstreak@28
|
613
|
flickerstreak@28
|
614 -- upgrade existing databases
|
flickerstreak@28
|
615 for db in pairs(AceDB.db_registry) do
|
flickerstreak@28
|
616 if not db.parent then
|
flickerstreak@28
|
617 for name,func in pairs(DBObjectLib) do
|
flickerstreak@28
|
618 db[name] = func
|
flickerstreak@28
|
619 end
|
flickerstreak@28
|
620 else
|
flickerstreak@28
|
621 db.RegisterDefaults = DBObjectLib.RegisterDefaults
|
flickerstreak@28
|
622 end
|
flickerstreak@28
|
623 end
|