Пример #1
0
        private void btnCopyRightToLeft_Click(object sender, EventArgs e)
        {
            List <TableChangesRange> rows = new List <TableChangesRange>();

            foreach (FastGridApp.SelectionRange range in grdLeft.Selection.SelectionRanges)
            {
                rows.Add(new TableChangesRange(range.StartRowId, range.EndRowId));
            }
            RowsCopier     copier = new RowsCopier(_tableChanges, _diff, rows, false);
            ProgressDialog dlg    = new ProgressDialog();

            dlg.Start(this, copier);
            grdRight.RefreshLayout();
            grdLeft.RefreshLayout();

            if (RowsChanged != null)
            {
                RowsChanged(this, EventArgs.Empty);
            }

            if (StateChanged != null)
            {
                StateChanged(this, EventArgs.Empty);
            }
        }
Пример #2
0
        private void DeleteRows(bool right)
        {
            List <TableChangesRange> rows = new List <TableChangesRange>();
            FastGrid grid;

            long totalDeleted = 0;

            if (right)
            {
                grid = grdRight;
                foreach (FastGridApp.SelectionRange range in grdRight.Selection.SelectionRanges)
                {
                    rows.Add(new TableChangesRange(range.StartRowId, range.EndRowId));
                    totalDeleted += range.EndRowId - range.StartRowId + 1;
                }
            }
            else
            {
                grid = grdLeft;
                foreach (FastGridApp.SelectionRange range in grdLeft.Selection.SelectionRanges)
                {
                    rows.Add(new TableChangesRange(range.StartRowId, range.EndRowId));
                    totalDeleted += range.EndRowId - range.StartRowId + 1;
                }
            }

            DialogResult res = MessageBox.Show(this,
                                               string.Format("Are you sure you want to delete {0} rows from the {1} database table?", totalDeleted, (right?"right":"left")),
                                               "Confirm Deletion", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);

            if (res == DialogResult.No)
            {
                return;
            }

            RowsDeleter    deleter = new RowsDeleter(_tableChanges, _diff, rows, !right);
            ProgressDialog dlg     = new ProgressDialog();

            dlg.Start(this, deleter);

            GC.Collect();

            // Notify that row(s) were deleted
            if (RowsChanged != null)
            {
                RowsChanged(this, EventArgs.Empty);
            }

            // Refresh the right/left grids again from the database.
            grdRight.RefreshLayout();
            grdLeft.RefreshLayout();
        }
        private void StartTableUpdate(string leftSQL, string rightSQL, bool skipNullRows)
        {
            // Create and start the updater object
            SchemaObjectUpdater updater = new SchemaObjectUpdater(_item,
                                                                  _leftSchema, _rightSchema, _leftdb, _rightdb, leftSQL, rightSQL, skipNullRows);
            ProgressDialog dlg = new ProgressDialog();

            dlg.Start(this, updater);

            if (dlg.Error == null)
            {
                // Compare again based on the updated schema objects found in the item object.
                CompareSchema(_item);

                // Notify about the change
                if (SchemaChanged != null)
                {
                    SchemaChanged(this, EventArgs.Empty);
                }
            } // else
            else
            {
                if (dlg.Error is UpdateTableException)
                {
                    UpdateTableException ue = (UpdateTableException)dlg.Error;
                    if (ue.CanRestart)
                    {
                        DialogResult res = MessageBox.Show(this,
                                                           "Press [Yes] to restart the operation and skip problem rows\r\n" +
                                                           "Press [No] to abort the operation",
                                                           "Information",
                                                           MessageBoxButtons.YesNo,
                                                           MessageBoxIcon.Warning,
                                                           MessageBoxDefaultButton.Button2);
                        if (res == DialogResult.No)
                        {
                            return;
                        }

                        StartTableUpdate(leftSQL, rightSQL, true);
                    }
                } // if
            }     // else

            // Remove the data tab
            tbcViews.TabPages.Remove(tbpData);
        }
