mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-06 18:24:26 +08:00
Introduce new dialog "Synchronize database", see issue #1289. Complex code behind "Analyze" and "Apply" buttons is missing yet.
This commit is contained in:
@ -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}
|
||||
|
@ -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>
|
||||
|
@ -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'
|
||||
|
@ -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
210
source/syncdb.dfm
Normal 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
179
source/syncdb.pas
Normal 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.
|
Reference in New Issue
Block a user