Introduce new dialog "Synchronize database", see issue #1289. Complex code behind "Analyze" and "Apply" buttons is missing yet.

This commit is contained in:
Ansgar Becker
2011-08-22 05:57:57 +00:00
parent 994ad81bb2
commit 01ac4b40e3
6 changed files with 417 additions and 3 deletions

View File

@ -38,7 +38,8 @@ uses
event_editor in '..\..\source\event_editor.pas' {frmEventEditor: TFrame},
loginform in '..\..\source\loginform.pas' {frmLogin},
Cromis.DirectoryWatch in '..\..\source\Cromis.DirectoryWatch.pas',
exportgrid in '..\..\source\exportgrid.pas' {frmExportGrid};
exportgrid in '..\..\source\exportgrid.pas' {frmExportGrid},
syncdb in '..\..\source\syncdb.pas' {frmSyncDB};
{$R ..\..\res\icon.RES}
{$R ..\..\res\version.RES}

View File

@ -212,6 +212,9 @@
<DCCReference Include="..\..\source\exportgrid.pas">
<Form>frmExportGrid</Form>
</DCCReference>
<DCCReference Include="..\..\source\syncdb.pas">
<Form>frmSyncDB</Form>
</DCCReference>
<RcCompile Include="..\..\res\updater.rc">
<Form>updater.res</Form>
</RcCompile>

View File

@ -1850,6 +1850,9 @@ object MainForm: TMainForm
object Exportdata1: TMenuItem
Action = actExportData
end
object Synchronizedatabase1: TMenuItem
Action = actSynchronizeDatabase
end
end
object Help1: TMenuItem
Tag = 22
@ -2583,6 +2586,12 @@ object MainForm: TMainForm
ImageIndex = 165
OnExecute = actToggleCommentExecute
end
object actSynchronizeDatabase: TAction
Category = 'Export/Import'
Caption = 'Synchronize database'
ImageIndex = 27
OnExecute = actSynchronizeDatabaseExecute
end
end
object SaveDialog2: TSaveDialog
DefaultExt = 'reg'

View File

