public RowsDeleter(TableChanges tchanges, string diff, List <TableChangesRange> rows, bool left) : base("RowsDeleter") { _diff = diff; _changes = tchanges; _rows = rows; _left = left; }
public RowsCopier(TableChanges tchanges, string diff, List <TableChangesRange> rows, bool leftToRight) : base("RowsCopier") { _diff = diff; _changes = tchanges; _rows = rows; _leftToRight = leftToRight; }
static void Main(string[] args) { try { _mutex = Mutex.OpenExisting("SQLiteCompare"); MessageBox.Show("Another instance of SQLiteCompare is already active.\r\n" + "Please close it first.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } catch (Exception ex) { _mutex = new Mutex(false, "SQLiteCompare"); } // Configure log4net BasicConfigurator.Configure(); AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException); // Issue a log message that contains the version of the application. _log.Info("==========================================================================="); _log.Info(" SQLite Compare [" + Utils.GetSoftwareVersion() + " build " + Utils.GetSoftwareBuild() + "]"); _log.Info("==========================================================================="); // Remove any stale table change files TableChanges.RemoveStaleChangeFiles(); try { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); MainForm mf = new MainForm(); if (args.Length > 1) { mf.setFiles(args[0], args[1]); } _mainForm = mf; Application.Run(_mainForm); _mainForm = null; } catch (Exception ex) { _mainForm = null; _log.Error("Got exception from main loop", ex); ShowUnexpectedErrorDialog(ex); } finally { // Remove all active change files TableChanges.RemoveActiveChangeFiles(); } // finally // If there are pending software updates - apply them now UpdateEngine.ApplyPendingUpdates(); }
public DiffExporter(TableChanges changes, string fpath, bool exportUpdates, bool exportAdded, bool exportDeleted) : base("Diff Exporter") { _changes = changes; _fpath = fpath; _exportAdded = exportAdded; _exportDeleted = exportDeleted; _exportUpdates = exportUpdates; }
public SearchDataWorker(bool isLeft, string diff, TableChanges tchanges, long rowIndex, long maxRowIndex, string sql) : base("SearchDataWorker") { _maxRowIndex = maxRowIndex; _isLeft = isLeft; _changes = tchanges; _rowIndex = rowIndex; _sql = sql; _diff = diff; }
/// <summary> /// Check if a specific flag is set /// </summary> /// <param name="value">Flag to check</param> /// <returns>True if set, false if unset</returns> public bool IsSet(TableChanges value) { // If value is None, then the enum must be zero, since no other change could have happened if (value == TableChanges.None) { return(value == 0); } return((TableChanges & value) != 0); }
public void SetTableChanges(SchemaComparisonItem item, string leftdb, string rightdb, TableChanges changes, string diff) { _item = item; _leftdb = leftdb; _rightdb = rightdb; _diff = diff; _tableChanges = changes; PrepareDataTab(); }
public DmSet GetChanges(DmRowState rowStates) { DmSet dsNew = null; if (0 != (rowStates & ~(DmRowState.Added | DmRowState.Deleted | DmRowState.Modified | DmRowState.Unchanged))) { throw new Exception($"InvalidRowState {rowStates}"); } // Initialize all the individual table bitmaps. TableChanges[] bitMatrix = new TableChanges[Tables.Count]; for (int i = 0; i < bitMatrix.Length; ++i) { bitMatrix[i] = new TableChanges(Tables[i].Rows.Count); } // find all the modified rows and their parents MarkModifiedRows(bitMatrix, rowStates); // copy the changes to a cloned table for (int i = 0; i < bitMatrix.Length; ++i) { Debug.Assert(0 <= bitMatrix[i].HasChanges, "negative change count"); if (0 < bitMatrix[i].HasChanges) { if (dsNew == null) { dsNew = this.Clone(); } DmTable table = this.Tables[i]; DmTable destTable = dsNew.Tables.First(t => t.TableName == table.TableName); for (int j = 0; 0 < bitMatrix[i].HasChanges; ++j) { // Loop through the rows. if (bitMatrix[i][j]) { destTable.ImportRow(table.Rows[j]); bitMatrix[i].HasChanges--; } } } } return(dsNew); }
/// <summary> /// Prepares the search dialog by initializing it with the columns list that can be searched, /// a column name to be searched by default (optional), and the table changes object that will /// be used for searching the database. /// </summary> /// <param name="clist">A list of columns that can be searched</param> /// <param name="colName">A default column name to be searched, or NULL if no column is searched by default.</param> /// <param name="tchanges">The table changes object</param> public void PrepareDialog(List <SQLiteColumnStatement> clist, string colName, string diff, TableChanges tchanges, long rowIndex, bool isLeft) { _matchedRowIndex = -1; _diff = diff; _isLeft = isLeft; _columns = clist; _changes = tchanges; _rowIndex = rowIndex; bool lastused = false; cboColumnName.Items.Clear(); foreach (SQLiteColumnStatement col in clist) { string cname = SQLiteParser.Utils.Chop(col.ObjectName.ToString()); cboColumnName.Items.Add(cname); if (cname == _lastColName) { lastused = true; } } // foreach if (lastused) { cboColumnName.SelectedItem = _lastColName; } else if (colName != null) { colName = SQLiteParser.Utils.Chop(colName); cboColumnName.SelectedItem = colName; } if (isLeft) { this.Text = "Search Rows (left database)"; } else { this.Text = "Search Rows (right database)"; } }
protected override void DoWork() { if (_changes != null) { _changes.ExportToCSV(_fpath, _exportUpdates, _exportAdded, _exportDeleted, ExportHandler); } else { // Check how many tables have changes in them List <TableChanges> list = new List <TableChanges>(); foreach (SchemaComparisonItem item in _multiChanges) { if (item.TableChanges != null && !item.TableChanges.SameTables) { list.Add(item.TableChanges); } } // foreach TableChanges.ExportMultipleToCSV(_fpath, list, _exportUpdates, _exportAdded, _exportDeleted, ExportHandler); } // else }
private void GenerateOpertions(TableChanges tableChanges) { switch (tableChanges.ChangeType) { case ChangeType.Added: this.AddTable(tableChanges.NewTable); break; case ChangeType.Removed: this.RemoveTable(tableChanges.OldTable); break; case ChangeType.Modified: foreach (var column in tableChanges.ColumnsChanged) { this.GenerateOpertions(column); } break; default: break; } }
/// <summary> /// For every table that has the same schema in both databases - compare its /// data and update the _result object if necessary. /// </summary> /// <param name="leftdb">The leftdb.</param> /// <param name="rightdb">The rightdb.</param> /// <param name="changes">The list of schema changes to check</param> private void CompareTables( string leftdb, string rightdb, Dictionary <SchemaObject, List <SchemaComparisonItem> > changes, bool allowBlobComparison) { // Go over all tables and select for comparison only those tables that have identical // schema. List <SchemaComparisonItem> clist = changes[SchemaObject.Table]; int total = clist.Count; int offset = 0; int prev = -1; foreach (SchemaComparisonItem item in clist) { if (item.Result == ComparisonResult.Same || item.Result == ComparisonResult.DifferentSchema) { offset++; double progress = 50.0 + 50.0 * offset / total; if ((int)progress > prev) { prev = (int)progress; NotifyPrimaryProgress(false, prev, "Comparing data for table [" + item.LeftDdlStatement.ObjectName.ToString() + "].."); } IWorker tableComparer = new TableCompareWorker((SQLiteCreateTableStatement)item.LeftDdlStatement, (SQLiteCreateTableStatement)item.RightDdlStatement, leftdb, rightdb, allowBlobComparison); _tableComparer = new SyncWorker(tableComparer); EventHandler <ProgressEventArgs> eh = new EventHandler <ProgressEventArgs>(delegate(object s, ProgressEventArgs e) { NotifySecondaryProgress(e.IsDone, e.Progress, e.Message); }); try { _tableComparer.ProgressChanged += eh; _tableComparer.BeginWork(); TableChanges tableChanges = (TableChanges)_tableComparer.Result; item.TableChanges = tableChanges; } catch (UserCancellationException uce) { // Ignore } catch (Exception ex) { // The tables data cannot be compared so ignore. item.ErrorMessage = ex.Message; } finally { _tableComparer.ProgressChanged -= eh; _tableComparer = null; } if (_cancelled) { throw new UserCancellationException(); } } } // foreach }
public DataSet GetChanges(DataRowState rowStates) { DataSet set2; IntPtr ptr; Bid.ScopeEnter(out ptr, "<ds.DataSet.GetChanges|API> %d#, rowStates=%d{ds.DataRowState}\n", this.ObjectID, (int) rowStates); try { DataSet set = null; bool enforceConstraints = false; if ((rowStates & ~(DataRowState.Modified | DataRowState.Deleted | DataRowState.Added | DataRowState.Unchanged)) != 0) { throw ExceptionBuilder.InvalidRowState(rowStates); } TableChanges[] bitMatrix = new TableChanges[this.Tables.Count]; for (int i = 0; i < bitMatrix.Length; i++) { bitMatrix[i] = new TableChanges(this.Tables[i].Rows.Count); } this.MarkModifiedRows(bitMatrix, rowStates); for (int j = 0; j < bitMatrix.Length; j++) { if (0 < bitMatrix[j].HasChanges) { if (set == null) { set = this.Clone(); enforceConstraints = set.EnforceConstraints; set.EnforceConstraints = false; } DataTable table = this.Tables[j]; DataTable table2 = set.Tables[table.TableName, table.Namespace]; for (int k = 0; 0 < bitMatrix[j].HasChanges; k++) { if (bitMatrix[j][k]) { table.CopyRow(table2, table.Rows[k]); bitMatrix[j].HasChanges--; } } } } if (set != null) { set.EnforceConstraints = enforceConstraints; } set2 = set; } finally { Bid.ScopeLeave(ref ptr); } return set2; }
private void MarkRelatedRowsAsModified(TableChanges[] bitMatrix, DataRow row) { DataRelationCollection parentRelations = row.Table.ParentRelations; int count = parentRelations.Count; for (int i = 0; i < count; i++) { foreach (DataRow row2 in row.GetParentRows(parentRelations[i], DataRowVersion.Current)) { int index = this.Tables.IndexOf(row2.Table); int num3 = row2.Table.Rows.IndexOf(row2); if (!bitMatrix[index][num3]) { bitMatrix[index][num3] = true; if (DataRowState.Deleted != row2.RowState) { this.MarkRelatedRowsAsModified(bitMatrix, row2); } } } } }
private void MarkModifiedRows(TableChanges[] bitMatrix, DataRowState rowStates) { for (int i = 0; i < bitMatrix.Length; i++) { DataRowCollection rows = this.Tables[i].Rows; int count = rows.Count; for (int j = 0; j < count; j++) { DataRow row = rows[j]; DataRowState rowState = row.RowState; if (((rowStates & rowState) != 0) && !bitMatrix[i][j]) { bitMatrix[i][j] = true; if (DataRowState.Deleted != rowState) { this.MarkRelatedRowsAsModified(bitMatrix, row); } } } } }
private void MarkRelatedRowsAsModified(TableChanges[] bitMatrix, DataRow row) { DataRelationCollection relations = row.Table.ParentRelations; int relationCount = relations.Count; for (int relatedIndex = 0; relatedIndex < relationCount; ++relatedIndex) { DataRow[] relatedRows = row.GetParentRows(relations[relatedIndex], DataRowVersion.Current); foreach (DataRow relatedRow in relatedRows) { int relatedTableIndex = this.Tables.IndexOf(relatedRow.Table); int relatedRowIndex = relatedRow.Table.Rows.IndexOf(relatedRow); if (!bitMatrix[relatedTableIndex][relatedRowIndex]) { bitMatrix[relatedTableIndex][relatedRowIndex] = true; if (DataRowState.Deleted != relatedRow.RowState) { // recurse into related rows MarkRelatedRowsAsModified(bitMatrix, relatedRow); } } } } }
private void MarkModifiedRows(TableChanges[] bitMatrix, DataRowState rowStates) { // for every table, every row & every relation find the modified rows and for non-deleted rows, their parents for (int tableIndex = 0; tableIndex < bitMatrix.Length; ++tableIndex) { DataRowCollection rows = Tables[tableIndex].Rows; int rowCount = rows.Count; for (int rowIndex = 0; rowIndex < rowCount; ++rowIndex) { DataRow row = rows[rowIndex]; DataRowState rowState = row.RowState; Debug.Assert(DataRowState.Added == rowState || DataRowState.Deleted == rowState || DataRowState.Modified == rowState || DataRowState.Unchanged == rowState, "unexpected DataRowState"); // if bit not already set and row is modified if ((0 != (rowStates & rowState)) && !bitMatrix[tableIndex][rowIndex]) { bitMatrix[tableIndex][rowIndex] = true; if (DataRowState.Deleted != rowState) { MarkRelatedRowsAsModified(bitMatrix, row); } } } } }
public DataSet GetChanges(DataRowState rowStates) { IntPtr hscp; Bid.ScopeEnter(out hscp, "<ds.DataSet.GetChanges|API> %d#, rowStates=%d{ds.DataRowState}\n", ObjectID, (int)rowStates); try { DataSet dsNew = null; bool fEnforceConstraints = false; if (0 != (rowStates & ~(DataRowState.Added | DataRowState.Deleted | DataRowState.Modified | DataRowState.Unchanged))) { throw ExceptionBuilder.InvalidRowState(rowStates); } // Initialize all the individual table bitmaps. TableChanges[] bitMatrix = new TableChanges[Tables.Count]; for (int i = 0; i < bitMatrix.Length; ++i) { bitMatrix[i] = new TableChanges(Tables[i].Rows.Count); } // find all the modified rows and their parents MarkModifiedRows(bitMatrix, rowStates); // copy the changes to a cloned table for (int i = 0; i < bitMatrix.Length; ++i) { Debug.Assert(0 <= bitMatrix[i].HasChanges, "negative change count"); if (0 < bitMatrix[i].HasChanges) { if (null == dsNew) { dsNew = this.Clone(); fEnforceConstraints = dsNew.EnforceConstraints; dsNew.EnforceConstraints = false; } DataTable table = this.Tables[i]; DataTable destTable = dsNew.Tables[table.TableName, table.Namespace]; Debug.Assert(bitMatrix[i].HasChanges <= table.Rows.Count, "to many changes"); for (int j = 0; 0 < bitMatrix[i].HasChanges; ++j) { // Loop through the rows. if (bitMatrix[i][j]) { table.CopyRow(destTable, table.Rows[j]); bitMatrix[i].HasChanges--; } } } } if (null != dsNew) { dsNew.EnforceConstraints = fEnforceConstraints; } return dsNew; } finally { Bid.ScopeLeave(ref hscp); } }
/// <summary> /// Set value flag in enum /// </summary> /// <param name="value">Flag to set</param> public void Set(TableChanges value) { TableChanges |= value; }
/// <summary> /// Unset value flag in enum /// </summary> /// <param name="value">Flag to unset</param> public void Unset(TableChanges value) { TableChanges &= ~value; }