mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-26 11:17:57 +08:00
Internal refactoring: Directly bind TDBObject's to nodes in ListTables, instead of copying everything to an internal array structure first. Most events on ListTables have their own procedures now. Also, when selecting a database in the tree without expanding it and a query tab is selected, do not fetch objects. Could annoy some SQL writers which won't see the objects in selected db highlighted in that case. On the other hand this avoids loading objects in situations where you don't need them. For larger databases this should be really helpful, e.g. for the reporter of issue #1742.
This commit is contained in:
@ -95,14 +95,11 @@ procedure TCopyTableForm.FormShow(Sender: TObject);
|
|||||||
var
|
var
|
||||||
i : Integer;
|
i : Integer;
|
||||||
struc_data : Byte;
|
struc_data : Byte;
|
||||||
NodeData: PVTreeData;
|
|
||||||
begin
|
begin
|
||||||
if Mainform.DBtree.Focused then
|
if Mainform.DBtree.Focused then
|
||||||
oldTableName := Mainform.SelectedTable.Name
|
oldTableName := Mainform.SelectedTable.Name
|
||||||
else begin
|
else
|
||||||
NodeData := Mainform.ListTables.GetNodeData(Mainform.ListTables.FocusedNode);
|
oldTableName := Mainform.ListTables.Text[Mainform.ListTables.FocusedNode, 0];
|
||||||
oldTableName := NodeData.Captions[0];
|
|
||||||
end;
|
|
||||||
editNewTablename.Text := oldTableName + '_copy';
|
editNewTablename.Text := oldTableName + '_copy';
|
||||||
editNewTablename.SetFocus;
|
editNewTablename.SetFocus;
|
||||||
lblNewTablename.Caption := 'Copy ''' + oldTableName + ''' to new table:';
|
lblNewTablename.Caption := 'Copy ''' + oldTableName + ''' to new table:';
|
||||||
|
@ -876,18 +876,18 @@ object MainForm: TMainForm
|
|||||||
TreeOptions.PaintOptions = [toHotTrack, toShowDropmark, toShowHorzGridLines, toShowVertGridLines, toThemeAware, toUseBlendedImages, toUseExplorerTheme]
|
TreeOptions.PaintOptions = [toHotTrack, toShowDropmark, toShowHorzGridLines, toShowVertGridLines, toThemeAware, toUseBlendedImages, toUseExplorerTheme]
|
||||||
TreeOptions.SelectionOptions = [toFullRowSelect, toMultiSelect, toRightClickSelect]
|
TreeOptions.SelectionOptions = [toFullRowSelect, toMultiSelect, toRightClickSelect]
|
||||||
OnAfterPaint = vstAfterPaint
|
OnAfterPaint = vstAfterPaint
|
||||||
|
OnBeforePaint = ListTablesBeforePaint
|
||||||
OnChange = ListTablesChange
|
OnChange = ListTablesChange
|
||||||
OnCompareNodes = vstCompareNodes
|
OnCompareNodes = vstCompareNodes
|
||||||
OnDblClick = ListTablesDblClick
|
OnDblClick = ListTablesDblClick
|
||||||
OnEditing = ListTablesEditing
|
OnEditing = ListTablesEditing
|
||||||
OnFreeNode = vstFreeNode
|
OnGetText = ListTablesGetText
|
||||||
OnGetText = vstGetText
|
OnGetImageIndex = ListTablesGetImageIndex
|
||||||
OnGetImageIndex = vstGetImageIndex
|
|
||||||
OnGetHint = vstGetHint
|
OnGetHint = vstGetHint
|
||||||
OnGetNodeDataSize = vstGetNodeDataSize
|
OnGetNodeDataSize = ListTablesGetNodeDataSize
|
||||||
OnHeaderClick = vstHeaderClick
|
OnHeaderClick = vstHeaderClick
|
||||||
OnHeaderDraggedOut = vstHeaderDraggedOut
|
OnHeaderDraggedOut = vstHeaderDraggedOut
|
||||||
OnInitNode = vstInitNode
|
OnInitNode = ListTablesInitNode
|
||||||
OnNewText = ListTablesNewText
|
OnNewText = ListTablesNewText
|
||||||
Columns = <
|
Columns = <
|
||||||
item
|
item
|
||||||
|
293
source/main.pas
293
source/main.pas
@ -550,10 +550,7 @@ type
|
|||||||
procedure ValidateControls(Sender: TObject);
|
procedure ValidateControls(Sender: TObject);
|
||||||
procedure ValidateQueryControls(Sender: TObject);
|
procedure ValidateQueryControls(Sender: TObject);
|
||||||
procedure RefreshQueryHelpers;
|
procedure RefreshQueryHelpers;
|
||||||
procedure LoadDatabaseProperties(db: String);
|
|
||||||
procedure ShowHost;
|
procedure ShowHost;
|
||||||
procedure ShowDatabase(db: String);
|
|
||||||
procedure ShowDBProperties(db: String);
|
|
||||||
procedure DataGridBeforePaint(Sender: TBaseVirtualTree;
|
procedure DataGridBeforePaint(Sender: TBaseVirtualTree;
|
||||||
TargetCanvas: TCanvas);
|
TargetCanvas: TCanvas);
|
||||||
procedure LogSQL(Msg: String; Category: TMySQLLogCategory=lcInfo);
|
procedure LogSQL(Msg: String; Category: TMySQLLogCategory=lcInfo);
|
||||||
@ -676,6 +673,14 @@ type
|
|||||||
procedure ListStatusBeforePaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas);
|
procedure ListStatusBeforePaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas);
|
||||||
procedure ListProcessesBeforePaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas);
|
procedure ListProcessesBeforePaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas);
|
||||||
procedure ListCommandStatsBeforePaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas);
|
procedure ListCommandStatsBeforePaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas);
|
||||||
|
procedure ListTablesBeforePaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas);
|
||||||
|
procedure ListTablesGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind;
|
||||||
|
Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer);
|
||||||
|
procedure ListTablesGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
|
||||||
|
procedure ListTablesGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
||||||
|
Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
|
||||||
|
procedure ListTablesInitNode(Sender: TBaseVirtualTree; ParentNode,
|
||||||
|
Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
|
||||||
procedure vstAfterPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas);
|
procedure vstAfterPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas);
|
||||||
procedure actCopyOrCutExecute(Sender: TObject);
|
procedure actCopyOrCutExecute(Sender: TObject);
|
||||||
procedure actPasteExecute(Sender: TObject);
|
procedure actPasteExecute(Sender: TObject);
|
||||||
@ -806,8 +811,7 @@ type
|
|||||||
VTRowDataListVariables,
|
VTRowDataListVariables,
|
||||||
VTRowDataListStatus,
|
VTRowDataListStatus,
|
||||||
VTRowDataListProcesses,
|
VTRowDataListProcesses,
|
||||||
VTRowDataListCommandStats,
|
VTRowDataListCommandStats: TVTreeDataArray;
|
||||||
VTRowDataListTables: TVTreeDataArray;
|
|
||||||
|
|
||||||
// Variables set by preferences dialog
|
// Variables set by preferences dialog
|
||||||
prefRememberFilters: Boolean;
|
prefRememberFilters: Boolean;
|
||||||
@ -1945,6 +1949,7 @@ procedure TMainForm.actTableToolsExecute(Sender: TObject);
|
|||||||
var
|
var
|
||||||
Act: TAction;
|
Act: TAction;
|
||||||
InDBTree: Boolean;
|
InDBTree: Boolean;
|
||||||
|
Node: PVirtualNode;
|
||||||
begin
|
begin
|
||||||
// Show table tools dialog
|
// Show table tools dialog
|
||||||
if TableToolsDialog = nil then
|
if TableToolsDialog = nil then
|
||||||
@ -1954,8 +1959,13 @@ begin
|
|||||||
and (TPopupMenu((Act.ActionComponent as TMenuItem).GetParentMenu).PopupComponent = DBTree);
|
and (TPopupMenu((Act.ActionComponent as TMenuItem).GetParentMenu).PopupComponent = DBTree);
|
||||||
if InDBTree then
|
if InDBTree then
|
||||||
TableToolsDialog.SelectedTables.Text := SelectedTable.Name
|
TableToolsDialog.SelectedTables.Text := SelectedTable.Name
|
||||||
else
|
else begin
|
||||||
TableToolsDialog.SelectedTables := GetVTCaptions(ListTables, True);
|
Node := ListTables.GetFirstSelected;
|
||||||
|
while Assigned(Node) do begin
|
||||||
|
TableToolsDialog.SelectedTables.Add(ListTables.Text[Node, 0]);
|
||||||
|
Node := ListTables.GetNextSelected(Node);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
if Sender = actMaintenance then
|
if Sender = actMaintenance then
|
||||||
TableToolsDialog.ToolMode := tmMaintenance
|
TableToolsDialog.ToolMode := tmMaintenance
|
||||||
else if Sender = actFindTextOnServer then
|
else if Sender = actFindTextOnServer then
|
||||||
@ -2318,11 +2328,12 @@ end;
|
|||||||
procedure TMainForm.actDropObjectsExecute(Sender: TObject);
|
procedure TMainForm.actDropObjectsExecute(Sender: TObject);
|
||||||
var
|
var
|
||||||
AllCount : Integer;
|
AllCount : Integer;
|
||||||
Tables, Views, Functions, Procedures, Triggers: TStringList;
|
Tables, Views, Functions, Procedures, Triggers, List: TStringList;
|
||||||
msg, activeDB : String;
|
msg, activeDB : String;
|
||||||
InDBTree: Boolean;
|
InDBTree: Boolean;
|
||||||
Act: TAction;
|
Act: TAction;
|
||||||
Node: PVirtualNode;
|
Node: PVirtualNode;
|
||||||
|
Obj: PDBObject;
|
||||||
|
|
||||||
procedure DoDrop(Kind: String; List: TStringList; MultiDrops: Boolean);
|
procedure DoDrop(Kind: String; List: TStringList; MultiDrops: Boolean);
|
||||||
var
|
var
|
||||||
@ -2389,11 +2400,19 @@ begin
|
|||||||
end;
|
end;
|
||||||
end else begin
|
end else begin
|
||||||
// Invoked from database tab
|
// Invoked from database tab
|
||||||
Tables := GetVTCaptions(ListTables, True, 0, [lntTable]);
|
Node := ListTables.GetFirstSelected;
|
||||||
Views := GetVTCaptions(ListTables, True, 0, [lntView]);
|
while Assigned(Node) do begin
|
||||||
Procedures := GetVTCaptions(ListTables, True, 0, [lntProcedure]);
|
Obj := ListTables.GetNodeData(Node);
|
||||||
Functions := GetVTCaptions(ListTables, True, 0, [lntFunction]);
|
case Obj.NodeType of
|
||||||
Triggers := GetVTCaptions(ListTables, True, 0, [lntTrigger]);
|
lntView: List := Views;
|
||||||
|
lntProcedure: List := Procedures;
|
||||||
|
lntFunction: List := Functions;
|
||||||
|
lntTrigger: List := Triggers;
|
||||||
|
else List := Tables;
|
||||||
|
end;
|
||||||
|
List.Add(Obj.Name);
|
||||||
|
Node := ListTables.GetNextSelected(Node);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Fix actions temporarily enabled for popup menu.
|
// Fix actions temporarily enabled for popup menu.
|
||||||
@ -2492,6 +2511,7 @@ begin
|
|||||||
ConnectionAttempt := TMySQLConnection.Create(Self);
|
ConnectionAttempt := TMySQLConnection.Create(Self);
|
||||||
ConnectionAttempt.OnLog := LogSQL;
|
ConnectionAttempt.OnLog := LogSQL;
|
||||||
ConnectionAttempt.OnDatabaseChanged := DatabaseChanged;
|
ConnectionAttempt.OnDatabaseChanged := DatabaseChanged;
|
||||||
|
ConnectionAttempt.ObjectNamesInSelectedDB := SynSQLSyn1.TableNames;
|
||||||
ConnectionAttempt.Parameters := Params;
|
ConnectionAttempt.Parameters := Params;
|
||||||
try
|
try
|
||||||
ConnectionAttempt.Active := True;
|
ConnectionAttempt.Active := True;
|
||||||
@ -2732,8 +2752,8 @@ begin
|
|||||||
List.Tag := VTREE_NOTLOADED;
|
List.Tag := VTREE_NOTLOADED;
|
||||||
List.Repaint;
|
List.Repaint;
|
||||||
end else if tab1 = tabDatabase then begin
|
end else if tab1 = tabDatabase then begin
|
||||||
RefreshTreeDB(ActiveDatabase);
|
ListTables.Tag := VTREE_NOTLOADED_PURGECACHE;
|
||||||
LoadDatabaseProperties(ActiveDatabase);
|
ListTables.Invalidate;
|
||||||
end else if tab1 = tabData then begin
|
end else if tab1 = tabData then begin
|
||||||
DataGrid.Tag := VTREE_NOTLOADED_PURGECACHE;
|
DataGrid.Tag := VTREE_NOTLOADED_PURGECACHE;
|
||||||
DataGrid.Invalidate;
|
DataGrid.Invalidate;
|
||||||
@ -3315,21 +3335,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TMainForm.ShowDatabase(db: String);
|
|
||||||
begin
|
|
||||||
if (not DBtree.Dragging) and (
|
|
||||||
(PageControlMain.ActivePage = tabHost) or
|
|
||||||
(PageControlMain.ActivePage = tabData)
|
|
||||||
) then PageControlMain.ActivePage := tabDatabase;
|
|
||||||
|
|
||||||
tabDatabase.TabVisible := true;
|
|
||||||
tabEditor.TabVisible := false;
|
|
||||||
tabData.TabVisible := false;
|
|
||||||
|
|
||||||
ShowDBProperties( db );
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure TMainForm.actDataShowNextExecute(Sender: TObject);
|
procedure TMainForm.actDataShowNextExecute(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
// Show next X rows in datagrid
|
// Show next X rows in datagrid
|
||||||
@ -3677,83 +3682,38 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TMainForm.LoadDatabaseProperties(db: String);
|
procedure TMainForm.ListTablesBeforePaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas);
|
||||||
var
|
var
|
||||||
i, img, NumObj: Integer;
|
i, NumObj: Integer;
|
||||||
Obj: TDBObject;
|
Obj: TDBObject;
|
||||||
Objects: TDBObjectList;
|
Objects: TDBObjectList;
|
||||||
Cap, SelectedCaptions, NumObjects: TStringList;
|
NumObjects: TStringList;
|
||||||
Msg: String;
|
Msg: String;
|
||||||
|
vt: TVirtualStringTree;
|
||||||
begin
|
begin
|
||||||
// DB-Properties
|
// DB-Properties
|
||||||
|
vt := Sender as TVirtualStringTree;
|
||||||
|
if vt.Tag = VTREE_LOADED then
|
||||||
|
Exit;
|
||||||
|
|
||||||
Screen.Cursor := crHourGlass;
|
Screen.Cursor := crHourGlass;
|
||||||
|
|
||||||
// Remember selected nodes
|
ShowStatus( 'Displaying objects from "' + ActiveDatabase + '" ...' );
|
||||||
SelectedCaptions := GetVTCaptions(ListTables, True);
|
Objects := Connection.GetDBObjects(ActiveDatabase, vt.Tag = VTREE_NOTLOADED_PURGECACHE);
|
||||||
|
|
||||||
Objects := Connection.GetDBObjects(db);
|
|
||||||
NumObjects := TStringList.Create;
|
|
||||||
ShowStatus( 'Displaying objects from "' + db + '" ...' );
|
|
||||||
|
|
||||||
ListTables.BeginUpdate;
|
ListTables.BeginUpdate;
|
||||||
ListTables.Clear;
|
ListTables.RootNodeCount := Objects.Count;
|
||||||
|
ListTables.ReinitChildren(nil, false);
|
||||||
|
ListTables.EndUpdate;
|
||||||
|
vt.Tag := VTREE_LOADED;
|
||||||
|
|
||||||
SetLength(VTRowDataListTables, Objects.Count);
|
NumObjects := TStringList.Create;
|
||||||
for i:=0 to Objects.Count-1 do begin
|
for i:=0 to Objects.Count-1 do begin
|
||||||
Obj := Objects[i];
|
Obj := Objects[i];
|
||||||
VTRowDataListTables[i].Captions := TStringList.Create;
|
|
||||||
Cap := VTRowDataListTables[i].Captions;
|
|
||||||
// Object name
|
|
||||||
Cap.Add(Obj.Name);
|
|
||||||
if Obj.Rows > -1 then Cap.Add(FormatNumber(Obj.Rows))
|
|
||||||
else Cap.Add('');
|
|
||||||
if Obj.Size > -1 then Cap.Add(FormatByteNumber(Obj.Size))
|
|
||||||
else Cap.Add('');
|
|
||||||
VTRowDataListTables[i].NodeType := Obj.NodeType;
|
|
||||||
// Find icon
|
|
||||||
case Obj.NodeType of
|
|
||||||
lntTable: img := ICONINDEX_TABLE;
|
|
||||||
lntView: img := ICONINDEX_VIEW;
|
|
||||||
lntProcedure: img := ICONINDEX_STOREDPROCEDURE;
|
|
||||||
lntFunction: img := ICONINDEX_STOREDFUNCTION;
|
|
||||||
lntTrigger: img := ICONINDEX_TRIGGER;
|
|
||||||
else img := -1;
|
|
||||||
end;
|
|
||||||
NumObj := StrToIntDef(NumObjects.Values[Obj.ObjType], 0);
|
NumObj := StrToIntDef(NumObjects.Values[Obj.ObjType], 0);
|
||||||
Inc(NumObj);
|
Inc(NumObj);
|
||||||
NumObjects.Values[Obj.ObjType] := IntToStr(NumObj);
|
NumObjects.Values[Obj.ObjType] := IntToStr(NumObj);
|
||||||
VTRowDataListTables[i].ImageIndex := img;
|
|
||||||
if Obj.Created = 0 then Cap.Add('')
|
|
||||||
else Cap.Add(DateTimeToStr(Obj.Created));
|
|
||||||
if Obj.Updated = 0 then Cap.Add('')
|
|
||||||
else Cap.Add(DateTimeToStr(Obj.Updated));
|
|
||||||
Cap.Add(Obj.Engine);
|
|
||||||
Cap.Add(Obj.Comment);
|
|
||||||
if Obj.Version > -1 then Cap.Add(IntToStr(Obj.Version))
|
|
||||||
else Cap.Add('');
|
|
||||||
Cap.Add(Obj.RowFormat);
|
|
||||||
if Obj.AvgRowLen > -1 then Cap.Add(FormatByteNumber(Obj.AvgRowLen))
|
|
||||||
else Cap.Add('');
|
|
||||||
if Obj.MaxDataLen > -1 then Cap.Add(FormatByteNumber(Obj.MaxDataLen))
|
|
||||||
else Cap.Add('');
|
|
||||||
if Obj.IndexLen > -1 then Cap.Add(FormatByteNumber(Obj.IndexLen))
|
|
||||||
else Cap.Add('');
|
|
||||||
if Obj.DataFree > -1 then Cap.Add(FormatByteNumber(Obj.DataFree))
|
|
||||||
else Cap.Add('');
|
|
||||||
if Obj.AutoInc > -1 then Cap.Add(FormatNumber(Obj.AutoInc))
|
|
||||||
else Cap.Add('');
|
|
||||||
if Obj.LastChecked = 0 then Cap.Add('')
|
|
||||||
else Cap.Add(DateTimeToStr(Obj.LastChecked));
|
|
||||||
Cap.Add(Obj.Collation);
|
|
||||||
if Obj.Checksum > -1 then Cap.Add(IntToStr(Obj.Checksum))
|
|
||||||
else Cap.Add('');
|
|
||||||
Cap.Add(Obj.CreateOptions);
|
|
||||||
Cap.Add(Obj.ObjType);
|
|
||||||
end;
|
end;
|
||||||
ListTables.RootNodeCount := Length(VTRowDataListTables);
|
Msg := ActiveDatabase + ': ' + FormatNumber(Objects.Count) + ' ';
|
||||||
ListTables.EndUpdate;
|
|
||||||
SetVTSelection(ListTables, SelectedCaptions);
|
|
||||||
Msg := db + ': ' + FormatNumber(Objects.Count) + ' ';
|
|
||||||
if NumObjects.Count = 1 then
|
if NumObjects.Count = 1 then
|
||||||
Msg := Msg + LowerCase(NumObjects.Names[0])
|
Msg := Msg + LowerCase(NumObjects.Names[0])
|
||||||
else
|
else
|
||||||
@ -3772,23 +3732,84 @@ begin
|
|||||||
Delete(Msg, Length(Msg)-1, 2);
|
Delete(Msg, Length(Msg)-1, 2);
|
||||||
Msg := Msg + ')';
|
Msg := Msg + ')';
|
||||||
end;
|
end;
|
||||||
showstatus(Msg, 0);
|
ShowStatus(Msg, 0);
|
||||||
tabDatabase.Caption := sstr('Database: ' + db, 30);
|
|
||||||
ShowStatus(STATUS_MSG_READY);
|
ShowStatus(STATUS_MSG_READY);
|
||||||
Screen.Cursor := crDefault;
|
Screen.Cursor := crDefault;
|
||||||
// Ensure tree db node displays its chidren initialized
|
// Ensure tree db node displays its chidren initialized
|
||||||
DBtree.ReinitChildren(FindDBNode(db), False);
|
DBtree.ReinitChildren(FindDBNode(ActiveDatabase), False);
|
||||||
ValidateControls(Self);
|
ValidateControls(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ Show tables and their properties on the tabsheet "Database" }
|
procedure TMainForm.ListTablesGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
||||||
procedure TMainForm.ShowDBProperties(db: String);
|
Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer);
|
||||||
|
var
|
||||||
|
Obj: PDBObject;
|
||||||
begin
|
begin
|
||||||
Screen.Cursor := crHourglass;
|
if not (Kind in [ikNormal, ikSelected]) then
|
||||||
PageControlMainChange(Self);
|
Exit;
|
||||||
ShowStatus( STATUS_MSG_READY );
|
if Column <> (Sender as TVirtualStringTree).Header.MainColumn then
|
||||||
Screen.Cursor := crDefault;
|
Exit;
|
||||||
|
Obj := Sender.GetNodeData(Node);
|
||||||
|
case Obj.NodeType of
|
||||||
|
lntTable: ImageIndex := ICONINDEX_TABLE;
|
||||||
|
lntView: ImageIndex := ICONINDEX_VIEW;
|
||||||
|
lntProcedure: ImageIndex := ICONINDEX_STOREDPROCEDURE;
|
||||||
|
lntFunction: ImageIndex := ICONINDEX_STOREDFUNCTION;
|
||||||
|
lntTrigger: ImageIndex := ICONINDEX_TRIGGER;
|
||||||
|
else ImageIndex := -1;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TMainForm.ListTablesGetNodeDataSize(Sender: TBaseVirtualTree;
|
||||||
|
var NodeDataSize: Integer);
|
||||||
|
begin
|
||||||
|
NodeDataSize := SizeOf(TDBObject);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TMainForm.ListTablesGetText(Sender: TBaseVirtualTree;
|
||||||
|
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
|
||||||
|
var CellText: string);
|
||||||
|
var
|
||||||
|
Obj: PDBObject;
|
||||||
|
begin
|
||||||
|
Obj := Sender.GetNodeData(Node);
|
||||||
|
CellText := '';
|
||||||
|
case Column of
|
||||||
|
0: CellText := Obj.Name;
|
||||||
|
1: if Obj.Rows > -1 then CellText := FormatNumber(Obj.Rows);
|
||||||
|
2: if Obj.Size > -1 then CellText := FormatByteNumber(Obj.Size);
|
||||||
|
3: if Obj.Created <> 0 then CellText := DateTimeToStr(Obj.Created);
|
||||||
|
4: if Obj.Updated <> 0 then CellText := DateTimeToStr(Obj.Updated);
|
||||||
|
5: CellText := Obj.Engine;
|
||||||
|
6: CellText := Obj.Comment;
|
||||||
|
7: if Obj.Version > -1 then CellText := IntToStr(Obj.Version);
|
||||||
|
8: CellText := Obj.RowFormat;
|
||||||
|
9: if Obj.AvgRowLen > -1 then CellText := FormatByteNumber(Obj.AvgRowLen);
|
||||||
|
10: if Obj.MaxDataLen > -1 then CellText := FormatByteNumber(Obj.MaxDataLen);
|
||||||
|
11: if Obj.IndexLen > -1 then CellText := FormatByteNumber(Obj.IndexLen);
|
||||||
|
12: if Obj.DataFree > -1 then CellText := FormatByteNumber(Obj.DataFree);
|
||||||
|
13: if Obj.AutoInc > -1 then CellText := FormatNumber(Obj.AutoInc);
|
||||||
|
14: if Obj.LastChecked <> 0 then CellText := DateTimeToStr(Obj.LastChecked);
|
||||||
|
15: CellText := Obj.Collation;
|
||||||
|
16: if Obj.Checksum > -1 then CellText := IntToStr(Obj.Checksum);
|
||||||
|
17: CellText := Obj.CreateOptions;
|
||||||
|
18: CellText := Obj.ObjType;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TMainForm.ListTablesInitNode(Sender: TBaseVirtualTree; ParentNode,
|
||||||
|
Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
|
||||||
|
var
|
||||||
|
Obj: PDBObject;
|
||||||
|
Objects: TDBObjectList;
|
||||||
|
begin
|
||||||
|
Obj := Sender.GetNodeData(Node);
|
||||||
|
Objects := Connection.GetDBObjects(ActiveDatabase);
|
||||||
|
Obj^ := Objects[Node.Index];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -4343,11 +4364,11 @@ end;
|
|||||||
procedure TMainForm.ListTablesEditing(Sender: TBaseVirtualTree;
|
procedure TMainForm.ListTablesEditing(Sender: TBaseVirtualTree;
|
||||||
Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean);
|
Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean);
|
||||||
var
|
var
|
||||||
NodeData: PVTreeData;
|
Obj: PDBObject;
|
||||||
begin
|
begin
|
||||||
// Tables and views can be renamed, routines cannot
|
// Tables and views can be renamed, routines cannot
|
||||||
NodeData := Sender.GetNodeData(Node);
|
Obj := Sender.GetNodeData(Node);
|
||||||
Allowed := NodeData.NodeType in [lntTable, lntView];
|
Allowed := Obj.NodeType in [lntTable, lntView];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -4357,22 +4378,22 @@ end;
|
|||||||
procedure TMainForm.ListTablesNewText(Sender: TBaseVirtualTree; Node:
|
procedure TMainForm.ListTablesNewText(Sender: TBaseVirtualTree; Node:
|
||||||
PVirtualNode; Column: TColumnIndex; NewText: String);
|
PVirtualNode; Column: TColumnIndex; NewText: String);
|
||||||
var
|
var
|
||||||
NodeData : PVTreeData;
|
Obj: PDBObject;
|
||||||
begin
|
begin
|
||||||
// Fetch data from node
|
// Fetch data from node
|
||||||
NodeData := Sender.GetNodeData(Node);
|
Obj := Sender.GetNodeData(Node);
|
||||||
|
|
||||||
// Try to rename, on any error abort and don't rename ListItem
|
// Try to rename, on any error abort and don't rename ListItem
|
||||||
try
|
try
|
||||||
ensureValidIdentifier( NewText );
|
ensureValidIdentifier( NewText );
|
||||||
// rename table
|
// rename table
|
||||||
Connection.Query('RENAME TABLE ' + mask(NodeData.Captions[0]) + ' TO ' + mask(NewText));
|
Connection.Query('RENAME TABLE ' + mask(Obj.Name) + ' TO ' + mask(NewText));
|
||||||
|
|
||||||
if SynSQLSyn1.TableNames.IndexOf( NewText ) = -1 then begin
|
if SynSQLSyn1.TableNames.IndexOf( NewText ) = -1 then begin
|
||||||
SynSQLSyn1.TableNames.Add(NewText);
|
SynSQLSyn1.TableNames.Add(NewText);
|
||||||
end;
|
end;
|
||||||
// Update nodedata
|
// Update nodedata
|
||||||
NodeData.Captions[0] := NewText;
|
Obj.Name := NewText;
|
||||||
// Now the active tree db has to be updated. But calling RefreshTreeDB here causes an AV
|
// Now the active tree db has to be updated. But calling RefreshTreeDB here causes an AV
|
||||||
// so we do it manually here
|
// so we do it manually here
|
||||||
Connection.ClearDbObjects(ActiveDatabase);
|
Connection.ClearDbObjects(ActiveDatabase);
|
||||||
@ -4754,7 +4775,7 @@ procedure TMainForm.popupDBPopup(Sender: TObject);
|
|||||||
var
|
var
|
||||||
L: Cardinal;
|
L: Cardinal;
|
||||||
HasFocus, InDBTree: Boolean;
|
HasFocus, InDBTree: Boolean;
|
||||||
NodeData: PVTreeData;
|
Obj: PDBObject;
|
||||||
begin
|
begin
|
||||||
// DBtree and ListTables both use popupDB as menu. Find out which of them was rightclicked.
|
// DBtree and ListTables both use popupDB as menu. Find out which of them was rightclicked.
|
||||||
if Sender is TPopupMenu then
|
if Sender is TPopupMenu then
|
||||||
@ -4793,8 +4814,8 @@ begin
|
|||||||
actDropObjects.Enabled := ListTables.SelectedCount > 0;
|
actDropObjects.Enabled := ListTables.SelectedCount > 0;
|
||||||
actEmptyTables.Enabled := False;
|
actEmptyTables.Enabled := False;
|
||||||
if HasFocus then begin
|
if HasFocus then begin
|
||||||
NodeData := ListTables.GetNodeData(ListTables.FocusedNode);
|
Obj := ListTables.GetNodeData(ListTables.FocusedNode);
|
||||||
actEmptyTables.Enabled := NodeData.NodeType in [lntTable, lntView];
|
actEmptyTables.Enabled := Obj.NodeType in [lntTable, lntView];
|
||||||
end;
|
end;
|
||||||
actEditObject.Enabled := HasFocus;
|
actEditObject.Enabled := HasFocus;
|
||||||
// Show certain items which are valid only here
|
// Show certain items which are valid only here
|
||||||
@ -5101,9 +5122,6 @@ end;
|
|||||||
procedure TMainForm.SetSelectedDatabase(db: String);
|
procedure TMainForm.SetSelectedDatabase(db: String);
|
||||||
var
|
var
|
||||||
n, f: PVirtualNode;
|
n, f: PVirtualNode;
|
||||||
i: Integer;
|
|
||||||
DBObjects: TDBObjectList;
|
|
||||||
Tables: String;
|
|
||||||
begin
|
begin
|
||||||
if db = '' then
|
if db = '' then
|
||||||
n := DBtree.GetFirst
|
n := DBtree.GetFirst
|
||||||
@ -5114,11 +5132,6 @@ begin
|
|||||||
f := DBtree.FocusedNode;
|
f := DBtree.FocusedNode;
|
||||||
if (not Assigned(f)) or (f.Parent <> n) then
|
if (not Assigned(f)) or (f.Parent <> n) then
|
||||||
SelectNode(DBtree, n);
|
SelectNode(DBtree, n);
|
||||||
// Add object names to highlighter
|
|
||||||
DBObjects := Connection.GetDBObjects(db);
|
|
||||||
for i:=0 to DBObjects.Count-1 do
|
|
||||||
Tables := Tables + DBObjects[i].Name + CRLF;
|
|
||||||
SynSQLSyn1.TableNames.Text := Trim(Tables);
|
|
||||||
end else
|
end else
|
||||||
raise Exception.Create('Database node ' + db + ' not found in tree.');
|
raise Exception.Create('Database node ' + db + ' not found in tree.');
|
||||||
end;
|
end;
|
||||||
@ -5607,8 +5620,6 @@ begin
|
|||||||
Result := @VTRowDataListCommandStats
|
Result := @VTRowDataListCommandStats
|
||||||
else if VT = ListProcesses then
|
else if VT = ListProcesses then
|
||||||
Result := @VTRowDataListProcesses
|
Result := @VTRowDataListProcesses
|
||||||
else if VT = ListTables then
|
|
||||||
Result := @VTRowDataListTables
|
|
||||||
else begin
|
else begin
|
||||||
raise Exception.Create( VT.ClassName + ' "' + VT.Name + '" doesn''t have an assigned array with data.' );
|
raise Exception.Create( VT.ClassName + ' "' + VT.Name + '" doesn''t have an assigned array with data.' );
|
||||||
end;
|
end;
|
||||||
@ -5624,7 +5635,6 @@ begin
|
|||||||
if P = @VTRowDataListStatus then Exit;
|
if P = @VTRowDataListStatus then Exit;
|
||||||
if P = @VTRowDataListCommandStats then Exit;
|
if P = @VTRowDataListCommandStats then Exit;
|
||||||
if P = @VTRowDataListProcesses then Exit;
|
if P = @VTRowDataListProcesses then Exit;
|
||||||
if P = @VTRowDataListTables then Exit;
|
|
||||||
raise Exception.Create('Assertion failed: Invalid global VT array.');
|
raise Exception.Create('Assertion failed: Invalid global VT array.');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -6332,7 +6342,7 @@ end;
|
|||||||
procedure TMainForm.DBtreeFocusChanged(Sender: TBaseVirtualTree;
|
procedure TMainForm.DBtreeFocusChanged(Sender: TBaseVirtualTree;
|
||||||
Node: PVirtualNode; Column: TColumnIndex);
|
Node: PVirtualNode; Column: TColumnIndex);
|
||||||
var
|
var
|
||||||
newDb, newDbObject: String;
|
newDb, oldDb, newDbObject: String;
|
||||||
begin
|
begin
|
||||||
debug('DBtreeFocusChanged()');
|
debug('DBtreeFocusChanged()');
|
||||||
SelectedTableCreateStatement := '';
|
SelectedTableCreateStatement := '';
|
||||||
@ -6354,7 +6364,12 @@ begin
|
|||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
ShowDatabase(newDb);
|
if (not DBtree.Dragging)
|
||||||
|
and ((PageControlMain.ActivePage = tabHost) or(PageControlMain.ActivePage = tabData)) then
|
||||||
|
PageControlMain.ActivePage := tabDatabase;
|
||||||
|
tabDatabase.TabVisible := true;
|
||||||
|
tabEditor.TabVisible := false;
|
||||||
|
tabData.TabVisible := false;
|
||||||
end;
|
end;
|
||||||
2: begin
|
2: begin
|
||||||
newDb := Databases[Node.Parent.Index];
|
newDb := Databases[Node.Parent.Index];
|
||||||
@ -6385,9 +6400,19 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
if Assigned(PreviousFocusedNode) then case DBTree.GetNodeLevel(PreviousFocusedNode) of
|
||||||
|
0: oldDb := '';
|
||||||
|
1: oldDb := DBTree.Text[PreviousFocusedNode, 0];
|
||||||
|
2: oldDb := DBTree.Text[PreviousFocusedNode.Parent, 0];
|
||||||
|
end;
|
||||||
|
if newDb <> oldDb then begin
|
||||||
|
tabDatabase.Caption := sstr('Database: ' + newDb, 30);
|
||||||
|
ListTables.ClearSelection;
|
||||||
|
ListTables.FocusedNode := nil;
|
||||||
|
ListTables.Tag := VTREE_NOTLOADED;
|
||||||
|
ListTables.Invalidate;
|
||||||
|
end;
|
||||||
PreviousFocusedNode := DBTree.FocusedNode;
|
PreviousFocusedNode := DBTree.FocusedNode;
|
||||||
if newDb <> '' then
|
|
||||||
LoadDatabaseProperties(newDb);
|
|
||||||
FixQueryTabCloseButtons;
|
FixQueryTabCloseButtons;
|
||||||
SetWindowCaption;
|
SetWindowCaption;
|
||||||
end;
|
end;
|
||||||
@ -8183,15 +8208,15 @@ end;
|
|||||||
|
|
||||||
procedure TMainForm.actEditObjectExecute(Sender: TObject);
|
procedure TMainForm.actEditObjectExecute(Sender: TObject);
|
||||||
var
|
var
|
||||||
NodeData: PVTreeData;
|
Obj: PDBObject;
|
||||||
db: String;
|
db: String;
|
||||||
begin
|
begin
|
||||||
debug('actEditObjectExecute()');
|
debug('actEditObjectExecute()');
|
||||||
if ListTables.Focused then begin
|
if ListTables.Focused then begin
|
||||||
// Got here from ListTables.OnDblClick or ListTables's context menu item "Edit"
|
// Got here from ListTables.OnDblClick or ListTables's context menu item "Edit"
|
||||||
NodeData := ListTables.GetNodeData(ListTables.FocusedNode);
|
Obj := ListTables.GetNodeData(ListTables.FocusedNode);
|
||||||
if (NodeData.Captions[0] <> SelectedTable.Name) or (NodeData.NodeType <> SelectedTable.NodeType) then
|
if (Obj.Name <> SelectedTable.Name) or (Obj.NodeType <> SelectedTable.NodeType) then
|
||||||
SelectDBObject(NodeData.Captions[0], NodeData.NodeType);
|
SelectDBObject(Obj.Name, Obj.NodeType);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
case GetFocusedTreeNodeType of
|
case GetFocusedTreeNodeType of
|
||||||
@ -8238,13 +8263,15 @@ end;
|
|||||||
|
|
||||||
procedure TMainForm.ListTablesDblClick(Sender: TObject);
|
procedure TMainForm.ListTablesDblClick(Sender: TObject);
|
||||||
var
|
var
|
||||||
NodeData: PVTreeData;
|
Obj: PDBObject;
|
||||||
|
vt: TVirtualStringTree;
|
||||||
begin
|
begin
|
||||||
// DoubleClick: Display editor
|
// DoubleClick: Display editor
|
||||||
debug('ListTablesDblClick()');
|
debug('ListTablesDblClick()');
|
||||||
if Assigned(ListTables.FocusedNode) then begin
|
vt := Sender as TVirtualStringTree;
|
||||||
NodeData := ListTables.GetNodeData(ListTables.FocusedNode);
|
if Assigned(vt.FocusedNode) then begin
|
||||||
SelectDBObject(ListTables.Text[ListTables.FocusedNode, ListTables.FocusedColumn], NodeData.NodeType);
|
Obj := vt.GetNodeData(vt.FocusedNode);
|
||||||
|
SelectDBObject(vt.Text[vt.FocusedNode, vt.FocusedColumn], Obj.NodeType);
|
||||||
PageControlMainChange(Sender);
|
PageControlMainChange(Sender);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -16,6 +16,7 @@ type
|
|||||||
Rows, Size, Version, AvgRowLen, MaxDataLen, IndexLen, DataLen, DataFree, AutoInc, CheckSum: Int64;
|
Rows, Size, Version, AvgRowLen, MaxDataLen, IndexLen, DataLen, DataFree, AutoInc, CheckSum: Int64;
|
||||||
NodeType: TListNodeType;
|
NodeType: TListNodeType;
|
||||||
end;
|
end;
|
||||||
|
PDBObject = ^TDBObject;
|
||||||
TDBObjectList = TObjectList<TDBObject>;
|
TDBObjectList = TObjectList<TDBObject>;
|
||||||
|
|
||||||
{$M+} // Needed to add published properties
|
{$M+} // Needed to add published properties
|
||||||
@ -96,6 +97,7 @@ type
|
|||||||
FCharsetTable: TMySQLQuery;
|
FCharsetTable: TMySQLQuery;
|
||||||
FInformationSchemaObjects: TStringList;
|
FInformationSchemaObjects: TStringList;
|
||||||
FDBObjectLists: TStringList;
|
FDBObjectLists: TStringList;
|
||||||
|
FObjectNamesInSelectedDB: TStrings;
|
||||||
procedure SetActive(Value: Boolean);
|
procedure SetActive(Value: Boolean);
|
||||||
procedure SetDatabase(Value: String);
|
procedure SetDatabase(Value: String);
|
||||||
function GetThreadId: Cardinal;
|
function GetThreadId: Cardinal;
|
||||||
@ -115,6 +117,7 @@ type
|
|||||||
function ParseDateTime(Str: String): TDateTime;
|
function ParseDateTime(Str: String): TDateTime;
|
||||||
procedure Log(Category: TMySQLLogCategory; Msg: String);
|
procedure Log(Category: TMySQLLogCategory; Msg: String);
|
||||||
procedure ClearCache;
|
procedure ClearCache;
|
||||||
|
procedure SetObjectNamesInSelectedDB;
|
||||||
public
|
public
|
||||||
constructor Create(AOwner: TComponent); override;
|
constructor Create(AOwner: TComponent); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
@ -153,6 +156,7 @@ type
|
|||||||
property CharsetTable: TMySQLQuery read GetCharsetTable;
|
property CharsetTable: TMySQLQuery read GetCharsetTable;
|
||||||
property CharsetList: TStringList read GetCharsetList;
|
property CharsetList: TStringList read GetCharsetList;
|
||||||
property InformationSchemaObjects: TStringList read GetInformationSchemaObjects;
|
property InformationSchemaObjects: TStringList read GetInformationSchemaObjects;
|
||||||
|
property ObjectNamesInSelectedDB: TStrings read FObjectNamesInSelectedDB write FObjectNamesInSelectedDB;
|
||||||
published
|
published
|
||||||
property Active: Boolean read FActive write SetActive default False;
|
property Active: Boolean read FActive write SetActive default False;
|
||||||
property Database: String read FDatabase write SetDatabase;
|
property Database: String read FDatabase write SetDatabase;
|
||||||
@ -452,6 +456,7 @@ begin
|
|||||||
FOnDatabaseChanged(Value);
|
FOnDatabaseChanged(Value);
|
||||||
end else
|
end else
|
||||||
Query('USE '+QuoteIdent(Value), False);
|
Query('USE '+QuoteIdent(Value), False);
|
||||||
|
SetObjectNamesInSelectedDB;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1122,6 +1127,26 @@ begin
|
|||||||
if not Assigned(FDBObjectLists) then
|
if not Assigned(FDBObjectLists) then
|
||||||
FDBObjectLists := TStringList.Create;
|
FDBObjectLists := TStringList.Create;
|
||||||
FDBObjectLists.AddObject(db, Result);
|
FDBObjectLists.AddObject(db, Result);
|
||||||
|
|
||||||
|
SetObjectNamesInSelectedDB;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TMySQLConnection.SetObjectNamesInSelectedDB;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
Objects: TDBObjectList;
|
||||||
|
ObjNames: String;
|
||||||
|
begin
|
||||||
|
// Add object names to additional stringlist
|
||||||
|
if Assigned(FObjectNamesInSelectedDB) and DbObjectsCached(FDatabase) then begin
|
||||||
|
Objects := GetDbObjects(FDatabase);
|
||||||
|
for i:=0 to Objects.Count-1 do
|
||||||
|
ObjNames := ObjNames + Objects[i].Name + CRLF;
|
||||||
|
if FObjectNamesInSelectedDB.Text <> ObjNames then
|
||||||
|
FObjectNamesInSelectedDB.Text := ObjNames;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user