/// <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(); } }
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); }
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(); }