mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-06 18:24:26 +08:00
Implement handling of triggers as separate database objects, on the same level as tables, routines and views. Means we have a trigger editor frame, a new icon and various code extensions. Fixes issue #806.
This commit is contained in:
197
source/trigger_editor.pas
Normal file
197
source/trigger_editor.pas
Normal file
@ -0,0 +1,197 @@
|
||||
unit trigger_editor;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
|
||||
Dialogs, StdCtrls, TntStdCtrls, SynEdit, SynMemo, ExtCtrls, mysql_connection, mysql_api,
|
||||
SynCompletionProposal, VirtualTrees;
|
||||
|
||||
type
|
||||
TfrmTriggerEditor = class(TFrame)
|
||||
lblName: TLabel;
|
||||
editName: TTntEdit;
|
||||
SynMemoStatement: TSynMemo;
|
||||
btnHelp: TButton;
|
||||
btnDiscard: TButton;
|
||||
btnSave: TButton;
|
||||
comboTable: TTntComboBox;
|
||||
lblTable: TLabel;
|
||||
lblBody: TLabel;
|
||||
SynCompletionProposalStatement: TSynCompletionProposal;
|
||||
lblEvent: TLabel;
|
||||
comboTiming: TComboBox;
|
||||
comboEvent: TComboBox;
|
||||
procedure btnHelpClick(Sender: TObject);
|
||||
procedure btnDiscardClick(Sender: TObject);
|
||||
procedure Modification(Sender: TObject);
|
||||
procedure btnSaveClick(Sender: TObject);
|
||||
procedure SynCompletionProposalStatementExecute(Kind: SynCompletionType; Sender: TObject;
|
||||
var CurrentInput: WideString; var x, y: Integer; var CanExecute: Boolean);
|
||||
private
|
||||
{ Private declarations }
|
||||
FEditTriggerName: WideString;
|
||||
public
|
||||
{ Public declarations }
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
procedure Init(EditTriggerName: WideString='');
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses main, helpers;
|
||||
|
||||
{$R *.dfm}
|
||||
|
||||
|
||||
{**
|
||||
Create: Restore GUI setup
|
||||
}
|
||||
constructor TfrmTriggerEditor.Create(AOwner: TComponent);
|
||||
var
|
||||
col: TProposalColumn;
|
||||
i: Integer;
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
Align := alClient;
|
||||
SynMemoStatement.Highlighter := Mainform.SynSQLSyn1;
|
||||
InheritFont(Font);
|
||||
editName.MaxLength := NAME_LEN;
|
||||
comboTiming.Items.Text := 'BEFORE'+CRLF+'AFTER';
|
||||
comboEvent.Items.Text := 'INSERT'+CRLF+'UPDATE'+CRLF+'DELETE';
|
||||
for i:=0 to Mainform.SynCompletionProposal.Columns.Count-1 do begin
|
||||
col := SynCompletionProposalStatement.Columns.Add;
|
||||
col.BiggestWord := Mainform.SynCompletionProposal.Columns[i].BiggestWord;
|
||||
end;
|
||||
SynCompletionProposalStatement.NbLinesInWindow := Mainform.SynCompletionProposal.NbLinesInWindow;
|
||||
SynCompletionProposalStatement.Width := Mainform.SynCompletionProposal.Width;
|
||||
SynCompletionProposalStatement.Options := Mainform.SynCompletionProposal.Options;
|
||||
SynCompletionProposalStatement.TimerInterval := Mainform.SynCompletionProposal.TimerInterval;
|
||||
SynCompletionProposalStatement.ItemHeight := Mainform.SynCompletionProposal.ItemHeight;
|
||||
SynCompletionProposalStatement.Margin := Mainform.SynCompletionProposal.Margin;
|
||||
SynCompletionProposalStatement.Font := Font;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTriggerEditor.Init(EditTriggerName: WideString='');
|
||||
var
|
||||
Definition, TableList: TMySQLQuery;
|
||||
begin
|
||||
Mainform.SetupSynEditors;
|
||||
FEditTriggerName := EditTriggerName;
|
||||
editName.Text := '';
|
||||
SynMemoStatement.Text := '';
|
||||
comboEvent.ItemIndex := 0;
|
||||
comboTiming.ItemIndex := 0;
|
||||
TableList := Mainform.FetchActiveDbTableList;
|
||||
comboTable.Items.Clear;
|
||||
while not TableList.Eof do begin
|
||||
if GetDBObjectType(TableList) in [lntTable, lntCrashedTable] then
|
||||
comboTable.Items.Add(TableList.Col(DBO_NAME));
|
||||
TableList.Next;
|
||||
end;
|
||||
if comboTable.Items.Count > 0 then
|
||||
comboTable.ItemIndex := 0;
|
||||
if FEditTriggerName <> '' then begin
|
||||
// Edit mode
|
||||
Mainform.SetEditorTabCaption(Self, FEditTriggerName);
|
||||
editName.Text := FEditTriggerName;
|
||||
Definition := Mainform.Connection.GetResults('SELECT '+
|
||||
'EVENT_MANIPULATION, EVENT_OBJECT_TABLE, ACTION_STATEMENT, ACTION_TIMING '+
|
||||
'FROM information_schema.TRIGGERS '+
|
||||
'WHERE TRIGGER_SCHEMA='+esc(Mainform.ActiveDatabase)+' AND TRIGGER_NAME='+esc(FEditTriggerName));
|
||||
comboTable.ItemIndex := comboTable.Items.IndexOf(Definition.Col('EVENT_OBJECT_TABLE'));
|
||||
comboTiming.ItemIndex := comboTiming.Items.IndexOf(UpperCase(Definition.Col('ACTION_TIMING')));
|
||||
comboEvent.ItemIndex := comboEvent.Items.IndexOf(UpperCase(Definition.Col('EVENT_MANIPULATION')));
|
||||
SynMemoStatement.Text := Definition.Col('ACTION_STATEMENT');
|
||||
end else begin
|
||||
Mainform.SetEditorTabCaption(Self, '');
|
||||
editName.Text := 'Enter trigger name';
|
||||
end;
|
||||
btnSave.Enabled := False;
|
||||
btnDiscard.Enabled := False;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTriggerEditor.Modification(Sender: TObject);
|
||||
begin
|
||||
// Enable buttons if anything has changed
|
||||
btnSave.Enabled := (editName.Text <> '') and (comboTable.ItemIndex > -1)
|
||||
and (comboTiming.ItemIndex > -1) and (comboEvent.ItemIndex > -1)
|
||||
and (SynMemoStatement.Text <> '');
|
||||
btnDiscard.Enabled := True;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTriggerEditor.btnDiscardClick(Sender: TObject);
|
||||
begin
|
||||
// Reinit editor, discarding changes
|
||||
Init(FEditTriggerName);
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTriggerEditor.btnSaveClick(Sender: TObject);
|
||||
var
|
||||
sql: WideString;
|
||||
FocusChangeEvent: procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex) of object;
|
||||
begin
|
||||
// Edit mode means we drop the trigger and recreate it, as there is no ALTER TRIGGER.
|
||||
try
|
||||
if FEditTriggerName <> '' then
|
||||
Mainform.Connection.Query('DROP TRIGGER '+Mainform.mask(FEditTriggerName));
|
||||
// CREATE
|
||||
// [DEFINER = { user | CURRENT_USER }]
|
||||
// TRIGGER trigger_name trigger_time trigger_event
|
||||
// ON tbl_name FOR EACH ROW trigger_stmt
|
||||
sql := 'CREATE TRIGGER '+Mainform.mask(editName.Text)+' '+
|
||||
comboTiming.Items[comboTiming.ItemIndex]+' '+comboEvent.Items[comboEvent.ItemIndex]+
|
||||
' ON '+Mainform.mask(comboTable.Text)+
|
||||
' FOR EACH ROW '+SynMemoStatement.Text;
|
||||
Mainform.Connection.Query(sql);
|
||||
FocusChangeEvent := Mainform.DBtree.OnFocusChanged;
|
||||
Mainform.DBtree.OnFocusChanged := nil;
|
||||
Mainform.RefreshTreeDB(Mainform.ActiveDatabase);
|
||||
Mainform.DBtree.OnFocusChanged := FocusChangeEvent;
|
||||
Mainform.SelectDBObject(editName.Text, lntTrigger);
|
||||
Init(editName.Text);
|
||||
except on E:Exception do
|
||||
MessageDlg(E.Message, mtError, [mbOK], 0);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTriggerEditor.SynCompletionProposalStatementExecute(Kind: SynCompletionType; Sender: TObject;
|
||||
var CurrentInput: WideString; var x, y: Integer; var CanExecute: Boolean);
|
||||
var
|
||||
Proposal: TSynCompletionProposal;
|
||||
Token: WideString;
|
||||
Columns: TMySQLQuery;
|
||||
begin
|
||||
// Propose column names from referencing table
|
||||
Proposal := Sender as TSynCompletionProposal;
|
||||
Token := UpperCase(Proposal.PreviousToken);
|
||||
Proposal.InsertList.Clear;
|
||||
Proposal.ItemList.Clear;
|
||||
if (Token = 'NEW') or (Token = 'OLD') then begin
|
||||
if comboTable.Text = '' then
|
||||
CanExecute := False
|
||||
else try
|
||||
Columns := Mainform.Connection.GetResults('SHOW COLUMNS FROM '+Mainform.mask(comboTable.Text));
|
||||
while not Columns.Eof do begin
|
||||
Proposal.InsertList.Add(Columns.Col('Field'));
|
||||
Proposal.ItemList.Add(WideFormat(SYNCOMPLETION_PATTERN, [ICONINDEX_FIELD, GetFirstWord(Columns.Col('Type')), Columns.Col('Field')]) );
|
||||
Columns.Next;
|
||||
end;
|
||||
except
|
||||
end;
|
||||
end else
|
||||
Mainform.SynCompletionProposalExecute(Kind, Sender, CurrentInput, x, y, CanExecute);
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTriggerEditor.btnHelpClick(Sender: TObject);
|
||||
begin
|
||||
Mainform.CallSQLHelpWithKeyword('TRIGGERS');
|
||||
end;
|
||||
|
||||
end.
|
Reference in New Issue
Block a user