mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-26 19:20:17 +08:00
Implement event editor for MySQL 5.1+ servers. Also, simplify some code around database objects and their editors. Fixes issue #1527
This commit is contained in:
@ -36,7 +36,8 @@ uses
|
||||
mysql_api in '..\..\source\mysql_api.pas',
|
||||
mysql_connection in '..\..\source\mysql_connection.pas',
|
||||
trigger_editor in '..\..\source\trigger_editor.pas' {frmTriggerEditor: TFrame},
|
||||
searchreplace in '..\..\source\searchreplace.pas' {frmSearchReplace};
|
||||
searchreplace in '..\..\source\searchreplace.pas' {frmSearchReplace},
|
||||
event_editor in '..\..\source\event_editor.pas' {frmEventEditor: TFrame};
|
||||
|
||||
{$R ..\..\res\icon.RES}
|
||||
{$R ..\..\res\version.RES}
|
||||
|
@ -198,6 +198,10 @@
|
||||
<DCCReference Include="..\..\source\searchreplace.pas">
|
||||
<Form>frmSearchReplace</Form>
|
||||
</DCCReference>
|
||||
<DCCReference Include="..\..\source\event_editor.pas">
|
||||
<Form>frmEventEditor</Form>
|
||||
<DesignClass>TFrame</DesignClass>
|
||||
</DCCReference>
|
||||
<RcCompile Include="..\..\res\updater.rc">
|
||||
<Form>updater.res</Form>
|
||||
</RcCompile>
|
||||
|
@ -279,6 +279,7 @@ const
|
||||
ICONINDEX_STOREDFUNCTION = 35;
|
||||
ICONINDEX_TRIGGER = 137;
|
||||
ICONINDEX_FUNCTION = 13;
|
||||
ICONINDEX_EVENT = 80;
|
||||
ICONINDEX_KEYWORD = 25;
|
||||
|
||||
// Size of byte units
|
||||
|
355
source/event_editor.dfm
Normal file
355
source/event_editor.dfm
Normal file
@ -0,0 +1,355 @@
|
||||
object frmEventEditor: TfrmEventEditor
|
||||
Left = 0
|
||||
Top = 0
|
||||
Width = 672
|
||||
Height = 438
|
||||
TabOrder = 0
|
||||
DesignSize = (
|
||||
672
|
||||
438)
|
||||
object lblBody: TLabel
|
||||
AlignWithMargins = True
|
||||
Left = 3
|
||||
Top = 175
|
||||
Width = 666
|
||||
Height = 13
|
||||
Align = alTop
|
||||
Caption = 'Execution body:'
|
||||
FocusControl = SynMemoBody
|
||||
end
|
||||
object SynMemoBody: TSynMemo
|
||||
AlignWithMargins = True
|
||||
Left = 3
|
||||
Top = 194
|
||||
Width = 666
|
||||
Height = 214
|
||||
Margins.Bottom = 30
|
||||
SingleLineMode = False
|
||||
Align = alClient
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -13
|
||||
Font.Name = 'Courier New'
|
||||
Font.Style = []
|
||||
TabOrder = 1
|
||||
Gutter.AutoSize = True
|
||||
Gutter.DigitCount = 2
|
||||
Gutter.Font.Charset = DEFAULT_CHARSET
|
||||
Gutter.Font.Color = clWindowText
|
||||
Gutter.Font.Height = -11
|
||||
Gutter.Font.Name = 'Courier New'
|
||||
Gutter.Font.Style = []
|
||||
Gutter.LeftOffset = 2
|
||||
Gutter.ShowLineNumbers = True
|
||||
Highlighter = MainForm.SynSQLSyn1
|
||||
Lines.Strings = (
|
||||
'SynMemoBody')
|
||||
Options = [eoAutoIndent, eoDragDropEditing, eoEnhanceEndKey, eoGroupUndo, eoHideShowScrollbars, eoKeepCaretX, eoShowScrollHint, eoSmartTabDelete, eoSmartTabs, eoTabsToSpaces]
|
||||
OnChange = Modification
|
||||
end
|
||||
object btnHelp: TButton
|
||||
Left = 3
|
||||
Top = 410
|
||||
Width = 75
|
||||
Height = 25
|
||||
Anchors = [akLeft, akBottom]
|
||||
Caption = 'Help'
|
||||
TabOrder = 2
|
||||
OnClick = btnHelpClick
|
||||
end
|
||||
object btnDiscard: TButton
|
||||
Left = 84
|
||||
Top = 410
|
||||
Width = 75
|
||||
Height = 25
|
||||
Anchors = [akLeft, akBottom]
|
||||
Caption = 'Discard'
|
||||
TabOrder = 3
|
||||
OnClick = btnDiscardClick
|
||||
end
|
||||
object btnSave: TButton
|
||||
Left = 165
|
||||
Top = 410
|
||||
Width = 75
|
||||
Height = 25
|
||||
Anchors = [akLeft, akBottom]
|
||||
Caption = 'Save'
|
||||
Default = True
|
||||
TabOrder = 4
|
||||
OnClick = btnSaveClick
|
||||
end
|
||||
object PageControlMain: TPageControl
|
||||
AlignWithMargins = True
|
||||
Left = 3
|
||||
Top = 3
|
||||
Width = 666
|
||||
Height = 166
|
||||
ActivePage = tabSettings
|
||||
Align = alTop
|
||||
Images = MainForm.ImageListMain
|
||||
TabOrder = 0
|
||||
OnChange = PageControlMainChange
|
||||
object tabSettings: TTabSheet
|
||||
Caption = 'Settings'
|
||||
ImageIndex = 39
|
||||
DesignSize = (
|
||||
658
|
||||
137)
|
||||
object lblName: TLabel
|
||||
Left = 3
|
||||
Top = 6
|
||||
Width = 31
|
||||
Height = 13
|
||||
Caption = 'Name:'
|
||||
FocusControl = editName
|
||||
end
|
||||
object lblComment: TLabel
|
||||
Left = 3
|
||||
Top = 33
|
||||
Width = 49
|
||||
Height = 13
|
||||
Caption = 'Comment:'
|
||||
end
|
||||
object editName: TEdit
|
||||
Left = 88
|
||||
Top = 3
|
||||
Width = 567
|
||||
Height = 21
|
||||
Anchors = [akLeft, akTop, akRight]
|
||||
TabOrder = 0
|
||||
Text = 'editName'
|
||||
TextHint = 'Enter event name ...'
|
||||
OnChange = Modification
|
||||
end
|
||||
object chkDropAfterExpiration: TCheckBox
|
||||
Left = 88
|
||||
Top = 57
|
||||
Width = 567
|
||||
Height = 17
|
||||
Anchors = [akLeft, akTop, akRight]
|
||||
Caption = 'Drop event after expiration'
|
||||
TabOrder = 2
|
||||
OnClick = Modification
|
||||
end
|
||||
object editComment: TEdit
|
||||
Left = 88
|
||||
Top = 30
|
||||
Width = 567
|
||||
Height = 21
|
||||
Anchors = [akLeft, akTop, akRight]
|
||||
TabOrder = 1
|
||||
Text = 'editComment'
|
||||
OnChange = Modification
|
||||
end
|
||||
object grpState: TRadioGroup
|
||||
Left = 88
|
||||
Top = 80
|
||||
Width = 349
|
||||
Height = 52
|
||||
Caption = 'State'
|
||||
Columns = 3
|
||||
TabOrder = 3
|
||||
OnClick = Modification
|
||||
end
|
||||
end
|
||||
object tabScheduling: TTabSheet
|
||||
Caption = 'Timing'
|
||||
ImageIndex = 80
|
||||
object radioOnce: TRadioButton
|
||||
Left = 3
|
||||
Top = 15
|
||||
Width = 74
|
||||
Height = 17
|
||||
Caption = 'Once, at:'
|
||||
Checked = True
|
||||
TabOrder = 0
|
||||
TabStop = True
|
||||
OnClick = radioScheduleClick
|
||||
end
|
||||
object radioEvery: TRadioButton
|
||||
Left = 3
|
||||
Top = 50
|
||||
Width = 54
|
||||
Height = 17
|
||||
Caption = 'Every'
|
||||
TabOrder = 3
|
||||
OnClick = radioScheduleClick
|
||||
end
|
||||
object dateOnce: TDateTimePicker
|
||||
Left = 96
|
||||
Top = 11
|
||||
Width = 133
|
||||
Height = 21
|
||||
Date = 40273.547337048610000000
|
||||
Time = 40273.547337048610000000
|
||||
TabOrder = 1
|
||||
OnChange = Modification
|
||||
end
|
||||
object timeOnce: TDateTimePicker
|
||||
Left = 235
|
||||
Top = 11
|
||||
Width = 133
|
||||
Height = 21
|
||||
Date = 40273.548026377310000000
|
||||
Time = 40273.548026377310000000
|
||||
Kind = dtkTime
|
||||
TabOrder = 2
|
||||
OnChange = Modification
|
||||
end
|
||||
object editEveryQuantity: TEdit
|
||||
Left = 96
|
||||
Top = 48
|
||||
Width = 53
|
||||
Height = 21
|
||||
TabOrder = 4
|
||||
Text = '1'
|
||||
OnChange = Modification
|
||||
end
|
||||
object udEveryQuantity: TUpDown
|
||||
Left = 149
|
||||
Top = 48
|
||||
Width = 16
|
||||
Height = 21
|
||||
Associate = editEveryQuantity
|
||||
Min = 1
|
||||
Max = 400000
|
||||
Position = 1
|
||||
TabOrder = 5
|
||||
end
|
||||
object comboEveryInterval: TComboBox
|
||||
Left = 172
|
||||
Top = 48
|
||||
Width = 133
|
||||
Height = 21
|
||||
Style = csDropDownList
|
||||
TabOrder = 6
|
||||
OnChange = comboEveryIntervalChange
|
||||
end
|
||||
object chkStarts: TCheckBox
|
||||
Left = 96
|
||||
Top = 78
|
||||
Width = 70
|
||||
Height = 17
|
||||
Caption = 'Starts at:'
|
||||
TabOrder = 7
|
||||
OnClick = chkStartsEndsClick
|
||||
end
|
||||
object chkEnds: TCheckBox
|
||||
Left = 96
|
||||
Top = 105
|
||||
Width = 70
|
||||
Height = 17
|
||||
Caption = 'Ends at:'
|
||||
TabOrder = 10
|
||||
OnClick = chkStartsEndsClick
|
||||
end
|
||||
object dateStarts: TDateTimePicker
|
||||
Left = 171
|
||||
Top = 75
|
||||
Width = 133
|
||||
Height = 21
|
||||
Date = 40273.548478379630000000
|
||||
Time = 40273.548478379630000000
|
||||
TabOrder = 8
|
||||
OnChange = Modification
|
||||
end
|
||||
object timeStarts: TDateTimePicker
|
||||
Left = 310
|
||||
Top = 75
|
||||
Width = 133
|
||||
Height = 21
|
||||
Date = 40273.549206851850000000
|
||||
Time = 40273.549206851850000000
|
||||
Kind = dtkTime
|
||||
TabOrder = 9
|
||||
OnChange = Modification
|
||||
end
|
||||
object timeEnds: TDateTimePicker
|
||||
Left = 310
|
||||
Top = 102
|
||||
Width = 133
|
||||
Height = 21
|
||||
Date = 40273.549548981480000000
|
||||
Time = 40273.549548981480000000
|
||||
Kind = dtkTime
|
||||
TabOrder = 12
|
||||
OnChange = Modification
|
||||
end
|
||||
object dateEnds: TDateTimePicker
|
||||
Left = 171
|
||||
Top = 102
|
||||
Width = 133
|
||||
Height = 21
|
||||
Date = 40273.549452245370000000
|
||||
Time = 40273.549452245370000000
|
||||
TabOrder = 11
|
||||
OnChange = Modification
|
||||
end
|
||||
end
|
||||
object tabCREATEcode: TTabSheet
|
||||
Caption = 'CREATE code'
|
||||
ImageIndex = 119
|
||||
object SynMemoCREATEcode: TSynMemo
|
||||
Left = 0
|
||||
Top = 0
|
||||
Width = 658
|
||||
Height = 137
|
||||
SingleLineMode = False
|
||||
Align = alClient
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -13
|
||||
Font.Name = 'Courier New'
|
||||
Font.Style = []
|
||||
TabOrder = 0
|
||||
Gutter.AutoSize = True
|
||||
Gutter.DigitCount = 2
|
||||
Gutter.Font.Charset = DEFAULT_CHARSET
|
||||
Gutter.Font.Color = clWindowText
|
||||
Gutter.Font.Height = -11
|
||||
Gutter.Font.Name = 'Courier New'
|
||||
Gutter.Font.Style = []
|
||||
Gutter.LeftOffset = 2
|
||||
Gutter.ShowLineNumbers = True
|
||||
Highlighter = MainForm.SynSQLSyn1
|
||||
Lines.Strings = (
|
||||
'SynMemoCREATEcode')
|
||||
Options = [eoAutoIndent, eoAutoSizeMaxScrollWidth, eoDragDropEditing, eoEnhanceEndKey, eoGroupUndo, eoHideShowScrollbars, eoKeepCaretX, eoShowScrollHint, eoSmartTabDelete, eoSmartTabs, eoTabsToSpaces]
|
||||
ReadOnly = True
|
||||
end
|
||||
end
|
||||
object tabALTERcode: TTabSheet
|
||||
Caption = 'ALTER code'
|
||||
ImageIndex = 119
|
||||
TabVisible = False
|
||||
object SynMemoALTERcode: TSynMemo
|
||||
Left = 0
|
||||
Top = 0
|
||||
Width = 658
|
||||
Height = 137
|
||||
SingleLineMode = False
|
||||
Align = alClient
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -13
|
||||
Font.Name = 'Courier New'
|
||||
Font.Style = []
|
||||
TabOrder = 0
|
||||
Gutter.AutoSize = True
|
||||
Gutter.DigitCount = 2
|
||||
Gutter.Font.Charset = DEFAULT_CHARSET
|
||||
Gutter.Font.Color = clWindowText
|
||||
Gutter.Font.Height = -11
|
||||
Gutter.Font.Name = 'Courier New'
|
||||
Gutter.Font.Style = []
|
||||
Gutter.LeftOffset = 2
|
||||
Gutter.ShowLineNumbers = True
|
||||
Highlighter = MainForm.SynSQLSyn1
|
||||
Lines.Strings = (
|
||||
'SynMemoALTERcode')
|
||||
Options = [eoAutoIndent, eoAutoSizeMaxScrollWidth, eoDragDropEditing, eoEnhanceEndKey, eoGroupUndo, eoHideShowScrollbars, eoKeepCaretX, eoShowScrollHint, eoSmartTabDelete, eoSmartTabs, eoTabsToSpaces]
|
||||
ReadOnly = True
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
386
source/event_editor.pas
Normal file
386
source/event_editor.pas
Normal file
@ -0,0 +1,386 @@
|
||||
unit event_editor;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
|
||||
Dialogs, StdCtrls, SynEdit, SynMemo, SynRegExpr, ComCtrls, ExtCtrls, WideStrUtils,
|
||||
helpers, mysql_connection;
|
||||
|
||||
type
|
||||
TFrame = TDBObjectEditor;
|
||||
TfrmEventEditor = class(TFrame)
|
||||
SynMemoBody: TSynMemo;
|
||||
btnHelp: TButton;
|
||||
btnDiscard: TButton;
|
||||
btnSave: TButton;
|
||||
lblBody: TLabel;
|
||||
PageControlMain: TPageControl;
|
||||
tabSettings: TTabSheet;
|
||||
tabScheduling: TTabSheet;
|
||||
tabCREATEcode: TTabSheet;
|
||||
tabALTERcode: TTabSheet;
|
||||
lblName: TLabel;
|
||||
editName: TEdit;
|
||||
lblComment: TLabel;
|
||||
chkDropAfterExpiration: TCheckBox;
|
||||
editComment: TEdit;
|
||||
grpState: TRadioGroup;
|
||||
radioOnce: TRadioButton;
|
||||
radioEvery: TRadioButton;
|
||||
dateOnce: TDateTimePicker;
|
||||
timeOnce: TDateTimePicker;
|
||||
editEveryQuantity: TEdit;
|
||||
udEveryQuantity: TUpDown;
|
||||
comboEveryInterval: TComboBox;
|
||||
chkStarts: TCheckBox;
|
||||
chkEnds: TCheckBox;
|
||||
dateStarts: TDateTimePicker;
|
||||
timeStarts: TDateTimePicker;
|
||||
timeEnds: TDateTimePicker;
|
||||
dateEnds: TDateTimePicker;
|
||||
SynMemoCREATEcode: TSynMemo;
|
||||
SynMemoALTERcode: TSynMemo;
|
||||
procedure Modification(Sender: TObject);
|
||||
procedure radioScheduleClick(Sender: TObject);
|
||||
procedure btnSaveClick(Sender: TObject);
|
||||
procedure btnHelpClick(Sender: TObject);
|
||||
procedure btnDiscardClick(Sender: TObject);
|
||||
procedure PageControlMainChange(Sender: TObject);
|
||||
procedure chkStartsEndsClick(Sender: TObject);
|
||||
procedure comboEveryIntervalChange(Sender: TObject);
|
||||
private
|
||||
{ Private declarations }
|
||||
AlterCodeValid, CreateCodeValid: Boolean;
|
||||
function ComposeCreateStatement: String;
|
||||
function ComposeAlterStatement: String;
|
||||
function ComposeBaseStatement: String;
|
||||
procedure UpdateSQLcode;
|
||||
public
|
||||
{ Public declarations }
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
procedure Init(Obj: TDBObject); override;
|
||||
function ApplyModifications: TModalResult; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses main;
|
||||
|
||||
{$R *.dfm}
|
||||
|
||||
|
||||
constructor TfrmEventEditor.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited;
|
||||
Mainform.SynCompletionProposal.AddEditor(SynMemoBody);
|
||||
comboEveryInterval.Items := Explode('|', 'YEAR|QUARTER|MONTH|DAY|HOUR|MINUTE|WEEK|SECOND|YEAR_MONTH|'+
|
||||
'DAY_HOUR|DAY_MINUTE|DAY_SECOND|HOUR_MINUTE|HOUR_SECOND|MINUTE_SECOND');
|
||||
grpState.Items := Explode('|', 'Enable|Disable|Disable on slave');
|
||||
end;
|
||||
|
||||
|
||||
destructor TfrmEventEditor.Destroy;
|
||||
begin
|
||||
// Store GUI setup? Nothing yet.
|
||||
inherited;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmEventEditor.Init(Obj: TDBObject);
|
||||
var
|
||||
CreateCode, DateExpr: String;
|
||||
rx: TRegExpr;
|
||||
d: TDateTime;
|
||||
i: Integer;
|
||||
begin
|
||||
inherited;
|
||||
editName.Clear;
|
||||
editComment.Clear;
|
||||
chkDropAfterExpiration.Checked := True;
|
||||
radioEvery.Checked := True;
|
||||
grpState.ItemIndex := 0;
|
||||
SynMemoBody.Text := 'BEGIN'+CRLF+CRLF+'END';
|
||||
dateOnce.Date := Now;
|
||||
timeOnce.Time := Now;
|
||||
dateStarts.Date := Now;
|
||||
timeStarts.Time := Now;
|
||||
dateEnds.Date := Now;
|
||||
timeEnds.Time := Now;
|
||||
udEveryQuantity.Position := 1;
|
||||
comboEveryInterval.ItemIndex := comboEveryInterval.Items.IndexOf('DAY');
|
||||
tabALTERcode.TabVisible := False;
|
||||
if DBObject.Name <> '' then begin
|
||||
// Edit mode
|
||||
tabALTERcode.TabVisible := True;
|
||||
editName.Text := DBObject.Name;
|
||||
// CREATE EVENT `eventb`
|
||||
// ON SCHEDULE EVERY 1 DAY STARTS '2010-04-08 08:05:04' ENDS '2010-04-30 01:01:28'
|
||||
// ON COMPLETION NOT PRESERVE
|
||||
// ENABLE
|
||||
// DO BEGIN END
|
||||
CreateCode := Mainform.Connection.GetVar('SHOW CREATE EVENT '+Mainform.mask(DBObject.Name), 'Create Event');
|
||||
DateExpr := '[''"]([^''"]+)[''"]';
|
||||
rx := TRegExpr.Create;
|
||||
rx.ModifierI := True;
|
||||
rx.Expression := '\bON\s+SCHEDULE\s+(EVERY|AT)\s+((\d+|''[^'']+'')\s+(\S+)(\s+STARTS\s+'+DateExpr+')?(\s+ENDS\s+'+DateExpr+')?|'+DateExpr+')';
|
||||
if rx.Exec(CreateCode) then begin
|
||||
if UpperCase(rx.Match[1]) = 'AT' then begin
|
||||
radioOnce.Checked := True;
|
||||
d := Mainform.Connection.ParseDateTime(rx.Match[9]);
|
||||
dateOnce.DateTime := d;
|
||||
timeOnce.DateTime := d;
|
||||
end else begin
|
||||
radioEvery.Checked := True;
|
||||
comboEveryInterval.ItemIndex := comboEveryInterval.Items.IndexOf(rx.Match[4]);
|
||||
comboEveryIntervalChange(Self);
|
||||
if udEveryQuantity.Enabled then
|
||||
udEveryQuantity.Position := MakeInt(rx.Match[3])
|
||||
else
|
||||
editEveryQuantity.Text := WideDequotedStr(rx.Match[3], '''');
|
||||
chkStarts.Checked := rx.MatchLen[5] > 0;
|
||||
if chkStarts.Checked then begin
|
||||
d := Mainform.Connection.ParseDateTime(rx.Match[6]);
|
||||
dateStarts.DateTime := d;
|
||||
timeStarts.DateTime := d;
|
||||
end;
|
||||
chkEnds.Checked := rx.MatchLen[7] > 0;
|
||||
if chkEnds.Checked then begin
|
||||
d := Mainform.Connection.ParseDateTime(rx.Match[8]);
|
||||
dateEnds.DateTime := d;
|
||||
timeEnds.DateTime := d;
|
||||
end;
|
||||
end;
|
||||
Delete(CreateCode, 1, rx.MatchPos[0]+rx.MatchLen[0]);
|
||||
end;
|
||||
|
||||
rx.Expression := '^ON\s+COMPLETION(\s+NOT)?\s+PRESERVE\b';
|
||||
if rx.Exec(CreateCode) then begin
|
||||
chkDropAfterExpiration.Checked := rx.MatchLen[1] > 0;
|
||||
Delete(CreateCode, 1, rx.MatchPos[0]+rx.MatchLen[0]);
|
||||
end;
|
||||
|
||||
for i:=grpState.Items.Count-1 downto 0 do begin
|
||||
if Pos(UpperCase(grpState.Items[i]), UpperCase(CreateCode)) = 1 then begin
|
||||
grpState.ItemIndex := i;
|
||||
Delete(CreateCode, 1, Length(grpState.Items[i]));
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
rx.Expression := '\bCOMMENT\s+''((.+)[^''])''';
|
||||
if rx.Exec(CreateCode) then begin
|
||||
editComment.Text := StringReplace(rx.Match[1], '''''', '''', [rfReplaceAll]);
|
||||
Delete(CreateCode, rx.MatchPos[0], rx.MatchLen[0]);
|
||||
end;
|
||||
|
||||
rx.Expression := '\bDO\s+(.*)';
|
||||
if rx.Exec(CreateCode) then
|
||||
SynMemoBody.Text := rx.Match[1];
|
||||
|
||||
rx.Free;
|
||||
|
||||
end;
|
||||
radioScheduleClick(Self);
|
||||
Modified := False;
|
||||
btnSave.Enabled := Modified;
|
||||
btnDiscard.Enabled := Modified;
|
||||
Mainform.ShowStatusMsg;
|
||||
Screen.Cursor := crDefault;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmEventEditor.Modification(Sender: TObject);
|
||||
begin
|
||||
Modified := True;
|
||||
btnSave.Enabled := Modified;
|
||||
btnDiscard.Enabled := Modified;
|
||||
CreateCodeValid := False;
|
||||
AlterCodeValid := False;
|
||||
UpdateSQLcode;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmEventEditor.btnSaveClick(Sender: TObject);
|
||||
begin
|
||||
ApplyModifications;
|
||||
end;
|
||||
|
||||
|
||||
function TfrmEventEditor.ApplyModifications: TModalResult;
|
||||
var
|
||||
sql: String;
|
||||
begin
|
||||
// Create or alter table
|
||||
Result := mrOk;
|
||||
if DBObject.Name = '' then
|
||||
sql := ComposeCreateStatement
|
||||
else
|
||||
sql := ComposeAlterStatement;
|
||||
try
|
||||
Mainform.Connection.Query(sql);
|
||||
DBObject.Name := editName.Text;
|
||||
tabALTERcode.TabVisible := DBObject.Name <> '';
|
||||
Mainform.UpdateEditorTab;
|
||||
Mainform.RefreshTreeDB(Mainform.ActiveDatabase, DBObject.Name, DBObject.NodeType);
|
||||
Modified := False;
|
||||
btnSave.Enabled := Modified;
|
||||
btnDiscard.Enabled := Modified;
|
||||
AlterCodeValid := False;
|
||||
CreateCodeValid := False;
|
||||
UpdateSQLcode;
|
||||
except
|
||||
on E:Exception do begin
|
||||
MessageDlg(E.Message, mtError, [mbOk], 0);
|
||||
Result := mrAbort;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function TfrmEventEditor.ComposeCreateStatement: String;
|
||||
begin
|
||||
Result := 'CREATE EVENT ' + Mainform.mask(editName.Text) + ' ' + ComposeBaseStatement;
|
||||
end;
|
||||
|
||||
|
||||
function TfrmEventEditor.ComposeAlterStatement: String;
|
||||
begin
|
||||
Result := 'ALTER EVENT ' + Mainform.mask(DBObject.Name) + ' ' + ComposeBaseStatement;
|
||||
end;
|
||||
|
||||
|
||||
function TfrmEventEditor.ComposeBaseStatement: String;
|
||||
var
|
||||
d: TDateTime;
|
||||
Quantity: String;
|
||||
begin
|
||||
// Return CREATE EVENT statement
|
||||
Result := 'ON SCHEDULE' + CRLF + #9#9;
|
||||
if radioOnce.Checked then begin
|
||||
d := dateOnce.DateTime;
|
||||
ReplaceTime(d, timeOnce.DateTime);
|
||||
Result := Result + 'AT ' + esc(DateTimeToStr(d)) + CRLF;
|
||||
end else begin
|
||||
if udEveryQuantity.Enabled then
|
||||
Quantity := IntToStr(udEveryQuantity.Position)
|
||||
else
|
||||
Quantity := esc(editEveryQuantity.Text);
|
||||
Result := Result + 'EVERY ' + Quantity + ' ' + comboEveryInterval.Text;
|
||||
if chkStarts.Checked then begin
|
||||
d := dateStarts.DateTime;
|
||||
ReplaceTime(d, timeStarts.DateTime);
|
||||
Result := Result + ' STARTS ' + esc(DateTimeToStr(d));
|
||||
end;
|
||||
if chkEnds.Checked then begin
|
||||
d := dateEnds.DateTime;
|
||||
ReplaceTime(d, timeEnds.DateTime);
|
||||
Result := Result + ' ENDS ' + esc(DateTimeToStr(d));
|
||||
end;
|
||||
Result := Result + CRLF;
|
||||
end;
|
||||
|
||||
if chkDropAfterExpiration.Checked then
|
||||
Result := Result + #9 + 'ON COMPLETION NOT PRESERVE'
|
||||
else
|
||||
Result := Result + #9 + 'ON COMPLETION PRESERVE';
|
||||
if (DBObject.Name <> '') and (DBObject.Name <> editName.Text) then
|
||||
Result := Result + CRLF + #9 + 'RENAME TO ' + MainForm.mask(editName.Text);
|
||||
Result := Result + CRLF + #9 + UpperCase(grpState.Items[grpState.ItemIndex]);
|
||||
Result := Result + CRLF + #9 + 'COMMENT ' + esc(editComment.Text);
|
||||
Result := Result + CRLF + #9 + 'DO ' + SynMemoBody.Text;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmEventEditor.PageControlMainChange(Sender: TObject);
|
||||
begin
|
||||
UpdateSQLcode;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmEventEditor.UpdateSQLcode;
|
||||
var
|
||||
OldTopLine: Integer;
|
||||
begin
|
||||
if (PageControlMain.ActivePage = tabALTERCode) and (not AlterCodeValid) then begin
|
||||
SynMemoALTERcode.BeginUpdate;
|
||||
OldTopLine := SynMemoALTERcode.TopLine;
|
||||
SynMemoALTERcode.Text := ComposeAlterStatement;
|
||||
SynMemoALTERcode.TopLine := OldTopLine;
|
||||
SynMemoALTERcode.EndUpdate;
|
||||
AlterCodeValid := True;
|
||||
end else if (PageControlMain.ActivePage = tabCREATECode) and (not CreateCodeValid) then begin
|
||||
SynMemoCREATEcode.BeginUpdate;
|
||||
OldTopLine := SynMemoCREATEcode.TopLine;
|
||||
SynMemoCREATEcode.Text := ComposeCreateStatement;
|
||||
SynMemoCREATEcode.TopLine := OldTopLine;
|
||||
SynMemoCREATEcode.EndUpdate;
|
||||
CreateCodeValid := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmEventEditor.radioScheduleClick(Sender: TObject);
|
||||
var
|
||||
IsOnce: Boolean;
|
||||
begin
|
||||
IsOnce := radioOnce.Checked;
|
||||
dateOnce.Enabled := IsOnce;
|
||||
timeOnce.Enabled := IsOnce;
|
||||
editEveryQuantity.Enabled := not IsOnce;
|
||||
udEveryQuantity.Enabled := not IsOnce;
|
||||
comboEveryInterval.Enabled := not IsOnce;
|
||||
comboEveryIntervalChange(Sender);
|
||||
chkStarts.Enabled := not IsOnce;
|
||||
chkEnds.Enabled := not IsOnce;
|
||||
chkStartsEndsClick(Sender);
|
||||
Modification(Sender);
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmEventEditor.chkStartsEndsClick(Sender: TObject);
|
||||
begin
|
||||
// Enable/disable start+end controls
|
||||
dateStarts.Enabled := chkStarts.Checked and chkStarts.Enabled;
|
||||
timeStarts.Enabled := chkStarts.Checked and chkStarts.Enabled;
|
||||
dateEnds.Enabled := chkEnds.Checked and chkEnds.Enabled;
|
||||
timeEnds.Enabled := chkEnds.Checked and chkEnds.Enabled;
|
||||
Modification(Sender);
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmEventEditor.comboEveryIntervalChange(Sender: TObject);
|
||||
begin
|
||||
// To enter DAY_HOUR values editor has to accept "1-2"
|
||||
if Pos('_', comboEveryInterval.Text) > 0 then begin
|
||||
udEveryQuantity.Associate := nil;
|
||||
udEveryQuantity.Enabled := False;
|
||||
end else begin
|
||||
udEveryQuantity.Associate := editEveryQuantity;
|
||||
udEveryQuantity.Enabled := True;
|
||||
end;
|
||||
Modification(Sender);
|
||||
end;
|
||||
|
||||
procedure TfrmEventEditor.btnDiscardClick(Sender: TObject);
|
||||
begin
|
||||
// Reinit editor, discarding changes
|
||||
Modified := False;
|
||||
Init(DBObject);
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmEventEditor.btnHelpClick(Sender: TObject);
|
||||
var
|
||||
keyword: String;
|
||||
begin
|
||||
if DBObject.Name = '' then
|
||||
keyword := 'CREATE EVENT'
|
||||
else
|
||||
keyword := 'ALTER EVENT';
|
||||
Mainform.CallSQLHelpWithKeyword(keyword);
|
||||
end;
|
||||
|
||||
|
||||
end.
|
@ -142,15 +142,16 @@ type
|
||||
FModified: Boolean;
|
||||
procedure SetModified(Value: Boolean);
|
||||
protected
|
||||
FEditObjectName: String;
|
||||
public
|
||||
DBObject: TDBObject;
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
procedure Init(ObjectName: String=''; ObjectType: TListNodeType=lntNone); virtual;
|
||||
procedure Init(Obj: TDBObject); virtual;
|
||||
function DeInit: TModalResult;
|
||||
property Modified: Boolean read FModified write SetModified;
|
||||
function ApplyModifications: TModalResult; virtual; abstract;
|
||||
end;
|
||||
TDBObjectEditorClass = class of TDBObjectEditor;
|
||||
|
||||
TWndProc = function (hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
|
||||
PGripInfo = ^TGripInfo;
|
||||
@ -271,7 +272,7 @@ var
|
||||
|
||||
implementation
|
||||
|
||||
uses main, uVistaFuncs, table_editor, view, routine_editor, trigger_editor;
|
||||
uses main, uVistaFuncs, table_editor, view, routine_editor, trigger_editor, event_editor;
|
||||
|
||||
|
||||
|
||||
@ -3250,7 +3251,7 @@ begin
|
||||
Value := esAddedDeleted;
|
||||
FStatus := Value;
|
||||
if Value <> esUntouched then
|
||||
Mainform.TableEditor.Modification(Self);
|
||||
TfrmTableEditor(Mainform.ActiveObjectEditor).Modification(Self);
|
||||
end;
|
||||
|
||||
|
||||
@ -3318,11 +3319,12 @@ begin
|
||||
FModified := Value;
|
||||
end;
|
||||
|
||||
procedure TDBObjectEditor.Init(ObjectName: String=''; ObjectType: TListNodeType=lntNone);
|
||||
procedure TDBObjectEditor.Init(Obj: TDBObject);
|
||||
begin
|
||||
Mainform.ShowStatusMsg('Initializing editor ...');
|
||||
FEditObjectName := ObjectName;
|
||||
Mainform.SetEditorTabCaption(Self, FEditObjectName);
|
||||
ScaleControls(Screen.PixelsPerInch, FORMS_DPI);
|
||||
DBObject := Obj;
|
||||
Mainform.UpdateEditorTab;
|
||||
Screen.Cursor := crHourglass;
|
||||
MainForm.SetupSynEditors;
|
||||
end;
|
||||
@ -3334,13 +3336,9 @@ begin
|
||||
// Ask for saving modifications
|
||||
Result := mrOk;
|
||||
if Modified then begin
|
||||
if Self is TfrmTableEditor then ObjType := 'table'
|
||||
else if Self is TfrmView then ObjType := 'view'
|
||||
else if Self is TfrmRoutineEditor then ObjType := 'routine'
|
||||
else if Self is TfrmTriggerEditor then ObjType := 'trigger'
|
||||
else ObjType := '<Unknown Type - should never appear>';
|
||||
if FEditObjectName <> '' then
|
||||
Msg := 'Save modified '+ObjType+' "'+FEditObjectName+'"?'
|
||||
ObjType := LowerCase(DBObject.ObjType);
|
||||
if DBObject.Name <> '' then
|
||||
Msg := 'Save modified '+ObjType+' "'+DBObject.Name+'"?'
|
||||
else
|
||||
Msg := 'Save new '+ObjType+'?';
|
||||
Result := MessageDlg(Msg, mtConfirmation, [mbYes, mbNo, mbCancel], 0);
|
||||
|
@ -2467,6 +2467,14 @@ object MainForm: TMainForm
|
||||
ImageIndex = 35
|
||||
OnExecute = actRunRoutinesExecute
|
||||
end
|
||||
object actCreateEvent: TAction
|
||||
Category = 'Database'
|
||||
Caption = 'Event'
|
||||
Enabled = False
|
||||
Hint = 'Create new event in selected database'
|
||||
ImageIndex = 80
|
||||
OnExecute = actCreateDBObjectExecute
|
||||
end
|
||||
end
|
||||
object SaveDialog2: TSaveDialog
|
||||
DefaultExt = 'reg'
|
||||
@ -7563,6 +7571,9 @@ object MainForm: TMainForm
|
||||
object menuCreateTrigger: TMenuItem
|
||||
Action = actCreateTrigger
|
||||
end
|
||||
object Event1: TMenuItem
|
||||
Action = actCreateEvent
|
||||
end
|
||||
end
|
||||
object N17: TMenuItem
|
||||
Caption = '-'
|
||||
|
220
source/main.pas
220
source/main.pas
@ -16,7 +16,7 @@ uses
|
||||
ShlObj, SynEditMiscClasses, SynEditSearch, SynEditRegexSearch, SynCompletionProposal, SynEditHighlighter,
|
||||
SynHighlighterSQL, Tabs, SynUnicode, SynRegExpr, WideStrUtils, ExtActns,
|
||||
CommCtrl, Contnrs, Generics.Collections, SynEditExport, SynExportHTML,
|
||||
routine_editor, trigger_editor, options, EditVar, helpers, createdatabase, table_editor,
|
||||
routine_editor, trigger_editor, event_editor, options, EditVar, helpers, createdatabase, table_editor,
|
||||
TableTools, View, Usermanager, SelectDBObject, connections, sqlhelp, mysql_connection,
|
||||
mysql_api, insertfiles, searchreplace, loaddata, copytable;
|
||||
|
||||
@ -472,6 +472,8 @@ type
|
||||
menuFetchDBitems: TMenuItem;
|
||||
actRunRoutines: TAction;
|
||||
Runroutines1: TMenuItem;
|
||||
actCreateEvent: TAction;
|
||||
Event1: TMenuItem;
|
||||
procedure actCreateDBObjectExecute(Sender: TObject);
|
||||
procedure menuConnectionsPopup(Sender: TObject);
|
||||
procedure actExitApplicationExecute(Sender: TObject);
|
||||
@ -781,7 +783,6 @@ type
|
||||
FilterTextDatabase,
|
||||
FilterTextData: String;
|
||||
PreviousFocusedNode: PVirtualNode;
|
||||
FActiveObjectEditor: TDBObjectEditor;
|
||||
FCmdlineFilenames: TStringlist;
|
||||
FCmdlineConnectionParams: TConnectionParameters;
|
||||
FCmdlineSessionName: String;
|
||||
@ -796,7 +797,7 @@ type
|
||||
procedure SetVisibleListColumns( List: TVirtualStringTree; Columns: TStringList );
|
||||
procedure ToggleFilterPanel(ForceVisible: Boolean = False);
|
||||
procedure AutoCalcColWidth(Tree: TVirtualStringTree; Column: TColumnIndex);
|
||||
function PlaceObjectEditor(Which: TListNodeType): TDBObjectEditor;
|
||||
procedure PlaceObjectEditor(Obj: TDBObject);
|
||||
procedure SetTabCaption(PageIndex: Integer; Text: String);
|
||||
function ConfirmTabClose(PageIndex: Integer): Boolean;
|
||||
procedure SaveQueryMemo(Tab: TQueryTab; Filename: String; OnlySelection: Boolean);
|
||||
@ -818,19 +819,16 @@ type
|
||||
DBObjectsMaxSize: Int64;
|
||||
DBObjectsMaxRows: Int64;
|
||||
ProcessListMaxTime: Int64;
|
||||
ActiveObjectEditor: TDBObjectEditor;
|
||||
|
||||
// Cached forms
|
||||
TableToolsDialog: TfrmTableTools;
|
||||
ViewEditor: TfrmView;
|
||||
UserManagerForm: TUserManagerForm;
|
||||
SelectDBObjectForm: TfrmSelectDBObject;
|
||||
SQLHelpForm: TfrmSQLhelp;
|
||||
RoutineEditor: TfrmRoutineEditor;
|
||||
TriggerEditor: TfrmTriggerEditor;
|
||||
OptionsForm: Toptionsform;
|
||||
SessionManager: TConnForm;
|
||||
CreateDatabaseForm: TCreateDatabaseForm;
|
||||
TableEditor: TfrmTableEditor;
|
||||
InsertFiles: TfrmInsertFiles;
|
||||
EditVariableForm: TfrmEditVariable;
|
||||
SearchReplaceDialog: TfrmSearchReplace;
|
||||
@ -941,7 +939,7 @@ type
|
||||
function GetRegKeyTable: String;
|
||||
procedure SaveListSetup( List: TVirtualStringTree );
|
||||
procedure RestoreListSetup( List: TVirtualStringTree );
|
||||
procedure SetEditorTabCaption(Editor: TDBObjectEditor; ObjName: String);
|
||||
procedure UpdateEditorTab;
|
||||
procedure SetWindowCaption;
|
||||
procedure OnMessageHandler(var Msg: TMsg; var Handled: Boolean);
|
||||
procedure DefaultHandler(var Message); override;
|
||||
@ -1025,8 +1023,8 @@ begin
|
||||
Exit;
|
||||
end;
|
||||
// Unsaved modified table, trigger, view or routine?
|
||||
if Assigned(FActiveObjectEditor) then
|
||||
CanClose := not (FActiveObjectEditor.DeInit in [mrAbort, mrCancel]);
|
||||
if Assigned(ActiveObjectEditor) then
|
||||
CanClose := not (ActiveObjectEditor.DeInit in [mrAbort, mrCancel]);
|
||||
end;
|
||||
|
||||
procedure TMainForm.FormDestroy(Sender: TObject);
|
||||
@ -1035,16 +1033,13 @@ var
|
||||
i: Integer;
|
||||
begin
|
||||
// Destroy editors and dialogs. Must be done before connection gets closed, as some destructors do SQL stuff.
|
||||
FreeAndNil(RoutineEditor);
|
||||
FreeAndNil(ActiveObjectEditor);
|
||||
FreeAndNil(TableToolsDialog);
|
||||
FreeAndNil(UserManagerForm);
|
||||
FreeAndNil(ViewEditor);
|
||||
FreeAndNil(SelectDBObjectForm);
|
||||
FreeAndNil(SQLHelpForm);
|
||||
FreeAndNil(OptionsForm);
|
||||
FreeAndNil(SessionManager);
|
||||
FreeAndNil(TableEditor);
|
||||
FreeAndNil(TriggerEditor);
|
||||
FreeAndNil(CreateDatabaseForm);
|
||||
FreeAndNil(SearchReplaceDialog);
|
||||
|
||||
@ -2487,21 +2482,20 @@ end;
|
||||
|
||||
procedure TMainForm.actCreateDBObjectExecute(Sender: TObject);
|
||||
var
|
||||
Editor: TDBObjectEditor;
|
||||
ObjType: TListNodeType;
|
||||
Obj: TDBObject;
|
||||
a: TAction;
|
||||
begin
|
||||
// Create a new table, view, etc.
|
||||
tabEditor.TabVisible := True;
|
||||
PagecontrolMain.ActivePage := tabEditor;
|
||||
a := Sender as TAction;
|
||||
ObjType := lntNone;
|
||||
if a = actCreateTable then ObjType := lntTable
|
||||
else if a = actCreateView then ObjType := lntView
|
||||
else if a = actCreateRoutine then ObjType := lntProcedure
|
||||
else if a = actCreateTrigger then ObjType := lntTrigger;
|
||||
Editor := PlaceObjectEditor(ObjType);
|
||||
Editor.Init;
|
||||
Obj := TDBObject.Create;
|
||||
if a = actCreateTable then Obj.NodeType := lntTable
|
||||
else if a = actCreateView then Obj.NodeType := lntView
|
||||
else if a = actCreateRoutine then Obj.NodeType := lntProcedure
|
||||
else if a = actCreateTrigger then Obj.NodeType := lntTrigger
|
||||
else if a = actCreateEvent then Obj.NodeType := lntEvent;
|
||||
PlaceObjectEditor(Obj);
|
||||
end;
|
||||
|
||||
|
||||
@ -3817,14 +3811,7 @@ begin
|
||||
if Column <> (Sender as TVirtualStringTree).Header.MainColumn then
|
||||
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;
|
||||
ImageIndex := Obj.ImageIndex;
|
||||
end;
|
||||
|
||||
|
||||
@ -4201,18 +4188,9 @@ var
|
||||
Queries : TStringList;
|
||||
|
||||
procedure addTable(Obj: TDBObject);
|
||||
var Icon: Integer;
|
||||
begin
|
||||
case Obj.NodeType of
|
||||
lntTable: Icon := ICONINDEX_TABLE;
|
||||
lntFunction: Icon := ICONINDEX_STOREDFUNCTION;
|
||||
lntProcedure: Icon := ICONINDEX_STOREDPROCEDURE;
|
||||
lntView: Icon := ICONINDEX_VIEW;
|
||||
lntTrigger: Icon := ICONINDEX_TRIGGER;
|
||||
else Icon := -1;
|
||||
end;
|
||||
Proposal.InsertList.Add(Obj.Name);
|
||||
Proposal.ItemList.Add( Format(SYNCOMPLETION_PATTERN, [Icon, LowerCase(Obj.ObjType), Obj.Name]) );
|
||||
Proposal.ItemList.Add( Format(SYNCOMPLETION_PATTERN, [Obj.ImageIndex, LowerCase(Obj.ObjType), Obj.Name]) );
|
||||
end;
|
||||
|
||||
procedure addColumns( tablename: String );
|
||||
@ -4795,6 +4773,7 @@ begin
|
||||
actCreateView.Enabled := L in [1,2];
|
||||
actCreateRoutine.Enabled := L in [1,2];
|
||||
actCreateTrigger.Enabled := L in [1,2];
|
||||
actCreateEvent.Enabled := L in [1,2];
|
||||
actDropObjects.Enabled := L in [1,2];
|
||||
actCopyTable.Enabled := HasFocus and (NodeType in [lntTable, lntView]);
|
||||
actEmptyTables.Enabled := HasFocus and (NodeType in [lntTable, lntView]);
|
||||
@ -4811,6 +4790,8 @@ begin
|
||||
actCreateTable.Enabled := True;
|
||||
actCreateView.Enabled := True;
|
||||
actCreateRoutine.Enabled := True;
|
||||
actCreateTrigger.Enabled := True;
|
||||
actCreateEvent.Enabled := True;
|
||||
actDropObjects.Enabled := ListTables.SelectedCount > 0;
|
||||
actEmptyTables.Enabled := False;
|
||||
actRunRoutines.Enabled := True;
|
||||
@ -4829,6 +4810,7 @@ begin
|
||||
actCreateView.Enabled := actCreateView.Enabled and (Connection.ServerVersionInt >= 50001);
|
||||
actCreateRoutine.Enabled := actCreateRoutine.Enabled and (Connection.ServerVersionInt >= 50003);
|
||||
actCreateTrigger.Enabled := actCreateTrigger.Enabled and (Connection.ServerVersionInt >= 50002);
|
||||
actCreateEvent.Enabled := actCreateEvent.Enabled and (Connection.ServerVersionInt >= 50100);
|
||||
end;
|
||||
|
||||
|
||||
@ -5271,9 +5253,9 @@ begin
|
||||
ActiveQueryHelpers.Items.Add(Col.Name);
|
||||
end;
|
||||
end;
|
||||
lntFunction, lntProcedure: if Assigned(RoutineEditor) then begin
|
||||
for i:=0 to RoutineEditor.Parameters.Count-1 do
|
||||
ActiveQueryHelpers.Items.Add(RoutineEditor.Parameters[i].Name);
|
||||
lntFunction, lntProcedure: if Assigned(ActiveObjectEditor) then begin
|
||||
for i:=0 to TfrmRoutineEditor(ActiveObjectEditor).Parameters.Count-1 do
|
||||
ActiveQueryHelpers.Items.Add(TfrmRoutineEditor(ActiveObjectEditor).Parameters[i].Name);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -6318,22 +6300,7 @@ begin
|
||||
// of DBObjects. Probably a timing issue. Work around that by doing a safety check here.
|
||||
if Node.Index >= Cardinal(DBObjects.Count) then
|
||||
Exit;
|
||||
case DBObjects[Node.Index].NodeType of
|
||||
lntTable:
|
||||
if Kind = ikSelected then
|
||||
ImageIndex := ICONINDEX_TABLE_HIGHLIGHT
|
||||
else ImageIndex := ICONINDEX_TABLE;
|
||||
lntView:
|
||||
if Kind = ikSelected then
|
||||
ImageIndex := ICONINDEX_VIEW_HIGHLIGHT
|
||||
else ImageIndex := ICONINDEX_VIEW;
|
||||
lntProcedure:
|
||||
ImageIndex := ICONINDEX_STOREDPROCEDURE;
|
||||
lntFunction:
|
||||
ImageIndex := ICONINDEX_STOREDFUNCTION;
|
||||
lntTrigger:
|
||||
ImageIndex := ICONINDEX_TRIGGER;
|
||||
end;
|
||||
ImageIndex := DBObjects[Node.Index].ImageIndex;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -6494,7 +6461,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
newDbObject := SelectedTable.Name;
|
||||
tabEditor.TabVisible := SelectedTable.NodeType in [lntTable, lntView, lntProcedure, lntFunction, lntTrigger];
|
||||
tabEditor.TabVisible := SelectedTable.NodeType in [lntTable, lntView, lntProcedure, lntFunction, lntTrigger, lntEvent];
|
||||
tabData.TabVisible := SelectedTable.NodeType in [lntTable, lntView];
|
||||
ParseSelectedTableStructure;
|
||||
if tabEditor.TabVisible then begin
|
||||
@ -6536,8 +6503,8 @@ procedure TMainForm.DBtreeFocusChanging(Sender: TBaseVirtualTree; OldNode,
|
||||
begin
|
||||
debug('DBtreeFocusChanging');
|
||||
// Check if some editor has unsaved changes
|
||||
if Assigned(FActiveObjectEditor) and Assigned(NewNode) then begin
|
||||
Allowed := not (FActiveObjectEditor.DeInit in [mrAbort, mrCancel]);
|
||||
if Assigned(ActiveObjectEditor) and Assigned(NewNode) then begin
|
||||
Allowed := not (ActiveObjectEditor.DeInit in [mrAbort, mrCancel]);
|
||||
DBTree.Selected[DBTree.FocusedNode] := not Allowed;
|
||||
end else
|
||||
Allowed := True;
|
||||
@ -8432,67 +8399,39 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
function TMainForm.PlaceObjectEditor(Which: TListNodeType): TDBObjectEditor;
|
||||
procedure TMainForm.PlaceObjectEditor(Obj: TDBObject);
|
||||
var
|
||||
EditorClass: TDBObjectEditorClass;
|
||||
begin
|
||||
// Place the relevant editor frame onto the editor tab, hide all others
|
||||
Result := nil;
|
||||
FActiveObjectEditor := nil;
|
||||
if (not (Which in [lntTable])) and Assigned(TableEditor) then
|
||||
FreeAndNil(TableEditor);
|
||||
if (Which <> lntView) and Assigned(ViewEditor) then
|
||||
FreeAndNil(ViewEditor);
|
||||
if (not (Which in [lntProcedure, lntFunction])) and Assigned(RoutineEditor) then
|
||||
FreeAndNil(RoutineEditor);
|
||||
if (Which <> lntTrigger) and Assigned(TriggerEditor) then
|
||||
FreeAndNil(TriggerEditor);
|
||||
if Which in [lntTable] then begin
|
||||
if not Assigned(TableEditor) then
|
||||
TableEditor := TfrmTableEditor.Create(tabEditor);
|
||||
Result := TableEditor;
|
||||
end else if Which = lntView then begin
|
||||
if not Assigned(ViewEditor) then
|
||||
ViewEditor := TfrmView.Create(tabEditor);
|
||||
Result := ViewEditor;
|
||||
end else if Which in [lntProcedure, lntFunction] then begin
|
||||
if not Assigned(RoutineEditor) then
|
||||
RoutineEditor := TfrmRoutineEditor.Create(tabEditor);
|
||||
Result := RoutineEditor;
|
||||
end else if Which = lntTrigger then begin
|
||||
if not Assigned(TriggerEditor) then
|
||||
TriggerEditor := TfrmTriggerEditor.Create(tabEditor);
|
||||
Result := TriggerEditor;
|
||||
end else
|
||||
Exit;
|
||||
Result.Parent := tabEditor;
|
||||
FActiveObjectEditor := Result;
|
||||
if Assigned(ActiveObjectEditor) and (Obj.NodeType <> ActiveObjectEditor.DBObject.NodeType) then
|
||||
FreeAndNil(ActiveObjectEditor);
|
||||
case Obj.NodeType of
|
||||
lntTable: EditorClass := TfrmTableEditor;
|
||||
lntView: EditorClass := TfrmView;
|
||||
lntProcedure, lntFunction: EditorClass := TfrmRoutineEditor;
|
||||
lntTrigger: EditorClass := TfrmTriggerEditor;
|
||||
lntEvent: EditorClass := TfrmEventEditor;
|
||||
else Exit;
|
||||
end;
|
||||
if not Assigned(ActiveObjectEditor) then begin
|
||||
ActiveObjectEditor := EditorClass.Create(tabEditor);
|
||||
ActiveObjectEditor.Parent := tabEditor;
|
||||
end;
|
||||
ActiveObjectEditor.Init(Obj);
|
||||
end;
|
||||
|
||||
|
||||
procedure TMainForm.SetEditorTabCaption(Editor: TDBObjectEditor; ObjName: String);
|
||||
procedure TMainForm.UpdateEditorTab;
|
||||
var
|
||||
ObjType, Cap: String;
|
||||
IconIndex: Integer;
|
||||
Cap: String;
|
||||
begin
|
||||
if Editor = TableEditor then begin
|
||||
ObjType := 'Table';
|
||||
IconIndex := ICONINDEX_TABLE;
|
||||
end else if Editor = ViewEditor then begin
|
||||
ObjType := 'View';
|
||||
IconIndex := ICONINDEX_VIEW;
|
||||
end else if Editor = RoutineEditor then begin
|
||||
ObjType := 'Routine';
|
||||
IconIndex := ICONINDEX_STOREDPROCEDURE;
|
||||
end else if Editor = TriggerEditor then begin
|
||||
ObjType := 'Trigger';
|
||||
IconIndex := ICONINDEX_Trigger;
|
||||
end else
|
||||
Exit;
|
||||
tabEditor.ImageIndex := IconIndex;
|
||||
Cap := ObjType+': ';
|
||||
if ObjName = '' then
|
||||
tabEditor.ImageIndex := ActiveObjectEditor.DBObject.ImageIndex;
|
||||
Cap := ActiveObjectEditor.DBObject.ObjType+': ';
|
||||
if ActiveObjectEditor.DBObject.Name = '' then
|
||||
Cap := Cap + '[Untitled]'
|
||||
else
|
||||
Cap := sstr(Cap + ObjName, 30);
|
||||
Cap := sstr(Cap + ActiveObjectEditor.DBObject.Name, 30);
|
||||
SetTabCaption(tabEditor.PageIndex, Cap);
|
||||
end;
|
||||
|
||||
@ -8510,8 +8449,8 @@ begin
|
||||
SelectDBObject(Obj.Name, Obj.NodeType);
|
||||
end;
|
||||
|
||||
case GetFocusedTreeNodeType of
|
||||
lntDb: begin
|
||||
case DBtree.GetNodeLevel(DBtree.FocusedNode) of
|
||||
1: begin
|
||||
if CreateDatabaseForm = nil then
|
||||
CreateDatabaseForm := TCreateDatabaseForm.Create(Self);
|
||||
CreateDatabaseForm.modifyDB := ActiveDatabase;
|
||||
@ -8528,27 +8467,9 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
lntTable: begin
|
||||
PlaceObjectEditor(SelectedTable.NodeType);
|
||||
TableEditor.Init(SelectedTable.Name);
|
||||
end;
|
||||
|
||||
lntView: begin
|
||||
PlaceObjectEditor(SelectedTable.NodeType);
|
||||
ViewEditor.Init(SelectedTable.Name);
|
||||
end;
|
||||
|
||||
lntFunction, lntProcedure: begin
|
||||
PlaceObjectEditor(SelectedTable.NodeType);
|
||||
RoutineEditor.Init(SelectedTable.Name, SelectedTable.NodeType);
|
||||
end;
|
||||
|
||||
lntTrigger: begin
|
||||
PlaceObjectEditor(SelectedTable.NodeType);
|
||||
TriggerEditor.Init(SelectedTable.Name);
|
||||
end;
|
||||
|
||||
2: PlaceObjectEditor(SelectedTable);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
@ -9166,6 +9087,17 @@ var
|
||||
ActiveLineColor: TColor;
|
||||
Attri: TSynHighlighterAttributes;
|
||||
Shortcut1, Shortcut2: TShortcut;
|
||||
|
||||
procedure FindEditors(Comp: TComponent);
|
||||
var i: Integer;
|
||||
begin
|
||||
for i:=0 to Comp.ComponentCount-1 do begin
|
||||
if Comp.Components[i] is TSynMemo then
|
||||
Editors.Add(Comp.Components[i]);
|
||||
FindEditors(Comp.Components[i]);
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
// Restore font, highlighter and shortcuts for each instantiated TSynMemo
|
||||
Editors := TObjectList.Create;
|
||||
@ -9175,18 +9107,8 @@ begin
|
||||
Editors.Add(SynMemoFilter);
|
||||
Editors.Add(SynMemoProcessView);
|
||||
Editors.Add(SynMemoSQLLog);
|
||||
if Assigned(TableEditor) then begin
|
||||
Editors.Add(TableEditor.SynMemoCREATEcode);
|
||||
Editors.Add(TableEditor.SynMemoALTERcode);
|
||||
end;
|
||||
if Assigned(ViewEditor) then
|
||||
Editors.Add(ViewEditor.SynMemoSelect);
|
||||
if Assigned(RoutineEditor) then begin
|
||||
Editors.Add(RoutineEditor.SynMemoBody);
|
||||
Editors.Add(RoutineEditor.SynMemoCREATEcode);
|
||||
end;
|
||||
if Assigned(TriggerEditor) then
|
||||
Editors.Add(TriggerEditor.SynMemoStatement);
|
||||
if Assigned(ActiveObjectEditor) then
|
||||
FindEditors(ActiveObjectEditor);
|
||||
if Assigned(CreateDatabaseForm) then
|
||||
Editors.Add(CreateDatabaseForm.SynMemoPreview);
|
||||
if Assigned(OptionsForm) then
|
||||
|
@ -9,13 +9,20 @@ uses
|
||||
type
|
||||
{ TDBObjectList and friends }
|
||||
|
||||
TListNodeType = (lntNone, lntDb, lntTable, lntView, lntFunction, lntProcedure, lntTrigger, lntColumn);
|
||||
TListNodeType = (lntNone, lntDb, lntTable, lntView, lntFunction, lntProcedure, lntTrigger, lntEvent, lntColumn);
|
||||
TListNodeTypes = Set of TListNodeType;
|
||||
TDBObject = class
|
||||
Name, Database, Engine, Comment, RowFormat, CreateOptions, Collation, ObjType: String;
|
||||
TDBObject = class(TObject)
|
||||
Name, Database, Engine, Comment, RowFormat, CreateOptions, Collation: String;
|
||||
Created, Updated, LastChecked: TDateTime;
|
||||
Rows, Size, Version, AvgRowLen, MaxDataLen, IndexLen, DataLen, DataFree, AutoInc, CheckSum: Int64;
|
||||
NodeType: TListNodeType;
|
||||
private
|
||||
function GetObjType: String;
|
||||
function GetImageIndex: Integer;
|
||||
public
|
||||
constructor Create;
|
||||
property ObjType: String read GetObjType;
|
||||
property ImageIndex: Integer read GetImageIndex;
|
||||
end;
|
||||
PDBObject = ^TDBObject;
|
||||
TDBObjectList = TObjectList<TDBObject>;
|
||||
@ -133,7 +140,6 @@ type
|
||||
function GetInformationSchemaObjects: TStringList;
|
||||
function GetConnectionUptime: Integer;
|
||||
function GetServerUptime: Integer;
|
||||
function ParseDateTime(Str: String): TDateTime;
|
||||
procedure Log(Category: TMySQLLogCategory; Msg: String);
|
||||
procedure ClearCache;
|
||||
procedure SetObjectNamesInSelectedDB;
|
||||
@ -154,6 +160,7 @@ type
|
||||
function GetDBObjects(db: String; Refresh: Boolean=False): TDBObjectList;
|
||||
function GetDBSize(db: String): Int64;
|
||||
function DbObjectsCached(db: String): Boolean;
|
||||
function ParseDateTime(Str: String): TDateTime;
|
||||
procedure ClearDbObjects(db: String);
|
||||
procedure ClearAllDbObjects;
|
||||
property Parameters: TConnectionParameters read FParameters write FParameters;
|
||||
@ -1071,12 +1078,9 @@ begin
|
||||
Obj.Size := StrToInt64Def(Results.Col('Data_length'), 0) + StrToInt64Def(Results.Col('Index_length'), 0);
|
||||
Inc(DBSize, Obj.Size);
|
||||
end;
|
||||
Obj.ObjType := 'TABLE';
|
||||
Obj.NodeType := lntTable;
|
||||
if Results.IsNull(1) and Results.IsNull(2) then begin // Engine column is NULL for views
|
||||
if Results.IsNull(1) and Results.IsNull(2) then // Engine column is NULL for views
|
||||
Obj.NodeType := lntView;
|
||||
Obj.ObjType := 'VIEW';
|
||||
end;
|
||||
Obj.Created := ParseDateTime(Results.Col('Create_time'));
|
||||
Obj.Updated := ParseDateTime(Results.Col('Update_time'));
|
||||
if Results.ColExists('Type') then
|
||||
@ -1117,7 +1121,6 @@ begin
|
||||
obj.Database := db;
|
||||
obj.Rows := -1;
|
||||
Obj.Size := -1;
|
||||
Obj.ObjType := 'FUNCTION';
|
||||
Obj.NodeType := lntFunction;
|
||||
Obj.Created := ParseDateTime(Results.Col('Created'));
|
||||
Obj.Updated := ParseDateTime(Results.Col('Modified'));
|
||||
@ -1153,7 +1156,6 @@ begin
|
||||
obj.Database := db;
|
||||
obj.Rows := -1;
|
||||
Obj.Size := -1;
|
||||
Obj.ObjType := 'PROCEDURE';
|
||||
Obj.NodeType := lntProcedure;
|
||||
Obj.Created := ParseDateTime(Results.Col('Created'));
|
||||
Obj.Updated := ParseDateTime(Results.Col('Modified'));
|
||||
@ -1189,7 +1191,6 @@ begin
|
||||
obj.Database := db;
|
||||
obj.Rows := -1;
|
||||
Obj.Size := -1;
|
||||
Obj.ObjType := 'TRIGGER';
|
||||
Obj.NodeType := lntTrigger;
|
||||
Obj.Created := ParseDateTime(Results.Col('Created'));
|
||||
Obj.Updated := 0;
|
||||
@ -1212,6 +1213,41 @@ begin
|
||||
FreeAndNil(Results);
|
||||
end;
|
||||
|
||||
// Events
|
||||
if ServerVersionInt >= 50100 then try
|
||||
Results := GetResults('SHOW EVENTS FROM '+QuoteIdent(db));
|
||||
except
|
||||
end;
|
||||
if Assigned(Results) then begin
|
||||
while not Results.Eof do begin
|
||||
obj := TDBObject.Create;
|
||||
Result.Add(obj);
|
||||
obj.Name := Results.Col('Name');
|
||||
obj.Database := db;
|
||||
obj.Rows := -1;
|
||||
Obj.Size := -1;
|
||||
Obj.NodeType := lntEvent;
|
||||
Obj.Created := 0;
|
||||
Obj.Updated := 0;
|
||||
Obj.Engine := '';
|
||||
Obj.Comment := '';
|
||||
Obj.Version := -1;
|
||||
Obj.AutoInc := -1;
|
||||
Obj.RowFormat := '';
|
||||
Obj.AvgRowLen := -1;
|
||||
Obj.MaxDataLen := -1;
|
||||
Obj.IndexLen := -1;
|
||||
Obj.DataLen := -1;
|
||||
Obj.DataFree := -1;
|
||||
Obj.LastChecked := 0;
|
||||
Obj.Collation := '';
|
||||
Obj.CheckSum := -1;
|
||||
Obj.CreateOptions := '';
|
||||
Results.Next;
|
||||
end;
|
||||
FreeAndNil(Results);
|
||||
end;
|
||||
|
||||
// Sort list like it get sorted in MainForm.vstCompareNodes
|
||||
Result.Sort;
|
||||
|
||||
@ -1468,4 +1504,40 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
{ TDBObject }
|
||||
|
||||
constructor TDBObject.Create;
|
||||
begin
|
||||
NodeType := lntNone;
|
||||
end;
|
||||
|
||||
|
||||
function TDBObject.GetObjType: String;
|
||||
begin
|
||||
case NodeType of
|
||||
lntTable: Result := 'Table';
|
||||
lntView: Result := 'View';
|
||||
lntFunction: Result := 'Function';
|
||||
lntProcedure: Result := 'Procedure';
|
||||
lntTrigger: Result := 'Trigger';
|
||||
lntEvent: Result := 'Event';
|
||||
else Result := 'Unknown, should never appear';
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDBObject.GetImageIndex: Integer;
|
||||
begin
|
||||
// Detect key icon index for specified db object (table, trigger, ...)
|
||||
case NodeType of
|
||||
lntTable: Result := ICONINDEX_TABLE;
|
||||
lntFunction: Result := ICONINDEX_STOREDFUNCTION;
|
||||
lntProcedure: Result := ICONINDEX_STOREDPROCEDURE;
|
||||
lntView: Result := ICONINDEX_VIEW;
|
||||
lntTrigger: Result := ICONINDEX_TRIGGER;
|
||||
lntEvent: Result := ICONINDEX_EVENT;
|
||||
else Result := -1;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
@ -34,7 +34,7 @@ type
|
||||
|
||||
implementation
|
||||
|
||||
uses main, helpers;
|
||||
uses main, helpers, table_editor, mysql_connection;
|
||||
|
||||
{$R *.DFM}
|
||||
|
||||
@ -78,8 +78,12 @@ begin
|
||||
else list := Mainform.ListCommandStats;
|
||||
end;
|
||||
1: list := Mainform.ListTables;
|
||||
2: if Assigned(Mainform.TableEditor) and Mainform.TableEditor.Visible then
|
||||
list := Mainform.TableEditor.listColumns;
|
||||
2: begin
|
||||
if Assigned(Mainform.ActiveObjectEditor)
|
||||
and (Mainform.ActiveObjectEditor.DBObject.NodeType = lntTable)
|
||||
and Mainform.ActiveObjectEditor.Visible then
|
||||
list := (Mainform.ActiveObjectEditor as TfrmTableEditor).listColumns;
|
||||
end;
|
||||
else list := Mainform.ActiveGrid;
|
||||
end;
|
||||
if Assigned(list) then
|
||||
|
@ -79,7 +79,7 @@ type
|
||||
Parameters: TRoutineParamList;
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
procedure Init(ObjectName: String=''; ObjectType: TListNodeType=lntNone); override;
|
||||
procedure Init(Obj: TDBObject); override;
|
||||
function ApplyModifications: TModalResult; override;
|
||||
end;
|
||||
|
||||
@ -126,15 +126,15 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmRoutineEditor.Init(ObjectName: String=''; ObjectType: TListNodeType=lntNone);
|
||||
procedure TfrmRoutineEditor.Init(Obj: TDBObject);
|
||||
var
|
||||
Create, Returns, DataAccess, Security, Comment, Body: String;
|
||||
Deterministic: Boolean;
|
||||
begin
|
||||
inherited;
|
||||
if ObjectType = lntProcedure then FAlterRoutineType := 'PROCEDURE'
|
||||
if Obj.NodeType = lntProcedure then FAlterRoutineType := 'PROCEDURE'
|
||||
else FAlterRoutineType := 'FUNCTION';
|
||||
editName.Text := FEditObjectName;
|
||||
editName.Text := DBObject.Name;
|
||||
comboType.ItemIndex := 0;
|
||||
comboReturns.Text := '';
|
||||
chkDeterministic.Checked := False;
|
||||
@ -144,7 +144,7 @@ begin
|
||||
comboSecurity.ItemIndex := 0;
|
||||
editComment.Clear;
|
||||
SynMemoBody.Text := 'BEGIN'+CRLF+CRLF+'END';
|
||||
if FEditObjectName <> '' then begin
|
||||
if DBObject.Name <> '' then begin
|
||||
// Editing existing routine
|
||||
comboType.ItemIndex := ListIndexByRegExpr(comboType.Items, '^'+FAlterRoutineType+'\b');
|
||||
Create := Mainform.Connection.GetVar('SHOW CREATE '+FAlterRoutineType+' '+Mainform.mask(editName.Text), 2);
|
||||
@ -166,7 +166,7 @@ begin
|
||||
Modified := False;
|
||||
btnSave.Enabled := Modified;
|
||||
btnDiscard.Enabled := Modified;
|
||||
Mainform.actRunRoutines.Enabled := FEditObjectName <> '';
|
||||
Mainform.actRunRoutines.Enabled := DBObject.Name <> '';
|
||||
Mainform.ShowStatusMsg;
|
||||
Screen.Cursor := crDefault;
|
||||
end;
|
||||
@ -407,7 +407,6 @@ var
|
||||
allRoutineNames: TStringList;
|
||||
ProcOrFunc: String;
|
||||
TargetExists: Boolean;
|
||||
t: TListNodeType;
|
||||
begin
|
||||
// Save changes
|
||||
Result := mrOk;
|
||||
@ -417,14 +416,14 @@ begin
|
||||
// Create a temp routine, check for syntax errors, then drop the old routine and create it.
|
||||
// See also: http://dev.mysql.com/doc/refman/5.0/en/alter-procedure.html
|
||||
try
|
||||
if FEditObjectName <> '' then begin
|
||||
if DBObject.Name <> '' then begin
|
||||
// Create temp name
|
||||
i := 0;
|
||||
allRoutineNames := Mainform.Connection.GetCol('SELECT ROUTINE_NAME FROM '+Mainform.mask(DBNAME_INFORMATION_SCHEMA)+'.'+Mainform.mask('ROUTINES')+
|
||||
' WHERE ROUTINE_SCHEMA = '+esc(Mainform.ActiveDatabase)+
|
||||
' AND ROUTINE_TYPE = '+esc(ProcOrFunc)
|
||||
);
|
||||
TargetExists := ((editName.Text <> FEditObjectName) or (ProcOrFunc <> FAlterRoutineType)) and
|
||||
TargetExists := ((editName.Text <> DBObject.Name) or (ProcOrFunc <> FAlterRoutineType)) and
|
||||
(allRoutineNames.IndexOf(editName.Text) > -1);
|
||||
if TargetExists then begin
|
||||
Result := MessageDlg('Routine "'+editName.Text+'" already exists. Overwrite it?',
|
||||
@ -442,7 +441,7 @@ begin
|
||||
// Drop temporary routine, used for syntax checking
|
||||
Mainform.Connection.Query('DROP '+ProcOrFunc+' IF EXISTS '+Mainform.mask(TempName));
|
||||
// Drop edited routine
|
||||
Mainform.Connection.Query('DROP '+FAlterRoutineType+' IF EXISTS '+Mainform.mask(FEditObjectName));
|
||||
Mainform.Connection.Query('DROP '+FAlterRoutineType+' IF EXISTS '+Mainform.mask(DBObject.Name));
|
||||
if TargetExists then begin
|
||||
// Drop target routine - overwriting has been confirmed, see above
|
||||
Mainform.Connection.Query('DROP '+ProcOrFunc+' IF EXISTS '+Mainform.mask(editName.Text));
|
||||
@ -450,12 +449,12 @@ begin
|
||||
end;
|
||||
Mainform.Connection.Query(ComposeCreateStatement(editName.Text));
|
||||
// Set editing name if create/alter query was successful
|
||||
FEditObjectName := editName.Text;
|
||||
DBObject.Name := editName.Text;
|
||||
FAlterRoutineType := UpperCase(GetFirstWord(comboType.Text));
|
||||
Mainform.SetEditorTabCaption(Self, FEditObjectName);
|
||||
if FAlterRoutineType = 'PROCEDURE' then t := lntProcedure
|
||||
else t := lntFunction;
|
||||
Mainform.RefreshTreeDB(Mainform.ActiveDatabase, FEditObjectName, t);
|
||||
if FAlterRoutineType = 'PROCEDURE' then DBObject.NodeType := lntProcedure
|
||||
else DBObject.NodeType := lntFunction;
|
||||
Mainform.UpdateEditorTab;
|
||||
Mainform.RefreshTreeDB(Mainform.ActiveDatabase, DBObject.Name, DBObject.NodeType);
|
||||
Modified := False;
|
||||
btnSave.Enabled := Modified;
|
||||
btnDiscard.Enabled := Modified;
|
||||
@ -498,13 +497,9 @@ end;
|
||||
|
||||
|
||||
procedure TfrmRoutineEditor.btnDiscardClick(Sender: TObject);
|
||||
var
|
||||
t: TListNodeType;
|
||||
begin
|
||||
Modified := False;
|
||||
if FAlterRoutineType = 'PROCEDURE' then t := lntProcedure
|
||||
else t := lntFunction;
|
||||
Init(FEditObjectName, t);
|
||||
Init(DBObject);
|
||||
end;
|
||||
|
||||
|
||||
|
@ -197,7 +197,7 @@ type
|
||||
{ Public declarations }
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
procedure Init(ObjectName: String=''; ObjectType: TListNodeType=lntNone); override;
|
||||
procedure Init(Obj: TDBObject); override;
|
||||
function ApplyModifications: TModalResult; override;
|
||||
end;
|
||||
|
||||
@ -217,7 +217,6 @@ const
|
||||
constructor TfrmTableEditor.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited;
|
||||
ScaleControls(Screen.PixelsPerInch, FORMS_DPI);
|
||||
PageControlMain.Height := GetRegValue(REGNAME_TABLEEDITOR_TABSHEIGHT, PageControlMain.Height);
|
||||
FixVT(listColumns);
|
||||
FixVT(treeIndexes);
|
||||
@ -253,7 +252,7 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTableEditor.Init(ObjectName: String=''; ObjectType: TListNodeType=lntNone);
|
||||
procedure TfrmTableEditor.Init(Obj: TDBObject);
|
||||
var
|
||||
CreateTable, AttrName, AttrValue: String;
|
||||
rx: TRegExpr;
|
||||
@ -267,7 +266,7 @@ begin
|
||||
FColumns.Clear;
|
||||
btnClearIndexesClick(Self);
|
||||
btnClearForeignKeysClick(Self);
|
||||
tabALTERcode.TabVisible := FEditObjectName <> '';
|
||||
tabALTERcode.TabVisible := DBObject.Name <> '';
|
||||
// Clear value editors
|
||||
memoComment.Text := '';
|
||||
editAutoInc.Text := '';
|
||||
@ -279,14 +278,14 @@ begin
|
||||
memoUnionTables.Clear;
|
||||
comboInsertMethod.ItemIndex := -1;
|
||||
|
||||
if FEditObjectName = '' then begin
|
||||
if DBObject.Name = '' then begin
|
||||
// Creating new table
|
||||
editName.Text := '';
|
||||
comboCollation.ItemIndex := comboCollation.Items.IndexOf(Mainform.Connection.GetVar('SHOW VARIABLES LIKE ''collation_database''', 1));
|
||||
PageControlMain.ActivePage := tabBasic;
|
||||
end else begin
|
||||
// Editing existing table
|
||||
editName.Text := FEditObjectName;
|
||||
editName.Text := DBObject.Name;
|
||||
CreateTable := Mainform.SelectedTableCreateStatement;
|
||||
rx := TRegExpr.Create;
|
||||
rx.ModifierI := True;
|
||||
@ -350,7 +349,7 @@ procedure TfrmTableEditor.btnDiscardClick(Sender: TObject);
|
||||
begin
|
||||
// Reinit GUI, discarding changes
|
||||
Modified := False;
|
||||
Init(FEditObjectName);
|
||||
Init(DBObject);
|
||||
end;
|
||||
|
||||
|
||||
@ -370,7 +369,7 @@ begin
|
||||
// Create or alter table
|
||||
Result := mrOk;
|
||||
Specs := TStringList.Create;
|
||||
if FEditObjectName = '' then
|
||||
if DBObject.Name = '' then
|
||||
sql := ComposeCreateStatement
|
||||
else begin
|
||||
sql := ComposeAlterStatement;
|
||||
@ -386,9 +385,9 @@ begin
|
||||
end;
|
||||
try
|
||||
if Specs.Count > 0 then
|
||||
Mainform.Connection.Query('ALTER TABLE '+Mainform.mask(FEditObjectName)+' '+ImplodeStr(', ', Specs));
|
||||
Mainform.Connection.Query('ALTER TABLE '+Mainform.mask(DBObject.Name)+' '+ImplodeStr(', ', Specs));
|
||||
Mainform.Connection.Query(sql);
|
||||
tabALTERcode.TabVisible := FEditObjectName <> '';
|
||||
tabALTERcode.TabVisible := DBObject.Name <> '';
|
||||
if chkCharsetConvert.Checked then begin
|
||||
// Autoadjust column collations
|
||||
for i:=0 to FColumns.Count-1 do begin
|
||||
@ -397,10 +396,10 @@ begin
|
||||
end;
|
||||
end;
|
||||
// Set table name for altering if Apply was clicked
|
||||
FEditObjectName := editName.Text;
|
||||
tabALTERcode.TabVisible := FEditObjectName <> '';
|
||||
Mainform.SetEditorTabCaption(Self, FEditObjectName);
|
||||
Mainform.RefreshTreeDB(Mainform.ActiveDatabase, FEditObjectName, lntTable);
|
||||
DBObject.Name := editName.Text;
|
||||
tabALTERcode.TabVisible := DBObject.Name <> '';
|
||||
Mainform.UpdateEditorTab;
|
||||
Mainform.RefreshTreeDB(Mainform.ActiveDatabase, DBObject.Name, DBObject.NodeType);
|
||||
Mainform.ParseSelectedTableStructure;
|
||||
ResetModificationFlags;
|
||||
AlterCodeValid := False;
|
||||
@ -463,7 +462,7 @@ begin
|
||||
Mainform.ShowStatusMsg('Composing ALTER statement ...');
|
||||
Screen.Cursor := crHourglass;
|
||||
Specs := TStringList.Create;
|
||||
if editName.Text <> FEditObjectName then
|
||||
if editName.Text <> DBObject.Name then
|
||||
Specs.Add('RENAME TO ' + Mainform.mask(editName.Text));
|
||||
if memoComment.Tag = ModifiedFlag then
|
||||
Specs.Add('COMMENT=' + esc(memoComment.Text));
|
||||
@ -582,7 +581,7 @@ begin
|
||||
Specs.Add('ADD '+GetForeignKeySQL(i));
|
||||
end;
|
||||
|
||||
Result := 'ALTER TABLE '+Mainform.mask(FEditObjectName) + CRLF + #9 + ImplodeStr(',' + CRLF + #9, Specs);
|
||||
Result := 'ALTER TABLE '+Mainform.mask(DBObject.Name) + CRLF + #9 + ImplodeStr(',' + CRLF + #9, Specs);
|
||||
Result := Trim(Result);
|
||||
FreeAndNil(Specs);
|
||||
Mainform.ShowStatusMsg;
|
||||
@ -1786,7 +1785,7 @@ end;
|
||||
|
||||
procedure TfrmTableEditor.chkCharsetConvertClick(Sender: TObject);
|
||||
begin
|
||||
chkCharsetConvert.Enabled := (FEditObjectName <> '') and (comboCollation.ItemIndex > -1);
|
||||
chkCharsetConvert.Enabled := (DBObject.Name <> '') and (comboCollation.ItemIndex > -1);
|
||||
listColumns.Repaint;
|
||||
Modification(Sender);
|
||||
end;
|
||||
@ -2114,7 +2113,7 @@ begin
|
||||
2: begin
|
||||
Key.ReferenceTable := NewText;
|
||||
if not Key.KeyNameWasCustomized then
|
||||
Key.KeyName := 'FK_'+FEditObjectName+'_'+Key.ReferenceTable;
|
||||
Key.KeyName := 'FK_'+DBObject.Name+'_'+Key.ReferenceTable;
|
||||
end;
|
||||
3: Key.ForeignColumns := Explode(',', NewText);
|
||||
4: Key.OnUpdate := NewText;
|
||||
|
@ -1031,7 +1031,7 @@ begin
|
||||
if chkExportTablesDrop.Checked or chkExportTablesCreate.Checked then begin
|
||||
Output(CRLF+CRLF+'# Dumping structure for '+LowerCase(DBObj.ObjType)+' '+DBObj.Database+'.'+DBObj.Name+CRLF, False, True, True, False, False);
|
||||
if chkExportTablesDrop.Checked then begin
|
||||
Struc := 'DROP '+DBObj.ObjType+' IF EXISTS ';
|
||||
Struc := 'DROP '+UpperCase(DBObj.ObjType)+' IF EXISTS ';
|
||||
if ToDb then
|
||||
Struc := Struc + m(FinalDbName)+'.';
|
||||
Struc := Struc + m(DBObj.Name);
|
||||
@ -1062,7 +1062,7 @@ begin
|
||||
|
||||
lntTrigger: begin
|
||||
StrucResult := Mainform.Connection.GetResults('SHOW TRIGGERS WHERE `Trigger`='+esc(DBObj.Name));
|
||||
Struc := 'CREATE '+DBObj.ObjType+' '+m(DBObj.Name)+' '+StrucResult.Col('Timing')+' '+StrucResult.Col('Event')+
|
||||
Struc := 'CREATE '+UpperCase(DBObj.ObjType)+' '+m(DBObj.Name)+' '+StrucResult.Col('Timing')+' '+StrucResult.Col('Event')+
|
||||
' ON '+m(StrucResult.Col('Table'))+' FOR EACH ROW '+StrucResult.Col('Statement');
|
||||
if ToDb then
|
||||
Insert(m(FinalDbName)+'.', Struc, Pos('TRIGGER', Struc) + 8 );
|
||||
@ -1076,7 +1076,7 @@ begin
|
||||
end;
|
||||
|
||||
lntFunction, lntProcedure: begin
|
||||
Struc := Mainform.Connection.GetVar('SHOW CREATE '+DBObj.ObjType+' '+m(DBObj.Database)+'.'+m(DBObj.Name), 2);
|
||||
Struc := Mainform.Connection.GetVar('SHOW CREATE '+UpperCase(DBObj.ObjType)+' '+m(DBObj.Database)+'.'+m(DBObj.Name), 2);
|
||||
// Todo: Why exploding?
|
||||
MultiSQL := Explode(';', Struc);
|
||||
Struc := ImplodeStr(';'+CRLF, MultiSQL);
|
||||
|
@ -34,7 +34,7 @@ type
|
||||
public
|
||||
{ Public declarations }
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
procedure Init(ObjectName: String=''; ObjectType: TListNodeType=lntNone); override;
|
||||
procedure Init(Obj: TDBObject); override;
|
||||
function ApplyModifications: TModalResult; override;
|
||||
end;
|
||||
|
||||
@ -54,7 +54,6 @@ var
|
||||
i: Integer;
|
||||
begin
|
||||
inherited;
|
||||
ScaleControls(Screen.PixelsPerInch, FORMS_DPI);
|
||||
SynMemoStatement.Highlighter := Mainform.SynSQLSyn1;
|
||||
editName.MaxLength := NAME_LEN;
|
||||
comboTiming.Items.Text := 'BEFORE'+CRLF+'AFTER';
|
||||
@ -73,7 +72,7 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTriggerEditor.Init(ObjectName: String=''; ObjectType: TListNodeType=lntNone);
|
||||
procedure TfrmTriggerEditor.Init(Obj: TDBObject);
|
||||
var
|
||||
Definitions: TMySQLQuery;
|
||||
DBObjects: TDBObjectList;
|
||||
@ -93,13 +92,13 @@ begin
|
||||
end;
|
||||
if comboTable.Items.Count > 0 then
|
||||
comboTable.ItemIndex := 0;
|
||||
if FEditObjectName <> '' then begin
|
||||
if DBObject.Name <> '' then begin
|
||||
// Edit mode
|
||||
editName.Text := FEditObjectName;
|
||||
editName.Text := DBObject.Name;
|
||||
Definitions := Mainform.Connection.GetResults('SHOW TRIGGERS FROM '+Mainform.mask(Mainform.ActiveDatabase));
|
||||
Found := False;
|
||||
while not Definitions.Eof do begin
|
||||
if Definitions.Col('Trigger') = FEditObjectName then begin
|
||||
if Definitions.Col('Trigger') = DBObject.Name then begin
|
||||
comboTable.ItemIndex := comboTable.Items.IndexOf(Definitions.Col('Table'));
|
||||
comboTiming.ItemIndex := comboTiming.Items.IndexOf(UpperCase(Definitions.Col('Timing')));
|
||||
comboEvent.ItemIndex := comboEvent.Items.IndexOf(UpperCase(Definitions.Col('Event')));
|
||||
@ -138,7 +137,7 @@ procedure TfrmTriggerEditor.btnDiscardClick(Sender: TObject);
|
||||
begin
|
||||
// Reinit editor, discarding changes
|
||||
Modified := False;
|
||||
Init(FEditObjectName);
|
||||
Init(DBObject);
|
||||
end;
|
||||
|
||||
|
||||
@ -160,8 +159,8 @@ begin
|
||||
// So, we take the risk of loosing the trigger for cases in which the user has SQL errors in
|
||||
// his statement. The user must fix such errors and re-press "Save" while we have them in memory,
|
||||
// otherwise the trigger attributes are lost forever.
|
||||
if FEditObjectName <> '' then try
|
||||
Mainform.Connection.Query('DROP TRIGGER '+Mainform.mask(FEditObjectName));
|
||||
if DBObject.Name <> '' then try
|
||||
Mainform.Connection.Query('DROP TRIGGER '+Mainform.mask(DBObject.Name));
|
||||
except
|
||||
end;
|
||||
// CREATE
|
||||
@ -173,9 +172,9 @@ begin
|
||||
' ON '+Mainform.mask(comboTable.Text)+
|
||||
' FOR EACH ROW '+SynMemoStatement.Text;
|
||||
Mainform.Connection.Query(sql);
|
||||
FEditObjectName := editName.Text;
|
||||
Mainform.SetEditorTabCaption(Self, FEditObjectName);
|
||||
Mainform.RefreshTreeDB(Mainform.ActiveDatabase, FEditObjectName, lntTrigger);
|
||||
DBObject.Name := editName.Text;
|
||||
Mainform.UpdateEditorTab;
|
||||
Mainform.RefreshTreeDB(Mainform.ActiveDatabase, DBObject.Name, DBObject.NodeType);
|
||||
Modified := False;
|
||||
btnSave.Enabled := Modified;
|
||||
btnDiscard.Enabled := Modified;
|
||||
|
@ -29,7 +29,7 @@ type
|
||||
public
|
||||
{ Public declarations }
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
procedure Init(ObjectName: String=''; ObjectType: TListNodeType=lntNone); override;
|
||||
procedure Init(Obj: TDBObject); override;
|
||||
function ApplyModifications: TModalResult; override;
|
||||
end;
|
||||
|
||||
@ -47,7 +47,6 @@ uses main;
|
||||
constructor TfrmView.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited;
|
||||
ScaleControls(Screen.PixelsPerInch, FORMS_DPI);
|
||||
SynMemoSelect.Highlighter := Mainform.SynSQLSyn1;
|
||||
Mainform.SynCompletionProposal.AddEditor(SynMemoSelect);
|
||||
editName.MaxLength := NAME_LEN;
|
||||
@ -57,21 +56,21 @@ end;
|
||||
{**
|
||||
FormShow: Fill controls with content in edit mode
|
||||
}
|
||||
procedure TfrmView.Init(ObjectName: String=''; ObjectType: TListNodeType=lntNone);
|
||||
procedure TfrmView.Init(Obj: TDBObject);
|
||||
var
|
||||
Results: TMySQLQuery;
|
||||
db: String;
|
||||
rx: TRegExpr;
|
||||
begin
|
||||
inherited;
|
||||
if FEditObjectName <> '' then begin
|
||||
if Obj.Name <> '' then begin
|
||||
// Edit mode
|
||||
editName.Text := FEditObjectName;
|
||||
editName.Text := Obj.Name;
|
||||
db := Mainform.ActiveDatabase;
|
||||
Results := Mainform.Connection.GetResults('SELECT * FROM '+Mainform.mask(DBNAME_INFORMATION_SCHEMA)+'.VIEWS ' +
|
||||
'WHERE TABLE_SCHEMA = '+esc(db)+' AND TABLE_NAME = '+esc(FEditObjectName));
|
||||
'WHERE TABLE_SCHEMA = '+esc(db)+' AND TABLE_NAME = '+esc(Obj.Name));
|
||||
if Results.RecordCount = 0 then
|
||||
raise Exception.Create('Can''t find view definition for "'+FEditObjectName+'" in '+DBNAME_INFORMATION_SCHEMA);
|
||||
raise Exception.Create('Can''t find view definition for "'+Obj.Name+'" in '+DBNAME_INFORMATION_SCHEMA);
|
||||
// Algorithm is not changeable as we cannot look up its current state!
|
||||
rgAlgorithm.Enabled := False;
|
||||
rgAlgorithm.ItemIndex := 0;
|
||||
@ -127,7 +126,7 @@ procedure TfrmView.btnHelpClick(Sender: TObject);
|
||||
var
|
||||
keyword: String;
|
||||
begin
|
||||
if FEditObjectName = '' then
|
||||
if DBObject.Name = '' then
|
||||
keyword := 'CREATE VIEW'
|
||||
else
|
||||
keyword := 'ALTER VIEW';
|
||||
@ -139,7 +138,7 @@ procedure TfrmView.btnDiscardClick(Sender: TObject);
|
||||
begin
|
||||
// Reinit editor, discarding changes
|
||||
Modified := False;
|
||||
Init(FEditObjectName);
|
||||
Init(DBObject);
|
||||
end;
|
||||
|
||||
|
||||
@ -158,12 +157,12 @@ var
|
||||
begin
|
||||
// Save changes
|
||||
Result := mrOk;
|
||||
if FEditObjectName = '' then begin
|
||||
if DBObject.Name = '' then begin
|
||||
sql := 'CREATE ';
|
||||
viewname := editName.Text;
|
||||
end else begin
|
||||
sql := 'ALTER ';
|
||||
viewname := FEditObjectName;
|
||||
viewname := DBObject.Name;
|
||||
end;
|
||||
viewname := Mainform.mask(viewname);
|
||||
if rgAlgorithm.Enabled and (rgAlgorithm.ItemIndex > -1) then
|
||||
@ -175,13 +174,13 @@ begin
|
||||
try
|
||||
Mainform.Connection.Query(sql);
|
||||
// Probably rename view
|
||||
if (FEditObjectName <> '') and (FEditObjectName <> editName.Text) then begin
|
||||
if (DBObject.Name <> '') and (DBObject.Name <> editName.Text) then begin
|
||||
renamed := Mainform.mask(editName.Text);
|
||||
Mainform.Connection.Query('RENAME TABLE '+viewname + ' TO '+renamed);
|
||||
end;
|
||||
FEditObjectName := editName.Text;
|
||||
Mainform.SetEditorTabCaption(Self, FEditObjectName);
|
||||
Mainform.RefreshTreeDB(Mainform.ActiveDatabase, FEditObjectName, lntView);
|
||||
DBObject.Name := editName.Text;
|
||||
Mainform.UpdateEditorTab;
|
||||
Mainform.RefreshTreeDB(Mainform.ActiveDatabase, DBObject.Name, DBObject.NodeType);
|
||||
Mainform.ParseSelectedTableStructure;
|
||||
Modified := False;
|
||||
btnSave.Enabled := Modified;
|
||||
|
Reference in New Issue
Block a user