fix: make learner db reads self-sustaining
This commit is contained in:
+79
-10
@@ -214,6 +214,25 @@ function QuestieDB:IsBaseDatabaseMissing()
|
|||||||
return QuestieDB.baseDatabaseMissing == true
|
return QuestieDB.baseDatabaseMissing == true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function _GetLearnerSettings()
|
||||||
|
local ld = Questie and Questie.dbLearner and Questie.dbLearner.global
|
||||||
|
return ld and ld.settings or nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _GetLearnerRecord(storeName, id)
|
||||||
|
local ld = Questie and Questie.dbLearner and Questie.dbLearner.global
|
||||||
|
if not ld then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local store = ld[storeName]
|
||||||
|
if not store then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return store[id] or store[tostring(id)]
|
||||||
|
end
|
||||||
|
|
||||||
---@type QuestieQuest
|
---@type QuestieQuest
|
||||||
local QuestieQuest = QuestieLoader:ImportModule("QuestieQuest")
|
local QuestieQuest = QuestieLoader:ImportModule("QuestieQuest")
|
||||||
---@type QuestieQuestPrivate
|
---@type QuestieQuestPrivate
|
||||||
@@ -542,11 +561,22 @@ function QuestieDB:GetObject(objectId)
|
|||||||
return _QuestieDB.objectCache[objectId];
|
return _QuestieDB.objectCache[objectId];
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Try to get from compiled DB first
|
local settings = _GetLearnerSettings()
|
||||||
local rawdata = QuestieDB.QueryObject(objectId, QuestieDB._objectAdapterQueryOrder)
|
local mode = settings and settings.dataSourceMode or "auto"
|
||||||
|
local learnerRecord = _GetLearnerRecord("objects", objectId)
|
||||||
|
|
||||||
-- Check for overrides
|
local rawdata
|
||||||
local override = QuestieDB.objectDataOverrides and (QuestieDB.objectDataOverrides[objectId] or QuestieDB.objectDataOverrides[tostring(objectId)])
|
local override
|
||||||
|
if mode == "learner" or QuestieDB:IsBaseDatabaseMissing() then
|
||||||
|
rawdata = learnerRecord
|
||||||
|
override = nil
|
||||||
|
else
|
||||||
|
rawdata = QuestieDB.QueryObject(objectId, QuestieDB._objectAdapterQueryOrder)
|
||||||
|
if not rawdata and learnerRecord then
|
||||||
|
rawdata = learnerRecord
|
||||||
|
end
|
||||||
|
override = QuestieDB.objectDataOverrides and (QuestieDB.objectDataOverrides[objectId] or QuestieDB.objectDataOverrides[tostring(objectId)])
|
||||||
|
end
|
||||||
|
|
||||||
if not rawdata and not override then
|
if not rawdata and not override then
|
||||||
Questie:Debug(Questie.DEBUG_CRITICAL, "[QuestieDB:GetObject] data not found for objectID:", objectId)
|
Questie:Debug(Questie.DEBUG_CRITICAL, "[QuestieDB:GetObject] data not found for objectID:", objectId)
|
||||||
@@ -588,8 +618,21 @@ function QuestieDB:GetItem(itemId)
|
|||||||
return _QuestieDB.itemCache[itemId];
|
return _QuestieDB.itemCache[itemId];
|
||||||
end
|
end
|
||||||
|
|
||||||
local rawdata = QuestieDB.QueryItem(itemId, QuestieDB._itemAdapterQueryOrder)
|
local settings = _GetLearnerSettings()
|
||||||
local override = QuestieDB.itemDataOverrides and (QuestieDB.itemDataOverrides[itemId] or QuestieDB.itemDataOverrides[tostring(itemId)])
|
local mode = settings and settings.dataSourceMode or "auto"
|
||||||
|
local learnerRecord = _GetLearnerRecord("items", itemId)
|
||||||
|
local rawdata
|
||||||
|
local override
|
||||||
|
if mode == "learner" or QuestieDB:IsBaseDatabaseMissing() then
|
||||||
|
rawdata = learnerRecord
|
||||||
|
override = nil
|
||||||
|
else
|
||||||
|
rawdata = QuestieDB.QueryItem(itemId, QuestieDB._itemAdapterQueryOrder)
|
||||||
|
if not rawdata and learnerRecord then
|
||||||
|
rawdata = learnerRecord
|
||||||
|
end
|
||||||
|
override = QuestieDB.itemDataOverrides and (QuestieDB.itemDataOverrides[itemId] or QuestieDB.itemDataOverrides[tostring(itemId)])
|
||||||
|
end
|
||||||
|
|
||||||
if not rawdata and not override then
|
if not rawdata and not override then
|
||||||
Questie:Debug(Questie.DEBUG_CRITICAL, "[QuestieDB:GetItem] data not found for itemID:", itemId)
|
Questie:Debug(Questie.DEBUG_CRITICAL, "[QuestieDB:GetItem] data not found for itemID:", itemId)
|
||||||
@@ -1457,8 +1500,21 @@ function QuestieDB.GetQuest(questId, ...) -- /dump QuestieDB.GetQuest(867)
|
|||||||
return _QuestieDB.questCache[questId];
|
return _QuestieDB.questCache[questId];
|
||||||
end
|
end
|
||||||
|
|
||||||
local rawdata = QuestieDB.QueryQuest(questId, QuestieDB._questAdapterQueryOrder)
|
local settings = _GetLearnerSettings()
|
||||||
local overrideData = QuestieDB.questDataOverrides and (QuestieDB.questDataOverrides[questId] or QuestieDB.questDataOverrides[tostring(questId)])
|
local mode = settings and settings.dataSourceMode or "auto"
|
||||||
|
local learnerRecord = _GetLearnerRecord("quests", questId)
|
||||||
|
local rawdata
|
||||||
|
local overrideData
|
||||||
|
if mode == "learner" or QuestieDB:IsBaseDatabaseMissing() then
|
||||||
|
rawdata = learnerRecord
|
||||||
|
overrideData = nil
|
||||||
|
else
|
||||||
|
rawdata = QuestieDB.QueryQuest(questId, QuestieDB._questAdapterQueryOrder)
|
||||||
|
if not rawdata and learnerRecord then
|
||||||
|
rawdata = learnerRecord
|
||||||
|
end
|
||||||
|
overrideData = QuestieDB.questDataOverrides and (QuestieDB.questDataOverrides[questId] or QuestieDB.questDataOverrides[tostring(questId)])
|
||||||
|
end
|
||||||
|
|
||||||
if (not rawdata) then
|
if (not rawdata) then
|
||||||
rawdata = overrideData
|
rawdata = overrideData
|
||||||
@@ -2057,8 +2113,21 @@ function QuestieDB:GetNPC(npcId)
|
|||||||
return _QuestieDB.npcCache[npcId]
|
return _QuestieDB.npcCache[npcId]
|
||||||
end
|
end
|
||||||
|
|
||||||
local rawdata = QuestieDB.QueryNPC(npcId, QuestieDB._npcAdapterQueryOrder)
|
local settings = _GetLearnerSettings()
|
||||||
local override = QuestieDB.npcDataOverrides and (QuestieDB.npcDataOverrides[npcId] or QuestieDB.npcDataOverrides[tostring(npcId)])
|
local mode = settings and settings.dataSourceMode or "auto"
|
||||||
|
local learnerRecord = _GetLearnerRecord("npcs", npcId)
|
||||||
|
local rawdata
|
||||||
|
local override
|
||||||
|
if mode == "learner" or QuestieDB:IsBaseDatabaseMissing() then
|
||||||
|
rawdata = learnerRecord
|
||||||
|
override = nil
|
||||||
|
else
|
||||||
|
rawdata = QuestieDB.QueryNPC(npcId, QuestieDB._npcAdapterQueryOrder)
|
||||||
|
if not rawdata and learnerRecord then
|
||||||
|
rawdata = learnerRecord
|
||||||
|
end
|
||||||
|
override = QuestieDB.npcDataOverrides and (QuestieDB.npcDataOverrides[npcId] or QuestieDB.npcDataOverrides[tostring(npcId)])
|
||||||
|
end
|
||||||
|
|
||||||
if not rawdata and not override then
|
if not rawdata and not override then
|
||||||
Questie:Debug(Questie.DEBUG_CRITICAL, "[QuestieDB:GetNPC] data not found for npcID:", npcId)
|
Questie:Debug(Questie.DEBUG_CRITICAL, "[QuestieDB:GetNPC] data not found for npcID:", npcId)
|
||||||
|
|||||||
@@ -148,17 +148,8 @@ monster = function(npcId, objective)
|
|||||||
and Questie.dbLearner.global
|
and Questie.dbLearner.global
|
||||||
and Questie.dbLearner.global.settings
|
and Questie.dbLearner.global.settings
|
||||||
and Questie.dbLearner.global.settings.dataSourceMode or "auto"
|
and Questie.dbLearner.global.settings.dataSourceMode or "auto"
|
||||||
local strictLearnerOnly = dataSourceMode == "learner"
|
local npcData = QuestieDB:GetNPC(npcId)
|
||||||
|
local name = npcData and npcData.name or nil
|
||||||
local name = strictLearnerOnly and nil or QuestieDB.QueryNPCSingle(npcId, "name")
|
|
||||||
if not name or name == "" then
|
|
||||||
if strictLearnerOnly then
|
|
||||||
local learnedNpc = Questie.dbLearner and Questie.dbLearner.global
|
|
||||||
and Questie.dbLearner.global.npcs
|
|
||||||
and Questie.dbLearner.global.npcs[npcId]
|
|
||||||
name = learnedNpc and learnedNpc[1] or nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not name or name == "" then
|
if not name or name == "" then
|
||||||
-- Last resort: extract NPC name from objective description text.
|
-- Last resort: extract NPC name from objective description text.
|
||||||
-- This mirrors the name-parsing logic in the killcredit function and
|
-- This mirrors the name-parsing logic in the killcredit function and
|
||||||
@@ -182,7 +173,7 @@ monster = function(npcId, objective)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local spawns = strictLearnerOnly and {} or QuestieDB.QueryNPCSingle(npcId, "spawns")
|
local spawns = npcData and npcData.spawns or {}
|
||||||
if (not spawns) then
|
if (not spawns) then
|
||||||
Questie:Debug(Questie.DEBUG_CRITICAL, "Spawn data missing for NPC:", npcId)
|
Questie:Debug(Questie.DEBUG_CRITICAL, "Spawn data missing for NPC:", npcId)
|
||||||
spawns = {}
|
spawns = {}
|
||||||
@@ -229,7 +220,7 @@ monster = function(npcId, objective)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local rank = QuestieDB.QueryNPCSingle(npcId, "rank")
|
local rank = npcData and npcData.rank
|
||||||
|
|
||||||
local enableSpawns = not QuestieCorrections.questNPCBlacklist[npcId]
|
local enableSpawns = not QuestieCorrections.questNPCBlacklist[npcId]
|
||||||
local enableWaypoints = enableSpawns and 2 ~= rank -- a rare mob spawn. todo: option for this
|
local enableWaypoints = enableSpawns and 2 ~= rank -- a rare mob spawn. todo: option for this
|
||||||
@@ -239,7 +230,7 @@ monster = function(npcId, objective)
|
|||||||
Id = npcId,
|
Id = npcId,
|
||||||
Name = name,
|
Name = name,
|
||||||
Spawns = enableSpawns and spawns or {},
|
Spawns = enableSpawns and spawns or {},
|
||||||
Waypoints = enableWaypoints and QuestieDB.QueryNPCSingle(npcId, "waypoints") or {},
|
Waypoints = enableWaypoints and (npcData and npcData.waypoints or {}) or {},
|
||||||
Hostile = true,
|
Hostile = true,
|
||||||
Icon = Questie.ICON_TYPE_SLAY,
|
Icon = Questie.ICON_TYPE_SLAY,
|
||||||
GetIconScale = _GetIconScaleForMonster,
|
GetIconScale = _GetIconScaleForMonster,
|
||||||
@@ -271,23 +262,14 @@ object = function(objectId, objective)
|
|||||||
and Questie.dbLearner.global
|
and Questie.dbLearner.global
|
||||||
and Questie.dbLearner.global.settings
|
and Questie.dbLearner.global.settings
|
||||||
and Questie.dbLearner.global.settings.dataSourceMode or "auto"
|
and Questie.dbLearner.global.settings.dataSourceMode or "auto"
|
||||||
local strictLearnerOnly = dataSourceMode == "learner"
|
local objectData = QuestieDB:GetObject(objectId)
|
||||||
|
local name = objectData and objectData.name or nil
|
||||||
local name = strictLearnerOnly and nil or QuestieDB.QueryObjectSingle(objectId, "name")
|
|
||||||
if not name or name == "" then
|
|
||||||
if strictLearnerOnly then
|
|
||||||
local learnedObj = Questie.dbLearner and Questie.dbLearner.global
|
|
||||||
and Questie.dbLearner.global.objects
|
|
||||||
and Questie.dbLearner.global.objects[objectId]
|
|
||||||
name = learnedObj and learnedObj[1] or nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if (not name) then
|
if (not name) then
|
||||||
Questie:Debug(Questie.DEBUG_CRITICAL, "Name missing for object:", objectId)
|
Questie:Debug(Questie.DEBUG_CRITICAL, "Name missing for object:", objectId)
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local spawns = strictLearnerOnly and {} or QuestieDB.QueryObjectSingle(objectId, "spawns")
|
local spawns = objectData and objectData.spawns or {}
|
||||||
if (not spawns) then
|
if (not spawns) then
|
||||||
Questie:Debug(Questie.DEBUG_CRITICAL, "Spawn data missing for object:", objectId)
|
Questie:Debug(Questie.DEBUG_CRITICAL, "Spawn data missing for object:", objectId)
|
||||||
spawns = {}
|
spawns = {}
|
||||||
|
|||||||
@@ -49,11 +49,13 @@ describe("QuestieLearner data source mode", function()
|
|||||||
|
|
||||||
it("keeps learner-only pin builders off the static DB lookup path", function()
|
it("keeps learner-only pin builders off the static DB lookup path", function()
|
||||||
local priv = read("Modules/Quest/QuestieQuestPrivates.lua")
|
local priv = read("Modules/Quest/QuestieQuestPrivates.lua")
|
||||||
assert.is_true(has(priv, "local strictLearnerOnly = dataSourceMode == \"learner\""))
|
assert.is_true(has(priv, "local npcData = QuestieDB:GetNPC(npcId)"))
|
||||||
assert.is_true(has(priv, "local name = strictLearnerOnly and nil or QuestieDB.QueryNPCSingle(npcId, \"name\")"))
|
assert.is_true(has(priv, "local name = npcData and npcData.name or nil"))
|
||||||
assert.is_true(has(priv, "local spawns = strictLearnerOnly and {} or QuestieDB.QueryNPCSingle(npcId, \"spawns\")"))
|
assert.is_true(has(priv, "local spawns = npcData and npcData.spawns or {}"))
|
||||||
assert.is_true(has(priv, "local name = strictLearnerOnly and nil or QuestieDB.QueryObjectSingle(objectId, \"name\")"))
|
assert.is_true(has(priv, "local rank = npcData and npcData.rank"))
|
||||||
assert.is_true(has(priv, "local spawns = strictLearnerOnly and {} or QuestieDB.QueryObjectSingle(objectId, \"spawns\")"))
|
assert.is_true(has(priv, "local objectData = QuestieDB:GetObject(objectId)"))
|
||||||
|
assert.is_true(has(priv, "local name = objectData and objectData.name or nil"))
|
||||||
|
assert.is_true(has(priv, "local spawns = objectData and objectData.spawns or {}"))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("maps object objectives from learner object captures before refresh", function()
|
it("maps object objectives from learner object captures before refresh", function()
|
||||||
@@ -106,3 +108,70 @@ describe("QuestieLearner learner mode activation", function()
|
|||||||
assert.is_true(QuestieLearner:IsEnabled())
|
assert.is_true(QuestieLearner:IsEnabled())
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
describe("QuestieDB learner source fallback", function()
|
||||||
|
before_each(function()
|
||||||
|
dofile("Tests/wow_api_mock.lua")
|
||||||
|
dofile("Database/QuestieDB.lua")
|
||||||
|
dofile("Database/npcDB.lua")
|
||||||
|
dofile("Database/objectDB.lua")
|
||||||
|
dofile("Database/questDB.lua")
|
||||||
|
dofile("Database/itemDB.lua")
|
||||||
|
|
||||||
|
Questie.dbLearner.global.settings.enabled = true
|
||||||
|
Questie.dbLearner.global.settings.dataSourceMode = "learner"
|
||||||
|
Questie.dbLearner.global.npcs = {
|
||||||
|
[9001] = {
|
||||||
|
[1] = "Learner Whelp",
|
||||||
|
[7] = {
|
||||||
|
[44] = {
|
||||||
|
{ 12.3, 45.6 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[8] = {
|
||||||
|
[44] = {
|
||||||
|
{ 13.3, 46.6 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[9] = 44,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Questie.dbLearner.global.objects = {
|
||||||
|
[9002] = {
|
||||||
|
[1] = "Learner Cache",
|
||||||
|
[4] = {
|
||||||
|
[44] = {
|
||||||
|
{ 11.1, 22.2 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[5] = 44,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
QuestieDB.QueryNPC = function() return nil end
|
||||||
|
QuestieDB.QueryObject = function() return nil end
|
||||||
|
QuestieDB.QueryQuest = function() return nil end
|
||||||
|
QuestieDB.QueryItem = function() return nil end
|
||||||
|
QuestieDB.private.npcCache = {}
|
||||||
|
QuestieDB.private.objectCache = {}
|
||||||
|
QuestieDB.private.questCache = {}
|
||||||
|
QuestieDB.private.itemCache = {}
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("returns learner NPC data when static queries are unavailable", function()
|
||||||
|
local npc = QuestieDB:GetNPC(9001)
|
||||||
|
assert.is_table(npc)
|
||||||
|
assert.equals("Learner Whelp", npc.name)
|
||||||
|
assert.is_table(npc.spawns)
|
||||||
|
assert.is_table(npc.waypoints)
|
||||||
|
assert.equals(44, npc.zoneID)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("returns learner object data when static queries are unavailable", function()
|
||||||
|
local obj = QuestieDB:GetObject(9002)
|
||||||
|
assert.is_table(obj)
|
||||||
|
assert.equals("Learner Cache", obj.name)
|
||||||
|
assert.is_table(obj.spawns)
|
||||||
|
assert.equals(44, obj.zoneID)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|||||||
Reference in New Issue
Block a user