@ -18,7 +18,7 @@ uses
CommCtrl, Contnrs, Generics.Collections, SynEditExport, SynExportHTML, Math, ExtDlgs, Registry, AppEvnts,
routine_editor, trigger_editor, event_editor, options, EditVar, helpers, createdatabase, table_editor,
TableTools, View, Usermanager, SelectDBObject, connections, sqlhelp, dbconnection,
insertfiles, searchreplace, loaddata, copytable, VTHeaderPopup, Cromis.DirectoryWatch;
insertfiles, searchreplace, loaddata, copytable, VTHeaderPopup, Cromis.DirectoryWatch, SyncDB;
type
@ -503,6 +503,8 @@ type
actCancelOperation: TAction;
actToggleComment: TAction;
Uncomment1: TMenuItem;
actSynchronizeDatabase: TAction;
Synchronizedatabase1: TMenuItem;
Disconnect1: TMenuItem;
procedure actCreateDBObjectExecute(Sender: TObject);
procedure menuConnectionsPopup(Sender: TObject);
@ -812,6 +814,7 @@ type
procedure actCancelOperationExecute(Sender: TObject);
procedure AnyGridChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
procedure actToggleCommentExecute(Sender: TObject);
procedure actSynchronizeDatabaseExecute(Sender: TObject);
procedure DBtreeBeforeCellPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas;
Node: PVirtualNode; Column: TColumnIndex; CellPaintMode: TVTCellPaintMode; CellRect: TRect;
var ContentRect: TRect);
@ -3299,6 +3302,15 @@ begin
end;
procedure TMainForm.actSynchronizeDatabaseExecute(Sender: TObject);
var
SyncForm: TfrmSyncDB;
begin
SyncForm := TfrmSyncDB.Create(Self);
SyncForm.ShowModal;
end;
{***
Show SQL Help window directly using a keyword
@param String SQL-keyword
@ -9406,7 +9418,7 @@ var
begin
// Resize "Size" column in dbtree to hold widest possible byte numbers without cutting text
VT := Sender as TVirtualStringTree;
if coVisible in VT.Header.Columns[1].Options then
if (VT.Header.Columns.Count >= 2) and (coVisible in VT.Header.Columns[1].Options) then
VT.Header.Columns[1].Width := TextWidth(VT.Canvas, FormatByteNumber(SIZE_MB-1))+VT.TextMargin*2;
end;

210
source/syncdb.dfm Normal file
View File

@ -0,0 +1,210 @@
object frmSyncDB: TfrmSyncDB
Left = 0
Top = 0
Caption = 'frmSyncDB'
ClientHeight = 373
ClientWidth = 539
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
Position = poMainFormCenter
OnClose = FormClose
OnCreate = FormCreate
DesignSize = (
539
373)
PixelsPerInch = 96
TextHeight = 13
object lblSource: TLabel
Left = 8
Top = 8
Width = 169
Height = 13
Caption = 'Select source database or table(s):'
end
object lblDifferences: TLabel
Left = 207
Top = 191
Width = 59
Height = 13
Caption = 'Differences:'
end
object treeSource: TVirtualStringTree
Left = 8
Top = 24
Width = 193
Height = 310
AccessibleName = 'tree'
Anchors = [akLeft, akTop, akBottom]
Header.AutoSizeIndex = 0
Header.DefaultHeight = 17
Header.Font.Charset = DEFAULT_CHARSET
Header.Font.Color = clWindowText
Header.Font.Height = -11
Header.Font.Name = 'Tahoma'
Header.Font.Style = []
Header.Options = [hoAutoResize, hoColumnResize, hoDrag, hoShowSortGlyphs]
Images = MainForm.ImageListMain
TabOrder = 0
TreeOptions.MiscOptions = [toAcceptOLEDrop, toCheckSupport, toFullRepaintOnResize, toInitOnSave, toToggleOnDblClick, toWheelPanning, toEditOnClick]
TreeOptions.PaintOptions = [toHotTrack, toShowButtons, toShowDropmark, toShowRoot, toShowTreeLines, toThemeAware, toUseBlendedImages, toGhostedIfUnfocused, toUseExplorerTheme, toHideTreeLinesIfThemed]
OnChange = treeSourceChange
OnGetText = treeSourceGetText
OnPaintText = treeSourcePaintText
OnGetImageIndex = treeSourceGetImageIndex
OnGetNodeDataSize = treeSourceGetNodeDataSize
OnInitChildren = treeSourceInitChildren
OnInitNode = treeSourceInitNode
Columns = <
item
Position = 0
Width = 193
WideText = 'Name'
end>
end
object grpTarget: TGroupBox
Left = 207
Top = 8
Width = 324
Height = 105
Anchors = [akLeft, akTop, akRight]
Caption = 'Target database or table'
TabOrder = 1
DesignSize = (
324
105)
object lblTargetServer: TLabel
Left = 9
Top = 21
Width = 36
Height = 13
Caption = 'Server:'
end
object lblTargetDatabase: TLabel
Left = 9
Top = 48
Width = 50
Height = 13
Caption = 'Database:'
end
object lblTargetTable: TLabel
Left = 9
Top = 75
Width = 30
Height = 13
Caption = 'Table:'
end
object comboTargetServer: TComboBox
Left = 88
Top = 18
Width = 228
Height = 21
Style = csDropDownList
Anchors = [akLeft, akTop, akRight]
TabOrder = 0
OnChange = comboTargetServerChange
end
object comboTargetDatabase: TComboBox
Left = 88
Top = 45
Width = 228
Height = 21
Style = csDropDownList
Anchors = [akLeft, akTop, akRight]
TabOrder = 1
OnChange = comboTargetDatabaseChange
end
object comboTargetTable: TComboBox
Left = 88
Top = 72
Width = 228
Height = 21
Style = csDropDownList
Anchors = [akLeft, akTop, akRight]
TabOrder = 2
end
end
object btnClose: TButton
Left = 456
Top = 340
Width = 75
Height = 25
Anchors = [akRight, akBottom]
Cancel = True
Caption = 'Close'
ImageIndex = 26
Images = MainForm.ImageListMain
ModalResult = 2
TabOrder = 2
end
object btnApply: TButton
Left = 375
Top = 340
Width = 75
Height = 25
Anchors = [akRight, akBottom]
Caption = 'Apply'
Enabled = False
ImageIndex = 120
Images = MainForm.ImageListMain
TabOrder = 3
end
object btnAnalyze: TButton
Left = 294
Top = 340
Width = 75
Height = 25
Anchors = [akRight, akBottom]
Caption = 'Analyze'
ImageIndex = 146
Images = MainForm.ImageListMain
TabOrder = 4
end
object grpOptions: TGroupBox
Left = 207
Top = 119
Width = 324
Height = 66
Anchors = [akLeft, akTop, akRight]
Caption = 'Options'
TabOrder = 5
object radioOptionsStructure: TCheckBox
Left = 88
Top = 16
Width = 97
Height = 17
Caption = 'Structure'
TabOrder = 0
end
object radioOptionsData: TCheckBox
Left = 88
Top = 39
Width = 97
Height = 17
Caption = 'Data'
TabOrder = 1
end
end
object treeDifferences: TVirtualStringTree
Left = 207
Top = 208
Width = 324
Height = 126
Anchors = [akLeft, akTop, akRight, akBottom]
Header.AutoSizeIndex = 0
Header.DefaultHeight = 17
Header.Font.Charset = DEFAULT_CHARSET
Header.Font.Color = clWindowText
Header.Font.Height = -11
Header.Font.Name = 'Tahoma'
Header.Font.Style = []
Header.MainColumn = -1
Images = MainForm.ImageListMain
TabOrder = 6
Columns = <>
end
end

179
source/syncdb.pas Normal file
View File

@ -0,0 +1,179 @@
unit syncdb;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, VirtualTrees;
type
TfrmSyncDB = class(TForm)
treeSource: TVirtualStringTree;
lblSource: TLabel;
grpTarget: TGroupBox;
comboTargetServer: TComboBox;
lblTargetServer: TLabel;
lblTargetDatabase: TLabel;
comboTargetDatabase: TComboBox;
comboTargetTable: TComboBox;
lblTargetTable: TLabel;
btnClose: TButton;
btnApply: TButton;
btnAnalyze: TButton;
grpOptions: TGroupBox;
radioOptionsStructure: TCheckBox;
radioOptionsData: TCheckBox;
treeDifferences: TVirtualStringTree;
lblDifferences: TLabel;
procedure treeSourceChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
procedure treeSourceGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer);
procedure treeSourceGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
procedure treeSourceGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
TextType: TVSTTextType; var CellText: string);
procedure treeSourceInitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode;
var ChildCount: Cardinal);
procedure treeSourceInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode;
var InitialStates: TVirtualNodeInitStates);
procedure treeSourcePaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure comboTargetServerChange(Sender: TObject);
procedure comboTargetDatabaseChange(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
implementation
uses main, helpers, dbconnection;
{$R *.dfm}
procedure TfrmSyncDB.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
procedure TfrmSyncDB.FormCreate(Sender: TObject);
begin
InheritFont(Font);
SetWindowSizeGrip(Self.Handle, True);
FixVT(treeSource);
FixVT(treeDifferences);
treeSource.RootNodeCount := Mainform.DBtree.RootNodeCount;
MainReg.OpenKey(RegPath + REGKEY_SESSIONS, True);
MainReg.GetKeyNames(comboTargetServer.Items);
comboTargetServer.Items.Insert(0, 'Select server session ...');
comboTargetServer.ItemIndex := 0;
end;
procedure TfrmSyncDB.comboTargetServerChange(Sender: TObject);
var
Parameters: TConnectionParameters;
Connection: TDBConnection;
begin
comboTargetDatabase.Clear;
if comboTargetServer.ItemIndex > 0 then begin
Parameters := LoadConnectionParams(comboTargetServer.Text);
Connection := Parameters.CreateConnection(Self);
Connection.OnLog := MainForm.LogSQL;
Connection.LogPrefix := comboTargetServer.Text;
Connection.Active := True;
comboTargetDatabase.Items.Assign(Connection.AllDatabases);
Connection.Active := False;
Connection.Free;
end;
comboTargetDatabase.Items.Insert(0, '[Same as source]');
comboTargetDatabase.ItemIndex := 0;
end;
procedure TfrmSyncDB.comboTargetDatabaseChange(Sender: TObject);
var
Parameters: TConnectionParameters;
Connection: TDBConnection;
Objects: TDBObjectList;
Obj: TDBObject;
begin
comboTargetTable.Clear;
if comboTargetDatabase.ItemIndex > 0 then begin
Parameters := LoadConnectionParams(comboTargetServer.Text);
Connection := Parameters.CreateConnection(Self);
Connection.OnLog := MainForm.LogSQL;
Connection.LogPrefix := comboTargetServer.Text;
Connection.Active := True;
Objects := Connection.GetDBObjects(comboTargetDatabase.Text);
for Obj in Objects do begin
if Obj.NodeType = lntTable then
comboTargetTable.Items.Add(Obj.Name);
end;
Connection.Active := False;
Connection.Free;
end;
comboTargetTable.Items.Insert(0, '[Same as source]');
comboTargetTable.ItemIndex := 0;
end;
procedure TfrmSyncDB.treeSourceChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
begin
MainForm.DBtree.OnChange(Sender, Node);
end;
procedure TfrmSyncDB.treeSourceGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer);
begin
MainForm.DBtree.OnGetImageIndex(Sender, Node, Kind, Column, Ghosted, ImageIndex);
end;
procedure TfrmSyncDB.treeSourceGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
begin
MainForm.DBtree.OnGetNodeDataSize(Sender, NodeDataSize);
end;
procedure TfrmSyncDB.treeSourceGetText(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var CellText: string);
begin
MainForm.DBtree.OnGetText(Sender, Node, Column, TextType, CellText);
end;
procedure TfrmSyncDB.treeSourceInitChildren(Sender: TBaseVirtualTree;
Node: PVirtualNode; var ChildCount: Cardinal);
begin
MainForm.DBtree.OnInitChildren(Sender, Node, ChildCount);
end;
procedure TfrmSyncDB.treeSourceInitNode(Sender: TBaseVirtualTree; ParentNode,
Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
begin
MainForm.DBtree.OnInitNode(Sender, ParentNode, Node, InitialStates);
if Sender.GetNodeLevel(Node) in [1, 2] then begin
Node.CheckType := ctTriStateCheckBox;
Node.CheckState := csUncheckedNormal;
end;
end;
procedure TfrmSyncDB.treeSourcePaintText(Sender: TBaseVirtualTree;
const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
TextType: TVSTTextType);
begin
MainForm.DBtree.OnPaintText(Sender, TargetCanvas, Node, Column, TextType);
end;
end.