unit view; {$mode delphi}{$H+} interface uses SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, SynEdit, ExtCtrls, Menus, LCLProc, dbconnection, dbstructures, dbstructures.mysql, apphelpers, ComCtrls, extra_controls; type TFrame = TDBObjectEditor; TfrmView = class(TFrame) SynMemoBody: TSynEdit; lblSelect: TLabel; btnDiscard: TButton; btnSave: TButton; btnHelp: TButton; lblDisabledWhy: TLabel; PageControlMain: TPageControl; tabOptions: TTabSheet; tabCreateCode: TTabSheet; rgAlgorithm: TRadioGroup; lblName: TLabel; editName: TEdit; lblDefiner: TLabel; comboDefiner: TComboBox; comboSecurity: TComboBox; lblSecurity: TLabel; rgCheck: TRadioGroup; SynMemoCreateCode: TSynEdit; procedure btnHelpClick(Sender: TObject); procedure btnSaveClick(Sender: TObject); procedure btnDiscardClick(Sender: TObject); procedure Modification(Sender: TObject); procedure comboDefinerDropDown(Sender: TObject); procedure PageControlMainChange(Sender: TObject); private { Private declarations } function ComposeCreateStatement: TSQLBatch; public { Public declarations } constructor Create(AOwner: TComponent); override; procedure Init(Obj: TDBObject); override; function ApplyModifications: TModalResult; override; end; implementation uses main; {$R *.lfm} {** Create: Restore GUI setup } constructor TfrmView.Create(AOwner: TComponent); begin inherited; SynMemoBody.Highlighter := Mainform.SynSQLSynUsed; Mainform.SynCompletionProposal.AddEditor(SynMemoBody); SynMemoCreateCode.Highlighter := Mainform.SynSQLSynUsed; Mainform.SynCompletionProposal.AddEditor(SynMemoCreateCode); editName.MaxLength := NAME_LEN; comboSecurity.Items.Add('Definer'); comboSecurity.Items.Add('Invoker'); FMainSynMemo := SynMemoBody; btnSave.Hint := ShortCutToText(MainForm.actSaveSQL.ShortCut); end; {** FormShow: Fill controls with content in edit mode } procedure TfrmView.Init(Obj: TDBObject); var Algorithm, CheckOption, SelectCode, Definer, SQLSecurity: String; i: Integer; begin inherited; lblDisabledWhy.Font.Color := clRed; comboDefiner.Text := ''; comboDefiner.TextHint := f_('Current user (%s)', [Obj.Connection.CurrentUserHostCombination]); comboDefiner.Hint := f_('Leave empty for current user (%s)', [Obj.Connection.CurrentUserHostCombination]); if Obj.Name <> '' then begin // Edit mode editName.Text := Obj.Name; Algorithm := ''; Definer := ''; SQLSecurity := ''; CheckOption := ''; SelectCode := ''; Obj.Connection.ParseViewStructure(Obj.CreateCode, Obj, Algorithm, Definer, SQLSecurity, CheckOption, SelectCode); comboDefiner.Text := Definer; rgAlgorithm.ItemIndex := rgAlgorithm.Items.IndexOf(Algorithm); rgCheck.ItemIndex := rgCheck.Items.IndexOf(CheckOption); if rgCheck.ItemIndex = -1 then rgCheck.ItemIndex := 0; for i:=0 to comboSecurity.Items.Count-1 do begin if LowerCase(SQLSecurity) = LowerCase(comboSecurity.Items[i]) then begin comboSecurity.ItemIndex := i; Break; end; end; SynMemoBody.Text := SelectCode; // User may not be allowed to run SHOW CREATE VIEW, in which case we have an empty CreateCode. // Disable editor in this case. lblDisabledWhy.Visible := SelectCode = ''; editName.Enabled := not lblDisabledWhy.Visible; rgAlgorithm.Enabled := editName.Enabled; rgCheck.Enabled := rgAlgorithm.Enabled; SynMemoBody.Enabled := rgAlgorithm.Enabled; SynMemoBody.TopLine := FMainSynMemoPreviousTopLine; end else begin // Create mode editName.Text := ''; rgAlgorithm.Enabled := True; rgAlgorithm.ItemIndex := 0; rgCheck.Enabled := True; rgCheck.ItemIndex := 0; comboSecurity.ItemIndex := 0; SynMemoBody.Text := 'SELECT '; lblDisabledWhy.Hide; end; // Most clauses only supported by MySQL comboDefiner.Enabled := comboDefiner.Enabled and Obj.Connection.Parameters.IsAnyMySQL; lblDefiner.Enabled := comboDefiner.Enabled; comboSecurity.Enabled := comboSecurity.Enabled and Obj.Connection.Parameters.IsAnyMySQL; lblSecurity.Enabled := comboSecurity.Enabled; rgAlgorithm.Enabled := rgAlgorithm.Enabled and Obj.Connection.Parameters.IsAnyMySQL; rgCheck.Enabled := rgCheck.Enabled and Obj.Connection.Parameters.IsAnyMySQL; // Update create code tab Modification(Self); Modified := False; btnSave.Enabled := Modified; btnDiscard.Enabled := Modified; Mainform.ShowStatusMsg; TExtForm.PageControlTabHighlight(PageControlMain); Screen.Cursor := crDefault; end; procedure TfrmView.comboDefinerDropDown(Sender: TObject); begin // Populate definers from mysql.user (Sender as TComboBox).Items.Assign(DBObject.Connection.AllUserHostCombinations); end; {** Lookup "Create|Alter View" in SQL help } procedure TfrmView.btnHelpClick(Sender: TObject); begin Help(Self, 'createview'); end; procedure TfrmView.btnDiscardClick(Sender: TObject); begin // Reinit editor, discarding changes Modified := False; Init(DBObject); end; {** Apply changes } procedure TfrmView.btnSaveClick(Sender: TObject); begin ApplyModifications; end; function TfrmView.ApplyModifications: TModalResult; var Batch: TSQLBatch; Query: TSQLSentence; begin // Save changes Result := mrOk; try Batch := ComposeCreateStatement; for Query in Batch do begin DBObject.Connection.Query(Query.SQL); end; Batch.Free; DBObject.Name := editName.Text; DBObject.UnloadDetails; Mainform.UpdateEditorTab; Mainform.RefreshTree(DBObject); Modified := False; btnSave.Enabled := Modified; btnDiscard.Enabled := Modified; except on E:EDbError do begin ErrorDialog(E.Message); Result := mrAbort; end; end; end; procedure TfrmView.Modification(Sender: TObject); var Batch: TSQLBatch; begin Modified := True; btnSave.Enabled := Modified and (editName.Text <> ''); btnDiscard.Enabled := Modified; // Update create code Batch := ComposeCreateStatement; SynMemoCreateCode.Text := Batch.SQL; Batch.Free; end; procedure TfrmView.PageControlMainChange(Sender: TObject); begin TExtForm.PageControlTabHighlight(PageControlMain); end; function TfrmView.ComposeCreateStatement: TSQLBatch; var sql, ViewName, RenameView: String; begin // Create or Alter code if not ObjectExists then begin sql := 'CREATE '; ViewName := editName.Text; end else begin sql := 'ALTER '; ViewName := DBObject.Name; end; ViewName := DBObject.Connection.QuoteIdent(ViewName); if rgAlgorithm.Enabled and (rgAlgorithm.ItemIndex > -1) then sql := sql + 'ALGORITHM = '+Uppercase(rgAlgorithm.Items[rgAlgorithm.ItemIndex])+' '; if comboDefiner.Enabled and (comboDefiner.Text <> '') then sql := sql + 'DEFINER='+DBObject.Connection.QuoteIdent(comboDefiner.Text, True, '@')+' '; if comboSecurity.Enabled and (comboSecurity.Text <> '') then sql := sql + 'SQL SECURITY ' + UpperCase(comboSecurity.Text)+' '; sql := sql + 'VIEW ' + ViewName+' AS '+SynMemoBody.Text+' '; if rgCheck.Enabled and (rgCheck.ItemIndex > 0) then sql := sql + 'WITH '+Uppercase(rgCheck.Items[rgCheck.ItemIndex])+' CHECK OPTION'; sql := sql + ';' + sLineBreak; if ObjectExists and (DBObject.Name <> editName.Text) then begin RenameView := DBObject.Connection.QuoteIdent(editName.Text); sql := sql + 'RENAME TABLE '+ViewName + ' TO '+RenameView + ';' + sLineBreak; end; Result := TSQLBatch.Create; Result.SQL := Trim(SQL); end; end.