Skip to content

Commit ca48343

Browse files
committed
feat: reverse foreign keys on "Foreign keys" tab in table editor
Refs #1825
1 parent 1ce80ea commit ca48343

File tree

4 files changed

+105
-8
lines changed

4 files changed

+105
-8
lines changed

source/dbstructures.mysql.pas

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3340,6 +3340,12 @@ function TMySqlProvider.GetSql(AId: TQueryId): string;
33403340
'SHOW TABLE STATUS LIKE :EscapedName',
33413341
''
33423342
);
3343+
qGetReverseForeignKeys: Result := 'SELECT DISTINCT'+
3344+
' k.TABLE_SCHEMA, k.TABLE_NAME'+
3345+
' FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE k'+
3346+
' WHERE'+
3347+
' REFERENCED_TABLE_SCHEMA = :EscapedDatabase AND'+
3348+
' REFERENCED_TABLE_NAME = :EscapedName';
33433349
else Result := inherited;
33443350
end;
33453351
end;

source/dbstructures.pas

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ interface
4545
qFuncLength, qFuncCeil, qFuncLeft, qFuncNow, qFuncLastAutoIncNumber,
4646
qLockedTables, qDisableForeignKeyChecks, qEnableForeignKeyChecks,
4747
qOrderAsc, qOrderDesc, qGetRowCountExact, qGetRowCountApprox,
48-
qForeignKeyDrop, qGetTableColumns, qGetCollations, qGetCollationsExtended, qGetCharsets);
48+
qForeignKeyDrop, qGetTableColumns, qGetCollations, qGetCollationsExtended, qGetCharsets,
49+
qGetReverseForeignKeys);
4950
TSqlProvider = class
5051
strict protected
5152
FNetType: TNetType;

source/table_editor.lfm

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ object frmTableEditor: TfrmTableEditor
2626
Width = 700
2727
ActivePage = tabBasic
2828
Align = alTop
29-
AutoSize = True
3029
Images = MainForm.ImageListMain
3130
TabIndex = 0
3231
TabOrder = 0
@@ -77,7 +76,6 @@ object frmTableEditor: TfrmTableEditor
7776
AnchorSideTop.Side = asrBottom
7877
AnchorSideRight.Control = tabBasic
7978
AnchorSideRight.Side = asrBottom
80-
AnchorSideBottom.Control = tabBasic
8179
AnchorSideBottom.Side = asrBottom
8280
Left = 96
8381
Height = 104
@@ -456,15 +454,21 @@ object frmTableEditor: TfrmTableEditor
456454
ClientWidth = 692
457455
ImageIndex = 136
458456
object tlbForeignKeys: TToolBar
457+
AnchorSideLeft.Control = tabForeignKeys
458+
AnchorSideTop.Control = tabForeignKeys
459+
AnchorSideBottom.Control = tabForeignKeys
460+
AnchorSideBottom.Side = asrBottom
459461
Left = 0
460462
Height = 142
461463
Top = 0
462464
Width = 67
463-
Align = alLeft
465+
Align = alNone
466+
Anchors = [akTop, akLeft, akBottom]
464467
AutoSize = True
465468
ButtonHeight = 28
466469
ButtonWidth = 66
467470
Caption = 'tlbForeignKeys'
471+
Constraints.MaxWidth = 100
468472
Images = MainForm.ImageListMain
469473
List = True
470474
ShowCaptions = True
@@ -496,11 +500,17 @@ object frmTableEditor: TfrmTableEditor
496500
end
497501
end
498502
object listForeignKeys: TLazVirtualStringTree
503+
AnchorSideLeft.Control = tlbForeignKeys
504+
AnchorSideLeft.Side = asrBottom
505+
AnchorSideTop.Control = tabForeignKeys
506+
AnchorSideRight.Control = spltForeignKeyListings
507+
AnchorSideBottom.Control = tabForeignKeys
508+
AnchorSideBottom.Side = asrBottom
499509
Left = 67
500510
Height = 142
501511
Top = 0
502-
Width = 625
503-
Align = alClient
512+
Width = 439
513+
Anchors = [akTop, akLeft, akRight, akBottom]
504514
EditDelay = 0
505515
Header.AutoSizeIndex = -1
506516
Header.Columns = <
@@ -538,7 +548,7 @@ object frmTableEditor: TfrmTableEditor
538548
Options = [coDraggable, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible, coAllowFocus]
539549
Position = 5
540550
Text = 'On DELETE'
541-
Width = 85
551+
Width = 10
542552
end>
543553
Header.Options = [hoAutoResize, hoColumnResize, hoDrag, hoShowSortGlyphs, hoVisible, hoDisableAnimatedResize]
544554
Header.PopupMenu = MainForm.popupListHeader
@@ -558,6 +568,50 @@ object frmTableEditor: TfrmTableEditor
558568
OnNewText = listForeignKeysNewText
559569
OnStructureChange = AnyTreeStructureChange
560570
end
571+
object ListViewReverseForeignKeys: TListView
572+
AnchorSideLeft.Control = spltForeignKeyListings
573+
AnchorSideLeft.Side = asrBottom
574+
AnchorSideTop.Control = tabForeignKeys
575+
AnchorSideRight.Control = tabForeignKeys
576+
AnchorSideRight.Side = asrBottom
577+
AnchorSideBottom.Control = tabForeignKeys
578+
AnchorSideBottom.Side = asrBottom
579+
Left = 514
580+
Height = 142
581+
Top = 0
582+
Width = 178
583+
Anchors = [akTop, akLeft, akRight, akBottom]
584+
Columns = <
585+
item
586+
AutoSize = True
587+
Caption = 'Database'
588+
Width = 63
589+
end
590+
item
591+
AutoSize = True
592+
Caption = 'Table'
593+
Width = 44
594+
end>
595+
ColumnClick = False
596+
ReadOnly = True
597+
RowSelect = True
598+
SmallImages = MainForm.ImageListMain
599+
TabOrder = 2
600+
ViewStyle = vsReport
601+
end
602+
object spltForeignKeyListings: TSplitter
603+
AnchorSideTop.Control = tabForeignKeys
604+
AnchorSideRight.Control = ListViewReverseForeignKeys
605+
AnchorSideBottom.Control = tabForeignKeys
606+
AnchorSideBottom.Side = asrBottom
607+
Left = 506
608+
Height = 142
609+
Top = 0
610+
Width = 8
611+
Align = alNone
612+
Anchors = [akTop, akBottom]
613+
ResizeAnchor = akRight
614+
end
561615
end
562616
object tabCheckConstraints: TTabSheet
563617
Caption = 'Check constraints'

