annotate LibModuleDBShare-1.0/LibModuleDBShare-1.0.lua @ 27:0739db0c99ac

Created a namespace in member DBs to store group data in.
author Andrew Knoll <andrewtknoll@gmail.com>
date Sat, 16 Mar 2013 22:56:03 -0400
parents 4bc47e7b549d
children 085d93d62782
rev   line source
>@5 1 --- **LibModuleDBShare-1.0**\\
>@5 2 -- A description will eventually be here.
>@5 3 --
>@5 4 -- @usage
>@5 5 -- Also coming soon.
>@5 6 -- @class file
>@5 7 -- @name LibModuleDBShare-1.0.lua
>@3 8 local MAJOR, MINOR = "LibModuleDBShare-1.0", 1
>@3 9 local LibModuleDBShare, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
>@3 10
>@4 11 if not LibModuleDBShare then return end -- No upgrade needed
>@4 12
andrewtknoll@15 13 -- Lua APIs
andrewtknoll@26 14 local error, type, pairs, time = error, type, pairs, time;
andrewtknoll@15 15
andrewtknoll@17 16 -- Required Libraries
@12 17 local AceDB = LibStub("AceDB-3.0");
andrewtknoll@17 18 local AceDBOptions = LibStub("AceDBOptions-3.0");
andrewtknoll@17 19 local AceConfigRegistry = LibStub("AceConfigRegistry-3.0");
andrewtknoll@17 20 local AceConfigDialog = LibStub("AceConfigDialog-3.0");
@12 21
>@4 22 LibModuleDBShare.groups = LibModuleDBShare.groups or {};
>@4 23
>@5 24 local DBGroup = {};
>@5 25
>@5 26 --- Creates a new DB group.
>@5 27 -- @param groupName The name of the new DB group.
andrewtknoll@21 28 -- @param groupDescription A description of the group to be shown in the root options panel.
andrewtknoll@21 29 -- @param initialDB The first DB to add to the group.
@12 30 -- @param usesDualSpec True if this group should use LibDualSpec, false otherwise. (NYI)
>@5 31 -- @usage
>@5 32 -- local myAddonDBGroup = LibStub("LibModuleDBShare-1.0"):NewGroup("MyAddonGroupName", true)
>@5 33 -- @return the new DB group object
andrewtknoll@21 34 function LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec)
andrewtknoll@21 35 -- verify parameters
andrewtknoll@26 36 if type(groupName) ~= "string" then
andrewtknoll@26 37 error("Usage: LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): 'groupName' must be a string.", 2);
andrewtknoll@26 38 elseif type(groupDescription) ~= "string" then
andrewtknoll@26 39 error("Usage: LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): 'groupDescription' must be a string.", 2);
andrewtknoll@26 40 elseif type(LibModuleDBShare.groups[groupName]) ~= "nil" then
andrewtknoll@26 41 error("LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): group '"..groupName.."' already exists.", 2);
andrewtknoll@27 42 elseif type(initialDB) ~= "table" or not AceDB.db_registry[initialDB] then
andrewtknoll@27 43 error("LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): 'initalDB' must be an AceDB-3.0 database.", 2);
andrewtknoll@26 44 end
andrewtknoll@21 45 -- create group
@12 46 local group = {}
@12 47 group.name = groupName;
andrewtknoll@21 48 group.members = {};
andrewtknoll@21 49 -- create root option panel for group
andrewtknoll@17 50 group.rootOptionsTable = {
andrewtknoll@17 51 type = "group",
andrewtknoll@17 52 name = groupName,
andrewtknoll@17 53 args = {
andrewtknoll@17 54 text = {
andrewtknoll@17 55 type = "description",
andrewtknoll@21 56 name = groupDescription,
andrewtknoll@17 57 },
andrewtknoll@17 58 },
andrewtknoll@17 59 };
andrewtknoll@17 60 AceConfigRegistry:RegisterOptionsTable(groupName, group.rootOptionsTable);
andrewtknoll@17 61 AceConfigDialog:AddToBlizOptions(groupName);
andrewtknoll@21 62 -- create sync DB and profile options page
@12 63 group.syncDBTable = {};
andrewtknoll@21 64 group.syncDB = AceDB:New(group.syncDBTable, nil, initialDB:GetCurrentProfile());
andrewtknoll@17 65 group.profileOptionsTable = AceDBOptions:GetOptionsTable(group.syncDB, false);
andrewtknoll@17 66 AceConfigRegistry:RegisterOptionsTable(groupName.."Profiles", group.profileOptionsTable);
andrewtknoll@18 67 AceConfigDialog:AddToBlizOptions(groupName.."Profiles", group.profileOptionsTable.name, groupName);
andrewtknoll@21 68 -- add all profiles from initialDB to syncDB
andrewtknoll@21 69 for i, profile in pairs(initialDB:GetProfiles()) do
andrewtknoll@21 70 group.syncDB:SetProfile(profile);
andrewtknoll@21 71 end
andrewtknoll@21 72 group.syncDB:SetProfile(initialDB:GetCurrentProfile());
andrewtknoll@27 73 group.members[initialDB] = initialDB:GetNamespace(MAJOR, true) or initialDB:RegisterNamespace(MAJOR);
andrewtknoll@27 74 if type(group.members[initialDB].char.logoutTimestamp) == "number" then
andrewtknoll@27 75 group.profileTimestamp = group.members[initialDB].char.logoutTimestamp;
andrewtknoll@22 76 else
andrewtknoll@22 77 group.profileTimestamp = 0;
andrewtknoll@22 78 end
andrewtknoll@21 79 -- add methods and callbacks
@12 80 for k, v in pairs(DBGroup) do
@12 81 group[k] = v;
@12 82 end
andrewtknoll@19 83 group.syncDB.RegisterCallback(group, "OnProfileChanged", "OnProfileChanged");
andrewtknoll@19 84 group.syncDB.RegisterCallback(group, "OnProfileDeleted", "OnProfileDeleted");
andrewtknoll@19 85 group.syncDB.RegisterCallback(group, "OnProfileCopied", "OnProfileCopied");
andrewtknoll@19 86 group.syncDB.RegisterCallback(group, "OnProfileReset", "OnProfileReset");
andrewtknoll@23 87 initialDB.RegisterCallback(group, "OnDatabaseShutdown", "OnDatabaseShutdown");
andrewtknoll@20 88 group.squelchCallbacks = false;
andrewtknoll@19 89 LibModuleDBShare.groups[groupName] = group;
@12 90 return group;
>@4 91 end
>@4 92
>@5 93 --- Retrieves an existing DB group.
>@5 94 -- @param groupName The name of the DB group to retrieve.
>@5 95 -- @usage
>@5 96 -- local myAddonDBGroup = LibStub("LibModuleDBShare-1.0"):GetGroup("MyAddonGroupName")
>@5 97 -- @return the DB group object, or nil if not found
>@5 98 function LibModuleDBShare:GetGroup(groupName)
andrewtknoll@27 99 if type(groupName) ~= "string" then
andrewtknoll@27 100 error("Usage: LibModuleDBShare:GetGroup(groupName): 'groupName' must be a string.", 2);
andrewtknoll@27 101 end
@12 102 return LibModuleDBShare.groups[groupName];
>@4 103 end
>@5 104
>@5 105 --- Adds a database to the group.
andrewtknoll@22 106 -- @param newDB The database to add.
>@5 107 -- @usage
>@5 108 -- myAddonDBGroup:AddDB(MyAddon.db)
andrewtknoll@22 109 function DBGroup:AddDB(newDB)
andrewtknoll@22 110 -- verify parameters
andrewtknoll@26 111 if type(newDB) ~= "table" or not AceDB.db_registry[newDB] then
andrewtknoll@26 112 error("Usage: DBGroup:AddDB(newDB): 'newDB' must be a table.", 2);
andrewtknoll@26 113 elseif type(self.members[newDB]) ~= "nil" then
andrewtknoll@26 114 error("DBGroup:AddDB(newDB): 'newDB' is already a member of DBGroup.", 2);
andrewtknoll@26 115 end
andrewtknoll@22 116 -- record current profile
andrewtknoll@20 117 local syncProfile = self.syncDB:GetCurrentProfile();
andrewtknoll@22 118 -- add new profiles to syncDB
andrewtknoll@20 119 self.squelchCallbacks = true;
andrewtknoll@22 120 for i, profile in pairs(newDB:GetProfiles()) do
andrewtknoll@20 121 self.syncDB:SetProfile(profile);
andrewtknoll@20 122 end
andrewtknoll@22 123 -- set current profile based on timestamps
andrewtknoll@27 124 local namespace = newDB:GetNamespace(MAJOR, true) or newDB:RegisterNamespace(MAJOR);
andrewtknoll@27 125 if type(namespace.char.logoutTimestamp) == "number" and namespace.char.logoutTimestamp > self.profileTimestamp then
andrewtknoll@22 126 self.squelchCallbacks = false;
andrewtknoll@22 127 self.syncDB:SetProfile(newDB:GetCurrentProfile());
andrewtknoll@27 128 self.profileTimestamp = namespace.character.logoutTimestamp;
andrewtknoll@20 129 else
andrewtknoll@20 130 self.syncDB:SetProfile(syncProfile);
andrewtknoll@22 131 newDB:SetProfile(syncProfile);
andrewtknoll@22 132 self.squelchCallbacks = false;
andrewtknoll@20 133 end
andrewtknoll@22 134 -- add to members list
andrewtknoll@27 135 self.members[newDB] = namespace;
andrewtknoll@23 136 newDB.RegisterCallback(self, "OnDatabaseShutdown", "OnDatabaseShutdown");
>@5 137 end
andrewtknoll@18 138
andrewtknoll@19 139 -- callback handlers (new profiles are handled by OnProfileChanged)
andrewtknoll@19 140
andrewtknoll@24 141 function DBGroup:OnProfileChanged(callback, syncDB, profile)
andrewtknoll@24 142 if not self.squelchCallbacks then
andrewtknoll@24 143 for db, _ in pairs(self.members) do
andrewtknoll@25 144 db:SetProfile(profile);
andrewtknoll@24 145 end
andrewtknoll@24 146 end
andrewtknoll@18 147 end
andrewtknoll@18 148
andrewtknoll@24 149 function DBGroup:OnProfileDeleted(callback, syncDB, profile)
andrewtknoll@24 150 for db, _ in pairs(self.members) do
andrewtknoll@24 151 db:DeleteProfile(profile, true);
andrewtknoll@24 152 end
andrewtknoll@18 153 end
andrewtknoll@18 154
andrewtknoll@24 155 function DBGroup:OnProfileCopied(callback, syncDB, profile)
andrewtknoll@24 156 for db, _ in pairs(self.members) do
andrewtknoll@24 157 db:CopyProfile(profile, true);
andrewtknoll@24 158 end
andrewtknoll@18 159 end
andrewtknoll@18 160
andrewtknoll@24 161 function DBGroup:OnProfileReset(callback, syncDB)
andrewtknoll@24 162 for db, _ in pairs(self.members) do
andrewtknoll@24 163 db:ResetProfile(false, false);
andrewtknoll@24 164 end
andrewtknoll@18 165 end
andrewtknoll@23 166
andrewtknoll@24 167 local timestamp = nil;
andrewtknoll@24 168
andrewtknoll@23 169 function DBGroup:OnDatabaseShutdown(callback, db)
andrewtknoll@27 170 if not timestamp then -- ensure uniform timestamps to minimize
andrewtknoll@27 171 timestamp = time(); -- calls to SetProfile in NewGroup
andrewtknoll@24 172 end
andrewtknoll@27 173 self.members[db].char.logoutTimestamp = timestamp;
andrewtknoll@23 174 end