624 lines
23 KiB
Lua
624 lines
23 KiB
Lua
-- ------------------------------------------------------------------------------ --
|
|
-- TradeSkillMaster --
|
|
-- https://tradeskillmaster.com --
|
|
-- All Rights Reserved - Detailed license information included with addon. --
|
|
-- ------------------------------------------------------------------------------ --
|
|
|
|
local _, TSM = ...
|
|
local Groups = TSM:NewPackage("Groups")
|
|
local Database = TSM.Include("Util.Database")
|
|
local TempTable = TSM.Include("Util.TempTable")
|
|
local Table = TSM.Include("Util.Table")
|
|
local SmartMap = TSM.Include("Util.SmartMap")
|
|
local String = TSM.Include("Util.String")
|
|
local Log = TSM.Include("Util.Log")
|
|
local ItemString = TSM.Include("Util.ItemString")
|
|
local private = {
|
|
db = nil,
|
|
itemDB = nil,
|
|
itemStringMap = nil,
|
|
itemStringMapReader = nil,
|
|
baseItemStringItemIteratorQuery = nil,
|
|
groupListCache = {},
|
|
}
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
-- New Modules Functions
|
|
-- ============================================================================
|
|
|
|
function Groups.OnInitialize()
|
|
private.db = Database.NewSchema("GROUPS")
|
|
:AddStringField("groupPath")
|
|
:AddStringField("orderStr")
|
|
:AddBooleanField("hasAuctioningOperation")
|
|
:AddBooleanField("hasCraftingOperation")
|
|
:AddBooleanField("hasMailingOperation")
|
|
:AddBooleanField("hasShoppingOperation")
|
|
:AddBooleanField("hasSniperOperation")
|
|
:AddBooleanField("hasVendoringOperation")
|
|
:AddBooleanField("hasWarehousingOperation")
|
|
:AddIndex("groupPath")
|
|
:Commit()
|
|
private.itemDB = Database.NewSchema("GROUP_ITEMS")
|
|
:AddUniqueStringField("itemString")
|
|
:AddStringField("groupPath")
|
|
:AddSmartMapField("baseItemString", ItemString.GetBaseMap(), "itemString")
|
|
:AddIndex("groupPath")
|
|
:AddIndex("baseItemString")
|
|
:Commit()
|
|
private.itemStringMapReader = private.itemStringMap:CreateReader()
|
|
Groups.RebuildDatabase()
|
|
private.baseItemStringItemIteratorQuery = private.itemDB:NewQuery()
|
|
:Select("itemString", "groupPath")
|
|
:Equal("baseItemString", Database.BoundQueryParam())
|
|
end
|
|
|
|
function Groups.RebuildDatabase()
|
|
wipe(private.groupListCache)
|
|
|
|
-- convert ignoreRandomEnchants to ignoreItemVariations
|
|
for _, info in pairs(TSM.db.profile.userData.groups) do
|
|
if info.ignoreRandomEnchants ~= nil then
|
|
info.ignoreItemVariations = info.ignoreRandomEnchants
|
|
info.ignoreRandomEnchants = nil
|
|
end
|
|
end
|
|
|
|
for groupPath, groupInfo in pairs(TSM.db.profile.userData.groups) do
|
|
if type(groupPath) == "string" and not strmatch(groupPath, TSM.CONST.GROUP_SEP..TSM.CONST.GROUP_SEP) then
|
|
-- check the contents of groupInfo
|
|
for _, moduleName in TSM.Operations.ModuleIterator() do
|
|
groupInfo[moduleName] = groupInfo[moduleName] or {}
|
|
if groupPath == TSM.CONST.ROOT_GROUP_PATH then
|
|
-- root group should have override flag set
|
|
groupInfo[moduleName].override = true
|
|
end
|
|
end
|
|
for key in pairs(groupInfo) do
|
|
if TSM.Operations.ModuleExists(key) then
|
|
-- this is a set of module operations
|
|
local operations = groupInfo[key]
|
|
while #operations > TSM.Operations.GetMaxNumber(key) do
|
|
-- remove extra operations
|
|
tremove(operations)
|
|
end
|
|
for key2 in pairs(operations) do
|
|
if key2 == "override" then
|
|
-- ensure the override field is either true or nil
|
|
operations.override = operations.override and true or nil
|
|
elseif type(key2) ~= "number" or key2 <= 0 or key2 > #operations then
|
|
-- this is an invalid key
|
|
Log.Err("Removing invalid operations key (%s, %s): %s", groupPath, key, tostring(key2))
|
|
operations[key2] = nil
|
|
end
|
|
end
|
|
for i = #operations, 1, -1 do
|
|
if type(operations[i]) ~= "string" or operations[i] == "" or not TSM.Operations.Exists(key, operations[i]) then
|
|
-- remove operations which no longer exist
|
|
-- we used to have a bunch of placeholder "" operations, so don't log for those
|
|
if operations[i] ~= "" then
|
|
Log.Err("Removing invalid operation from group (%s): %s, %s", groupPath, key, tostring(operations[i]))
|
|
end
|
|
tremove(operations, i)
|
|
end
|
|
end
|
|
elseif key ~= "ignoreItemVariations" then
|
|
-- invalid key
|
|
Log.Err("Removing invalid groupInfo key (%s): %s", groupPath, tostring(key))
|
|
groupInfo[key] = nil
|
|
end
|
|
end
|
|
else
|
|
-- remove invalid group paths
|
|
Log.Err("Removing invalid group path: %s", tostring(groupPath))
|
|
TSM.db.profile.userData.groups[groupPath] = nil
|
|
end
|
|
end
|
|
|
|
if not TSM.db.profile.userData.groups[TSM.CONST.ROOT_GROUP_PATH] then
|
|
-- set the override flag for all top-level groups and then create it
|
|
for groupPath, moduleOperations in pairs(TSM.db.profile.userData.groups) do
|
|
if not strfind(groupPath, TSM.CONST.GROUP_SEP) then
|
|
for _, moduleName in TSM.Operations.ModuleIterator() do
|
|
moduleOperations[moduleName].override = true
|
|
end
|
|
end
|
|
end
|
|
-- create the root group manually with default operations
|
|
TSM.db.profile.userData.groups[TSM.CONST.ROOT_GROUP_PATH] = {}
|
|
for _, moduleName in TSM.Operations.ModuleIterator() do
|
|
assert(TSM.Operations.Exists(moduleName, "#Default"))
|
|
TSM.db.profile.userData.groups[TSM.CONST.ROOT_GROUP_PATH][moduleName] = { "#Default", override = true }
|
|
end
|
|
end
|
|
|
|
for _, groupPath in Groups.GroupIterator() do
|
|
local parentPath = TSM.Groups.Path.GetParent(groupPath)
|
|
if not TSM.db.profile.userData.groups[parentPath] then
|
|
-- the parent group doesn't exist, so remove this group
|
|
Log.Err("Removing group with non-existent parent: %s", tostring(groupPath))
|
|
TSM.db.profile.userData.groups[groupPath] = nil
|
|
else
|
|
for _, moduleName in TSM.Operations.ModuleIterator() do
|
|
if not Groups.HasOperationOverride(groupPath, moduleName) then
|
|
private.InheritParentOperations(groupPath, moduleName)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- fix up any invalid items
|
|
local newPaths = TempTable.Acquire()
|
|
for itemString, groupPath in pairs(TSM.db.profile.userData.items) do
|
|
local newItemString = ItemString.Get(itemString)
|
|
if not newItemString then
|
|
-- this itemstring is invalid
|
|
Log.Err("Itemstring (%s) is invalid", tostring(itemString))
|
|
TSM.db.profile.userData.items[itemString] = nil
|
|
elseif groupPath == TSM.CONST.ROOT_GROUP_PATH or not TSM.db.profile.userData.groups[groupPath] then
|
|
-- this group doesn't exist
|
|
Log.Err("Group (%s) doesn't exist, so removing item (%s)", groupPath, itemString)
|
|
TSM.db.profile.userData.items[itemString] = nil
|
|
elseif newItemString ~= itemString then
|
|
-- remove this invalid itemstring from this group
|
|
Log.Err("Itemstring changed (%s -> %s), so removing it from group (%s)", itemString, newItemString, groupPath)
|
|
TSM.db.profile.userData.items[itemString] = nil
|
|
-- add this new item to this group if it's not already in one
|
|
if not TSM.db.profile.userData.items[newItemString] then
|
|
newPaths[newItemString] = groupPath
|
|
Log.Err("Adding to group instead (%s)", groupPath)
|
|
end
|
|
end
|
|
end
|
|
for itemString, groupPath in pairs(newPaths) do
|
|
TSM.db.profile.userData.items[itemString] = groupPath
|
|
end
|
|
TempTable.Release(newPaths)
|
|
|
|
-- populate our database
|
|
private.itemDB:TruncateAndBulkInsertStart()
|
|
for itemString, groupPath in pairs(TSM.db.profile.userData.items) do
|
|
private.itemDB:BulkInsertNewRow(itemString, groupPath)
|
|
end
|
|
private.itemDB:BulkInsertEnd()
|
|
private.itemStringMap:SetCallbacksPaused(true)
|
|
for key in private.itemStringMap:Iterator() do
|
|
private.itemStringMap:ValueChanged(key)
|
|
end
|
|
private.RebuildDB()
|
|
private.itemStringMap:SetCallbacksPaused(false)
|
|
end
|
|
|
|
function Groups.TranslateItemString(itemString)
|
|
return private.itemStringMapReader[itemString]
|
|
end
|
|
|
|
function Groups.GetAutoBaseItemStringSmartMap()
|
|
return private.itemStringMap
|
|
end
|
|
|
|
function Groups.GetItemDBForJoin()
|
|
return private.itemDB
|
|
end
|
|
|
|
function Groups.CreateQuery()
|
|
return private.db:NewQuery()
|
|
:OrderBy("orderStr", true)
|
|
end
|
|
|
|
function Groups.Create(groupPath)
|
|
private.CreateGroup(groupPath)
|
|
private.RebuildDB()
|
|
end
|
|
|
|
function Groups.Move(groupPath, newGroupPath)
|
|
assert(not TSM.db.profile.userData.groups[newGroupPath], "Target group already exists")
|
|
assert(groupPath ~= TSM.CONST.ROOT_GROUP_PATH, "Can't move root group")
|
|
assert(TSM.db.profile.userData.groups[groupPath], "Group doesn't exist")
|
|
local newParentPath = TSM.Groups.Path.GetParent(newGroupPath)
|
|
assert(newParentPath and TSM.db.profile.userData.groups[newParentPath], "Parent of target is invalid")
|
|
|
|
local changes = TempTable.Acquire()
|
|
private.itemDB:SetQueryUpdatesPaused(true)
|
|
|
|
-- get a list of group path changes for this group and all its subgroups
|
|
local gsubEscapedNewGroupPath = gsub(newGroupPath, "%%", "%%%%")
|
|
for path in pairs(TSM.db.profile.userData.groups) do
|
|
if path == groupPath or TSM.Groups.Path.IsChild(path, groupPath) then
|
|
changes[path] = gsub(path, "^"..String.Escape(groupPath), gsubEscapedNewGroupPath)
|
|
end
|
|
end
|
|
|
|
for oldPath, newPath in pairs(changes) do
|
|
-- move the group
|
|
assert(TSM.db.profile.userData.groups[oldPath] and not TSM.db.profile.userData.groups[newPath])
|
|
TSM.db.profile.userData.groups[newPath] = TSM.db.profile.userData.groups[oldPath]
|
|
TSM.db.profile.userData.groups[oldPath] = nil
|
|
|
|
-- move the items
|
|
local query = private.itemDB:NewQuery()
|
|
:Equal("groupPath", oldPath)
|
|
for _, row in query:Iterator() do
|
|
local itemString = row:GetField("itemString")
|
|
assert(TSM.db.profile.userData.items[itemString])
|
|
TSM.db.profile.userData.items[itemString] = newPath
|
|
row:SetField("groupPath", newPath)
|
|
:Update()
|
|
end
|
|
query:Release()
|
|
end
|
|
|
|
-- update the operations all groups which were moved
|
|
for _, moduleName in TSM.Operations.ModuleIterator() do
|
|
if not Groups.HasOperationOverride(newGroupPath, moduleName) then
|
|
private.InheritParentOperations(newGroupPath, moduleName)
|
|
private.UpdateChildGroupOperations(newGroupPath, moduleName)
|
|
end
|
|
end
|
|
|
|
TempTable.Release(changes)
|
|
private.RebuildDB()
|
|
private.itemDB:SetQueryUpdatesPaused(false)
|
|
end
|
|
|
|
function Groups.Delete(groupPath)
|
|
assert(groupPath ~= TSM.CONST.ROOT_GROUP_PATH and TSM.db.profile.userData.groups[groupPath])
|
|
local parentPath = TSM.Groups.Path.GetParent(groupPath)
|
|
assert(parentPath)
|
|
if parentPath == TSM.CONST.ROOT_GROUP_PATH then
|
|
parentPath = nil
|
|
end
|
|
|
|
-- delete this group and all subgroups
|
|
for path in pairs(TSM.db.profile.userData.groups) do
|
|
if path == groupPath or TSM.Groups.Path.IsChild(path, groupPath) then
|
|
-- delete this group
|
|
TSM.db.profile.userData.groups[path] = nil
|
|
end
|
|
end
|
|
-- remove all items from our DB
|
|
private.itemDB:SetQueryUpdatesPaused(true)
|
|
local query = private.itemDB:NewQuery()
|
|
:Or()
|
|
:Equal("groupPath", groupPath)
|
|
:Matches("groupPath", "^"..String.Escape(groupPath)..TSM.CONST.GROUP_SEP)
|
|
:End()
|
|
local updateMapItems = TempTable.Acquire()
|
|
for _, row in query:Iterator() do
|
|
local itemString = row:GetField("itemString")
|
|
assert(TSM.db.profile.userData.items[itemString])
|
|
TSM.db.profile.userData.items[itemString] = nil
|
|
private.itemDB:DeleteRow(row)
|
|
updateMapItems[itemString] = true
|
|
end
|
|
query:Release()
|
|
private.itemStringMap:SetCallbacksPaused(true)
|
|
for itemString in private.itemStringMap:Iterator() do
|
|
if updateMapItems[itemString] or updateMapItems[ItemString.GetBaseFast(itemString)] then
|
|
-- either this item itself was removed from a group, or the base item was - in either case trigger an update
|
|
private.itemStringMap:ValueChanged(itemString)
|
|
end
|
|
end
|
|
private.itemStringMap:SetCallbacksPaused(false)
|
|
TempTable.Release(updateMapItems)
|
|
private.RebuildDB()
|
|
private.itemDB:SetQueryUpdatesPaused(false)
|
|
end
|
|
|
|
function Groups.Exists(groupPath)
|
|
return TSM.db.profile.userData.groups[groupPath] and true or false
|
|
end
|
|
|
|
function Groups.SetItemGroup(itemString, groupPath)
|
|
assert(not groupPath or (groupPath ~= TSM.CONST.ROOT_GROUP_PATH and TSM.db.profile.userData.groups[groupPath]))
|
|
|
|
local row = private.itemDB:GetUniqueRow("itemString", itemString)
|
|
local updateMap = false
|
|
if row then
|
|
if groupPath then
|
|
row:SetField("groupPath", groupPath)
|
|
:Update()
|
|
row:Release()
|
|
else
|
|
private.itemDB:DeleteRow(row)
|
|
row:Release()
|
|
-- we just removed an item from a group, so update the map
|
|
updateMap = true
|
|
end
|
|
else
|
|
assert(groupPath)
|
|
private.itemDB:NewRow()
|
|
:SetField("itemString", itemString)
|
|
:SetField("groupPath", groupPath)
|
|
:Create()
|
|
-- we just added a new item to a group, so update the map
|
|
updateMap = true
|
|
end
|
|
TSM.db.profile.userData.items[itemString] = groupPath
|
|
if updateMap then
|
|
private.itemStringMap:SetCallbacksPaused(true)
|
|
private.itemStringMap:ValueChanged(itemString)
|
|
if itemString == ItemString.GetBaseFast(itemString) then
|
|
-- this is a base item string, so need to also update all other items whose base item is equal to this item
|
|
for mapItemString in private.itemStringMap:Iterator() do
|
|
if ItemString.GetBaseFast(mapItemString) == itemString then
|
|
private.itemStringMap:ValueChanged(mapItemString)
|
|
end
|
|
end
|
|
end
|
|
private.itemStringMap:SetCallbacksPaused(false)
|
|
end
|
|
end
|
|
|
|
function Groups.BulkCreateFromImport(groupName, items, groups, groupOperations, moveExistingItems)
|
|
-- create all the groups
|
|
assert(not TSM.db.profile.userData.groups[groupName])
|
|
for relGroupPath in pairs(groups) do
|
|
local groupPath = relGroupPath == "" and groupName or TSM.Groups.Path.Join(groupName, relGroupPath)
|
|
if not TSM.db.profile.userData.groups[groupPath] then
|
|
private.CreateGroup(groupPath)
|
|
end
|
|
end
|
|
for relGroupPath, moduleOperations in pairs(groupOperations) do
|
|
local groupPath = relGroupPath == "" and groupName or TSM.Groups.Path.Join(groupName, relGroupPath)
|
|
for moduleName, operations in pairs(moduleOperations) do
|
|
if operations.override then
|
|
TSM.db.profile.userData.groups[groupPath][moduleName] = operations
|
|
private.UpdateChildGroupOperations(groupPath, moduleName)
|
|
end
|
|
end
|
|
end
|
|
local numItems = 0
|
|
for itemString, relGroupPath in pairs(items) do
|
|
if moveExistingItems or not Groups.IsItemInGroup(itemString) then
|
|
local groupPath = relGroupPath == "" and groupName or TSM.Groups.Path.Join(groupName, relGroupPath)
|
|
Groups.SetItemGroup(itemString, groupPath)
|
|
numItems = numItems + 1
|
|
end
|
|
end
|
|
private.RebuildDB()
|
|
return numItems
|
|
end
|
|
|
|
function Groups.GetPathByItem(itemString)
|
|
itemString = TSM.Groups.TranslateItemString(itemString)
|
|
assert(itemString)
|
|
local groupPath = private.itemDB:GetUniqueRowField("itemString", itemString, "groupPath") or TSM.CONST.ROOT_GROUP_PATH
|
|
assert(TSM.db.profile.userData.groups[groupPath])
|
|
return groupPath
|
|
end
|
|
|
|
function Groups.IsItemInGroup(itemString)
|
|
return private.itemDB:HasUniqueRow("itemString", itemString)
|
|
end
|
|
|
|
function Groups.ItemByBaseItemStringIterator(baseItemString)
|
|
private.baseItemStringItemIteratorQuery:BindParams(baseItemString)
|
|
return private.baseItemStringItemIteratorQuery:Iterator()
|
|
end
|
|
|
|
function Groups.ItemIterator(groupPathFilter, includeSubGroups)
|
|
assert(groupPathFilter ~= TSM.CONST.ROOT_GROUP_PATH)
|
|
local query = private.itemDB:NewQuery()
|
|
:Select("itemString", "groupPath")
|
|
if groupPathFilter then
|
|
if includeSubGroups then
|
|
query:StartsWith("groupPath", groupPathFilter)
|
|
query:Custom(private.GroupPathQueryFilter, groupPathFilter)
|
|
else
|
|
query:Equal("groupPath", groupPathFilter)
|
|
end
|
|
end
|
|
return query:IteratorAndRelease()
|
|
end
|
|
|
|
function private.GroupPathQueryFilter(row, groupPathFilter)
|
|
return row:GetField("groupPath") == groupPathFilter or strmatch(row:GetField("groupPath"), "^"..String.Escape(groupPathFilter)..TSM.CONST.GROUP_SEP)
|
|
end
|
|
|
|
function Groups.GetNumItems(groupPathFilter)
|
|
assert(groupPathFilter ~= TSM.CONST.ROOT_GROUP_PATH)
|
|
return private.itemDB:NewQuery()
|
|
:Equal("groupPath", groupPathFilter)
|
|
:CountAndRelease()
|
|
end
|
|
|
|
function Groups.GroupIterator()
|
|
if #private.groupListCache == 0 then
|
|
for groupPath in pairs(TSM.db.profile.userData.groups) do
|
|
if groupPath ~= TSM.CONST.ROOT_GROUP_PATH then
|
|
tinsert(private.groupListCache, groupPath)
|
|
end
|
|
end
|
|
Groups.SortGroupList(private.groupListCache)
|
|
end
|
|
return ipairs(private.groupListCache)
|
|
end
|
|
|
|
function Groups.SortGroupList(list)
|
|
Table.Sort(list, private.GroupSortFunction)
|
|
end
|
|
|
|
function Groups.SetOperationOverride(groupPath, moduleName, override)
|
|
assert(TSM.db.profile.userData.groups[groupPath])
|
|
assert(groupPath ~= TSM.CONST.ROOT_GROUP_PATH)
|
|
if override == (TSM.db.profile.userData.groups[groupPath][moduleName].override and true or false) then
|
|
return
|
|
end
|
|
|
|
if not override then
|
|
TSM.db.profile.userData.groups[groupPath][moduleName].override = nil
|
|
private.InheritParentOperations(groupPath, moduleName)
|
|
private.UpdateChildGroupOperations(groupPath, moduleName)
|
|
else
|
|
wipe(TSM.db.profile.userData.groups[groupPath][moduleName])
|
|
TSM.db.profile.userData.groups[groupPath][moduleName].override = true
|
|
private.UpdateChildGroupOperations(groupPath, moduleName)
|
|
end
|
|
private.RebuildDB()
|
|
end
|
|
|
|
function Groups.HasOperationOverride(groupPath, moduleName)
|
|
return TSM.db.profile.userData.groups[groupPath][moduleName].override
|
|
end
|
|
|
|
function Groups.OperationIterator(groupPath, moduleName)
|
|
return ipairs(TSM.db.profile.userData.groups[groupPath][moduleName])
|
|
end
|
|
|
|
function Groups.AppendOperation(groupPath, moduleName, operationName)
|
|
assert(TSM.Operations.Exists(moduleName, operationName))
|
|
local groupOperations = TSM.db.profile.userData.groups[groupPath][moduleName]
|
|
assert(groupOperations.override and #groupOperations < TSM.Operations.GetMaxNumber(moduleName))
|
|
tinsert(groupOperations, operationName)
|
|
private.UpdateChildGroupOperations(groupPath, moduleName)
|
|
private.RebuildDB()
|
|
end
|
|
|
|
function Groups.RemoveOperation(groupPath, moduleName, operationIndex)
|
|
local groupOperations = TSM.db.profile.userData.groups[groupPath][moduleName]
|
|
assert(groupOperations.override and groupOperations[operationIndex])
|
|
tremove(groupOperations, operationIndex)
|
|
private.UpdateChildGroupOperations(groupPath, moduleName)
|
|
private.RebuildDB()
|
|
end
|
|
|
|
function Groups.RemoveOperationByName(groupPath, moduleName, operationName)
|
|
local groupOperations = TSM.db.profile.userData.groups[groupPath][moduleName]
|
|
assert(groupOperations.override)
|
|
assert(Table.RemoveByValue(groupOperations, operationName) > 0)
|
|
private.UpdateChildGroupOperations(groupPath, moduleName)
|
|
private.RebuildDB()
|
|
end
|
|
|
|
function Groups.RemoveOperationFromAllGroups(moduleName, operationName)
|
|
-- just blindly remove from all groups - no need to check for override
|
|
Table.RemoveByValue(TSM.db.profile.userData.groups[TSM.CONST.ROOT_GROUP_PATH][moduleName], operationName)
|
|
for _, groupPath in Groups.GroupIterator() do
|
|
Table.RemoveByValue(TSM.db.profile.userData.groups[groupPath][moduleName], operationName)
|
|
end
|
|
private.RebuildDB()
|
|
end
|
|
|
|
function Groups.SwapOperation(groupPath, moduleName, fromIndex, toIndex)
|
|
local groupOperations = TSM.db.profile.userData.groups[groupPath][moduleName]
|
|
groupOperations[fromIndex], groupOperations[toIndex] = groupOperations[toIndex], groupOperations[fromIndex]
|
|
private.UpdateChildGroupOperations(groupPath, moduleName)
|
|
end
|
|
|
|
function Groups.OperationRenamed(moduleName, oldName, newName)
|
|
-- just blindly rename in all groups - no need to check for override
|
|
for _, info in pairs(TSM.db.profile.userData.groups) do
|
|
for i = 1, #info[moduleName] do
|
|
if info[moduleName][i] == oldName then
|
|
info[moduleName][i] = newName
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
-- Private Helper Functions
|
|
-- ============================================================================
|
|
|
|
function private.RebuildDB()
|
|
private.db:TruncateAndBulkInsertStart()
|
|
for groupPath in pairs(TSM.db.profile.userData.groups) do
|
|
local orderStr = gsub(groupPath, TSM.CONST.GROUP_SEP, "\001")
|
|
orderStr = strlower(orderStr)
|
|
local hasAuctioningOperation = false
|
|
for _ in TSM.Operations.GroupOperationIterator("Auctioning", groupPath) do
|
|
hasAuctioningOperation = true
|
|
end
|
|
local hasCraftingOperation = false
|
|
for _ in TSM.Operations.GroupOperationIterator("Crafting", groupPath) do
|
|
hasCraftingOperation = true
|
|
end
|
|
local hasMailingOperation = false
|
|
for _ in TSM.Operations.GroupOperationIterator("Mailing", groupPath) do
|
|
hasMailingOperation = true
|
|
end
|
|
local hasShoppingOperation = false
|
|
for _ in TSM.Operations.GroupOperationIterator("Shopping", groupPath) do
|
|
hasShoppingOperation = true
|
|
end
|
|
local hasSniperOperation = false
|
|
for _ in TSM.Operations.GroupOperationIterator("Sniper", groupPath) do
|
|
hasSniperOperation = true
|
|
end
|
|
local hasVendoringOperation = false
|
|
for _ in TSM.Operations.GroupOperationIterator("Vendoring", groupPath) do
|
|
hasVendoringOperation = true
|
|
end
|
|
local hasWarehousingOperation = false
|
|
for _ in TSM.Operations.GroupOperationIterator("Warehousing", groupPath) do
|
|
hasWarehousingOperation = true
|
|
end
|
|
private.db:BulkInsertNewRow(groupPath, orderStr, hasAuctioningOperation, hasCraftingOperation, hasMailingOperation, hasShoppingOperation, hasSniperOperation, hasVendoringOperation, hasWarehousingOperation)
|
|
end
|
|
private.db:BulkInsertEnd()
|
|
wipe(private.groupListCache)
|
|
end
|
|
|
|
function private.CreateGroup(groupPath)
|
|
assert(not TSM.db.profile.userData.groups[groupPath])
|
|
local parentPath = TSM.Groups.Path.GetParent(groupPath)
|
|
assert(parentPath)
|
|
if parentPath ~= TSM.CONST.ROOT_GROUP_PATH and not TSM.db.profile.userData.groups[parentPath] then
|
|
-- recursively create the parent group first
|
|
private.CreateGroup(parentPath)
|
|
end
|
|
TSM.db.profile.userData.groups[groupPath] = {}
|
|
for _, moduleName in TSM.Operations.ModuleIterator() do
|
|
TSM.db.profile.userData.groups[groupPath][moduleName] = {}
|
|
-- assign all parent operations to this group
|
|
for _, operationName in ipairs(TSM.db.profile.userData.groups[parentPath][moduleName]) do
|
|
tinsert(TSM.db.profile.userData.groups[groupPath][moduleName], operationName)
|
|
end
|
|
end
|
|
end
|
|
|
|
function private.GroupSortFunction(a, b)
|
|
return strlower(gsub(a, TSM.CONST.GROUP_SEP, "\001")) < strlower(gsub(b, TSM.CONST.GROUP_SEP, "\001"))
|
|
end
|
|
|
|
function private.InheritParentOperations(groupPath, moduleName)
|
|
local parentGroupPath = TSM.Groups.Path.GetParent(groupPath)
|
|
local override = TSM.db.profile.userData.groups[groupPath][moduleName].override
|
|
wipe(TSM.db.profile.userData.groups[groupPath][moduleName])
|
|
TSM.db.profile.userData.groups[groupPath][moduleName].override = override
|
|
for _, operationName in ipairs(TSM.db.profile.userData.groups[parentGroupPath][moduleName]) do
|
|
tinsert(TSM.db.profile.userData.groups[groupPath][moduleName], operationName)
|
|
end
|
|
end
|
|
|
|
function private.UpdateChildGroupOperations(groupPath, moduleName)
|
|
for _, childGroupPath in Groups.GroupIterator() do
|
|
if TSM.Groups.Path.IsChild(childGroupPath, groupPath) and not Groups.HasOperationOverride(childGroupPath, moduleName) then
|
|
private.InheritParentOperations(childGroupPath, moduleName)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
-- Item String Smart Map
|
|
-- ============================================================================
|
|
|
|
do
|
|
private.itemStringMap = SmartMap.New("string", "string", function(itemString)
|
|
if Groups.IsItemInGroup(itemString) then
|
|
-- this item is in a group, so just return it
|
|
return itemString
|
|
end
|
|
local baseItemString = ItemString.GetBaseFast(itemString)
|
|
-- return the base item if it's in a group; otherwise return the original item
|
|
return Groups.IsItemInGroup(baseItemString) and baseItemString or itemString
|
|
end)
|
|
end
|