lazarus/components/sqldb/sqlstringspropertyeditordlg.pas
2014-01-08 16:31:31 +00:00

405 lines
11 KiB
ObjectPascal

unit SQLStringsPropertyEditorDlg;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, strutils,
SynEdit, ButtonPanel, SynHighlighterSQL, ComCtrls, SQLDb, db, DBGrids, Menus,
SrcEditorIntf, clipbrd, StdCtrls, fpsqltree, fpsqlparser;
type
{ TSQLStringsPropertyEditorDlg }
TSQLStringsPropertyEditorDlg = class(TForm)
ButtonsPanel: TButtonPanel;
CbxMetaData: TComboBox;
MIPaste: TMenuItem;
MetaDBGrid: TDBGrid;
EdtObject: TEdit;
ImageList: TImageList;
Label1: TLabel;
MIMeta: TMenuItem;
MIMetaColumns: TMenuItem;
MICheck: TMenuItem;
MICreateConstant: TMenuItem;
MICleanup: TMenuItem;
PMSQL: TPopupMenu;
PMMeta: TPopupMenu;
ResultDBGrid: TDBGrid;
SQLDataSource: TDatasource;
OpenDialog: TOpenDialog;
PageControl: TPageControl;
SaveDialog: TSaveDialog;
SQLDataSource1: TDatasource;
SQLEditor: TSynEdit;
SQLHighlighter: TSynSQLSyn;
EditorTabSheet: TTabSheet;
ResultTabSheet: TTabSheet;
SQLQuery: TSQLQuery;
MetaTabSheet: TTabSheet;
SQLMeta: TSQLQuery;
ToolBar: TToolBar;
OpenToolButton: TToolButton;
SaveToolButton: TToolButton;
DividerToolButton: TToolButton;
ExecuteToolButton: TToolButton;
TBCheck: TToolButton;
procedure MetaDBGridDblClick(Sender: TObject);
procedure ExecuteToolButtonClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure MICleanupClick(Sender: TObject);
procedure MICreateConstantClick(Sender: TObject);
procedure MIMetaColumnsClick(Sender: TObject);
procedure MIPasteClick(Sender: TObject);
procedure OpenToolButtonClick(Sender: TObject);
procedure SaveToolButtonClick(Sender: TObject);
procedure SQLEditorMouseDown(Sender: TObject; Button: TMouseButton;
{%H-}Shift: TShiftState; X, Y: Integer);
procedure TBCheckClick(Sender: TObject);
private
{ private declarations }
FMetaFromSynedit: Boolean;
FConnection:TSQLConnection;
FISSQLScript: Boolean;
FTransaction:TSQLTransaction;
FWordUnderCursor:string;
function CheckConnection:boolean;
procedure CheckSQLSyntax({%H-}SQL: TStrings);
procedure CleanupDelphiCode;
procedure CreateConstant;
procedure ShowMetaData;
public
{ public declarations }
constructor Create(AOwner:TComponent);override;
published
property Connection: TSQLConnection read FConnection write FConnection;
property Transaction:TSQLTransaction read FTransaction write FTransaction;
Property IsSQLScript : Boolean Read FISSQLScript Write FIsSQLScript;
end;
implementation
{$R *.lfm}
resourcestring
SResultTabCaption = 'Results';
SSQLTabCaption = 'SQL Code';
SMetaTabCaption = 'Metadata';
SMetaTables = 'Tables';
SMetaColumns = 'Columns';
SMetaProcedures = 'Procedures';
SMetaPleaseSpecifyATableInTheObjectField = 'Please specify a table in the '
+'object field.';
SMetaSysTables = 'SysTables';
SLoadSQLCodeHint = 'Load SQL code ...';
SSaveSQLCodeHint = 'Save SQL code ...';
SRunSQLCodeHint = 'Run SQL code';
SQuickCheckOfSQLSyntaxHint = 'Quick check of SQL syntax';
// SQL Parser results:
// Note: sql parser is not quite exact, so indicate it's not completely sure
SSQLOK = 'Quick SQL check OK';
SQLSyntaxOK = 'No syntax errors in SQL statement found.';
SSQLError = 'Probable SQL error';
SSQLSyntaxError = 'Probable syntax error in SQL statement:'+slineBreak+'%s';
{ TSQLStringsPropertyEditorDlg }
//----------------------------------------------------------------//
constructor TSQLStringsPropertyEditorDlg.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
SourceEditorManagerIntf.GetEditorControlSettings(SQLEditor);
SourceEditorManagerIntf.GetHighlighterSettings(SQLHighlighter);
EditorTabSheet.Caption := SSQLTabCaption;
ResultTabSheet.Caption := SResultTabCaption;
MetaTabSheet.Caption := SMetaTabCaption;
OpenToolButton.Hint := SLoadSQLCodeHint;
SaveToolButton.Hint := SSaveSQLCodeHint;
ExecuteToolButton.Hint := SRunSQLCodeHint;
TBCheck.Hint := SQuickCheckOfSQLSyntaxHint;
CbxMetaData.Items.Add(SMetaTables);
CbxMetaData.Items.Add(SMetaSysTables);
CbxMetaData.Items.Add(SMetaColumns);
CbxMetaData.Items.Add(SMetaProcedures);
end;
//----------------------------------------------------------//
function TSQLStringsPropertyEditorDlg.CheckConnection:boolean;
begin
Result := (Assigned(FConnection)) and (Assigned(FTransaction))
and(FConnection.Connected);
end;
//------------------------------------------------------------------------//
procedure TSQLStringsPropertyEditorDlg.OpenToolButtonClick(Sender: TObject);
begin
if(OpenDialog.Execute)then
SQLEditor.Lines.LoadFromFile(UTF8ToSys(OpenDialog.FileName));
end;
//---------------------------------------------------------------------------//
procedure TSQLStringsPropertyEditorDlg.ExecuteToolButtonClick(Sender: TObject);
begin
FMetaFromSynedit:=Sender.ClassNameIs('TMenuItem');
if PageControl.ActivePage=MetaTabSheet then
ShowMetaData
else
try
SQLQuery.Close;
SQLQuery.SQL.Text := SQLEditor.Text;
SQLQuery.Open;
PageControl.ActivePage := ResultTabSheet;
except
on e:Exception do
MessageDlg(e.Message, mtError, [mbOK], 0);
end;
end;
procedure TSQLStringsPropertyEditorDlg.MetaDBGridDblClick(Sender: TObject);
begin
if assigned(MetaDBGrid.SelectedField) and (MetaDBGrid.SelectedField.Value <> NULL) then
if FMetaFromSynedit then
begin
MIPasteClick(Sender);
end
else
EdtObject.Text:=MetaDBGrid.SelectedField.AsString;
end;
//-------------------------------------------------------------//
procedure TSQLStringsPropertyEditorDlg.FormShow(Sender: TObject);
Var
D : TSQLDialect;
begin
TBCheck.Visible:=True;
MICheck.Visible:=True;
D:=sqlStandard;
If Assigned(FConnection) then
begin
if (copy(LowerCase(FConnection.ClassName),1,3)='tib') then
D:=sqlinterbase6
else if (copy(LowerCase(FConnection.ClassName),1,7)='toracle') then
D:=sqloracle
else if (Copy(LowerCase(FConnection.ClassName),1,6)='tmysql') then
D:=sqlmysql;
end;
if (CheckConnection) then
begin
SQLQuery.DataBase := FConnection;
SQLQuery.Transaction := FTransaction;
SQLMeta.DataBase := FConnection;
SQLMeta.Transaction := FTransaction;
ResultTabSheet.TabVisible := True;
MetaTabSheet.TabVisible := True;
ExecuteToolButton.Visible := True;
FConnection.GetTableNames(SQLHighLighter.TableNames);
end
else
begin
ResultTabSheet.TabVisible := False;
MetaTabSheet.TabVisible := False;
ExecuteToolButton.Visible := False;
end;
SQLHighlighter.SQLDIalect:=D;
SQLHighlighter.Enabled:=True;
CbxMetaData.ItemIndex:=0;
{$ifdef unix}
// keep this only because of gtk1
{$ifdef LCLGtk}
SQLEditor.Font.Name:='-adobe-courier-medium-r-normal-*-8-*-*-*-m-*-iso10646-1';
{$endif}
{$endif}
SQLEditor.SetFocus;
end;
procedure TSQLStringsPropertyEditorDlg.MICleanupClick(Sender: TObject);
begin
CleanupDelphiCode;
end;
procedure TSQLStringsPropertyEditorDlg.CleanupDelphiCode;
Var
L : TStringList;
I,J,K : Integer;
S : String;
begin
L:=TStringList.Create;
try
L.Assign(SQLEditor.Lines);
For I:=0 to L.Count-1 do
begin
S:=L[i];
K:=0;
For J:=1 to Length(S) do
If S[j]='''' then
Inc(K);
if (K<>0) and ((K mod 2)=0) then
begin
J:=Pos('''',S);
Delete(S,1,J);
J:=RPos('''',S);
S:=Copy(S,1,J-1);
L[i]:=S;
end;
end;
SQLEditor.Lines:=L;
finally
L.Free;
end;
end;
procedure TSQLStringsPropertyEditorDlg.MICreateConstantClick(Sender: TObject);
begin
CreateConstant;
end;
procedure TSQLStringsPropertyEditorDlg.MIMetaColumnsClick(Sender: TObject);
begin
if FWordUnderCursor<>'' then
begin
CbxMetaData.ItemIndex:=2; //stColumns
EdtObject.Text:=FWordUnderCursor;
PageControl.ActivePage:=MetaTabSheet;
ExecuteToolButtonClick(Sender);
end;
end;
procedure TSQLStringsPropertyEditorDlg.MIPasteClick(Sender: TObject);
begin
if assigned(MetaDBGrid.SelectedField) and (MetaDBGrid.SelectedField.Value <> NULL) then
begin
SQLEditor.InsertTextAtCaret(' '+TSQLConnection(SQLMeta.DataBase).FieldNameQuoteChars[0]+
trim(MetaDBGrid.SelectedField.AsString)+TSQLConnection(SQLMeta.DataBase).FieldNameQuoteChars[1]);
PageControl.ActivePage:=EditorTabSheet;
end;
end;
procedure TSQLStringsPropertyEditorDlg.CreateConstant;
Var
C,S : String;
I : Integer;
begin
C:='';
For I:=0 to SQLEditor.Lines.Count-1 do
begin
S:=SQLEditor.Lines[i];
If (C<>'') then
C:=C+'+sLineBreak+'+sLineBreak;
C:=C+''''+StringReplace(S,'''','''''',[rfReplaceAll])+'''';
end;
C:='SQL = '+C+';';
Clipboard.AsText:=C;
end;
procedure TSQLStringsPropertyEditorDlg.ShowMetaData;
var
SchemaType:TSchemaType;
begin
case CbxMetaData.ItemIndex of
0:SchemaType:=stTables;
2:begin
SchemaType:=stColumns;
if EdtObject.Text='' then
begin
ShowMessage(SMetaPleaseSpecifyATableInTheObjectField);
exit;
end;
end;
3:SchemaType:=stProcedures;
1:SchemaType:=stSysTables;
else
SchemaType:=stNoSchema;
end;
if SchemaType<>stNoSchema then
try
SQLMeta.Close;
SQLMeta.SetSchemaInfo(SchemaType,EdtObject.Text,'');
SQLMeta.Open;
except
on e:Exception do
MessageDlg(e.Message, mtError, [mbOK], 0);
end;
end;
//------------------------------------------------------------------------//
procedure TSQLStringsPropertyEditorDlg.SaveToolButtonClick(Sender: TObject);
begin
if(SaveDialog.Execute)then
SQLEditor.Lines.SaveToFile(UTF8ToSys(SaveDialog.FileName));
end;
procedure TSQLStringsPropertyEditorDlg.SQLEditorMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
MPos,Caret:tpoint;
begin
If Button=mbRight then // save word under cursor
begin
FWordUnderCursor:='';
MPos.x:=x;
MPos.y:=y;
Caret:=SQLEditor.PhysicalToLogicalPos(SQLEditor.PixelsToLogicalPos(MPos));
FWordUnderCursor:=SQLEditor.GetWordAtRowCol(Caret);
end;
end;
procedure TSQLStringsPropertyEditorDlg.TBCheckClick(Sender: TObject);
begin
CheckSQLSyntax(SQLEditor.Lines)
end;
procedure TSQLStringsPropertyEditorDlg.CheckSQLSyntax(SQL : TStrings);
Var
S : TStream;
P : TSQLParser;
E : TSQLElement;
EL : TSQLElementList;
Msg : String;
begin
S:=TMemoryStream.Create;
try
SQL.SaveToStream(S);
S.Position:=0;
P:=TSQLParser.Create(S);
try
try
E:=Nil;
EL:=Nil;
If IsSQLScript then
EL:=P.ParseScript
else
E:=P.Parse;
E.Free;
EL.Free;
MessageDLG(SSQLOK,SQLSyntaxOK,mtInformation,[mbOK],0);
except
On E : Exception do
begin
Msg:=Format(SSQLSyntaxError,[E.Message]);
MessageDLG(SSQLError,Msg,mtError,[mbOK],0);
end;
end;
finally
P.Free;
end;
finally
S.Free;
end;
end;
end.