📄 aoraupdatesqled.pas
字号:
{*******************************************************}
{ }
{ AXIOMA Delphi Visual Component Library }
{ AOraUpdateSQL Component Editor }
{ }
{ Copyright (c) 1997,2001 AXIOMA Corp }
{ }
{*******************************************************}
unit AOraUpdateSQLEd;
{$INCLUDE dOCI.inc}
interface
uses Forms, DB, ExtCtrls, StdCtrls, Controls, ComCtrls,
Classes, SysUtils, Windows, Menus, OraDB, AOraUpdateSQL, OraSQL,
AOraSQL, VirtualDataSet, DataSetQuery, dOCIMessages
{$IFDEF D4} ,Dsgnintf {$ENDIF}
{$IFDEF D5} ,Dsgnintf {$ENDIF}
{$IFDEF D6} ,DesignIntf, DesignEditors {$ENDIF}
{$IFDEF D7} ,DesignIntf, DesignEditors {$ENDIF}
;
type
TWaitMethod = procedure of object;
TAOraUpdateSQLEditForm = class(TForm)
OkButton: TButton;
CancelButton: TButton;
HelpButton: TButton;
GenerateButton: TButton;
PrimaryKeyButton: TButton;
DefaultButton: TButton;
UpdateTableName: TComboBox;
FieldsPage: TTabSheet;
SQLPage: TTabSheet;
PageControl: TPageControl;
KeyFieldList: TListBox;
UpdateFieldList: TListBox;
GroupBox1: TGroupBox;
Label1: TLabel;
SQLMemo: TMemo;
StatementType: TRadioGroup;
QuoteFields: TCheckBox;
GetTableFieldsButton: TButton;
FieldListPopup: TPopupMenu;
miSelectAll: TMenuItem;
miClearAll: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure HelpButtonClick(Sender: TObject);
procedure StatementTypeClick(Sender: TObject);
procedure OkButtonClick(Sender: TObject);
procedure DefaultButtonClick(Sender: TObject);
procedure GenerateButtonClick(Sender: TObject);
procedure PrimaryKeyButtonClick(Sender: TObject);
procedure PageControlChanging(Sender: TObject;
var AllowChange: Boolean);
procedure FormDestroy(Sender: TObject);
procedure GetTableFieldsButtonClick(Sender: TObject);
procedure SettingsChanged(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure UpdateTableNameChange(Sender: TObject);
procedure UpdateTableNameClick(Sender: TObject);
procedure SelectAllClick(Sender: TObject);
procedure ClearAllClick(Sender: TObject);
procedure SQLMemoKeyPress(Sender: TObject; var Key: Char);
private
StmtIndex: Integer;
DataSet: TOraSQL;//TDBDataSet;
// Database: TOraDB;//TDatabase
// DatabaseOpened: Boolean;
DatabaseSelfOpen:Boolean;
UpdateSQL: TAOraUpdateSQL;//TUpdateSQL
FSettingsChanged: Boolean;
FDatasetDefaults: Boolean;
FTempSQL:TOraSQL;
SQLText: array[TUpdateKind] of TStrings;
function GetTableRef(const TabName, QuoteChar: string): string;
// function DatabaseOpen: Boolean;
function Edit: Boolean;
procedure GenWhereClause(const TabAlias, QuoteChar: string;
KeyFields, SQL: TStrings);
procedure GenDeleteSQL(const TableName, QuoteChar: string;
KeyFields, SQL: TStrings);
procedure GenInsertSQL(const TableName, QuoteChar: string;
UpdateFields, SQL: TStrings);
procedure GenModifySQL(const TableName, QuoteChar: string;
KeyFields, UpdateFields, SQL: TStrings);
procedure GenerateSQL;
procedure GetDataSetFieldNames;
procedure GetTableFieldNames;
procedure InitGenerateOptions;
procedure InitUpdateTableNames;
procedure SetButtonStates;
procedure SelectPrimaryKeyFields;
procedure SetDefaultSelections;
procedure ShowWait(WaitMethod: TWaitMethod);
function TempTable: TOraSQL;
end;
{ TSQLParser }
TSQLToken = (stSymbol, stAlias, stNumber, stComma, stEQ, stOther, stLParen,
stRParen, stEnd);
TSQLParser = class
private
FText: string;
FSourcePtr: PChar;
FTokenPtr: PChar;
FTokenString: string;
FToken: TSQLToken;
FSymbolQuoted: Boolean;
function NextToken: TSQLToken;
function TokenSymbolIs(const S: string): Boolean;
procedure Reset;
public
constructor Create(const Text: string);
procedure GetSelectTableNames(List: TStrings);
procedure GetUpdateTableName(var TableName: string);
procedure GetUpdateFields(List: TStrings);
procedure GetWhereFields(List: TStrings);
end;
TAOraUpdateSQLEditor = class(TComponentEditor)
public
procedure ExecuteVerb(Index: Integer); override;
function GetVerb(Index: Integer): string; override;
function GetVerbCount: Integer; override;
end;
//function EditUpdateSQL(AUpdateSQL: TUpdateSQL): Boolean;
function EditUpdateSQL(AOraUpdateSQL: TAOraUpdateSQL): Boolean;
implementation
{$R *.DFM}
uses Dialogs;//, LibHelp;//, TypInfo;
{ Global Interface functions }
function EditUpdateSQL(AOraUpdateSQL: TAOraUpdateSQL): Boolean;
begin
with TAOraUpdateSQLEditForm.Create(Application) do
try
UpdateSQL := AOraUpdateSQL;
Result := Edit;
finally
Free;
end;
end;
{ Utility Routines }
procedure GetSelectedItems(ListBox: TListBox; List: TStrings);
var
I: Integer;
begin
List.Clear;
for I := 0 to ListBox.Items.Count - 1 do
if ListBox.Selected[I] then
List.Add(ListBox.Items[I]);
end;
function SetSelectedItems(ListBox: TListBox; List: TStrings): Integer;
var
I: Integer;
begin
Result := 0;
ListBox.Items.BeginUpdate;
try
for I := 0 to ListBox.Items.Count - 1 do
if List.IndexOf(ListBox.Items[I]) > -1 then
begin
ListBox.Selected[I] := True;
Inc(Result);
end
else
ListBox.Selected[I] := False;
if ListBox.Items.Count > 0 then
begin
ListBox.ItemIndex := 0;
ListBox.TopIndex := 0;
end;
finally
ListBox.Items.EndUpdate;
end;
end;
procedure SelectAll(ListBox: TListBox);
var
I: Integer;
begin
ListBox.Items.BeginUpdate;
try
with ListBox do
for I := 0 to Items.Count - 1 do
Selected[I] := True;
if ListBox.Items.Count > 0 then
begin
ListBox.ItemIndex := 0;
ListBox.TopIndex := 0;
end;
finally
ListBox.Items.EndUpdate;
end;
end;
procedure GetDataFieldNames(Dataset: TDataset; ErrorName: string; List: TStrings);
var
I: Integer;
begin
with Dataset do
try
FieldDefs.Update;
List.BeginUpdate;
try
List.Clear;
for I := 0 to FieldDefs.Count - 1 do
List.Add(FieldDefs[I].Name);
finally
List.EndUpdate;
end;
except
if ErrorName <> '' then
MessageDlg(Format(SSQLDataSetOpen, [ErrorName]), mtError, [mbOK], 0);
end;
end;
procedure GetSQLTableNames(const SQL: string; List: TStrings);
begin
with TSQLParser.Create(SQL) do
try
GetSelectTableNames(List);
finally
Free;
end;
end;
procedure ParseUpdateSQL(const SQL: string; var TableName: string;
UpdateFields: TStrings; WhereFields: TStrings);
begin
with TSQLParser.Create(SQL) do
try
GetUpdateTableName(TableName);
if Assigned(UpdateFields) then
begin
Reset;
GetUpdateFields(UpdateFields);
end;
if Assigned(WhereFields) then
begin
Reset;
GetWhereFields(WhereFields);
end;
finally
Free;
end;
end;
{ TUpdateSQLEditor }
procedure TAOraUpdateSQLEditor.ExecuteVerb(Index: Integer);
begin
if EditUpdateSQL(TAOraUpdateSQL(Component)) then Designer.Modified;
end;
function TAOraUpdateSQLEditor.GetVerb(Index: Integer): string;
begin
if Component=nil
then Result := Format(SUpdateSQLEditor,['AOraUpdateSQL'])
else Result := Format(SUpdateSQLEditor,[(Component as TAOraUpdateSQL).Name]);
end;
function TAOraUpdateSQLEditor.GetVerbCount: Integer;
begin
Result := 1;
end;
{ TSQLParser }
constructor TSQLParser.Create(const Text: string);
begin
FText := Text;
FSourcePtr := PChar(Text);
NextToken;
end;
function TSQLParser.NextToken: TSQLToken;
var
P, TokenStart: PChar;
QuoteChar: Char;
IsParam: Boolean;
function IsKatakana(const Chr: Byte): Boolean;
begin
Result := (SysLocale.PriLangID = LANG_JAPANESE) and (Chr in [$A1..$DF]);
end;
begin
if FToken = stEnd then SysUtils.Abort;
FTokenString := '';
FSymbolQuoted := False;
P := FSourcePtr;
while (P^ <> #0) and (P^ <= ' ') do Inc(P);
FTokenPtr := P;
case P^ of
'A'..'Z', 'a'..'z', '_', '$', #127..#255:
begin
TokenStart := P;
if not SysLocale.FarEast then
begin
Inc(P);
while P^ in ['A'..'Z', 'a'..'z', '0'..'9', '_', '.', '"', '$', #127..#255] do Inc(P);
end
else
begin
while TRUE do
begin
if (P^ in ['A'..'Z', 'a'..'z', '0'..'9', '_', '.', '"', '$']) or
IsKatakana(Byte(P^)) then
Inc(P)
else
if P^ in LeadBytes then
Inc(P, 2)
else
Break;
end;
end;
SetString(FTokenString, TokenStart, P - TokenStart);
FToken := stSymbol;
end;
'''', '"':
begin
QuoteChar := P^;
Inc(P);
IsParam := P^ = ':';
if IsParam then Inc(P);
TokenStart := P;
while not (P^ in [QuoteChar, #0]) do Inc(P);
SetString(FTokenString, TokenStart, P - TokenStart);
Inc(P);
Trim(FTokenString);
FToken := stSymbol;
FSymbolQuoted := True;
end;
'-', '0'..'9':
begin
TokenStart := P;
Inc(P);
while P^ in ['0'..'9', '.', 'e', 'E', '+', '-'] do Inc(P);
SetString(FTokenString, TokenStart, P - TokenStart);
FToken := stNumber;
end;
',':
begin
Inc(P);
FToken := stComma;
end;
'=':
begin
Inc(P);
FToken := stEQ;
end;
'(':
begin
Inc(P);
FToken := stLParen;
end;
')':
begin
Inc(P);
FToken := stRParen;
end;
#0:
FToken := stEnd;
else
begin
FToken := stOther;
Inc(P);
end;
end;
FSourcePtr := P;
if (FToken = stSymbol) and
(FTokenString[Length(FTokenString)] = '.') then FToken := stAlias;
Result := FToken;
end;
procedure TSQLParser.Reset;
begin
FSourcePtr := PChar(FText);
FToken := stSymbol;
NextToken;
end;
function TSQLParser.TokenSymbolIs(const S: string): Boolean;
begin
Result := (FToken = stSymbol) and (CompareText(FTokenString, S) = 0);
end;
procedure TSQLParser.GetSelectTableNames(List: TStrings);
begin
List.BeginUpdate;
try
List.Clear;
if TokenSymbolIs('SELECT') then { Do not localize }
try
while not TokenSymbolIs('FROM') do NextToken; { Do not localize }
NextToken;
while FToken = stSymbol do
begin
List.AddObject(FTokenString, Pointer(Integer(FSymbolQuoted)));
if NextToken = stSymbol then NextToken;
if FToken = stComma then NextToken
else break;
end;
except
end;
finally
List.EndUpdate;
end;
end;
procedure TSQLParser.GetUpdateTableName(var TableName: string);
begin
if TokenSymbolIs('UPDATE') and (NextToken = stSymbol) then { Do not localize }
TableName := FTokenString else
TableName := '';
end;
procedure TSQLParser.GetUpdateFields(List: TStrings);
begin
List.BeginUpdate;
try
List.Clear;
if TokenSymbolIs('UPDATE') then { Do not localize }
try
while not TokenSymbolIs('SET') do NextToken; { Do not localize }
NextToken;
while True do
begin
if FToken = stAlias then NextToken;
if FToken <> stSymbol then Break;
List.Add(FTokenString);
if NextToken <> stEQ then Break;
while NextToken <> stComma do
if TokenSymbolIs('WHERE') then Exit;{ Do not localize }
NextToken;
end;
except
end;
finally
List.EndUpdate;
end;
end;
procedure TSQLParser.GetWhereFields(List: TStrings);
begin
List.BeginUpdate;
try
List.Clear;
if TokenSymbolIs('UPDATE') then { Do not localize }
try
while not TokenSymbolIs('WHERE') do NextToken; { Do not localize }
NextToken;
while True do
begin
while FToken in [stLParen, stAlias] do NextToken;
if FToken <> stSymbol then Break;
List.Add(FTokenString);
if NextToken <> stEQ then Break;
while true do
begin
NextToken;
if FToken = stEnd then Exit;
if TokenSymbolIs('AND') then Break; { Do not localize }
end;
NextToken;
end;
except
end;
finally
List.EndUpdate;
end;
end;
{ TUpdateSQLEditor }
{ Private Methods }
{function TAOraUpdateSQLEditForm.DatabaseOpen: Boolean;
begin
if Assigned(Database) then
Result := True
else
begin
Result := False;
if not Assigned(DataSet) then Exit;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -