Quantcast

Added a db migrate module.

Peter Eliasson [02-08-15 - 18:32]
Added a db migrate module.

The migrate module is for migrating instead of resetting the db between changes.

This commit also changes the db version twice;

7->8: dbVersion is now kept as a per-realm value, as all other data is stored that way. If it would be kept global it would mean migration would only run on on realm, then increase the dbVersion globally, making other realm's data out of sync.

8->9: Added "links" back from a groupParse to the encounter it was for.
Filename
src/highscore.lua
src/main.lua
src/migrate.lua
src/src_include.xml
diff --git a/src/highscore.lua b/src/highscore.lua
index fc673ca..f52b047 100644
--- a/src/highscore.lua
+++ b/src/highscore.lua
@@ -25,7 +25,7 @@ addon.highscore = highscore;
 -- db defaults
 addon.dbDefaults.realm.modules["highscore"] = {
 	["guilds"] = {
-		["*"] = { -- Guild Name
+		["*"] = { -- guildName
 			["zones"] = {
 				["*"] = { -- zoneId
 					["difficulties"] = {
@@ -79,14 +79,18 @@ addon.dbDefaults.realm.modules["highscore"] = {
 		-- keys. We have to be able to test for existence.
 		--[[
 		["*"] = { -- groupParseId
-			startTime 	= 0,
-			duration 	= 0,
+			startTime    = 0,
+			duration     = 0,
+			guildName    = "",
+			zoneId       = 0,
+			difficultyId = 0,
+			encounterId  = 0,
 		}
 		--]]
 	}
 }

-addon.dbVersion = addon.dbVersion + 5
+addon.dbVersion = addon.dbVersion + 6;

 -- Constants
 local TRACKED_ZONE_IDS = {
@@ -358,6 +362,21 @@ function highscore:GetGuildNameById(guildId)
 	return guildId;
 end

+-- Removes parses that is older than "olderThanDate". If minParsesPerPlayer
+-- is > 0, that many parses will be kept for the player/encounter combination.
+function highscore:PurgeParses(olderThanDate, minParsesPerPlayer)
+	local oldGroupParseIds = {};
+
+	for id, groupParse in pairs(self.db.groupParses) do
+		if groupParse.startTime < olderThanDate then
+			tinsert(oldGroupParseIds, id);
+		end
+	end
+
+	for _, id in ipairs(oldGroupParseIds) do
+
+	end
+end

 function highscore:OnEnable()
 	self.db = addon.db.realm.modules["highscore"];
diff --git a/src/main.lua b/src/main.lua
index dfa6c26..01b8158 100644
--- a/src/main.lua
+++ b/src/main.lua
@@ -33,16 +33,14 @@ addon:SetDefaultModulePrototype(modPrototype)
 addon.dbDefaults = {
 	realm = {
 		modules = {},
-		options = {}
-	},
-	global = {
+		options = {},
 		dbVersion = 1
-	}
+	},
 }

 -- The current db version. Clear (migrate?) the database if
 -- version of database doesn't match this version.
-addon.dbVersion = 2;
+addon.dbVersion = 3;

 -- Constants
 DEBUG_PRINT = false;
@@ -177,13 +175,7 @@ function addon:OnInitialize()
 	self.db = LibStub("AceDB-3.0"):New("GuildSkadaHighScoreDB", addon.dbDefaults, true)

 	-- Make sure db version is in sync
-	if self.db.global.dbVersion ~= self.dbVersion then
-		self:Debug(format("Found not matching db versions: db=%d, addon=%d",
-			self.db.global.dbVersion, self.dbVersion));
-		self:Debug("Resetting db");
-		self.db:ResetDB();
-		self.db.global.dbVersion = self.dbVersion;
-	end
+	self.migrate:DoMigration();
 end

 function addon:OnEnable()
diff --git a/src/migrate.lua b/src/migrate.lua
new file mode 100644
index 0000000..b58c5ad
--- /dev/null
+++ b/src/migrate.lua
@@ -0,0 +1,99 @@
+--
+-- migrate.lua
+--
+-- Contains database migration
+--
+
+local addonName, addonTable = ...
+
+-- Global functions for faster access
+local tinsert = tinsert;
+
+-- Set up module
+local addon = addonTable[1];
+local migrate = addon:NewModule("migrate");
+addon.migrate = migrate;
+
+
+local function migrate7to8(db)
+	-- dbVersion is now saved per realm, as every other
+	-- options is stored per realm.
+	local version = db.global.dbVersion;
+	db.realm.dbVersion = version;
+	return 8;
+end
+
+local function migrate8to9(db)
+	-- Each highscore groupParse should have the
+	-- guildName, zoneId, difficultyId and encounterId
+	-- it is associated with, so that it is possible to
+	-- find parses that is connected to a groupParse without
+	-- having to look trough all parses.
+
+	local highscoreDb = db.realm.modules["highscore"];
+
+	for guildName, guildData in pairs(highscoreDb.guilds) do
+		for zoneId, zoneData in pairs(guildData.zones) do
+			for diffId, diffData in pairs(zoneData.difficulties) do
+				for encId, encData in pairs(diffData.encounters) do
+					for _, parse in pairs(encData.playerParses) do
+						local groupParseId = parse.groupParseId;
+						local groupParse = highscoreDb.groupParses[groupParseId];
+						groupParse.guildName = guildName;
+						groupParse.zoneId = zoneId;
+						groupParse.difficultyId = diffId;
+						groupParse.encounterId = encId;
+					end
+				end
+			end
+		end
+	end
+	return 9;
+end
+
+local migrateTable = {
+	[7] = migrate7to8,
+	[8] = migrate8to9
+}
+
+local function resetDb()
+	self:Debug("Resetting db");
+	addon.db:ResetDB();
+end
+
+function migrate:DoMigration()
+	local db = addon.db;
+	local targetVersion = addon.dbVersion;
+
+	local currentVersion = 1;
+	if db.global.dbVersion then
+		-- dbVersion used to be stored in global
+		currentVersion = db.global.dbVersion;
+	end
+
+	if db.realm.dbVersion and db.realm.dbVersion > currentVersion then
+		currentVersion = db.realm.dbVersion
+	end
+
+	if currentVersion == targetVersion then
+		return;
+	end
+
+	self:Debug(format("Attempting to migrate from dbVersion: %d to %d.",
+		currentVersion, targetVersion));
+
+	while currentVersion < targetVersion do
+		local migrateFunction = migrateTable[currentVersion];
+		if migrateFunction then
+			currentVersion = migrateFunction(db);
+		else
+			self:Debug(format("Could not migrate from dbVersion: %d!", currentVersion));
+			resetDb();
+			break;
+		end
+	end
+
+	db.realm.dbVersion = targetVersion;
+	self:Debug(format("Migration to dbVersion: %d completed.",
+		targetVersion));
+end
diff --git a/src/src_include.xml b/src/src_include.xml
index 0bb3dfd..cb4905d 100644
--- a/src/src_include.xml
+++ b/src/src_include.xml
@@ -5,5 +5,6 @@
 	<Script file="gui.lua"/>
 	<Script file="report.lua"/>
 	<Script file="options.lua"/>
+	<Script file="migrate.lua"/>
 	<Include file="parse_modules\parse_modules_include.xml"/>
 </Ui>
\ No newline at end of file