WoWInterface SVN NeedyGreedy

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /trunk/libs/AceDB-3.0
    from Rev 2 to Rev 126
    Reverse comparison

Rev 2 → Rev 126

AceDB-3.0.lua
20,6 → 20,9
-- the profile related APIs are not available. Only `:RegisterDefaults` and `:ResetProfile` are available on child-databases.
--
-- For more details on how to use AceDB-3.0, see the [[AceDB-3.0 Tutorial]].
--
-- You may also be interested in [[libdualspec-1-0|LibDualSpec-1.0]] to do profile switching automatically when switching specs.
--
-- @usage
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("DBExample")
--
36,17 → 39,23
-- end
-- @class file
-- @name AceDB-3.0.lua
-- @release $Id: AceDB-3.0.lua 799 2009-04-09 05:00:05Z kaelten $
local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 13
-- @release $Id: AceDB-3.0.lua 940 2010-06-19 08:01:47Z nevcairiel $
local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 21
local AceDB, oldminor = LibStub:NewLibrary(ACEDB_MAJOR, ACEDB_MINOR)
 
if not AceDB then return end -- No upgrade needed
 
local type = type
local pairs, next = pairs, next
local rawget, rawset = rawget, rawset
local setmetatable = setmetatable
-- Lua APIs
local type, pairs, next, error = type, pairs, next, error
local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget
 
-- WoW APIs
local _G = _G
 
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: LibStub
 
AceDB.db_registry = AceDB.db_registry or {}
AceDB.frame = AceDB.frame or CreateFrame("Frame")
 
126,6 → 135,9
 
-- Called to remove all defaults in the default table from the database
local function removeDefaults(db, defaults, blocker)
-- remove all metatables from the db, so we don't accidentally create new sub-tables through them
setmetatable(db, nil)
-- loop through the defaults and remove their content
for k,v in pairs(defaults) do
if k == "*" or k == "**" then
if type(v) == "table" then
140,7 → 152,7
db[key] = nil
end
-- if it was specified, only strip ** content, but block values which were set in the key table
elseif k == "**" then
elseif k == "**" then
removeDefaults(value, v, defaults[key])
end
end
166,28 → 178,26
end
end
end
-- remove all metatables from the db
setmetatable(db, nil)
end
 
-- This is called when a table section is first accessed, to set up the defaults
local function initSection(db, section, svstore, key, defaults)
local sv = rawget(db, "sv")
 
 
local tableCreated
if not sv[svstore] then sv[svstore] = {} end
if not sv[svstore][key] then
sv[svstore][key] = {}
tableCreated = true
end
 
 
local tbl = sv[svstore][key]
 
 
if defaults then
copyDefaults(tbl, defaults)
end
rawset(db, section, tbl)
 
 
return tableCreated, tbl
end
 
199,7 → 209,7
if key then
local defaultTbl = rawget(t, "defaults")
local defaults = defaultTbl and defaultTbl[section]
 
 
if section == "profile" then
local new = initSection(t, section, "profiles", key, defaults)
if new then
221,7 → 231,7
initSection(t, section, section, key, defaults)
end
end
 
 
return rawget(t, section)
end
}
253,18 → 263,29
-- Actual database initialization function
local function initdb(sv, defaults, defaultProfile, olddb, parent)
-- Generate the database keys for each section
 
-- Make a container for profile keys
if not sv.profileKeys then sv.profileKeys = {} end
 
 
-- map "true" to our "Default" profile
if defaultProfile == true then defaultProfile = "Default" end
 
-- Try to get the profile selected from the char db
local profileKey = sv.profileKeys[charKey] or defaultProfile or charKey
sv.profileKeys[charKey] = profileKey
 
-- This table contains keys that enable the dynamic creation
 
local profileKey
if not parent then
-- Make a container for profile keys
if not sv.profileKeys then sv.profileKeys = {} end
 
-- Try to get the profile selected from the char db
profileKey = sv.profileKeys[charKey] or defaultProfile or charKey
 
-- save the selected profile for later
sv.profileKeys[charKey] = profileKey
else
-- Use the profile of the parents DB
profileKey = parent.keys.profile or defaultProfile or charKey
 
-- clear the profileKeys in the DB, namespaces don't need to store them
sv.profileKeys = nil
end
 
-- This table contains keys that enable the dynamic creation
-- of each section of the table. The 'global' and 'profiles'
-- have a key of true, since they are handled in a special case
local keyTbl= {
278,27 → 299,27
["global"] = true,
["profiles"] = true,
}
 
 
validateDefaults(defaults, keyTbl, 1)
 
 
-- This allows us to use this function to reset an entire database
-- Clear out the old database
if olddb then
for k,v in pairs(olddb) do if not preserve_keys[k] then olddb[k] = nil end end
end
 
 
-- Give this database the metatable so it initializes dynamically
local db = setmetatable(olddb or {}, dbmt)
 
