Пример #1
0
        /// <summary>
        /// Opens the search data dialog
        /// </summary>
        public void SearchData()
        {
            bool isLeft = grdLeft.Focused;
            SQLiteCreateTableStatement table =
                isLeft ? (SQLiteCreateTableStatement)_item.LeftDdlStatement : (SQLiteCreateTableStatement)_item.RightDdlStatement;

            FastGrid         grid  = isLeft ? grdLeft : grdRight;
            FastGridLocation loc   = grid.SelectedCellLocation;
            FastGridColumn   fcol  = grid.Columns[loc.ColumnIndex];
            string           cname = (string)fcol.Tag;

            _searchDialog.PrepareDialog(table.Columns, cname, _diff, _tableChanges, loc.RowIndex + 1, isLeft);
            DialogResult res = _searchDialog.ShowDialog(this);

            if (res == DialogResult.OK && _searchDialog.MatchedRowIndex != -1)
            {
                FastGridSelection sel = new FastGridSelection();
                sel.AddSelection(_searchDialog.MatchedRowIndex, _searchDialog.MatchedRowIndex);

                FastGridLocation nloc = new FastGridLocation(_searchDialog.MatchedRowIndex, loc.ColumnIndex);
                grdLeft.SelectedCellLocation  = nloc;
                grdLeft.Selection             = sel;
                grdRight.SelectedCellLocation = nloc;
                grdRight.Selection            = (FastGridSelection)sel.Clone();
            }
        }
Пример #2
0
        private bool CanEditGrid(bool right, out TableChangeItem citem, out FastGridLocation sloc)
        {
            citem = null;
            sloc  = FastGridLocation.Empty;
            if (_item == null)
            {
                return(false);
            }

            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;
            }

            sloc = grid.SelectedCellLocation;

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

            if (column == null)
            {
                return(false);
            }

            long total = _tableChanges.GetTotalChangesCount(new string[] { _diff });

            if (sloc.RowIndex >= total)
            {
                return(false);
            }
            citem = _tableChanges.GetChangeItem(_diff, sloc.RowIndex);

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

            return(true);
        }
Пример #3
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();
        }