mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-06 18:24:26 +08:00
* Factor more code out of each database object editors into parent TDBObjectEditor.
* Use this chance to add a confirmation dialog when leaving the editors, to ask the user if he wants to save modifications. Fixes issue #1524. * Also, enhance Mainform.RefreshTreeDB in a way that it does not trigger the OnFocusChange event. Important for the editors when saving changes.
This commit is contained in:
@ -147,9 +147,15 @@ type
|
||||
private
|
||||
FModified: Boolean;
|
||||
procedure SetModified(Value: Boolean);
|
||||
protected
|
||||
FEditObjectName: WideString;
|
||||
public
|
||||
procedure Init(ObjectName: WideString=''; ObjectType: TListNodeType=lntNone); Virtual; Abstract;
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
procedure Init(ObjectName: WideString=''; ObjectType: TListNodeType=lntNone); virtual;
|
||||
procedure DeInit;
|
||||
property Modified: Boolean read FModified write SetModified;
|
||||
procedure ApplyModifications; virtual; abstract;
|
||||
end;
|
||||
|
||||
|
||||
@ -245,7 +251,7 @@ var
|
||||
|
||||
implementation
|
||||
|
||||
uses main, uVistaFuncs;
|
||||
uses main, uVistaFuncs, table_editor, view, routine_editor, trigger_editor;
|
||||
|
||||
type
|
||||
CharacterSet = record
|
||||
@ -3236,11 +3242,56 @@ end;
|
||||
|
||||
{ *** TDBObjectEditor }
|
||||
|
||||
constructor TDBObjectEditor.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited;
|
||||
// Do not set alClient via DFM! In conjunction with ExplicitXXX properties that
|
||||
// repeatedly breaks the GUI layout when you reload the project
|
||||
Align := alClient;
|
||||
InheritFont(Font);
|
||||
end;
|
||||
|
||||
destructor TDBObjectEditor.Destroy;
|
||||
begin
|
||||
DeInit;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TDBObjectEditor.SetModified(Value: Boolean);
|
||||
begin
|
||||
FModified := Value;
|
||||
end;
|
||||
|
||||
procedure TDBObjectEditor.Init(ObjectName: WideString=''; ObjectType: TListNodeType=lntNone);
|
||||
begin
|
||||
DeInit;
|
||||
Mainform.showstatus('Initializing editor ...');
|
||||
FEditObjectName := ObjectName;
|
||||
Mainform.SetEditorTabCaption(Self, FEditObjectName);
|
||||
Screen.Cursor := crHourglass;
|
||||
MainForm.SetupSynEditors;
|
||||
end;
|
||||
|
||||
procedure TDBObjectEditor.DeInit;
|
||||
var
|
||||
Msg, ObjType: WideString;
|
||||
begin
|
||||
// Ask for saving modifications
|
||||
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+'"?'
|
||||
else
|
||||
Msg := 'Save new '+ObjType+'?';
|
||||
if MessageDlg(Msg, mtConfirmation, [mbYes, mbNo], 0) = mrYes then
|
||||
ApplyModifications;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
@ -1056,6 +1056,20 @@ procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
|
||||
var
|
||||
filename : String;
|
||||
begin
|
||||
// Destroy editors and dialogs. Must be done before connection gets closed, as some destructors do SQL stuff.
|
||||
FreeAndNil(RoutineEditor);
|
||||
FreeAndNil(TableToolsDialog);
|
||||
FreeAndNil(UserManagerForm);
|
||||
FreeAndNil(ViewEditor);
|
||||
FreeAndNil(SelectDBObjectForm);
|
||||
FreeAndNil(SQLHelpForm);
|
||||
FreeAndNil(OptionsForm);
|
||||
FreeAndNil(SessionManager);
|
||||
FreeAndNil(TableEditor);
|
||||
FreeAndNil(TriggerEditor);
|
||||
FreeAndNil(CreateDatabaseForm);
|
||||
|
||||
// Close database connection
|
||||
DoDisconnect;
|
||||
|
||||
OpenRegistry;
|
||||
@ -1086,18 +1100,6 @@ begin
|
||||
SaveListSetup(ListCommandStats);
|
||||
SaveListSetup(ListTables);
|
||||
|
||||
FreeAndNil(RoutineEditor);
|
||||
FreeAndNil(TableToolsDialog);
|
||||
FreeAndNil(UserManagerForm);
|
||||
FreeAndNil(ViewEditor);
|
||||
FreeAndNil(SelectDBObjectForm);
|
||||
FreeAndNil(SQLHelpForm);
|
||||
FreeAndNil(OptionsForm);
|
||||
FreeAndNil(SessionManager);
|
||||
FreeAndNil(TableEditor);
|
||||
FreeAndNil(TriggerEditor);
|
||||
FreeAndNil(CreateDatabaseForm);
|
||||
|
||||
debug('mem: clearing query and browse data.');
|
||||
SetLength(DataGridResult.Rows, 0);
|
||||
SetLength(DataGridResult.Columns, 0);
|
||||
@ -6286,15 +6288,39 @@ end;
|
||||
procedure TMainForm.RefreshTreeDB(db: WideString);
|
||||
var
|
||||
oldActiveDatabase: WideString;
|
||||
dbnode: PVirtualNode;
|
||||
DBNode, FNode: PVirtualNode;
|
||||
oldSelectedTable: TListNode;
|
||||
TableHereHadFocus: Boolean;
|
||||
Results: TMySQLQuery;
|
||||
FocusChangeEvent: procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex) of object;
|
||||
begin
|
||||
oldActiveDatabase := ActiveDatabase;
|
||||
DBtree.ClearSelection;
|
||||
oldSelectedTable := SelectedTable;
|
||||
DBNode := FindDBNode(db);
|
||||
FNode := DBtree.FocusedNode;
|
||||
TableHereHadFocus := FNode.Parent = DBNode;
|
||||
// Suspend focus changing event, to avoid tab jumping
|
||||
FocusChangeEvent := DBtree.OnFocusChanged;
|
||||
DBtree.OnFocusChanged := nil;
|
||||
// Refresh db node
|
||||
RefreshDbTableList(db);
|
||||
DBTree.ReinitNode(dbnode, true);
|
||||
DBtree.InvalidateChildren(dbnode, false);
|
||||
ActiveDatabase := oldActiveDatabase;
|
||||
DBTree.ReinitNode(DBNode, true);
|
||||
DBtree.InvalidateChildren(DBNode, false);
|
||||
// Set focus on previously focused table node
|
||||
if TableHereHadFocus then begin
|
||||
Results := FetchDbTableList(db);
|
||||
while not Results.Eof do begin
|
||||
// Need to check if table was renamed, in which case oldSelectedTable is no longer available
|
||||
if (Results.Col(DBO_NAME) = oldSelectedTable.Text)
|
||||
and (GetDBObjectType(Results) = oldSelectedTable.NodeType) then begin
|
||||
SelectDBObject(oldSelectedTable.Text, oldSelectedTable.NodeType);
|
||||
break;
|
||||
end;
|
||||
Results.Next;
|
||||
end;
|
||||
end;
|
||||
// Reactivate focus changing event
|
||||
DBtree.OnFocusChanged := FocusChangeEvent;
|
||||
end;
|
||||
|
||||
|
||||
|
@ -85,7 +85,7 @@ object frmRoutineEditor: TfrmRoutineEditor
|
||||
Caption = 'Save'
|
||||
Default = True
|
||||
TabOrder = 12
|
||||
OnClick = PostChanges
|
||||
OnClick = btnSaveClick
|
||||
end
|
||||
object btnDiscard: TButton
|
||||
Left = 84
|
||||
|
@ -36,7 +36,7 @@ type
|
||||
lblSQLcode: TLabel;
|
||||
SynMemoBody: TSynMemo;
|
||||
procedure comboTypeSelect(Sender: TObject);
|
||||
procedure PostChanges(Sender: TObject);
|
||||
procedure btnSaveClick(Sender: TObject);
|
||||
procedure btnHelpClick(Sender: TObject);
|
||||
procedure editNameChange(Sender: TObject);
|
||||
procedure btnAddParamClick(Sender: TObject);
|
||||
@ -69,12 +69,12 @@ type
|
||||
private
|
||||
{ Private declarations }
|
||||
Parameters: TWideStringList;
|
||||
FAlterRoutineName: WideString;
|
||||
FAlterRoutineType: String;
|
||||
public
|
||||
{ Public declarations }
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
procedure Init(ObjectName: WideString=''; ObjectType: TListNodeType=lntNone); override;
|
||||
procedure ApplyModifications; override;
|
||||
end;
|
||||
|
||||
|
||||
@ -92,8 +92,7 @@ constructor TfrmRoutineEditor.Create(AOwner: TComponent);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
Align := alClient;
|
||||
inherited;
|
||||
// Combo items in a .dfm are sporadically lost after an IDE restart,
|
||||
// so we set them here to avoid developer annoyance
|
||||
comboType.Items.Add('Procedure (doesn''t return a result)');
|
||||
@ -106,8 +105,6 @@ begin
|
||||
comboSecurity.Items.Add('Invoker');
|
||||
for i := Low(Datatypes) to High(Datatypes) do
|
||||
comboReturns.Items.Add(Datatypes[i].Name);
|
||||
SetWindowSizeGrip(Handle, True);
|
||||
InheritFont(Font);
|
||||
Mainform.SynCompletionProposal.AddEditor(SynMemoBody);
|
||||
FixVT(listParameters);
|
||||
Parameters := TWideStringList.Create;
|
||||
@ -124,11 +121,10 @@ var
|
||||
rx: TRegExpr;
|
||||
i: Integer;
|
||||
begin
|
||||
MainForm.SetupSynEditors;
|
||||
FAlterRoutineName := ObjectName;
|
||||
inherited;
|
||||
if ObjectType = lntProcedure then FAlterRoutineType := 'PROCEDURE'
|
||||
else FAlterRoutineType := 'FUNCTION';
|
||||
editName.Text := FAlterRoutineName;
|
||||
editName.Text := FEditObjectName;
|
||||
comboType.ItemIndex := 0;
|
||||
comboReturns.Text := '';
|
||||
listParameters.Clear;
|
||||
@ -137,16 +133,15 @@ begin
|
||||
comboSecurity.ItemIndex := 0;
|
||||
editComment.Clear;
|
||||
SynMemoBody.Text := 'BEGIN'+CRLF+CRLF+'END';
|
||||
if FAlterRoutineName <> '' then begin
|
||||
if FEditObjectName <> '' then begin
|
||||
// Editing existing routine
|
||||
Mainform.SetEditorTabCaption(Self, FAlterRoutineName);
|
||||
Results := Mainform.Connection.GetResults('SELECT * FROM '+DBNAME_INFORMATION_SCHEMA+'.ROUTINES'+
|
||||
' WHERE ROUTINE_SCHEMA='+esc(Mainform.ActiveDatabase)+
|
||||
' AND ROUTINE_NAME='+esc(FAlterRoutineName)+
|
||||
' AND ROUTINE_NAME='+esc(FEditObjectName)+
|
||||
' AND ROUTINE_TYPE='+esc(FAlterRoutineType)
|
||||
);
|
||||
if Results.RecordCount <> 1 then
|
||||
Exception.Create('Cannot find properties of stored routine '+FAlterRoutineName);
|
||||
Exception.Create('Cannot find properties of stored routine '+FEditObjectName);
|
||||
comboType.ItemIndex := ListIndexByRegExpr(comboType.Items, '^'+FAlterRoutineType+'\b');
|
||||
chkDeterministic.Checked := Results.Col('IS_DETERMINISTIC') = 'YES';
|
||||
comboReturns.Text := Results.Col('DTD_IDENTIFIER');
|
||||
@ -185,7 +180,6 @@ begin
|
||||
FreeAndNil(Results);
|
||||
end else begin
|
||||
editName.Text := 'Enter routine name';
|
||||
Mainform.SetEditorTabCaption(Self, '');
|
||||
end;
|
||||
editNameChange(Self);
|
||||
comboTypeSelect(comboType);
|
||||
@ -403,7 +397,14 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmRoutineEditor.PostChanges(Sender: TObject);
|
||||
procedure TfrmRoutineEditor.btnSaveClick(Sender: TObject);
|
||||
begin
|
||||
// Apply or OK button clicked
|
||||
ApplyModifications;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmRoutineEditor.ApplyModifications;
|
||||
var
|
||||
BaseSQL, TempSQL, FinalSQL, TempName: WideString;
|
||||
i: Integer;
|
||||
@ -411,18 +412,8 @@ var
|
||||
ProcOrFunc: String;
|
||||
TargetExists: Boolean;
|
||||
begin
|
||||
// Apply or OK button clicked
|
||||
// Save changes
|
||||
ProcOrFunc := UpperCase(GetFirstWord(comboType.Text));
|
||||
if editName.Text = '' then begin
|
||||
MessageDlg('Please specify the routine''s name.', mtError, [mbOK], 0);
|
||||
editName.SetFocus;
|
||||
Exit;
|
||||
end else if (ProcOrFunc = 'FUNCTION') and (comboReturns.Text = '') then begin
|
||||
MessageDlg('Please specify the function''s returning datatype.', mtError, [mbOK], 0);
|
||||
comboReturns.SetFocus;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
BaseSQL := '';
|
||||
for i := 0 to Parameters.Count - 1 do begin
|
||||
par := explode(DELIM, Parameters[i]);
|
||||
@ -448,18 +439,18 @@ 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 FAlterRoutineName <> '' then begin
|
||||
if FEditObjectName <> '' 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 <> FAlterRoutineName) or (ProcOrFunc <> FAlterRoutineType)) and
|
||||
TargetExists := ((editName.Text <> FEditObjectName) or (ProcOrFunc <> FAlterRoutineType)) and
|
||||
(allRoutineNames.IndexOf(editName.Text) > -1);
|
||||
if TargetExists then begin
|
||||
if MessageDlg('Routine "'+editName.Text+'" already exists. Overwrite it?',
|
||||
mtConfirmation, [mbOk, mbCancel], 0) = mrCancel then begin
|
||||
mtConfirmation, [mbYes, mbNo], 0) = mrNo then begin
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
@ -474,7 +465,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(FAlterRoutineName));
|
||||
Mainform.Connection.Query('DROP '+FAlterRoutineType+' IF EXISTS '+Mainform.mask(FEditObjectName));
|
||||
if TargetExists then begin
|
||||
// Drop target routine - overwriting has been confirmed, see above
|
||||
Mainform.Connection.Query('DROP '+ProcOrFunc+' IF EXISTS '+Mainform.mask(editName.Text));
|
||||
@ -483,10 +474,10 @@ begin
|
||||
FinalSQL := 'CREATE '+ProcOrFunc+' '+Mainform.mask(editName.Text)+'(' + BaseSQL;
|
||||
Mainform.Connection.Query(FinalSQL);
|
||||
// Set editing name if create/alter query was successful
|
||||
FAlterRoutineName := editName.Text;
|
||||
FAlterRoutineType := ProcOrFunc;
|
||||
Mainform.SetEditorTabCaption(Self, FAlterRoutineName);
|
||||
Mainform.actRefresh.Execute;
|
||||
FEditObjectName := editName.Text;
|
||||
FAlterRoutineType := UpperCase(GetFirstWord(comboType.Text));
|
||||
Mainform.SetEditorTabCaption(Self, FEditObjectName);
|
||||
Mainform.RefreshTreeDB(Mainform.ActiveDatabase);
|
||||
Modified := False;
|
||||
btnSave.Enabled := Modified;
|
||||
btnDiscard.Enabled := Modified;
|
||||
@ -501,9 +492,10 @@ procedure TfrmRoutineEditor.btnDiscardClick(Sender: TObject);
|
||||
var
|
||||
t: TListNodeType;
|
||||
begin
|
||||
Modified := False;
|
||||
if FAlterRoutineType = 'PROCEDURE' then t := lntProcedure
|
||||
else t := lntFunction;
|
||||
Init(FAlterRoutineName, t);
|
||||
Init(FEditObjectName, t);
|
||||
end;
|
||||
|
||||
|
||||
|
@ -170,7 +170,6 @@ type
|
||||
private
|
||||
{ Private declarations }
|
||||
FLoaded: Boolean;
|
||||
FAlterTableName: WideString;
|
||||
CreateCodeValid, AlterCodeValid: Boolean;
|
||||
FColumns, FKeys, FForeignKeys: TObjectList;
|
||||
DeletedKeys, DeletedForeignKeys: TWideStringList;
|
||||
@ -190,6 +189,7 @@ type
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
procedure Init(ObjectName: WideString=''; ObjectType: TListNodeType=lntNone); override;
|
||||
procedure ApplyModifications; override;
|
||||
end;
|
||||
|
||||
|
||||
@ -207,12 +207,8 @@ const
|
||||
|
||||
constructor TfrmTableEditor.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
// Do not set alClient via DFM! In conjunction with ExplicitXXX properties that
|
||||
// repeatedly breaks the GUI layout when you reload the project
|
||||
Align := alClient;
|
||||
inherited;
|
||||
PageControlMain.Height := GetRegValue(REGNAME_TABLEEDITOR_TABSHEIGHT, PageControlMain.Height);
|
||||
InheritFont(Font);
|
||||
FixVT(listColumns);
|
||||
FixVT(treeIndexes);
|
||||
FixVT(listForeignKeys);
|
||||
@ -243,7 +239,7 @@ begin
|
||||
Mainform.SaveListSetup(listColumns);
|
||||
Mainform.SaveListSetup(treeIndexes);
|
||||
Mainform.SaveListSetup(listForeignKeys);
|
||||
Inherited;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
|
||||
@ -252,22 +248,16 @@ var
|
||||
CreateTable, AttrName, AttrValue: WideString;
|
||||
rx: TRegExpr;
|
||||
begin
|
||||
Mainform.showstatus('Initializing editor ...');
|
||||
Screen.Cursor := crHourglass;
|
||||
inherited;
|
||||
FLoaded := False;
|
||||
// Start with "basic" tab activated when just called
|
||||
if FAlterTableName <> ObjectName then
|
||||
PageControlMain.ActivePage := tabBasic;
|
||||
comboEngine.Items := Mainform.Connection.TableEngines;
|
||||
comboEngine.ItemIndex := comboEngine.Items.IndexOf(Mainform.Connection.TableEngineDefault);
|
||||
comboCollation.Items := Mainform.Connection.CollationList;
|
||||
FAlterTableName := ObjectName;
|
||||
listColumns.BeginUpdate;
|
||||
FColumns.Clear;
|
||||
btnClearIndexesClick(Self);
|
||||
btnClearForeignKeysClick(Self);
|
||||
tabALTERcode.TabVisible := FAlterTableName <> '';
|
||||
MainForm.SetupSynEditors;
|
||||
tabALTERcode.TabVisible := FEditObjectName <> '';
|
||||
// Clear value editors
|
||||
memoComment.Text := '';
|
||||
editAutoInc.Text := '';
|
||||
@ -279,16 +269,14 @@ begin
|
||||
memoUnionTables.Clear;
|
||||
comboInsertMethod.ItemIndex := -1;
|
||||
|
||||
if FAlterTableName = '' then begin
|
||||
if FEditObjectName = '' then begin
|
||||
// Creating new table
|
||||
editName.Text := 'Enter table name';
|
||||
Mainform.SetEditorTabCaption(Self, '');
|
||||
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 := FAlterTableName;
|
||||
Mainform.SetEditorTabCaption(Self, FAlterTableName);
|
||||
editName.Text := FEditObjectName;
|
||||
CreateTable := Mainform.SelectedTableCreateStatement;
|
||||
rx := TRegExpr.Create;
|
||||
rx.ModifierI := True;
|
||||
@ -347,22 +335,28 @@ end;
|
||||
procedure TfrmTableEditor.btnDiscardClick(Sender: TObject);
|
||||
begin
|
||||
// Reinit GUI, discarding changes
|
||||
Init(FAlterTableName);
|
||||
Modified := False;
|
||||
Init(FEditObjectName);
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTableEditor.btnSaveClick(Sender: TObject);
|
||||
begin
|
||||
ApplyModifications;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTableEditor.ApplyModifications;
|
||||
var
|
||||
sql: WideString;
|
||||
i: Integer;
|
||||
Specs: TWideStringlist;
|
||||
Key: TForeignKey;
|
||||
Col: TTableColumn;
|
||||
FocusChangeEvent: procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex) of object;
|
||||
begin
|
||||
// Create or alter table
|
||||
try
|
||||
if FAlterTableName = '' then
|
||||
Specs := TWideStringList.Create;
|
||||
if FEditObjectName = '' then
|
||||
sql := ComposeCreateStatement
|
||||
else begin
|
||||
sql := ComposeAlterStatement;
|
||||
@ -371,19 +365,17 @@ begin
|
||||
// See also http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html :
|
||||
// "You cannot add a foreign key and drop a foreign key in separate clauses of a single
|
||||
// ALTER TABLE statement. Separate statements are required."
|
||||
Specs := TWideStringList.Create;
|
||||
for i:=0 to FForeignKeys.Count-1 do begin
|
||||
Key := FForeignKeys[i] as TForeignKey;
|
||||
if Key.Modified and (not Key.Added) then
|
||||
Specs.Add('DROP FOREIGN KEY '+Mainform.mask(Key.KeyName));
|
||||
end;
|
||||
if Specs.Count > 0 then
|
||||
Mainform.Connection.Query('ALTER TABLE '+Mainform.mask(FAlterTableName)+' '+ImplodeStr(', ', Specs));
|
||||
end;
|
||||
try
|
||||
if Specs.Count > 0 then
|
||||
Mainform.Connection.Query('ALTER TABLE '+Mainform.mask(FEditObjectName)+' '+ImplodeStr(', ', Specs));
|
||||
Mainform.Connection.Query(sql);
|
||||
// Set table name for altering if Apply was clicked
|
||||
FAlterTableName := editName.Text;
|
||||
tabALTERcode.TabVisible := FAlterTableName <> '';
|
||||
tabALTERcode.TabVisible := FEditObjectName <> '';
|
||||
if chkCharsetConvert.Checked then begin
|
||||
// Autoadjust column collations
|
||||
for i:=0 to FColumns.Count-1 do begin
|
||||
@ -392,15 +384,12 @@ begin
|
||||
Col.Collation := comboCollation.Text;
|
||||
end;
|
||||
end;
|
||||
ResetModificationFlags;
|
||||
|
||||
// Refresh db tree and reselect edited table node.
|
||||
// Supress tab jumping, implicitely invoked by RefreshTreeDB.
|
||||
FocusChangeEvent := Mainform.DBtree.OnFocusChanged;
|
||||
Mainform.DBtree.OnFocusChanged := nil;
|
||||
// Set table name for altering if Apply was clicked
|
||||
FEditObjectName := editName.Text;
|
||||
tabALTERcode.TabVisible := FEditObjectName <> '';
|
||||
Mainform.SetEditorTabCaption(Self, FEditObjectName);
|
||||
Mainform.RefreshTreeDB(Mainform.ActiveDatabase);
|
||||
Mainform.DBtree.OnFocusChanged := FocusChangeEvent;
|
||||
Mainform.SelectDBObject(FAlterTableName, lntTable);
|
||||
ResetModificationFlags;
|
||||
except
|
||||
on E:Exception do
|
||||
MessageDlg(E.Message, mtError, [mbOk], 0);
|
||||
@ -466,7 +455,7 @@ begin
|
||||
Mainform.showstatus('Composing ALTER statement ...');
|
||||
Screen.Cursor := crHourglass;
|
||||
Specs := TWideStringlist.Create;
|
||||
if editName.Text <> FAlterTableName then
|
||||
if editName.Text <> FEditObjectName then
|
||||
Specs.Add('RENAME TO ' + Mainform.mask(editName.Text));
|
||||
if memoComment.Tag = ModifiedFlag then
|
||||
Specs.Add('COMMENT=' + esc(memoComment.Text));
|
||||
@ -595,7 +584,7 @@ begin
|
||||
Specs.Add('ADD '+GetForeignKeySQL(i));
|
||||
end;
|
||||
|
||||
Result := 'ALTER TABLE '+Mainform.mask(FAlterTableName) + CRLF + #9 + ImplodeStr(',' + CRLF + #9, Specs);
|
||||
Result := 'ALTER TABLE '+Mainform.mask(FEditObjectName) + CRLF + #9 + ImplodeStr(',' + CRLF + #9, Specs);
|
||||
Result := Trim(Result);
|
||||
FreeAndNil(Specs);
|
||||
Mainform.showstatus;
|
||||
@ -1731,7 +1720,7 @@ end;
|
||||
|
||||
procedure TfrmTableEditor.chkCharsetConvertClick(Sender: TObject);
|
||||
begin
|
||||
chkCharsetConvert.Enabled := (FAlterTablename <> '') and (comboCollation.ItemIndex > -1);
|
||||
chkCharsetConvert.Enabled := (FEditObjectName <> '') and (comboCollation.ItemIndex > -1);
|
||||
listColumns.Repaint;
|
||||
Modification(Sender);
|
||||
end;
|
||||
|
@ -31,11 +31,11 @@ type
|
||||
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(ObjectName: WideString=''; ObjectType: TListNodeType=lntNone); override;
|
||||
procedure ApplyModifications; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -53,10 +53,8 @@ var
|
||||
col: TProposalColumn;
|
||||
i: Integer;
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
Align := alClient;
|
||||
inherited;
|
||||
SynMemoStatement.Highlighter := Mainform.SynSQLSyn1;
|
||||
InheritFont(Font);
|
||||
editName.MaxLength := NAME_LEN;
|
||||
comboTiming.Items.Text := 'BEFORE'+CRLF+'AFTER';
|
||||
comboEvent.Items.Text := 'INSERT'+CRLF+'UPDATE'+CRLF+'DELETE';
|
||||
@ -78,8 +76,7 @@ procedure TfrmTriggerEditor.Init(ObjectName: WideString=''; ObjectType: TListNod
|
||||
var
|
||||
Definition, TableList: TMySQLQuery;
|
||||
begin
|
||||
Mainform.SetupSynEditors;
|
||||
FEditTriggerName := ObjectName;
|
||||
inherited;
|
||||
editName.Text := '';
|
||||
SynMemoStatement.Text := '';
|
||||
comboEvent.ItemIndex := 0;
|
||||
@ -93,20 +90,18 @@ begin
|
||||
end;
|
||||
if comboTable.Items.Count > 0 then
|
||||
comboTable.ItemIndex := 0;
|
||||
if FEditTriggerName <> '' then begin
|
||||
if FEditObjectName <> '' then begin
|
||||
// Edit mode
|
||||
Mainform.SetEditorTabCaption(Self, FEditTriggerName);
|
||||
editName.Text := FEditTriggerName;
|
||||
editName.Text := FEditObjectName;
|
||||
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));
|
||||
'WHERE TRIGGER_SCHEMA='+esc(Mainform.ActiveDatabase)+' AND TRIGGER_NAME='+esc(FEditObjectName));
|
||||
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;
|
||||
Modified := False;
|
||||
@ -129,19 +124,25 @@ end;
|
||||
procedure TfrmTriggerEditor.btnDiscardClick(Sender: TObject);
|
||||
begin
|
||||
// Reinit editor, discarding changes
|
||||
Init(FEditTriggerName);
|
||||
Modified := False;
|
||||
Init(FEditObjectName);
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTriggerEditor.btnSaveClick(Sender: TObject);
|
||||
begin
|
||||
ApplyModifications;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTriggerEditor.ApplyModifications;
|
||||
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));
|
||||
if FEditObjectName <> '' then
|
||||
Mainform.Connection.Query('DROP TRIGGER '+Mainform.mask(FEditObjectName));
|
||||
// CREATE
|
||||
// [DEFINER = { user | CURRENT_USER }]
|
||||
// TRIGGER trigger_name trigger_time trigger_event
|
||||
@ -151,12 +152,12 @@ begin
|
||||
' ON '+Mainform.mask(comboTable.Text)+
|
||||
' FOR EACH ROW '+SynMemoStatement.Text;
|
||||
Mainform.Connection.Query(sql);
|
||||
FocusChangeEvent := Mainform.DBtree.OnFocusChanged;
|
||||
Mainform.DBtree.OnFocusChanged := nil;
|
||||
FEditObjectName := editName.Text;
|
||||
Mainform.SetEditorTabCaption(Self, FEditObjectName);
|
||||
Mainform.RefreshTreeDB(Mainform.ActiveDatabase);
|
||||
Mainform.DBtree.OnFocusChanged := FocusChangeEvent;
|
||||
Mainform.SelectDBObject(editName.Text, lntTrigger);
|
||||
Init(editName.Text);
|
||||
Modified := False;
|
||||
btnSave.Enabled := Modified;
|
||||
btnDiscard.Enabled := Modified;
|
||||
except on E:Exception do
|
||||
MessageDlg(E.Message, mtError, [mbOK], 0);
|
||||
end;
|
||||
|
@ -26,11 +26,11 @@ type
|
||||
procedure Modification(Sender: TObject);
|
||||
private
|
||||
{ Private declarations }
|
||||
FEditViewName: WideString;
|
||||
public
|
||||
{ Public declarations }
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
procedure Init(ObjectName: WideString=''; ObjectType: TListNodeType=lntNone); override;
|
||||
procedure ApplyModifications; override;
|
||||
end;
|
||||
|
||||
|
||||
@ -46,11 +46,9 @@ uses main;
|
||||
}
|
||||
constructor TfrmView.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
Align := alClient;
|
||||
inherited;
|
||||
SynMemoSelect.Highlighter := Mainform.SynSQLSyn1;
|
||||
Mainform.SynCompletionProposal.AddEditor(SynMemoSelect);
|
||||
InheritFont(Font);
|
||||
editName.MaxLength := NAME_LEN;
|
||||
end;
|
||||
|
||||
@ -64,16 +62,15 @@ var
|
||||
db: WideString;
|
||||
rx: TRegExpr;
|
||||
begin
|
||||
FEditViewName := ObjectName;
|
||||
if FEditViewName <> '' then begin
|
||||
inherited;
|
||||
if FEditObjectName <> '' then begin
|
||||
// Edit mode
|
||||
editName.Text := FEditViewName;
|
||||
Mainform.SetEditorTabCaption(Self, FEditViewName);
|
||||
editName.Text := FEditObjectName;
|
||||
db := Mainform.ActiveDatabase;
|
||||
Results := Mainform.Connection.GetResults('SELECT * FROM '+Mainform.mask(DBNAME_INFORMATION_SCHEMA)+'.VIEWS ' +
|
||||
'WHERE TABLE_SCHEMA = '+esc(db)+' AND TABLE_NAME = '+esc(FEditViewName));
|
||||
'WHERE TABLE_SCHEMA = '+esc(db)+' AND TABLE_NAME = '+esc(FEditObjectName));
|
||||
if Results.RecordCount = 0 then
|
||||
raise Exception.Create('Can''t find view definition for "'+FEditViewName+'" in '+DBNAME_INFORMATION_SCHEMA);
|
||||
raise Exception.Create('Can''t find view definition for "'+FEditObjectName+'" in '+DBNAME_INFORMATION_SCHEMA);
|
||||
// Algorithm is not changeable as we cannot look up its current state!
|
||||
rgAlgorithm.Enabled := False;
|
||||
rgAlgorithm.ItemIndex := 0;
|
||||
@ -88,7 +85,6 @@ begin
|
||||
rx.Free;
|
||||
end else begin
|
||||
// Create mode
|
||||
Mainform.SetEditorTabCaption(Self, '');
|
||||
editName.Text := 'Enter view name';
|
||||
rgAlgorithm.Enabled := True;
|
||||
rgAlgorithm.ItemIndex := 0;
|
||||
@ -98,7 +94,6 @@ begin
|
||||
end;
|
||||
// Ensure name is validated
|
||||
editNameChange(Self);
|
||||
MainForm.SetupSynEditors;
|
||||
Modified := False;
|
||||
btnSave.Enabled := Modified;
|
||||
btnDiscard.Enabled := Modified;
|
||||
@ -129,7 +124,7 @@ procedure TfrmView.btnHelpClick(Sender: TObject);
|
||||
var
|
||||
keyword: String;
|
||||
begin
|
||||
if FEditViewName = '' then
|
||||
if FEditObjectName = '' then
|
||||
keyword := 'CREATE VIEW'
|
||||
else
|
||||
keyword := 'ALTER VIEW';
|
||||
@ -140,24 +135,31 @@ end;
|
||||
procedure TfrmView.btnDiscardClick(Sender: TObject);
|
||||
begin
|
||||
// Reinit editor, discarding changes
|
||||
Init(FEditViewName);
|
||||
Modified := False;
|
||||
Init(FEditObjectName);
|
||||
end;
|
||||
|
||||
|
||||
{**
|
||||
Apply changes: Compose and execute SQL
|
||||
Apply changes
|
||||
}
|
||||
procedure TfrmView.btnSaveClick(Sender: TObject);
|
||||
begin
|
||||
ApplyModifications;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmView.ApplyModifications;
|
||||
var
|
||||
sql, viewname, renamed: String;
|
||||
begin
|
||||
// Compose CREATE or ALTER statement
|
||||
if FEditViewName = '' then begin
|
||||
// Save changes
|
||||
if FEditObjectName = '' then begin
|
||||
sql := 'CREATE ';
|
||||
viewname := editName.Text;
|
||||
end else begin
|
||||
sql := 'ALTER ';
|
||||
viewname := FEditViewName;
|
||||
viewname := FEditObjectName;
|
||||
end;
|
||||
viewname := Mainform.mask(viewname);
|
||||
if rgAlgorithm.Enabled and (rgAlgorithm.ItemIndex > -1) then
|
||||
@ -169,11 +171,16 @@ begin
|
||||
try
|
||||
Mainform.Connection.Query(sql);
|
||||
// Probably rename view
|
||||
if (FEditViewName <> '') and (FEditViewName <> editName.Text) then begin
|
||||
if (FEditObjectName <> '') and (FEditObjectName <> 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);
|
||||
Modified := False;
|
||||
btnSave.Enabled := Modified;
|
||||
btnDiscard.Enabled := Modified;
|
||||
except
|
||||
on E:Exception do
|
||||
MessageDlg(E.Message, mtError, [mbOk], 0);
|
||||
|
Reference in New Issue
Block a user