Пример #4
0
        private void ExportToFile(bool openInExternal)
        {
            AbstractWorker worker = null;

            if (_changes != null)
            {
                worker = new DiffExporter(_changes, txtFile.Text.Trim(), cbxExportUpdates.Checked,
                                          cbxExportAdded.Checked, cbxExportDeleted.Checked);
            }
            else
            {
                worker = new DiffExporter(_multiChanges, txtFile.Text.Trim(), cbxExportUpdates.Checked,
                                          cbxExportAdded.Checked, cbxExportDeleted.Checked);
            }
            ProgressDialog dlg = new ProgressDialog();

            dlg.Start(this, worker);

            if (dlg.Error == null)
            {
                this.Close();

                if (openInExternal)
                {
                    try
                    {
                        // Open in external application
                        Process          p   = new Process();
                        ProcessStartInfo psi = new ProcessStartInfo(txtFile.Text.Trim());
                        p.StartInfo         = psi;
                        psi.UseShellExecute = true;
                        p.Start();
                    }
                    catch (Exception ex)
                    {
                        DialogResult res = MessageBox.Show(this, "There is no external viewer for this type of file. Do yo want to open the file using notepad?",
                                                           "No Viewer Available", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
                        if (res == DialogResult.Yes)
                        {
                            // Try to open using notepad
                            OpenAsTextFile(txtFile.Text.Trim());
                        }
                    } // catch
                }
            }         // if
        }
Пример #5
0
        /// <summary>
        /// Allows to refresh the comparison results
        /// </summary>
        /// <param name="cancellable">TRUE means that the user will be allowed to cancel
        /// the comparison process. FALSE prevents this from happening (by making the CANCEL
        /// button disabled).</param>
        private void RefreshComparison(bool cancellable)
        {
            CompareWorker  worker = new CompareWorker(_compareParams);
            ProgressDialog pdlg   = new ProgressDialog();

            if (cancellable)
            {
                pdlg.Start(this, worker);
            }
            else
            {
                pdlg.StartNonCancellable(this, worker);
            }

            Dictionary <SchemaObject, List <SchemaComparisonItem> > results =
                (Dictionary <SchemaObject, List <SchemaComparisonItem> >)pdlg.Result;

            if (results != null)
            {
                // Create the schema comparison view and populate it with the results
                if (_schemaView == null)
                {
                    _schemaView           = new SchemaComparisonView();
                    _schemaView.BackColor = SystemColors.Control;
                    pnlContents.Controls.Add(_schemaView);
                    _schemaView.Dock              = DockStyle.Fill;
                    _schemaView.SelectionChanged += new EventHandler(_schemaView_SelectionChanged);
                }

                _leftSchema  = worker.LeftSchema;
                _rightSchema = worker.RightSchema;
                _results     = results;
                _leftdb      = _compareParams.LeftDbPath;
                _rightdb     = _compareParams.RightDbPath;

                _schemaView.ShowComparisonResults(results, _compareParams.LeftDbPath, _compareParams.RightDbPath,
                                                  worker.LeftSchema, worker.RightSchema, _compareParams.ComparisonType == ComparisonType.CompareSchemaAndData);
            }

            UpdateState();
        }
Пример #6
0
        private void HandleCellEdit(bool right)
        {
            FastGrid grid;
            SQLiteCreateTableStatement table;
            string dbpath;

            if (right)
            {
                grid   = grdRight;
                table  = (SQLiteCreateTableStatement)_item.RightDdlStatement;
                dbpath = _rightdb;
            }
            else
            {
                grid   = grdLeft;
                table  = (SQLiteCreateTableStatement)_item.LeftDdlStatement;
                dbpath = _leftdb;
            }

            FastGridLocation sloc = grid.SelectedCellLocation;

            string columnName            = (string)grid.Columns[sloc.ColumnIndex].Tag;
            SQLiteColumnStatement column = Utils.FindColumn(table.Columns, columnName);

            if (column == null)
            {
                return;
            }

            TableChangeItem citem = null;

            try
            {
                citem = _tableChanges.GetChangeItem(_diff, sloc.RowIndex);
            }
            catch (IndexOutOfRangeException iox)
            {
                // Ignore (the user must have pressed on a cell when the table is actually empty)
                return;
            } // catch

            // Can't edit a cell that belongs to a row that doesn't exist
            if (right && citem.Result == ComparisonResult.ExistsInLeftDB)
            {
                return;
            }
            else if (!right && citem.Result == ComparisonResult.ExistsInRightDB)
            {
                return;
            }

            object otherBlob = null;

            // The row id is needed when displaying editor dialog for a BLOB field
            long rowId = -1;

            if (right)
            {
                rowId = citem.RightRowId;
                if (citem.LeftFields != null && TableContainsColumn((SQLiteCreateTableStatement)_item.LeftDdlStatement, column))
                {
                    otherBlob = GetRowFieldValue(citem, false, columnName);
                }
            }
            else
            {
                rowId = citem.LeftRowId;
                if (citem.RightFields != null && TableContainsColumn((SQLiteCreateTableStatement)_item.RightDdlStatement, column))
                {
                    otherBlob = GetRowFieldValue(citem, true, columnName);
                }
            }

            // Extract the current field value from the change item
            object value = GetRowFieldValue(citem, right, columnName);

            // Adjust the BLOB value since it was fetched as the IS NOT NULL expression
            // in order to avoid loading the BLOB field into main memory.
            if (Utils.GetDbType(column.ColumnType) == DbType.Binary)
            {
                long v = (long)value;
                if (v == 0) // means NULL
                {
                    value = DBNull.Value;
                }
            }

            // When the user is clicking on a BLOB field - we need to extract its value
            // to a local file before opening the cell-edit dialog.
            Be.Windows.Forms.DynamicFileByteProvider origProvider = null;
            if (value != DBNull.Value && Utils.GetDbType(column.ColumnType) == DbType.Binary)
            {
                // In case of BLOBs - we have to first load them to the local file-system and
                // only then we can allow the user to edit their contents
                using (BlobLoader loader = new BlobLoader(dbpath,
                                                          table.ObjectName.ToString(), column.ObjectName.ToString(), rowId, Configuration.TempBlobFilePath))
                {
                    ProgressDialog dlg = new ProgressDialog();
                    dlg.Start(this, loader);

                    if (dlg.Error != null)
                    {
                        return;
                    }
                } // using

                // Instead of passing a byte[] array to the cell editor dialog - we'll pass
                // a reference to the dynamic file byte provider that is opened on the data file
                // that was written with the BLOB data. This allows us to conserve memory (BLOB
                // fields can be quite large).
                origProvider = new Be.Windows.Forms.DynamicFileByteProvider(Configuration.TempBlobFilePath);
                value        = origProvider;
            }

            // Open the cell editor dialog and allow the user to edit the contents of the field.
            DialogResult res = OpenCellEditDialog(table, column, ref value);

            if (res == DialogResult.Cancel)
            {
                return;
            }

            // This part of the IF statement deals with BLOB fields - these require
            // a special (and lengthy) handling.
            if (Utils.GetDbType(column.ColumnType) == DbType.Binary || value is Be.Windows.Forms.DynamicFileByteProvider)
            {
                if (otherBlob != null && (citem.Result == ComparisonResult.Same || citem.Result == ComparisonResult.DifferentData))
                {
                    if (otherBlob is long)
                    {
                        // Another adjustment for the other BLOB field value
                        long ob = (long)otherBlob;
                        if (ob == 0) // means NULL blob field
                        {
                            otherBlob = DBNull.Value;
                        }
                    }
                }

                if (value != DBNull.Value)
                {
                    string fpath      = null;
                    long   blobLength = 0;
                    if (value is Be.Windows.Forms.DynamicFileByteProvider)
                    {
                        Be.Windows.Forms.DynamicFileByteProvider dp = (Be.Windows.Forms.DynamicFileByteProvider)value;
                        if (dp.HasChanges())
                        {
                            dp.ApplyChanges();
                        }
                        dp.Dispose();

                        blobLength = dp.Length;
                    }
                    else
                    {
                        throw new InvalidOperationException("cell editor returned unexpected value");
                    }

                    BlobSaver saver = null;
                    try
                    {
                        // In this case we need to store the updated file/buffer back to the BLOB field
                        // and run BLOB comparison in order to check if the BLOB is different then
                        // the one in the other database.

                        // Save the file specified in the call as a BLOB
                        saver = new BlobSaver(dbpath, table.ObjectName.ToString(), column.ObjectName.ToString(), rowId, fpath);

                        ProgressDialog dlg = new ProgressDialog();
                        dlg.Start(this, saver);
                        if (dlg.Error != null)
                        {
                            // Notify that a row has changed
                            if (RowsChanged != null)
                            {
                                RowsChanged(this, EventArgs.Empty);
                            }

                            return;
                        }
                    }
                    finally
                    {
                        saver.Dispose();
                    } // finally

                    // Update the table change item with an indication that the BLOB field that was just saved
                    // is not null.
                    citem.SetField(column.ObjectName.ToString(), !right, (long)1);

                    if (otherBlob != null && (citem.Result == ComparisonResult.DifferentData || citem.Result == ComparisonResult.Same))
                    {
                        // At this point we need to compare the BLOB that was saved with the BLOB field in the other
                        // database in order to update the ChangedBlobsColumnNames field of the table change item so
                        // that the user can know if the BLOB is equal to the other BLOB or if the BLOB is different.
                        if (otherBlob != DBNull.Value)
                        {
                            // Run BLOB comparison
                            bool equalBlobs = false;
                            using (BlobCompareWorker bcw = new BlobCompareWorker(_leftdb, _rightdb,
                                                                                 SQLiteParser.Utils.Chop(table.ObjectName.ToString()),
                                                                                 SQLiteParser.Utils.Chop(column.ObjectName.ToString()),
                                                                                 citem.LeftRowId, citem.RightRowId))
                            {
                                ProgressDialog pdlg = new ProgressDialog();
                                pdlg.Start(this, bcw);
                                if (pdlg.Error != null)
                                {
                                    // Notify that a row has changed
                                    if (RowsChanged != null)
                                    {
                                        RowsChanged(this, EventArgs.Empty);
                                    }

                                    return;
                                }
                                equalBlobs = bcw.IsBlobsEqual;
                            } // using

                            if (equalBlobs)
                            {
                                // The two BLOBs are equal so remove any difference mark
                                if (citem.ChangedBlobsColumnNames != null && citem.ChangedBlobsColumnNames.Contains(column.ObjectName.ToString()))
                                {
                                    citem.ChangedBlobsColumnNames.Remove(column.ObjectName.ToString());
                                }
                            }
                            else
                            {
                                // The two BLOBs are different so add a difference mark if necessary
                                if (citem.ChangedBlobsColumnNames == null)
                                {
                                    citem.ChangedBlobsColumnNames = new List <string>();
                                }
                                if (!citem.ChangedBlobsColumnNames.Contains(column.ObjectName.ToString()))
                                {
                                    citem.ChangedBlobsColumnNames.Add(column.ObjectName.ToString());
                                }
                                citem.Result = ComparisonResult.DifferentData;
                            } // else
                        }
                        else
                        {
                            // If the other BLOB field is NULL - it means that the two BLOBs are different
                            // because one is NULL and the other is not.
                            if (citem.ChangedBlobsColumnNames == null)
                            {
                                citem.ChangedBlobsColumnNames = new List <string>();
                            }
                            if (!citem.ChangedBlobsColumnNames.Contains(column.ObjectName.ToString()))
                            {
                                citem.ChangedBlobsColumnNames.Add(column.ObjectName.ToString());
                            }
                            citem.Result = ComparisonResult.DifferentData;
                        } // else
                    }     // if
                }
                else
                {
                    // Ask the table changes object to set this field to null
                    _tableChanges.SetColumnField(_diff, sloc.RowIndex, column.ObjectName.ToString(), right, DBNull.Value);
                    citem.SetField(column.ObjectName.ToString(), !right, (long)0);

                    if (otherBlob != null && (citem.Result == ComparisonResult.Same || citem.Result == ComparisonResult.DifferentData))
                    {
                        // A BLOB field was set to NULL - compare it again to the other BLOB field and decide
                        // if the ChangedBlobsColumnNames field should be updated to reflect this.
                        if (otherBlob == DBNull.Value)
                        {
                            // The other BLOB field is NULL so the two fields are equal
                            if (citem.ChangedBlobsColumnNames != null && citem.ChangedBlobsColumnNames.Contains(column.ObjectName.ToString()))
                            {
                                citem.ChangedBlobsColumnNames.Remove(column.ObjectName.ToString());
                            }
                        }
                        else
                        {
                            if (citem.ChangedBlobsColumnNames == null)
                            {
                                citem.ChangedBlobsColumnNames = new List <string>();
                            }

                            // The other BLOB field is not NULL so the two fields are not equal
                            if (!citem.ChangedBlobsColumnNames.Contains(column.ObjectName.ToString()))
                            {
                                citem.ChangedBlobsColumnNames.Add(column.ObjectName.ToString());
                            }
                            citem.Result = ComparisonResult.DifferentData;
                        } // else
                    }     // if
                }         // else
            }
            else
            {
                // The field that was edited is not a BLOB so we can deal with it normally
                try
                {
                    _tableChanges.SetColumnField(_diff, sloc.RowIndex, column.ObjectName.ToString(), right, value);
                }
                catch (Exception ex)
                {
                    _log.Error("Failed to set column field", ex);
                    MessageBox.Show(this, ex.Message, "Operation Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                } // catch
            }     // else

            GC.Collect();

            // Mark that the table changes object does not contain precise results
            _tableChanges.HasPreciseResults = false;

            // Notify that a row has changed
            if (RowsChanged != null)
            {
                RowsChanged(this, EventArgs.Empty);
            }

            // Refresh the right/left grids again from the database.
            grdRight.RefreshLayout();
            grdLeft.RefreshLayout();
        }
        private void btnCompareData_Click(object sender, EventArgs e)
        {
            // Before comparing data we have to check if there are any BLOB columns
            // in the any common columns of the tables. If there are any - we have to
            // ask the user if he wants to compare BLOB fields or not.
            SQLiteCreateTableStatement   leftTable  = _item.LeftDdlStatement as SQLiteCreateTableStatement;
            SQLiteCreateTableStatement   rightTable = _item.RightDdlStatement as SQLiteCreateTableStatement;
            List <SQLiteColumnStatement> common     = Utils.GetCommonColumns(leftTable, rightTable);
            bool allowBlobComparison = false;

            if (Utils.ContainsBlobColumn(common))
            {
                DialogResult res = MessageBox.Show(this,
                                                   "At least one column that will be compared is a BLOB.\r\nComparing BLOB fields can potentially take " +
                                                   "a lot of time to perform.\r\nDo you want to disable BLOB content comparison in order\r\nto make " +
                                                   "the comparison go faster?",
                                                   "Disable BLOB Contents Comparison?",
                                                   MessageBoxButtons.YesNo,
                                                   MessageBoxIcon.Warning);
                if (res == DialogResult.No)
                {
                    allowBlobComparison = true;
                }
            }

            string errmsg;

            if (!Utils.IsTableComparisonAllowed(leftTable, rightTable,
                                                out errmsg, allowBlobComparison))
            {
                MessageBox.Show(this, errmsg, "Data comparison is not allowed",
                                MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            TableCompareWorker worker = new TableCompareWorker(
                leftTable, rightTable, _leftdb, _rightdb, allowBlobComparison);
            ProgressDialog dlg = new ProgressDialog();

            dlg.Start(this, worker);
            if (dlg.Error != null)
            {
                if (dlg.Error.GetType() != typeof(UserCancellationException))
                {
                    _item.ErrorMessage = dlg.Error.Message;
                }
                return;
            }
            _tableChanges = (TableChanges)dlg.Result;
            if (!tbcViews.TabPages.Contains(tbpData))
            {
                tbcViews.TabPages.Add(tbpData);
            }

            // Update the schema comparison item
            panel1.Visible     = false;
            _item.ErrorMessage = null;
            _item.TableChanges = _tableChanges;
            if (SchemaChanged != null)
            {
                SchemaChanged(this, EventArgs.Empty);
            }

            // Set the table changes object into the table diff control
            UpdateDataTab();

            tbcViews.SelectedTab = tbpData;
        }
        private void btnOK_Click(object sender, EventArgs e)
        {
            SearchDataWorker worker = null;
            string           sql;

            if (tbcSearch.SelectedTab == tbpExact)
            {
                string colName = (string)cboColumnName.SelectedItem;

                if (cbxValue.Checked)
                {
                    sql = FormatColumnValue(colName);
                }
                else
                {
                    sql = SQLiteParser.Utils.QuoteIfNeeded(colName) + " IS NULL";
                }
            }
            else
            {
                sql = txtSQL.Text.Trim();
            }
            worker = new SearchDataWorker(_isLeft, _diff, _changes, _rowIndex, -1, sql);

            ProgressDialog dlg = new ProgressDialog();

            dlg.Start(this, worker);

            if (dlg.Result != null)
            {
                _matchedRowIndex = (long)dlg.Result;
            }
            if (_matchedRowIndex == -1 && dlg.Error == null)
            {
                if (_rowIndex > 0)
                {
                    DialogResult res = MessageBox.Show(this, "No match was found, do you want to search from the beginning?",
                                                       "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
                    if (res == DialogResult.Yes)
                    {
                        worker = new SearchDataWorker(_isLeft, _diff, _changes, 0, _rowIndex - 1, sql);
                        dlg    = new ProgressDialog();
                        dlg.Start(this, worker);
                        if (dlg.Result != null)
                        {
                            _matchedRowIndex = (long)dlg.Result;
                        }
                        if (_matchedRowIndex != -1 || dlg.Error != null)
                        {
                            this.DialogResult = DialogResult.OK;
                        }
                        else
                        {
                            MessageBox.Show(this, "No match was found", "Search Completed", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                    }
                }
                else
                {
                    MessageBox.Show(this, "No match was found", "Search Completed", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            else
            {
                this.DialogResult = DialogResult.OK;
            }
        }