if not rawget(db, "callbacks") then
 
if not rawget(db, "callbacks") then
-- try to load CallbackHandler-1.0 if it loaded after our library
if not CallbackHandler then CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0", true) end
db.callbacks = CallbackHandler and CallbackHandler:New(db) or CallbackDummy
end
 
 
-- Copy methods locally into the database object, to avoid hitting
-- the metatable when calling methods
 
 
if not parent then
for name, func in pairs(DBObjectLib) do
db[name] = func
308,7 → 329,7
db.RegisterDefaults = DBObjectLib.RegisterDefaults
db.ResetProfile = DBObjectLib.ResetProfile
end
 
 
-- Set some properties in the database object
db.profiles = sv.profiles
db.keys = keyTbl
316,22 → 337,38
--db.sv_name = name
db.defaults = defaults
db.parent = parent
 
 
-- store the DB in the registry
AceDB.db_registry[db] = true
 
 
return db
end
 
-- handle PLAYER_LOGOUT
-- strip all defaults from all databases
-- and cleans up empty sections
local function logoutHandler(frame, event)
if event == "PLAYER_LOGOUT" then
for db in pairs(AceDB.db_registry) do
db.callbacks:Fire("OnDatabaseShutdown", db)
for section, key in pairs(db.keys) do
if db.defaults and db.defaults[section] and rawget(db, section) then
removeDefaults(db[section], db.defaults[section])
db:RegisterDefaults(nil)
 
-- cleanup sections that are empty without defaults
local sv = rawget(db, "sv")
for section in pairs(db.keys) do
if rawget(sv, section) then
-- global is special, all other sections have sub-entrys
-- also don't delete empty profiles on main dbs, only on namespaces
if section ~= "global" and (section ~= "profiles" or rawget(db, "parent")) then
for key in pairs(sv[section]) do
if not next(sv[section][key]) then
sv[section][key] = nil
end
end
end
if not next(sv[section]) then
sv[section] = nil
end
end
end
end
353,9 → 390,9
if defaults and type(defaults) ~= "table" then
error("Usage: AceDBObject:RegisterDefaults(defaults): 'defaults' - table or nil expected.", 2)
end
 
 
validateDefaults(defaults, self.keys)
 
 
-- Remove any currently set defaults
if self.defaults then
for section,key in pairs(self.keys) do
364,10 → 401,10
end
end
end
 
 
-- Set the DBObject.defaults table
self.defaults = defaults
 
 
-- Copy in any defaults, only touching those sections already created
if defaults then
for section,key in pairs(self.keys) do
385,32 → 422,37
if type(name) ~= "string" then
error("Usage: AceDBObject:SetProfile(name): 'name' - string expected.", 2)
end
 
 
-- changing to the same profile, dont do anything
if name == self.keys.profile then return end
 
 
local oldProfile = self.profile
local defaults = self.defaults and self.defaults.profile
 
 
-- Callback: OnProfileShutdown, database
self.callbacks:Fire("OnProfileShutdown", self)
 
 
if oldProfile and defaults then
-- Remove the defaults from the old profile
removeDefaults(oldProfile, defaults)
end
 
 
self.profile = nil
self.keys["profile"] = name
self.sv.profileKeys[charKey] = name
 
-- if the storage exists, save the new profile
-- this won't exist on namespaces.
if self.sv.profileKeys then
self.sv.profileKeys[charKey] = name
end
 
-- populate to child namespaces
if self.children then
for _, db in pairs(self.children) do
DBObjectLib.SetProfile(db, name)
end
end
 
 
-- Callback: OnProfileChanged, database, newProfileKey
self.callbacks:Fire("OnProfileChanged", self, name)
end
431,7 → 473,7
end
 
local curProfile = self.keys.profile
 
 
local i = 0
for profileKey in pairs(self.profiles) do
i = i + 1
444,7 → 486,7
i = i + 1
tbl[i] = curProfile
end
 
 
return tbl, i
end
 
460,24 → 502,24
if type(name) ~= "string" then
error("Usage: AceDBObject:DeleteProfile(name): 'name' - string expected.", 2)
end
 
 
if self.keys.profile == name then
error("Cannot delete the active profile in an AceDBObject.", 2)
end
 
if not rawget(self.sv.profiles, name) and not silent then
 
if not rawget(self.profiles, name) and not silent then
error("Cannot delete profile '" .. name .. "'. It does not exist.", 2)
end
 
self.sv.profiles[name] = nil
 
 
self.profiles[name] = nil
 
