using System; using System.IO; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Data.OleDb; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace AdvertsingProfitControl { internal class DatabaseVersionControl { FrmLogConsole _console = FrmLogConsole.GetStaticInstance; public string GetDatabaseVerionNumber(string connectionString) { var versionNumber = "0.0.0.0"; var oleDbCommand = new OleDbCommand { CommandText = "SELECT VersionNumber FROM Version" }; var connection = new OleDbConnection(connectionString); oleDbCommand.Connection = connection; try { connection.Open(); var reader = oleDbCommand.ExecuteReader(); while(reader != null && reader.Read()) { versionNumber = reader[0].ToString(); } } catch (OleDbException e) { //Due to primitive nature of the original database (v0.3.0.0), which did not contain a Version table, an error //will be kicked out trying to extract the version number from the database. So, just assume this isn't an //OleDb error of some type. _console.WriteToLog(FrmLogConsole.Level.Warning, "Testing for the database's version yielded an error.\nVersion number will be assumed to be 0.3.0.0."); _console.WriteToLog(FrmLogConsole.Level.Debug, e.Message); versionNumber = "0.3.0.0"; } finally { connection.Close(); } return versionNumber; } public bool UpdateVersionPointFive(string connectionString, out string versionNumber) { var updated = false; //Create a backup of the database File.Copy(Application.StartupPath + "\\APCDatabase.accdb", Application.StartupPath + "\\APCDatabase.bak", true); var connection = new OleDbConnection(connectionString); var oleDbCommand = new OleDbCommand { CommandText = "SELECT FK_AdItemID, FK_DateID, FK_GroupID FROM APC", Connection = connection }; using (connection) { connection.Open(); var apcReturnTable = new List(); using(var reader = oleDbCommand.ExecuteReader()) { //Each record's structure is as follows (index based): // 0 - FK_AdItemID, 1 - FK_DateID and 2 - FK_GroupID var groupID = 0; var rowAttribute = 0; var adItemID = ""; var dateID = ""; while(reader != null && reader.Read()) { apcReturnTable.Add(reader[0] + "," + reader[1] + "," + reader[2]); } reader?.Close(); //Update the FK_GroupID's data type. //oleDbCommand.CommandText = "ALTER TABLE APC ALTER COLUMN FK_GroupID NUMBER"; //oleDbCommand.ExecuteNonQuery(); //Insert the new columns into the APC table. oleDbCommand.CommandText = "ALTER TABLE APC ADD COLUMN RowPosition NUMBER, RowAttribute NUMBER"; oleDbCommand.ExecuteNonQuery(); //Change the object to update mode oleDbCommand.CommandText = "UPDATE APC SET RowAttribute = ?, RowPosition = ?, FK_GroupID = ? WHERE FK_AdItemID = ? AND FK_DateID = ?"; var rowPosition = 1; foreach (var splitRow in apcReturnTable.Select(row => row.Split(','))) { if (splitRow[1] != dateID) { rowPosition = 1; } groupID = 0; rowAttribute = 0; if (splitRow.Length == 3) { adItemID = splitRow[0]; dateID = splitRow[1]; var splitGroupIDs = splitRow[2].Split('|'); if (splitGroupIDs.Length == 2) { if (splitGroupIDs[1] != "") { groupID = int.Parse(splitGroupIDs[1]); } if (splitGroupIDs[0] != "") { rowAttribute = int.Parse(splitGroupIDs[0]); } } else if (splitGroupIDs.Length == 1) { //Try parsing the value to an int and check how big it is. //Less then three (3) means either a header or member row identifier, whereas a three (3) or greater means an ad special row. var parsedVal = 0; if (int.TryParse(splitGroupIDs[0], out parsedVal)) { if (parsedVal > 2) { groupID = parsedVal; } else if (parsedVal < 3) { rowAttribute = parsedVal; } } } } else { adItemID = splitRow[0]; dateID = splitRow[1]; } //Update the new row with the information. oleDbCommand.Parameters.Clear(); if (rowAttribute == 0) { oleDbCommand.Parameters.AddWithValue("RowAttribute", OleDbType.Empty); } else { oleDbCommand.Parameters.AddWithValue("RowAttribute", rowAttribute); } oleDbCommand.Parameters.AddWithValue("RowPosition", rowPosition); if (groupID == 0) { oleDbCommand.Parameters.AddWithValue("RowAttribute", OleDbType.Empty); } else { oleDbCommand.Parameters.AddWithValue("GroupID", groupID); } oleDbCommand.Parameters.AddWithValue("AdItemID", adItemID); oleDbCommand.Parameters.AddWithValue("DateID", dateID); if (oleDbCommand.ExecuteNonQuery() != 1) { MessageBox.Show("An error has occurred trying to upgrade the database", "Fatal Error"); break; } rowPosition++; } //Update the FK_GroupID's data type. oleDbCommand.Parameters.Clear(); oleDbCommand.CommandText = "ALTER TABLE APC ALTER COLUMN FK_GroupID NUMBER"; oleDbCommand.ExecuteNonQuery(); oleDbCommand.CommandText = "ALTER TABLE APC ALTER COLUMN ProjectionSold TEXT"; oleDbCommand.ExecuteNonQuery(); //Apply an update patch for version 0.3.0.0 database by adding a version table and inserting the version number into the database. oleDbCommand.CommandText = "CREATE TABLE Version (ID AUTOINCREMENT PRIMARY KEY, VersionNumber TEXT)"; oleDbCommand.ExecuteNonQuery(); //Insert the version number into the new table oleDbCommand.CommandText = "INSERT INTO Version (VersionNumber) VALUES ('0.5.0.0')"; oleDbCommand.ExecuteNonQuery(); versionNumber = "0.5.0.0"; updated = true; } } return updated; } } }