annotate lib/AceDB-3.0/AceDB-3.0.lua @ 28:21bcaf8215ff

- converted to Ace3 - rearranged file layout - configGUI menus not working right now
author Flick <flickerstreak@gmail.com>
date Mon, 17 Mar 2008 18:24:53 +0000
parents
children
rev   line source
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