diff options
Diffstat (limited to 'Software/Visual_Studio/Tango.Synchronization/Local/LocalDBComparer.cs')
| -rw-r--r-- | Software/Visual_Studio/Tango.Synchronization/Local/LocalDBComparer.cs | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Tango.Synchronization/Local/LocalDBComparer.cs b/Software/Visual_Studio/Tango.Synchronization/Local/LocalDBComparer.cs new file mode 100644 index 000000000..63f2ecfaa --- /dev/null +++ b/Software/Visual_Studio/Tango.Synchronization/Local/LocalDBComparer.cs @@ -0,0 +1,200 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Logging; + +namespace Tango.Synchronization.Local +{ + /// <summary> + /// Represents an <see cref="ILocalDataBase"/> synchronization engine. + /// </summary> + /// <seealso cref="System.IDisposable" /> + public class LocalDBComparer : IDisposable + { + /// <summary> + /// Gets the master SQL. + /// </summary> + public ILocalDataBase MasterSQL { get; private set; } + + /// <summary> + /// Gets the slave SQL. + /// </summary> + public ILocalDataBase SlaveSQL { get; private set; } + + /// <summary> + /// Initializes a new instance of the <see cref="LocalDBComparer"/> class. + /// </summary> + /// <param name="masterSQL">The master SQL.</param> + /// <param name="slaveSQL">The slave SQL.</param> + public LocalDBComparer(ILocalDataBase masterSQL, ILocalDataBase slaveSQL) + { + MasterSQL = masterSQL; + SlaveSQL = slaveSQL; + } + + /// <summary> + /// Compares the master and slave SQL data base and returns a collection of <see cref="Diff"/>. + /// </summary> + /// <returns></returns> + public List<Diff> Compare() + { + LogManager.Log("Comparing databases " + Path.GetFileName(MasterSQL.Source) + " <=> " + Path.GetFileName(SlaveSQL.Source)); + + LogManager.Log("Loading master tables..."); + MasterSQL.LoadTables(); + + LogManager.Log("Loading slave tables..."); + SlaveSQL.LoadTables(); + + List<Diff> diffs = new List<Diff>(); + + foreach (var masterTable in MasterSQL.Tables) + { + LogManager.Log("Comparing table " + masterTable.TableName); + LogManager.Log("Searching table " + masterTable.TableName + " on slave..."); + + var slaveTable = SlaveSQL.Tables.SingleOrDefault(x => x.TableName == masterTable.TableName); //Get matching slave table on slave db. + + if (slaveTable == null) //Table not found on slave. + { + LogManager.Log("Table not found on slave, adding difference."); + //Clone table from slave db to master db including records! + diffs.Add(new Diff(DiffAction.AddTableToSlave, String.Format("Add table {0} to slave", masterTable.TableName), () => SlaveSQL.CloneTableFrom(MasterSQL, masterTable), SlaveSQL.GetCloneTableFromCommand(MasterSQL, masterTable))); + continue; + } + + LogManager.Log("Table found, comparing columns..."); + + foreach (DataColumn masterColumn in masterTable.Columns) + { + LogManager.Log("Searching for column " + masterColumn.ColumnName + " on slave..."); + + var slaveColumn = slaveTable.Columns[masterColumn.ColumnName]; //Get matching slave column on slave table. + + if (slaveColumn == null) //Slave column not found. + { + LogManager.Log("Column not found on slave, adding difference."); + //Add column to slave table. + diffs.Add(new Diff(DiffAction.AddColumnToSlave, String.Format("Add column {0} to slave table", masterColumn.ColumnName), () => SlaveSQL.AddColumn(masterTable, masterColumn), SlaveSQL.GetAddColumnCommand(masterTable, masterColumn))); + } + + LogManager.Log("Column found."); + } + + List<DataRow> addToSlave = new List<DataRow>(); + List<DataRow> updateSlave = new List<DataRow>(); + List<DataRow> addToMaster = new List<DataRow>(); + List<DataRow> updateMaster = new List<DataRow>(); + + LogManager.Log("Comparing rows..."); + + int count = 0; + + foreach (DataRow masterRow in masterTable.Rows) + { + LogManager.Log("Comparing row " + count++); + + String guid = masterRow.Field<String>(Constants.GUID); + + LogManager.Log("Searching for row with GUID " + guid + " on slave table..."); + + //Get Matching slave row. + DataRow slaveRow = slaveTable.AsEnumerable().SingleOrDefault(x => x.Field<String>(Constants.GUID) == guid); + + if (slaveRow != null) + { + LogManager.Log("Slave row found, comparing dates..."); + + DateTime masterDate = masterRow.Field<DateTime>(Constants.LAST_UPDATED); + DateTime slaveDate = slaveRow.Field<DateTime>(Constants.LAST_UPDATED); + + if (masterDate > slaveDate) + { + LogManager.Log("Master => Slave Update " + masterDate.ToSQLiteDateString() + ", adding difference."); + updateSlave.Add(masterRow); + } + else if (slaveDate > masterDate) + { + LogManager.Log("Master <= Slave Update " + masterDate.ToSQLiteDateString() + ", adding difference."); + updateMaster.Add(slaveRow); + } + else + { + LogManager.Log("Master <=> Slave No Update."); + } + } + else + { + LogManager.Log("Slave row not found, adding difference."); + addToSlave.Add(masterRow); + } + } + + LogManager.Log("Done comparing rows..."); + + LogManager.Log("Searching for missing rows on master..."); + + foreach (DataRow slaveRow in slaveTable.Rows) + { + String guid = slaveRow.Field<String>(Constants.GUID); + + LogManager.Log("Searching for row with GUID " + guid + " on master table..."); + + //Get Matching slave row. + DataRow masterRow = masterTable.AsEnumerable().SingleOrDefault(x => x.Field<String>(Constants.GUID) == guid); + + if (masterRow == null) + { + LogManager.Log("Master row not found, adding difference."); + addToMaster.Add(slaveRow); + } + else + { + LogManager.Log("Master row found."); + } + } + + LogManager.Log("Done searching for missing rows on master..."); + + foreach (var row in addToSlave) + { + diffs.Add(new Diff(DiffAction.AddRowToSlave, String.Format("Add row to slave table {0}", slaveTable.TableName), () => SlaveSQL.AddRow(slaveTable, row), SlaveSQL.GetAddRowCommand(slaveTable, row))); + } + + foreach (var row in addToMaster) + { + diffs.Add(new Diff(DiffAction.AddRowToMaster, String.Format("Add row to master table {0}", masterTable.TableName), () => MasterSQL.AddRow(masterTable, row), MasterSQL.GetAddRowCommand(masterTable, row))); + } + + foreach (var row in updateSlave) + { + diffs.Add(new Diff(DiffAction.UpdateRowInSlave, String.Format("Update row in slave table {0}", slaveTable.TableName), () => SlaveSQL.UpdateRow(slaveTable, row), SlaveSQL.GetUpdateRowCommand(slaveTable, row))); + } + + foreach (var row in updateMaster) + { + diffs.Add(new Diff(DiffAction.UpdateRowInMaster, String.Format("Update row in master table {0}", masterTable.TableName), () => MasterSQL.UpdateRow(masterTable, row), MasterSQL.GetUpdateRowCommand(masterTable, row))); + } + + LogManager.Log("Done comparing table " + masterTable.TableName); + } + + LogManager.Log("Databases comparison completed."); + + return diffs; + } + + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public void Dispose() + { + MasterSQL.Dispose(); + SlaveSQL.Dispose(); + } + } +} |
