Mercurial > wow > hotcorners
comparison Libs/AceDB-3.0/AceDB-3.0.lua @ 0:fc346da3afd9
First commit Hot Corners standalone.
| author | tercio |
|---|---|
| date | Fri, 08 Aug 2014 12:35:17 -0300 |
| parents | |
| children | c31ee4251181 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:fc346da3afd9 |
|---|---|
| 1 --- **AceDB-3.0** manages the SavedVariables of your addon. | |
| 2 -- It offers profile management, smart defaults and namespaces for modules.\\ | |
| 3 -- Data can be saved in different data-types, depending on its intended usage. | |
| 4 -- The most common data-type is the `profile` type, which allows the user to choose | |
| 5 -- the active profile, and manage the profiles of all of his characters.\\ | |
| 6 -- The following data types are available: | |
| 7 -- * **char** Character-specific data. Every character has its own database. | |
| 8 -- * **realm** Realm-specific data. All of the players characters on the same realm share this database. | |
| 9 -- * **class** Class-specific data. All of the players characters of the same class share this database. | |
| 10 -- * **race** Race-specific data. All of the players characters of the same race share this database. | |
| 11 -- * **faction** Faction-specific data. All of the players characters of the same faction share this database. | |
| 12 -- * **factionrealm** Faction and realm specific data. All of the players characters on the same realm and of the same faction share this database. | |
| 13 -- * **global** Global Data. All characters on the same account share this database. | |
| 14 -- * **profile** Profile-specific data. All characters using the same profile share this database. The user can control which profile should be used. | |
| 15 -- | |
| 16 -- Creating a new Database using the `:New` function will return a new DBObject. A database will inherit all functions | |
| 17 -- of the DBObjectLib listed here. \\ | |
| 18 -- If you create a new namespaced child-database (`:RegisterNamespace`), you'll get a DBObject as well, but note | |
| 19 -- that the child-databases cannot individually change their profile, and are linked to their parents profile - and because of that, | |
| 20 -- the profile related APIs are not available. Only `:RegisterDefaults` and `:ResetProfile` are available on child-databases. | |
| 21 -- | |
| 22 -- For more details on how to use AceDB-3.0, see the [[AceDB-3.0 Tutorial]]. | |
| 23 -- | |
| 24 -- You may also be interested in [[libdualspec-1-0|LibDualSpec-1.0]] to do profile switching automatically when switching specs. | |
| 25 -- | |
| 26 -- @usage | |
| 27 -- MyAddon = LibStub("AceAddon-3.0"):NewAddon("DBExample") | |
| 28 -- | |
| 29 -- -- declare defaults to be used in the DB | |
| 30 -- local defaults = { | |
| 31 -- profile = { | |
| 32 -- setting = true, | |
| 33 -- } | |
| 34 -- } | |
| 35 -- | |
| 36 -- function MyAddon:OnInitialize() | |
| 37 -- -- Assuming the .toc says ## SavedVariables: MyAddonDB | |
| 38 -- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true) | |
| 39 -- end | |
| 40 -- @class file | |
| 41 -- @name AceDB-3.0.lua | |
| 42 -- @release $Id: AceDB-3.0.lua 1096 2013-09-13 15:05:40Z nevcairiel $ | |
| 43 local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 23 | |
| 44 local AceDB, oldminor = LibStub:NewLibrary(ACEDB_MAJOR, ACEDB_MINOR) | |
| 45 | |
| 46 if not AceDB then return end -- No upgrade needed | |
| 47 | |
| 48 -- Lua APIs | |
| 49 local type, pairs, next, error = type, pairs, next, error | |
| 50 local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget | |
| 51 | |
| 52 -- WoW APIs | |
| 53 local _G = _G | |
| 54 | |
| 55 -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded | |
| 56 -- List them here for Mikk's FindGlobals script | |
| 57 -- GLOBALS: LibStub | |
| 58 | |
| 59 AceDB.db_registry = AceDB.db_registry or {} | |
| 60 AceDB.frame = AceDB.frame or CreateFrame("Frame") | |
| 61 | |
| 62 local CallbackHandler | |
| 63 local CallbackDummy = { Fire = function() end } | |
| 64 | |
| 65 local DBObjectLib = {} | |
| 66 | |
| 67 --[[------------------------------------------------------------------------- | |
| 68 AceDB Utility Functions | |
| 69 ---------------------------------------------------------------------------]] | |
| 70 | |
| 71 -- Simple shallow copy for copying defaults | |
| 72 local function copyTable(src, dest) | |
| 73 if type(dest) ~= "table" then dest = {} end | |
| 74 if type(src) == "table" then | |
| 75 for k,v in pairs(src) do | |
| 76 if type(v) == "table" then | |
| 77 -- try to index the key first so that the metatable creates the defaults, if set, and use that table | |
| 78 v = copyTable(v, dest[k]) | |
| 79 end | |
| 80 dest[k] = v | |
| 81 end | |
| 82 end | |
| 83 return dest | |
| 84 end | |
| 85 | |
| 86 -- Called to add defaults to a section of the database | |
| 87 -- | |
| 88 -- When a ["*"] default section is indexed with a new key, a table is returned | |
| 89 -- and set in the host table. These tables must be cleaned up by removeDefaults | |
| 90 -- in order to ensure we don't write empty default tables. | |
| 91 local function copyDefaults(dest, src) | |
| 92 -- this happens if some value in the SV overwrites our default value with a non-table | |
| 93 --if type(dest) ~= "table" then return end | |
| 94 for k, v in pairs(src) do | |
| 95 if k == "*" or k == "**" then | |
| 96 if type(v) == "table" then | |
| 97 -- This is a metatable used for table defaults | |
| 98 local mt = { | |
| 99 -- This handles the lookup and creation of new subtables | |
| 100 __index = function(t,k) | |
| 101 if k == nil then return nil end | |
| 102 local tbl = {} | |
| 103 copyDefaults(tbl, v) | |
| 104 rawset(t, k, tbl) | |
| 105 return tbl | |
| 106 end, | |
| 107 } | |
| 108 setmetatable(dest, mt) | |
| 109 -- handle already existing tables in the SV | |
| 110 for dk, dv in pairs(dest) do | |
| 111 if not rawget(src, dk) and type(dv) == "table" then | |
| 112 copyDefaults(dv, v) | |
| 113 end | |
| 114 end | |
| 115 else | |
| 116 -- Values are not tables, so this is just a simple return | |
| 117 local mt = {__index = function(t,k) return k~=nil and v or nil end} | |
| 118 setmetatable(dest, mt) | |
| 119 end | |
| 120 elseif type(v) == "table" then | |
| 121 if not rawget(dest, k) then rawset(dest, k, {}) end | |
| 122 if type(dest[k]) == "table" then | |
| 123 copyDefaults(dest[k], v) | |
| 124 if src['**'] then | |
| 125 copyDefaults(dest[k], src['**']) | |
| 126 end | |
| 127 end | |
| 128 else | |
| 129 if rawget(dest, k) == nil then | |
| 130 rawset(dest, k, v) | |
| 131 end | |
| 132 end | |
| 133 end | |
| 134 end | |
| 135 | |
| 136 -- Called to remove all defaults in the default table from the database | |
| 137 local function removeDefaults(db, defaults, blocker) | |
| 138 -- remove all metatables from the db, so we don't accidentally create new sub-tables through them | |
| 139 setmetatable(db, nil) | |
| 140 -- loop through the defaults and remove their content | |
| 141 for k,v in pairs(defaults) do | |
| 142 if k == "*" or k == "**" then | |
| 143 if type(v) == "table" then | |
| 144 -- Loop through all the actual k,v pairs and remove | |
| 145 for key, value in pairs(db) do | |
| 146 if type(value) == "table" then | |
| 147 -- if the key was not explicitly specified in the defaults table, just strip everything from * and ** tables | |
| 148 if defaults[key] == nil and (not blocker or blocker[key] == nil) then | |
| 149 removeDefaults(value, v) | |
| 150 -- if the table is empty afterwards, remove it | |
| 151 if next(value) == nil then | |
| 152 db[key] = nil | |
| 153 end | |
| 154 -- if it was specified, only strip ** content, but block values which were set in the key table | |
| 155 elseif k == "**" then | |
| 156 removeDefaults(value, v, defaults[key]) | |
| 157 end | |
| 158 end | |
| 159 end | |
| 160 elseif k == "*" then | |
| 161 -- check for non-table default | |
| 162 for key, value in pairs(db) do | |
| 163 if defaults[key] == nil and v == value then | |
| 164 db[key] = nil | |
| 165 end | |
| 166 end | |
| 167 end | |
| 168 elseif type(v) == "table" and type(db[k]) == "table" then | |
| 169 -- if a blocker was set, dive into it, to allow multi-level defaults | |
| 170 removeDefaults(db[k], v, blocker and blocker[k]) | |
| 171 if next(db[k]) == nil then | |
| 172 db[k] = nil | |
| 173 end | |
| 174 else | |
| 175 -- check if the current value matches the default, and that its not blocked by another defaults table | |
| 176 if db[k] == defaults[k] and (not blocker or blocker[k] == nil) then | |
| 177 db[k] = nil | |
| 178 end | |
| 179 end | |
| 180 end | |
| 181 end | |
| 182 | |
| 183 -- This is called when a table section is first accessed, to set up the defaults | |
| 184 local function initSection(db, section, svstore, key, defaults) | |
| 185 local sv = rawget(db, "sv") | |
| 186 | |
| 187 local tableCreated | |
| 188 if not sv[svstore] then sv[svstore] = {} end | |
| 189 if not sv[svstore][key] then | |
| 190 sv[svstore][key] = {} | |
| 191 tableCreated = true | |
| 192 end | |
| 193 | |
| 194 local tbl = sv[svstore][key] | |
| 195 | |
| 196 if defaults then | |
| 197 copyDefaults(tbl, defaults) | |
| 198 end | |
| 199 rawset(db, section, tbl) | |
| 200 | |
| 201 return tableCreated, tbl | |
| 202 end | |
| 203 | |
| 204 -- Metatable to handle the dynamic creation of sections and copying of sections. | |
| 205 local dbmt = { | |
| 206 __index = function(t, section) | |
| 207 local keys = rawget(t, "keys") | |
| 208 local key = keys[section] | |
| 209 if key then | |
| 210 local defaultTbl = rawget(t, "defaults") | |
| 211 local defaults = defaultTbl and defaultTbl[section] | |
| 212 | |
| 213 if section == "profile" then | |
| 214 local new = initSection(t, section, "profiles", key, defaults) | |
| 215 if new then | |
| 216 -- Callback: OnNewProfile, database, newProfileKey | |
| 217 t.callbacks:Fire("OnNewProfile", t, key) | |
| 218 end | |
| 219 elseif section == "profiles" then | |
| 220 local sv = rawget(t, "sv") | |
| 221 if not sv.profiles then sv.profiles = {} end | |
| 222 rawset(t, "profiles", sv.profiles) | |
| 223 elseif section == "global" then | |
| 224 local sv = rawget(t, "sv") | |
| 225 if not sv.global then sv.global = {} end | |
| 226 if defaults then | |
| 227 copyDefaults(sv.global, defaults) | |
| 228 end | |
| 229 rawset(t, section, sv.global) | |
| 230 else | |
| 231 initSection(t, section, section, key, defaults) | |
| 232 end | |
| 233 end | |
| 234 | |
| 235 return rawget(t, section) | |
| 236 end | |
| 237 } | |
| 238 | |
| 239 local function validateDefaults(defaults, keyTbl, offset) | |
| 240 if not defaults then return end | |
| 241 offset = offset or 0 | |
| 242 for k in pairs(defaults) do | |
| 243 if not keyTbl[k] or k == "profiles" then | |
| 244 error(("Usage: AceDBObject:RegisterDefaults(defaults): '%s' is not a valid datatype."):format(k), 3 + offset) | |
| 245 end | |
| 246 end | |
| 247 end | |
| 248 | |
| 249 local preserve_keys = { | |
| 250 ["callbacks"] = true, | |
| 251 ["RegisterCallback"] = true, | |
| 252 ["UnregisterCallback"] = true, | |
| 253 ["UnregisterAllCallbacks"] = true, | |
| 254 ["children"] = true, | |
| 255 } | |
| 256 | |
| 257 local realmKey = GetRealmName() | |
| 258 local charKey = UnitName("player") .. " - " .. realmKey | |
| 259 local _, classKey = UnitClass("player") | |
| 260 local _, raceKey = UnitRace("player") | |
| 261 local factionKey = UnitFactionGroup("player") | |
| 262 local factionrealmKey = factionKey .. " - " .. realmKey | |
| 263 local factionrealmregionKey = factionrealmKey .. " - " .. string.sub(GetCVar("realmList"), 1, 2):upper() | |
| 264 local localeKey = GetLocale():lower() | |
| 265 | |
| 266 -- Actual database initialization function | |
| 267 local function initdb(sv, defaults, defaultProfile, olddb, parent) | |
| 268 -- Generate the database keys for each section | |
| 269 | |
| 270 -- map "true" to our "Default" profile | |
| 271 if defaultProfile == true then defaultProfile = "Default" end | |
| 272 | |
| 273 local profileKey | |
| 274 if not parent then | |
| 275 -- Make a container for profile keys | |
| 276 if not sv.profileKeys then sv.profileKeys = {} end | |
| 277 | |
| 278 -- Try to get the profile selected from the char db | |
| 279 profileKey = sv.profileKeys[charKey] or defaultProfile or charKey | |
| 280 | |
| 281 -- save the selected profile for later | |
| 282 sv.profileKeys[charKey] = profileKey | |
| 283 else | |
| 284 -- Use the profile of the parents DB | |
| 285 profileKey = parent.keys.profile or defaultProfile or charKey | |
| 286 | |
| 287 -- clear the profileKeys in the DB, namespaces don't need to store them | |
| 288 sv.profileKeys = nil | |
| 289 end | |
| 290 | |
| 291 -- This table contains keys that enable the dynamic creation | |
| 292 -- of each section of the table. The 'global' and 'profiles' | |
| 293 -- have a key of true, since they are handled in a special case | |
| 294 local keyTbl= { | |
| 295 ["char"] = charKey, | |
| 296 ["realm"] = realmKey, | |
| 297 ["class"] = classKey, | |
| 298 ["race"] = raceKey, | |
| 299 ["faction"] = factionKey, | |
| 300 ["factionrealm"] = factionrealmKey, | |
| 301 ["factionrealmregion"] = factionrealmregionKey, | |
| 302 ["profile"] = profileKey, | |
| 303 ["locale"] = localeKey, | |
| 304 ["global"] = true, | |
| 305 ["profiles"] = true, | |
| 306 } | |
| 307 | |
| 308 validateDefaults(defaults, keyTbl, 1) | |
| 309 | |
| 310 -- This allows us to use this function to reset an entire database | |
| 311 -- Clear out the old database | |
| 312 if olddb then | |
| 313 for k,v in pairs(olddb) do if not preserve_keys[k] then olddb[k] = nil end end | |
| 314 end | |
| 315 | |
| 316 -- Give this database the metatable so it initializes dynamically | |
| 317 local db = setmetatable(olddb or {}, dbmt) | |
| 318 | |
| 319 if not rawget(db, "callbacks") then | |
| 320 -- try to load CallbackHandler-1.0 if it loaded after our library | |
| 321 if not CallbackHandler then CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0", true) end | |
| 322 db.callbacks = CallbackHandler and CallbackHandler:New(db) or CallbackDummy | |
| 323 end | |
| 324 | |
| 325 -- Copy methods locally into the database object, to avoid hitting | |
| 326 -- the metatable when calling methods | |
| 327 | |
| 328 if not parent then | |
| 329 for name, func in pairs(DBObjectLib) do | |
| 330 db[name] = func | |
| 331 end | |
| 332 else | |
| 333 -- hack this one in | |
| 334 db.RegisterDefaults = DBObjectLib.RegisterDefaults | |
| 335 db.ResetProfile = DBObjectLib.ResetProfile | |
| 336 end | |
| 337 | |
| 338 -- Set some properties in the database object | |
| 339 db.profiles = sv.profiles | |
| 340 db.keys = keyTbl | |
| 341 db.sv = sv | |
| 342 --db.sv_name = name | |
| 343 db.defaults = defaults | |
| 344 db.parent = parent | |
| 345 | |
| 346 -- store the DB in the registry | |
| 347 AceDB.db_registry[db] = true | |
| 348 | |
| 349 return db | |
| 350 end | |
| 351 | |
| 352 -- handle PLAYER_LOGOUT | |
| 353 -- strip all defaults from all databases | |
| 354 -- and cleans up empty sections | |
| 355 local function logoutHandler(frame, event) | |
| 356 if event == "PLAYER_LOGOUT" then | |
| 357 for db in pairs(AceDB.db_registry) do | |
| 358 db.callbacks:Fire("OnDatabaseShutdown", db) | |
| 359 db:RegisterDefaults(nil) | |
| 360 | |
| 361 -- cleanup sections that are empty without defaults | |
| 362 local sv = rawget(db, "sv") | |
| 363 for section in pairs(db.keys) do | |
| 364 if rawget(sv, section) then | |
| 365 -- global is special, all other sections have sub-entrys | |
| 366 -- also don't delete empty profiles on main dbs, only on namespaces | |
| 367 if section ~= "global" and (section ~= "profiles" or rawget(db, "parent")) then | |
| 368 for key in pairs(sv[section]) do | |
| 369 if not next(sv[section][key]) then | |
| 370 sv[section][key] = nil | |
| 371 end | |
| 372 end | |
| 373 end | |
| 374 if not next(sv[section]) then | |
| 375 sv[section] = nil | |
| 376 end | |
| 377 end | |
| 378 end | |
| 379 end | |
| 380 end | |
| 381 end | |
| 382 | |
| 383 AceDB.frame:RegisterEvent("PLAYER_LOGOUT") | |
| 384 AceDB.frame:SetScript("OnEvent", logoutHandler) | |
| 385 | |
| 386 | |
| 387 --[[------------------------------------------------------------------------- | |
| 388 AceDB Object Method Definitions | |
| 389 ---------------------------------------------------------------------------]] | |
| 390 | |
| 391 --- Sets the defaults table for the given database object by clearing any | |
| 392 -- that are currently set, and then setting the new defaults. | |
| 393 -- @param defaults A table of defaults for this database | |
| 394 function DBObjectLib:RegisterDefaults(defaults) | |
| 395 if defaults and type(defaults) ~= "table" then | |
| 396 error("Usage: AceDBObject:RegisterDefaults(defaults): 'defaults' - table or nil expected.", 2) | |
| 397 end | |
| 398 | |
| 399 validateDefaults(defaults, self.keys) | |
| 400 | |
| 401 -- Remove any currently set defaults | |
| 402 if self.defaults then | |
| 403 for section,key in pairs(self.keys) do | |
| 404 if self.defaults[section] and rawget(self, section) then | |
| 405 removeDefaults(self[section], self.defaults[section]) | |
| 406 end | |
| 407 end | |
| 408 end | |
| 409 | |
| 410 -- Set the DBObject.defaults table | |
| 411 self.defaults = defaults | |
| 412 | |
| 413 -- Copy in any defaults, only touching those sections already created | |
| 414 if defaults then | |
| 415 for section,key in pairs(self.keys) do | |
| 416 if defaults[section] and rawget(self, section) then | |
| 417 copyDefaults(self[section], defaults[section]) | |
| 418 end | |
| 419 end | |
| 420 end | |
| 421 end | |
| 422 | |
| 423 --- Changes the profile of the database and all of it's namespaces to the | |
| 424 -- supplied named profile | |
| 425 -- @param name The name of the profile to set as the current profile | |
| 426 function DBObjectLib:SetProfile(name) | |
| 427 if type(name) ~= "string" then | |
| 428 error("Usage: AceDBObject:SetProfile(name): 'name' - string expected.", 2) | |
| 429 end | |
| 430 | |
| 431 -- changing to the same profile, dont do anything | |
| 432 if name == self.keys.profile then return end | |
| 433 | |
| 434 local oldProfile = self.profile | |
| 435 local defaults = self.defaults and self.defaults.profile | |
| 436 | |
| 437 -- Callback: OnProfileShutdown, database | |
| 438 self.callbacks:Fire("OnProfileShutdown", self) | |
| 439 | |
| 440 if oldProfile and defaults then | |
| 441 -- Remove the defaults from the old profile | |
| 442 removeDefaults(oldProfile, defaults) | |
| 443 end | |
| 444 | |
| 445 self.profile = nil | |
| 446 self.keys["profile"] = name | |
| 447 | |
| 448 -- if the storage exists, save the new profile | |
| 449 -- this won't exist on namespaces. | |
| 450 if self.sv.profileKeys then | |
| 451 self.sv.profileKeys[charKey] = name | |
| 452 end | |
| 453 | |
| 454 -- populate to child namespaces | |
| 455 if self.children then | |
| 456 for _, db in pairs(self.children) do | |
| 457 DBObjectLib.SetProfile(db, name) | |
| 458 end | |
| 459 end | |
| 460 | |
| 461 -- Callback: OnProfileChanged, database, newProfileKey | |
| 462 self.callbacks:Fire("OnProfileChanged", self, name) | |
| 463 end | |
| 464 | |
| 465 --- Returns a table with the names of the existing profiles in the database. | |
| 466 -- You can optionally supply a table to re-use for this purpose. | |
| 467 -- @param tbl A table to store the profile names in (optional) | |
| 468 function DBObjectLib:GetProfiles(tbl) | |
| 469 if tbl and type(tbl) ~= "table" then | |
| 470 error("Usage: AceDBObject:GetProfiles(tbl): 'tbl' - table or nil expected.", 2) | |
| 471 end | |
| 472 | |
| 473 -- Clear the container table | |
| 474 if tbl then | |
| 475 for k,v in pairs(tbl) do tbl[k] = nil end | |
| 476 else | |
| 477 tbl = {} | |
| 478 end | |
| 479 | |
| 480 local curProfile = self.keys.profile | |
| 481 | |
| 482 local i = 0 | |
| 483 for profileKey in pairs(self.profiles) do | |
| 484 i = i + 1 | |
| 485 tbl[i] = profileKey | |
| 486 if curProfile and profileKey == curProfile then curProfile = nil end | |
| 487 end | |
| 488 | |
| 489 -- Add the current profile, if it hasn't been created yet | |
| 490 if curProfile then | |
| 491 i = i + 1 | |
| 492 tbl[i] = curProfile | |
| 493 end | |
| 494 | |
| 495 return tbl, i | |
| 496 end | |
| 497 | |
| 498 --- Returns the current profile name used by the database | |
| 499 function DBObjectLib:GetCurrentProfile() | |
| 500 return self.keys.profile | |
| 501 end | |
| 502 | |
| 503 --- Deletes a named profile. This profile must not be the active profile. | |
| 504 -- @param name The name of the profile to be deleted | |
| 505 -- @param silent If true, do not raise an error when the profile does not exist | |
| 506 function DBObjectLib:DeleteProfile(name, silent) | |
| 507 if type(name) ~= "string" then | |
| 508 error("Usage: AceDBObject:DeleteProfile(name): 'name' - string expected.", 2) | |
| 509 end | |
| 510 | |
| 511 if self.keys.profile == name then | |
| 512 error("Cannot delete the active profile in an AceDBObject.", 2) | |
| 513 end | |
| 514 | |
| 515 if not rawget(self.profiles, name) and not silent then | |
| 516 error("Cannot delete profile '" .. name .. "'. It does not exist.", 2) | |
| 517 end | |
| 518 | |
| 519 self.profiles[name] = nil | |
| 520 | |
| 521 -- populate to child namespaces | |
| 522 if self.children then | |
| 523 for _, db in pairs(self.children) do | |
| 524 DBObjectLib.DeleteProfile(db, name, true) | |
| 525 end | |
| 526 end | |
| 527 | |
| 528 -- switch all characters that use this profile back to the default | |
| 529 if self.sv.profileKeys then | |
| 530 for key, profile in pairs(self.sv.profileKeys) do | |
| 531 if profile == name then | |
| 532 self.sv.profileKeys[key] = nil | |
| 533 end | |
| 534 end | |
| 535 end | |
| 536 | |
| 537 -- Callback: OnProfileDeleted, database, profileKey | |
| 538 self.callbacks:Fire("OnProfileDeleted", self, name) | |
| 539 end | |
| 540 | |
| 541 --- Copies a named profile into the current profile, overwriting any conflicting | |
| 542 -- settings. | |
| 543 -- @param name The name of the profile to be copied into the current profile | |
| 544 -- @param silent If true, do not raise an error when the profile does not exist | |
| 545 function DBObjectLib:CopyProfile(name, silent) | |
| 546 if type(name) ~= "string" then | |
| 547 error("Usage: AceDBObject:CopyProfile(name): 'name' - string expected.", 2) | |
| 548 end | |
| 549 | |
| 550 if name == self.keys.profile then | |
| 551 error("Cannot have the same source and destination profiles.", 2) | |
| 552 end | |
| 553 | |
| 554 if not rawget(self.profiles, name) and not silent then | |
| 555 error("Cannot copy profile '" .. name .. "'. It does not exist.", 2) | |
| 556 end | |
| 557 | |
| 558 -- Reset the profile before copying | |
| 559 DBObjectLib.ResetProfile(self, nil, true) | |
| 560 | |
| 561 local profile = self.profile | |
| 562 local source = self.profiles[name] | |
| 563 | |
| 564 copyTable(source, profile) | |
| 565 | |
| 566 -- populate to child namespaces | |
| 567 if self.children then | |
| 568 for _, db in pairs(self.children) do | |
| 569 DBObjectLib.CopyProfile(db, name, true) | |
| 570 end | |
| 571 end | |
| 572 | |
| 573 -- Callback: OnProfileCopied, database, sourceProfileKey | |
| 574 self.callbacks:Fire("OnProfileCopied", self, name) | |
| 575 end | |
| 576 | |
| 577 --- Resets the current profile to the default values (if specified). | |
| 578 -- @param noChildren if set to true, the reset will not be populated to the child namespaces of this DB object | |
| 579 -- @param noCallbacks if set to true, won't fire the OnProfileReset callback | |
| 580 function DBObjectLib:ResetProfile(noChildren, noCallbacks) | |
| 581 local profile = self.profile | |
| 582 | |
| 583 for k,v in pairs(profile) do | |
| 584 profile[k] = nil | |
| 585 end | |
| 586 | |
| 587 local defaults = self.defaults and self.defaults.profile | |
| 588 if defaults then | |
| 589 copyDefaults(profile, defaults) | |
| 590 end | |
| 591 | |
| 592 -- populate to child namespaces | |
| 593 if self.children and not noChildren then | |
| 594 for _, db in pairs(self.children) do | |
| 595 DBObjectLib.ResetProfile(db, nil, noCallbacks) | |
| 596 end | |
| 597 end | |
| 598 | |
| 599 -- Callback: OnProfileReset, database | |
| 600 if not noCallbacks then | |
| 601 self.callbacks:Fire("OnProfileReset", self) | |
| 602 end | |
| 603 end | |
| 604 | |
| 605 --- Resets the entire database, using the string defaultProfile as the new default | |
| 606 -- profile. | |
| 607 -- @param defaultProfile The profile name to use as the default | |
| 608 function DBObjectLib:ResetDB(defaultProfile) | |
| 609 if defaultProfile and type(defaultProfile) ~= "string" then | |
| 610 error("Usage: AceDBObject:ResetDB(defaultProfile): 'defaultProfile' - string or nil expected.", 2) | |
| 611 end | |
| 612 | |
| 613 local sv = self.sv | |
| 614 for k,v in pairs(sv) do | |
| 615 sv[k] = nil | |
| 616 end | |
| 617 | |
| 618 local parent = self.parent | |
| 619 | |
| 620 initdb(sv, self.defaults, defaultProfile, self) | |
| 621 | |
| 622 -- fix the child namespaces | |
| 623 if self.children then | |
| 624 if not sv.namespaces then sv.namespaces = {} end | |
| 625 for name, db in pairs(self.children) do | |
| 626 if not sv.namespaces[name] then sv.namespaces[name] = {} end | |
| 627 initdb(sv.namespaces[name], db.defaults, self.keys.profile, db, self) | |
| 628 end | |
| 629 end | |
| 630 | |
| 631 -- Callback: OnDatabaseReset, database | |
| 632 self.callbacks:Fire("OnDatabaseReset", self) | |
| 633 -- Callback: OnProfileChanged, database, profileKey | |
| 634 self.callbacks:Fire("OnProfileChanged", self, self.keys["profile"]) | |
| 635 | |
| 636 return self | |
| 637 end | |
| 638 | |
| 639 --- Creates a new database namespace, directly tied to the database. This | |
| 640 -- is a full scale database in it's own rights other than the fact that | |
| 641 -- it cannot control its profile individually | |
| 642 -- @param name The name of the new namespace | |
| 643 -- @param defaults A table of values to use as defaults | |
| 644 function DBObjectLib:RegisterNamespace(name, defaults) | |
| 645 if type(name) ~= "string" then | |
| 646 error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - string expected.", 2) | |
| 647 end | |
| 648 if defaults and type(defaults) ~= "table" then | |
| 649 error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'defaults' - table or nil expected.", 2) | |
| 650 end | |
| 651 if self.children and self.children[name] then | |
| 652 error ("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - a namespace with that name already exists.", 2) | |
| 653 end | |
| 654 | |
| 655 local sv = self.sv | |
| 656 if not sv.namespaces then sv.namespaces = {} end | |
| 657 if not sv.namespaces[name] then | |
| 658 sv.namespaces[name] = {} | |
| 659 end | |
| 660 | |
| 661 local newDB = initdb(sv.namespaces[name], defaults, self.keys.profile, nil, self) | |
| 662 | |
| 663 if not self.children then self.children = {} end | |
| 664 self.children[name] = newDB | |
| 665 return newDB | |
| 666 end | |
| 667 | |
| 668 --- Returns an already existing namespace from the database object. | |
| 669 -- @param name The name of the new namespace | |
| 670 -- @param silent if true, the addon is optional, silently return nil if its not found | |
| 671 -- @usage | |
| 672 -- local namespace = self.db:GetNamespace('namespace') | |
| 673 -- @return the namespace object if found | |
| 674 function DBObjectLib:GetNamespace(name, silent) | |
| 675 if type(name) ~= "string" then | |
| 676 error("Usage: AceDBObject:GetNamespace(name): 'name' - string expected.", 2) | |
| 677 end | |
| 678 if not silent and not (self.children and self.children[name]) then | |
| 679 error ("Usage: AceDBObject:GetNamespace(name): 'name' - namespace does not exist.", 2) | |
| 680 end | |
| 681 if not self.children then self.children = {} end | |
| 682 return self.children[name] | |
| 683 end | |
| 684 | |
| 685 --[[------------------------------------------------------------------------- | |
| 686 AceDB Exposed Methods | |
| 687 ---------------------------------------------------------------------------]] | |
| 688 | |
| 689 --- Creates a new database object that can be used to handle database settings and profiles. | |
| 690 -- By default, an empty DB is created, using a character specific profile. | |
| 691 -- | |
| 692 -- You can override the default profile used by passing any profile name as the third argument, | |
| 693 -- or by passing //true// as the third argument to use a globally shared profile called "Default". | |
| 694 -- | |
| 695 -- Note that there is no token replacement in the default profile name, passing a defaultProfile as "char" | |
| 696 -- will use a profile named "char", and not a character-specific profile. | |
| 697 -- @param tbl The name of variable, or table to use for the database | |
| 698 -- @param defaults A table of database defaults | |
| 699 -- @param defaultProfile The name of the default profile. If not set, a character specific profile will be used as the default. | |
| 700 -- You can also pass //true// to use a shared global profile called "Default". | |
| 701 -- @usage | |
| 702 -- -- Create an empty DB using a character-specific default profile. | |
| 703 -- self.db = LibStub("AceDB-3.0"):New("MyAddonDB") | |
| 704 -- @usage | |
| 705 -- -- Create a DB using defaults and using a shared default profile | |
| 706 -- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true) | |
| 707 function AceDB:New(tbl, defaults, defaultProfile) | |
| 708 if type(tbl) == "string" then | |
| 709 local name = tbl | |
| 710 tbl = _G[name] | |
| 711 if not tbl then | |
| 712 tbl = {} | |
| 713 _G[name] = tbl | |
| 714 end | |
| 715 end | |
| 716 | |
| 717 if type(tbl) ~= "table" then | |
| 718 error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'tbl' - table expected.", 2) | |
| 719 end | |
| 720 | |
| 721 if defaults and type(defaults) ~= "table" then | |
| 722 error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaults' - table expected.", 2) | |
| 723 end | |
| 724 | |
| 725 if defaultProfile and type(defaultProfile) ~= "string" and defaultProfile ~= true then | |
| 726 error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaultProfile' - string or true expected.", 2) | |
| 727 end | |
| 728 | |
| 729 return initdb(tbl, defaults, defaultProfile) | |
| 730 end | |
| 731 | |
| 732 -- upgrade existing databases | |
| 733 for db in pairs(AceDB.db_registry) do | |
| 734 if not db.parent then | |
| 735 for name,func in pairs(DBObjectLib) do | |
| 736 db[name] = func | |
| 737 end | |
| 738 else | |
| 739 db.RegisterDefaults = DBObjectLib.RegisterDefaults | |
| 740 db.ResetProfile = DBObjectLib.ResetProfile | |
| 741 end | |
| 742 end |