source/table_editor.pas

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ TfrmTableEditor = class(TFrame)
2121
btnDiscard: TButton;
2222
btnHelp: TButton;
2323
listColumns: TLazVirtualStringTree;
24+
ListViewReverseForeignKeys: TListView;
2425
PageControlMain: TPageControl;
26+
spltForeignKeyListings: TSplitter;
2527
tabBasic: TTabSheet;
2628
tabIndexes: TTabSheet;
2729
tabOptions: TTabSheet;
@@ -213,6 +215,7 @@ TfrmTableEditor = class(TFrame)
213215
{ Private declarations }
214216
FLoaded: Boolean;
215217
CreateCodeValid, AlterCodeValid: Boolean;
218+
FReverseForeignKeysLoaded: Boolean;
216219
FColumns: TTableColumnList;
217220
FKeys, FDeletedKeys: TTableKeyList;
218221
FForeignKeys: TForeignKeyList;
@@ -248,6 +251,7 @@ TfrmTableEditor = class(TFrame)
248251
procedure CalcMinColWidth;
249252
procedure UpdateTabCaptions;
250253
function MoveNodeAllowed(Sender: TLazVirtualStringTree): Boolean;
254+
procedure LoadReverseForeignKeys(Sender: TObject);
251255
public
252256
{ Public declarations }
253257
constructor Create(AOwner: TComponent); override;
@@ -448,6 +452,7 @@ procedure TfrmTableEditor.Init(Obj: TDBObject);
448452
ResetModificationFlags;
449453
CreateCodeValid := False;
450454
AlterCodeValid := False;
455+
FReverseForeignKeysLoaded := False;
451456
PageControlMainChange(Self); // Foreign key editor needs a hit
452457
// Buttons are randomly moved, since VirtualTree update, see #440
453458
btnSave.Top := Height - btnSave.Height - 3;
@@ -2556,7 +2561,10 @@ procedure TfrmTableEditor.PageControlMainChange(Sender: TObject);
25562561
listForeignKeys.EndEditNode;
25572562
listCheckConstraints.EndEditNode;
25582563
// Ensure SynMemo's have focus, otherwise Select-All and Copy actions may fail
2559-
if PageControlMain.ActivePage = tabCREATEcode then begin
2564+
if PageControlMain.ActivePage = tabForeignKeys then begin
2565+
LoadReverseForeignKeys(Sender);
2566+
end
2567+
else if PageControlMain.ActivePage = tabCREATEcode then begin
25602568
SynMemoCreateCode.TrySetFocus;
25612569
end
25622570
else if PageControlMain.ActivePage = tabALTERcode then begin
@@ -3070,6 +3078,34 @@ procedure TfrmTableEditor.listForeignKeysNewText(Sender: TBaseVirtualTree;
30703078
end;
30713079
end;
30723080

3081+
procedure TfrmTableEditor.LoadReverseForeignKeys(Sender: TObject);
3082+
var
3083+
SqlGet: String;
3084+
Results: TDBQuery;
3085+
ListItem: TListItem;
3086+
begin
3087+
if FReverseForeignKeysLoaded then
3088+
Exit;
3089+
SqlGet := DBObject.Connection.SqlProvider.GetSql(qGetReverseForeignKeys, DBObject.AsStringMap);
3090+
if SqlGet.IsEmpty then
3091+
Exit;
3092+
ListViewReverseForeignKeys.BeginUpdate;
3093+
ListViewReverseForeignKeys.Clear;
3094+
try
3095+
Results := DBObject.Connection.GetResults(SqlGet);
3096+
while not Results.Eof do begin
3097+
ListItem := ListViewReverseForeignKeys.Items.Add;
3098+
ListItem.ImageIndex := ICONINDEX_TABLE;
3099+
ListItem.Caption := Results.Col(0);
3100+
ListItem.SubItems.Add(Results.Col(1));
3101+
Results.Next;
3102+
end;
3103+
except
3104+
on EDbError do;
3105+
end;
3106+
ListViewReverseForeignKeys.EndUpdate;
3107+
FReverseForeignKeysLoaded := True;
3108+
end;
30733109

30743110
procedure TfrmTableEditor.btnHelpClick(Sender: TObject);
30753111
begin

0 commit comments

Comments
 (0)