-- populate to child namespaces
if self.children then
for _, db in pairs(self.children) do
DBObjectLib.DeleteProfile(db, name, true)
end
end
 
 
-- Callback: OnProfileDeleted, database, profileKey
self.callbacks:Fire("OnProfileDeleted", self, name)
end
490,57 → 532,60
if type(name) ~= "string" then
error("Usage: AceDBObject:CopyProfile(name): 'name' - string expected.", 2)
end
 
 
if name == self.keys.profile then
error("Cannot have the same source and destination profiles.", 2)
end
 
if not rawget(self.sv.profiles, name) and not silent then
 
if not rawget(self.profiles, name) and not silent then
error("Cannot copy profile '" .. name .. "'. It does not exist.", 2)
end
 
 
-- Reset the profile before copying
DBObjectLib.ResetProfile(self)
 
DBObjectLib.ResetProfile(self, nil, true)
 
local profile = self.profile
local source = self.sv.profiles[name]
 
local source = self.profiles[name]
 
copyTable(source, profile)
 
 
-- populate to child namespaces
if self.children then
for _, db in pairs(self.children) do
DBObjectLib.CopyProfile(db, name, true)
end
end
 
 
-- Callback: OnProfileCopied, database, sourceProfileKey
self.callbacks:Fire("OnProfileCopied", self, name)
end
 
--- Resets the current profile to the default values (if specified).
-- @param noChildren if set to true, the reset will not be populated to the child namespaces of this DB object
function DBObjectLib:ResetProfile(noChildren)
-- @param noCallbacks if set to true, won't fire the OnProfileReset callback
function DBObjectLib:ResetProfile(noChildren, noCallbacks)
local profile = self.profile
 
 
for k,v in pairs(profile) do
profile[k] = nil
end
 
 
local defaults = self.defaults and self.defaults.profile
if defaults then
copyDefaults(profile, defaults)
end
 
 
-- populate to child namespaces
if self.children and not noChildren then
for _, db in pairs(self.children) do
DBObjectLib.ResetProfile(db)
DBObjectLib.ResetProfile(db, nil, noCallbacks)
end
end
 
 
-- Callback: OnProfileReset, database
self.callbacks:Fire("OnProfileReset", self)
if not noCallbacks then
self.callbacks:Fire("OnProfileReset", self)
end
end
 
--- Resets the entire database, using the string defaultProfile as the new default
550,16 → 595,16
if defaultProfile and type(defaultProfile) ~= "string" then
error("Usage: AceDBObject:ResetDB(defaultProfile): 'defaultProfile' - string or nil expected.", 2)
end
 
 
local sv = self.sv
for k,v in pairs(sv) do
sv[k] = nil
end
 
 
local parent = self.parent
 
 
initdb(sv, self.defaults, defaultProfile, self)
 
 
-- fix the child namespaces
if self.children then
if not sv.namespaces then sv.namespaces = {} end
568,12 → 613,12
initdb(sv.namespaces[name], db.defaults, self.keys.profile, db, self)
end
end
 
-- Callback: OnDatabaseReset, database
 
-- Callback: OnDatabaseReset, database
self.callbacks:Fire("OnDatabaseReset", self)
-- Callback: OnProfileChanged, database, profileKey
self.callbacks:Fire("OnProfileChanged", self, self.keys["profile"])
 
 
return self
end
 
592,15 → 637,15
if self.children and self.children[name] then
error ("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - a namespace with that name already exists.", 2)
end
 
 
local sv = self.sv
if not sv.namespaces then sv.namespaces = {} end
if not sv.namespaces[name] then
sv.namespaces[name] = {}
end
 
 
local newDB = initdb(sv.namespaces[name], defaults, self.keys.profile, nil, self)
 
 
if not self.children then self.children = {} end
self.children[name] = newDB
return newDB
608,7 → 653,7
 
--- Returns an already existing namespace from the database object.
-- @param name The name of the new namespace
-- @param silent if true, the addon is optional, silently return nil if its not found
-- @param silent if true, the addon is optional, silently return nil if its not found
-- @usage
-- local namespace = self.db:GetNamespace('namespace')
-- @return the namespace object if found
648,25 → 693,25
function AceDB:New(tbl, defaults, defaultProfile)
if type(tbl) == "string" then
local name = tbl
tbl = getglobal(name)
tbl = _G[name]
if not tbl then
tbl = {}
setglobal(name, tbl)
_G[name] = tbl
end
end
 
 
if type(tbl) ~= "table" then
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'tbl' - table expected.", 2)
end
 
 
if defaults and type(defaults) ~= "table" then
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaults' - table expected.", 2)
end
 
 
if defaultProfile and type(defaultProfile) ~= "string" and defaultProfile ~= true then
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaultProfile' - string or true expected.", 2)
end
 
 
return initdb(tbl, defaults, defaultProfile)
end