mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2026-03-13 09:24:25 +08:00
Move code from GetSQLSplitMarkers and SplitSQL into TSQLBatch class. Enables me to access details like string size of batch. Preparation for query history.
This commit is contained in:
@@ -50,11 +50,27 @@ type
|
||||
GripRect: TRect;
|
||||
end;
|
||||
|
||||
TSQLBatch = class;
|
||||
TSQLSentence = class(TObject)
|
||||
LeftOffset, RightOffset: Integer;
|
||||
SQL: String;
|
||||
private
|
||||
FOwner: TSQLBatch;
|
||||
function GetSize: Integer;
|
||||
function GetSQL: String;
|
||||
public
|
||||
LeftOffset, RightOffset: Integer;
|
||||
constructor Create(Owner: TSQLBatch);
|
||||
property SQL: String read GetSQL;
|
||||
property Size: Integer read GetSize;
|
||||
end;
|
||||
TSQLBatch = class(TObjectList<TSQLSentence>)
|
||||
private
|
||||
FSQL: String;
|
||||
procedure SetSQL(Value: String);
|
||||
function GetSize: Integer;
|
||||
public
|
||||
property Size: Integer read GetSize;
|
||||
property SQL: String read FSQL write SetSQL;
|
||||
end;
|
||||
TSQLBatch = TObjectList<TSQLSentence>;
|
||||
|
||||
// Threading stuff
|
||||
TQueryThread = class(TThread)
|
||||
@@ -100,8 +116,6 @@ type
|
||||
function Explode(Separator, Text: String) :TStringList;
|
||||
procedure ExplodeQuotedList(Text: String; var List: TStringList);
|
||||
function getEnumValues(str: String): String;
|
||||
function GetSQLSplitMarkers(const SQL: String): TSQLBatch;
|
||||
function SplitSQL(const SQL: String): TSQLBatch;
|
||||
function sstr(str: String; len: Integer) : String;
|
||||
function encrypt(str: String): String;
|
||||
function decrypt(str: String): String;
|
||||
@@ -289,109 +303,6 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
function GetSQLSplitMarkers(const SQL: String): TSQLBatch;
|
||||
var
|
||||
i, AllLen, DelimLen, DelimStart, LastLeftOffset, RightOffset, LastNewLineOffset: Integer;
|
||||
c, n, LastStringEncloser: Char;
|
||||
Delim, DelimTest, QueryTest: String;
|
||||
InString, InComment, InBigComment, InEscape: Boolean;
|
||||
Marker: TSQLSentence;
|
||||
rx: TRegExpr;
|
||||
const
|
||||
StringEnclosers = ['"', '''', '`'];
|
||||
NewLines = [#13, #10];
|
||||
WhiteSpaces = NewLines + [#9, ' '];
|
||||
begin
|
||||
// Scan SQL batch for delimiters and return a list with start + end offsets
|
||||
AllLen := Length(SQL);
|
||||
i := 0;
|
||||
LastLeftOffset := 1;
|
||||
Delim := Mainform.Delimiter;
|
||||
InString := False; // Loop in "enclosed string" or `identifier`
|
||||
InComment := False; // Loop in one-line comment (# or --)
|
||||
InBigComment := False; // Loop in /* multi-line */ or /*! condictional comment */
|
||||
InEscape := False; // Previous char was backslash
|
||||
LastStringEncloser := #0;
|
||||
DelimLen := Length(Delim);
|
||||
Result := TSQLBatch.Create;
|
||||
rx := TRegExpr.Create;
|
||||
rx.Expression := '^\s*DELIMITER\s+(\S+)';
|
||||
rx.ModifierG := True;
|
||||
rx.ModifierI := True;
|
||||
rx.ModifierM := False;
|
||||
while i < AllLen do begin
|
||||
Inc(i);
|
||||
// Current and next char
|
||||
c := SQL[i];
|
||||
if i < AllLen then n := SQL[i+1]
|
||||
else n := #0;
|
||||
|
||||
// Check for comment syntax and for enclosed literals, so a query delimiter can be ignored
|
||||
if (not InComment) and (not InBigComment) and (not InString) and ((c + n = '--') or (c = '#')) then
|
||||
InComment := True;
|
||||
if (not InComment) and (not InBigComment) and (not InString) and (c + n = '/*') then
|
||||
InBigComment := True;
|
||||
if InBigComment and (not InComment) and (not InString) and (c + n = '*/') then
|
||||
InBigComment := False;
|
||||
if (not InEscape) and (not InComment) and (not InBigComment) and CharInSet(c, StringEnclosers) then begin
|
||||
if (not InString) or (InString and (c = LastStringEncloser)) then begin
|
||||
InString := not InString;
|
||||
LastStringEncloser := c;
|
||||
end;
|
||||
end;
|
||||
if (CharInSet(c, NewLines) and (not CharInSet(n, NewLines))) or (i = 1) then begin
|
||||
if i > 1 then
|
||||
InComment := False;
|
||||
if (not InString) and (not InBigComment) and rx.Exec(copy(SQL, i, 100)) then begin
|
||||
Delim := rx.Match[1];
|
||||
DelimLen := rx.MatchLen[1];
|
||||
Inc(i, rx.MatchLen[0]);
|
||||
LastLeftOffset := i;
|
||||
continue;
|
||||
end;
|
||||
end;
|
||||
if not InEscape then
|
||||
InEscape := c = '\'
|
||||
else
|
||||
InEscape := False;
|
||||
|
||||
// Prepare delimiter test string
|
||||
if (not InComment) and (not InString) and (not InBigComment) then begin
|
||||
DelimStart := Max(1, i+1-DelimLen);
|
||||
DelimTest := Copy(SQL, DelimStart, i-Max(i-DelimLen, 0));
|
||||
end else
|
||||
DelimTest := '';
|
||||
|
||||
// End of query or batch reached. Add query markers to result list if sentence is not empty.
|
||||
if (DelimTest = Delim) or (i = AllLen) then begin
|
||||
RightOffset := i+1;
|
||||
if DelimTest = Delim then
|
||||
Dec(RightOffset, DelimLen);
|
||||
QueryTest := Trim(Copy(SQL, LastLeftOffset, RightOffset-LastLeftOffset));
|
||||
if (QueryTest <> '') and (QueryTest <> Delim) then begin
|
||||
Marker := TSQLSentence.Create;
|
||||
while CharInSet(SQL[LastLeftOffset], WhiteSpaces) do
|
||||
Inc(LastLeftOffset);
|
||||
Marker.LeftOffset := LastLeftOffset;
|
||||
Marker.RightOffset := RightOffset;
|
||||
Result.Add(Marker);
|
||||
LastLeftOffset := i+1;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function SplitSQL(const SQL: String): TSQLBatch;
|
||||
var
|
||||
Query: TSQLSentence;
|
||||
begin
|
||||
// Return a list of queries tokenized from a big string. Replaces earlier parseSQL() method.
|
||||
Result := GetSQLSplitMarkers(SQL);
|
||||
for Query in Result do
|
||||
Query.SQL := Copy(SQL, Query.LeftOffset, Query.RightOffset-Query.LeftOffset);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{***
|
||||
@@ -2813,6 +2724,135 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
{ TSQLSentence }
|
||||
|
||||
constructor TSQLSentence.Create(Owner: TSQLBatch);
|
||||
begin
|
||||
// Use a back reference to the parent batch object, so we can extract SQL from it
|
||||
FOwner := Owner;
|
||||
end;
|
||||
|
||||
|
||||
function TSQLSentence.GetSize: Integer;
|
||||
begin
|
||||
Result := RightOffset - LeftOffset;
|
||||
end;
|
||||
|
||||
|
||||
function TSQLSentence.GetSQL: String;
|
||||
begin
|
||||
Result := Copy(FOwner.SQL, LeftOffset, RightOffset-LeftOffset);
|
||||
end;
|
||||
|
||||
|
||||
{ TSQLBatch }
|
||||
|
||||
function TSQLBatch.GetSize: Integer;
|
||||
var
|
||||
Query: TSQLSentence;
|
||||
begin
|
||||
// Return overall string length of batch
|
||||
Result := 0;
|
||||
for Query in Self do
|
||||
Inc(Result, Query.Size);
|
||||
end;
|
||||
|
||||
|
||||
procedure TSQLBatch.SetSQL(Value: String);
|
||||
var
|
||||
i, AllLen, DelimLen, DelimStart, LastLeftOffset, RightOffset, LastNewLineOffset: Integer;
|
||||
c, n, LastStringEncloser: Char;
|
||||
Delim, DelimTest, QueryTest: String;
|
||||
InString, InComment, InBigComment, InEscape: Boolean;
|
||||
Marker: TSQLSentence;
|
||||
rx: TRegExpr;
|
||||
const
|
||||
StringEnclosers = ['"', '''', '`'];
|
||||
NewLines = [#13, #10];
|
||||
WhiteSpaces = NewLines + [#9, ' '];
|
||||
begin
|
||||
// Scan SQL batch for delimiters and store a list with start + end offsets
|
||||
FSQL := Value;
|
||||
Clear;
|
||||
AllLen := Length(FSQL);
|
||||
i := 0;
|
||||
LastLeftOffset := 1;
|
||||
Delim := Mainform.Delimiter;
|
||||
InString := False; // Loop in "enclosed string" or `identifier`
|
||||
InComment := False; // Loop in one-line comment (# or --)
|
||||
InBigComment := False; // Loop in /* multi-line */ or /*! condictional comment */
|
||||
InEscape := False; // Previous char was backslash
|
||||
LastStringEncloser := #0;
|
||||
DelimLen := Length(Delim);
|
||||
rx := TRegExpr.Create;
|
||||
rx.Expression := '^\s*DELIMITER\s+(\S+)';
|
||||
rx.ModifierG := True;
|
||||
rx.ModifierI := True;
|
||||
rx.ModifierM := False;
|
||||
while i < AllLen do begin
|
||||
Inc(i);
|
||||
// Current and next char
|
||||
c := FSQL[i];
|
||||
if i < AllLen then n := FSQL[i+1]
|
||||
else n := #0;
|
||||
|
||||
// Check for comment syntax and for enclosed literals, so a query delimiter can be ignored
|
||||
if (not InComment) and (not InBigComment) and (not InString) and ((c + n = '--') or (c = '#')) then
|
||||
InComment := True;
|
||||
if (not InComment) and (not InBigComment) and (not InString) and (c + n = '/*') then
|
||||
InBigComment := True;
|
||||
if InBigComment and (not InComment) and (not InString) and (c + n = '*/') then
|
||||
InBigComment := False;
|
||||
if (not InEscape) and (not InComment) and (not InBigComment) and CharInSet(c, StringEnclosers) then begin
|
||||
if (not InString) or (InString and (c = LastStringEncloser)) then begin
|
||||
InString := not InString;
|
||||
LastStringEncloser := c;
|
||||
end;
|
||||
end;
|
||||
if (CharInSet(c, NewLines) and (not CharInSet(n, NewLines))) or (i = 1) then begin
|
||||
if i > 1 then
|
||||
InComment := False;
|
||||
if (not InString) and (not InBigComment) and rx.Exec(copy(FSQL, i, 100)) then begin
|
||||
Delim := rx.Match[1];
|
||||
DelimLen := rx.MatchLen[1];
|
||||
Inc(i, rx.MatchLen[0]);
|
||||
LastLeftOffset := i;
|
||||
continue;
|
||||
end;
|
||||
end;
|
||||
if not InEscape then
|
||||
InEscape := c = '\'
|
||||
else
|
||||
InEscape := False;
|
||||
|
||||
// Prepare delimiter test string
|
||||
if (not InComment) and (not InString) and (not InBigComment) then begin
|
||||
DelimStart := Max(1, i+1-DelimLen);
|
||||
DelimTest := Copy(FSQL, DelimStart, i-Max(i-DelimLen, 0));
|
||||
end else
|
||||
DelimTest := '';
|
||||
|
||||
// End of query or batch reached. Add query markers to result list if sentence is not empty.
|
||||
if (DelimTest = Delim) or (i = AllLen) then begin
|
||||
RightOffset := i+1;
|
||||
if DelimTest = Delim then
|
||||
Dec(RightOffset, DelimLen);
|
||||
QueryTest := Trim(Copy(FSQL, LastLeftOffset, RightOffset-LastLeftOffset));
|
||||
if (QueryTest <> '') and (QueryTest <> Delim) then begin
|
||||
Marker := TSQLSentence.Create(Self);
|
||||
while CharInSet(FSQL[LastLeftOffset], WhiteSpaces) do
|
||||
Inc(LastLeftOffset);
|
||||
Marker.LeftOffset := LastLeftOffset;
|
||||
Marker.RightOffset := RightOffset;
|
||||
Add(Marker);
|
||||
LastLeftOffset := i+1;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
||||
|
||||
@@ -2199,9 +2199,8 @@ end;
|
||||
procedure TMainForm.actExecuteQueryExecute(Sender: TObject);
|
||||
var
|
||||
Query: TSQLSentence;
|
||||
Text, LB: String;
|
||||
ProfileNode: PVirtualNode;
|
||||
Batch: TSQLBatch;
|
||||
BatchAll, Batch: TSQLBatch;
|
||||
Tab: TQueryTab;
|
||||
|
||||
begin
|
||||
@@ -2210,32 +2209,25 @@ begin
|
||||
OperationRunning(True);
|
||||
|
||||
ShowStatusMsg('Splitting SQL queries ...');
|
||||
Batch := TSQLBatch.Create;
|
||||
if Sender = actExecuteCurrentQuery then begin
|
||||
Batch := GetSQLSplitMarkers(Tab.Memo.Text);
|
||||
for Query in Batch do begin
|
||||
BatchAll := TSQLBatch.Create;
|
||||
BatchAll.SQL := Tab.Memo.Text;
|
||||
for Query in BatchAll do begin
|
||||
if (Tab.Memo.SelStart >= Query.LeftOffset-1) and (Tab.Memo.SelStart < Query.RightOffset) then begin
|
||||
Text := Copy(Tab.Memo.Text, Query.LeftOffset, Query.RightOffset-Query.LeftOffset);
|
||||
Batch.SQL := Query.SQL;
|
||||
Tab.LeftOffsetInMemo := Query.LeftOffset;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
BatchAll.Free;
|
||||
end else if Sender = actExecuteSelection then begin
|
||||
Text := Tab.Memo.SelText;
|
||||
Batch.SQL := Tab.Memo.SelText;
|
||||
Tab.LeftOffsetInMemo := Tab.Memo.SelStart;
|
||||
end else begin
|
||||
Text := Tab.Memo.Text;
|
||||
Batch.SQL := Tab.Memo.Text;
|
||||
Tab.LeftOffsetInMemo := 0;
|
||||
end;
|
||||
// Give text back its original linebreaks if possible
|
||||
case Tab.MemoLineBreaks of
|
||||
lbsUnix: LB := LB_UNIX;
|
||||
lbsMac: LB := LB_MAC;
|
||||
lbsWide: LB := LB_WIDE;
|
||||
end;
|
||||
if LB <> '' then
|
||||
Text := StringReplace(Text, CRLF, LB, [rfReplaceAll]);
|
||||
Batch := SplitSQL(Text);
|
||||
Text := '';
|
||||
|
||||
EnableProgress(Batch.Count);
|
||||
Tab.ResultTabs.Clear;
|
||||
@@ -2985,10 +2977,10 @@ end;
|
||||
}
|
||||
function TMainform.InitConnection(Params: TConnectionParameters; ActivateMe: Boolean; var Connection: TDBConnection): Boolean;
|
||||
var
|
||||
i: Integer;
|
||||
SessionExists, RestoreLastActiveDatabase: Boolean;
|
||||
StartupScript, StartupSQL, LastActiveDatabase: String;
|
||||
StartupScript, LastActiveDatabase: String;
|
||||
StartupBatch: TSQLBatch;
|
||||
Query: TSQLSentence;
|
||||
SessionNode, DBNode: PVirtualNode;
|
||||
begin
|
||||
Connection := Params.CreateConnection(Self);
|
||||
@@ -3051,10 +3043,10 @@ begin
|
||||
if not FileExists(StartupScript) then
|
||||
ErrorDialog('Startup script file not found: '+StartupScript)
|
||||
else begin
|
||||
StartupSQL := ReadTextfile(StartupScript, nil);
|
||||
StartupBatch := SplitSQL(StartupSQL);
|
||||
for i:=0 to StartupBatch.Count-1 do try
|
||||
Connection.Query(StartupBatch[i].SQL);
|
||||
StartupBatch := TSQLBatch.Create;
|
||||
StartupBatch.SQL := ReadTextfile(StartupScript, nil);
|
||||
for Query in StartupBatch do try
|
||||
Connection.Query(Query.SQL);
|
||||
except
|
||||
// Suppress popup, errors get logged into SQL log
|
||||
end;
|
||||
@@ -4820,7 +4812,7 @@ var
|
||||
Attri: TSynHighlighterAttributes;
|
||||
Proposal: TSynCompletionProposal;
|
||||
Editor: TCustomSynEdit;
|
||||
QueryMarkers: TSQLBatch;
|
||||
Queries: TSQLBatch;
|
||||
Query: TSQLSentence;
|
||||
Conn: TDBConnection;
|
||||
RoutineEditor: TfrmRoutineEditor;
|
||||
@@ -4921,14 +4913,15 @@ begin
|
||||
sql := 'SELECT * FROM '+ActiveDbObj.QuotedName+' WHERE ' + Editor.Text;
|
||||
end else begin
|
||||
// In a query tab
|
||||
QueryMarkers := GetSQLSplitMarkers(Editor.Text);
|
||||
for Query in QueryMarkers do begin
|
||||
Queries := TSQLBatch.Create;
|
||||
Queries.SQL := Editor.Text;
|
||||
for Query in Queries do begin
|
||||
if (Query.LeftOffset <= Editor.SelStart) and (Editor.SelStart < Query.RightOffset) then begin
|
||||
sql := Copy(Editor.Text, Query.LeftOffset, Query.RightOffset-Query.LeftOffset);
|
||||
sql := Query.SQL;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
FreeAndNil(QueryMarkers);
|
||||
Queries.Free;
|
||||
end;
|
||||
|
||||
// 2. Parse FROM clause, detect relevant table/view, probably aliased
|
||||
|
||||
@@ -48,15 +48,12 @@ uses
|
||||
}
|
||||
procedure TRunSQLFileForm.FormActivate(Sender: TObject);
|
||||
var
|
||||
Stream : TFileStream;
|
||||
lines : String;
|
||||
filesize,
|
||||
querycount,
|
||||
rowsaffected : Int64;
|
||||
starttime : Cardinal;
|
||||
SQL : TSQLBatch;
|
||||
i : Integer;
|
||||
lines_remaining : String;
|
||||
Stream: TFileStream;
|
||||
lines, lines_remaining: String;
|
||||
filesize, querycount, rowsaffected: Int64;
|
||||
starttime: Cardinal;
|
||||
Queries: TSQLBatch;
|
||||
i: Integer;
|
||||
begin
|
||||
if Running then
|
||||
abort;
|
||||
@@ -71,6 +68,7 @@ begin
|
||||
rowsaffected := 0;
|
||||
lines_remaining := '';
|
||||
starttime := GetTickCount;
|
||||
Queries := TSQLBatch.Create;
|
||||
|
||||
Screen.Cursor := crHourGlass;
|
||||
|
||||
@@ -100,17 +98,17 @@ begin
|
||||
Repaint;
|
||||
|
||||
// Split buffer into single queries
|
||||
SQL := SplitSQL( lines_remaining + lines );
|
||||
Queries.SQL := lines_remaining + lines;
|
||||
lines := '';
|
||||
lines_remaining := '';
|
||||
|
||||
// Execute detected queries
|
||||
for i := 0 to SQL.Count - 1 do
|
||||
for i:=0 to Queries.Count-1 do
|
||||
begin
|
||||
// Last line has to be processed in next loop if end of file is not reached
|
||||
if (i = SQL.Count-1) and (Stream.Position < Stream.Size) then
|
||||
if (i = Queries.Count-1) and (Stream.Position < Stream.Size) then
|
||||
begin
|
||||
lines_remaining := SQL[i].SQL;
|
||||
lines_remaining := Queries[i].SQL;
|
||||
break;
|
||||
end;
|
||||
|
||||
@@ -119,19 +117,19 @@ begin
|
||||
lblQueryCountValue.Caption := FormatNumber( querycount );
|
||||
|
||||
// Display part of query
|
||||
memoQueryValue.Text := sstr( SQL[i].SQL, 100 );
|
||||
memoQueryValue.Text := sstr(Queries[i].SQL, 100 );
|
||||
|
||||
// Time
|
||||
lblTimeValue.Caption := FormatTimeNumber((GetTickCount - starttime) DIV 1000, True);
|
||||
|
||||
// Execute single query and display affected rows
|
||||
Mainform.ActiveConnection.Query(SQL[i].SQL);
|
||||
Mainform.ActiveConnection.Query(Queries[i].SQL);
|
||||
rowsaffected := rowsaffected + Mainform.ActiveConnection.RowsAffected;
|
||||
lblAffectedRowsValue.Caption := FormatNumber( rowsaffected );
|
||||
|
||||
Repaint;
|
||||
end;
|
||||
SQL.Free;
|
||||
Queries.Free;
|
||||
|
||||
end;
|
||||
Stream.Free;
|
||||
|
||||
@@ -454,8 +454,7 @@ end;
|
||||
function TfrmTableEditor.ComposeAlterStatement: TSQLBatch;
|
||||
var
|
||||
Specs: TStringList;
|
||||
ColSpec, IndexSQL: String;
|
||||
Query: TSQLSentence;
|
||||
ColSpec, IndexSQL, SQL: String;
|
||||
i: Integer;
|
||||
Results: TDBQuery;
|
||||
Col, PreviousCol: PTableColumn;
|
||||
@@ -465,19 +464,16 @@ var
|
||||
procedure AddQuery;
|
||||
begin
|
||||
if Specs.Count > 0 then begin
|
||||
Query := TSQLSentence.Create;
|
||||
Query.SQL := 'ALTER TABLE '+DBObject.Connection.QuoteIdent(DBObject.Name) + CRLF + #9 + ImplodeStr(',' + CRLF + #9, Specs);
|
||||
Query.SQL := Trim(Query.SQL);
|
||||
Result.Add(Query);
|
||||
SQL := SQL + Trim('ALTER TABLE '+DBObject.Connection.QuoteIdent(DBObject.Name) + CRLF + #9 + ImplodeStr(',' + CRLF + #9, Specs)) + ';' + CRLF;
|
||||
Specs.Clear;
|
||||
end;
|
||||
end;
|
||||
begin
|
||||
// Compose ALTER query, called by buttons and for SQL code tab
|
||||
Mainform.ShowStatusMsg('Composing ALTER statement ...');
|
||||
Result := TSQLBatch.Create;
|
||||
Screen.Cursor := crHourglass;
|
||||
Specs := TStringList.Create;
|
||||
SQL := '';
|
||||
|
||||
// Special case for altered foreign keys: These have to be dropped in a seperate query
|
||||
// otherwise the server would return error 121 "Duplicate key on write or update"
|
||||
@@ -631,6 +627,9 @@ begin
|
||||
|
||||
AddQuery;
|
||||
|
||||
Result := TSQLBatch.Create;
|
||||
Result.SQL := SQL;
|
||||
|
||||
FreeAndNil(Specs);
|
||||
Mainform.ShowStatusMsg;
|
||||
MainForm.DisableProgress;
|
||||
@@ -643,18 +642,14 @@ var
|
||||
i, IndexCount: Integer;
|
||||
Col: PTableColumn;
|
||||
Node: PVirtualNode;
|
||||
tmp: String;
|
||||
Query: TSQLSentence;
|
||||
tmp, SQL: String;
|
||||
begin
|
||||
// Compose CREATE query, called by buttons and for SQL code tab
|
||||
Result := TSQLBatch.Create;
|
||||
Query := TSQLSentence.Create;
|
||||
Result.Add(Query);
|
||||
Query.SQL := 'CREATE TABLE '+DBObject.Connection.QuoteIdent(editName.Text)+' ('+CRLF;
|
||||
SQL := 'CREATE TABLE '+DBObject.Connection.QuoteIdent(editName.Text)+' ('+CRLF;
|
||||
Node := listColumns.GetFirst;
|
||||
while Assigned(Node) do begin
|
||||
Col := listColumns.GetNodeData(Node);
|
||||
Query.SQL := Query.SQL + #9 + Col.SQLCode + ','+CRLF;
|
||||
SQL := SQL + #9 + Col.SQLCode + ','+CRLF;
|
||||
Node := listColumns.GetNextSibling(Node);
|
||||
end;
|
||||
|
||||
@@ -662,43 +657,44 @@ begin
|
||||
for i:=0 to FKeys.Count-1 do begin
|
||||
tmp := FKeys[i].SQLCode;
|
||||
if tmp <> '' then begin
|
||||
Query.SQL := Query.SQL + #9 + tmp + ','+CRLF;
|
||||
SQL := SQL + #9 + tmp + ','+CRLF;
|
||||
Inc(IndexCount);
|
||||
end;
|
||||
end;
|
||||
|
||||
for i:=0 to FForeignKeys.Count-1 do
|
||||
Query.SQL := Query.SQL + #9 + FForeignKeys[i].SQLCode(True) + ','+CRLF;
|
||||
SQL := SQL + #9 + FForeignKeys[i].SQLCode(True) + ','+CRLF;
|
||||
|
||||
if Integer(listColumns.RootNodeCount) + IndexCount + FForeignKeys.Count > 0 then
|
||||
Delete(Query.SQL, Length(Query.SQL)-2, 3);
|
||||
Delete(SQL, Length(SQL)-2, 3);
|
||||
|
||||
Query.SQL := Query.SQL + CRLF + ')' + CRLF;
|
||||
SQL := SQL + CRLF + ')' + CRLF;
|
||||
if memoComment.Text <> '' then
|
||||
Query.SQL := Query.SQL + 'COMMENT='+esc(memoComment.Text) + CRLF;
|
||||
SQL := SQL + 'COMMENT='+esc(memoComment.Text) + CRLF;
|
||||
if comboCollation.Text <> '' then
|
||||
Query.SQL := Query.SQL + 'COLLATE='+esc(comboCollation.Text) + CRLF;
|
||||
SQL := SQL + 'COLLATE='+esc(comboCollation.Text) + CRLF;
|
||||
if comboEngine.Text <> '' then begin
|
||||
if DBObject.Connection.ServerVersionInt < 40018 then
|
||||
Query.SQL := Query.SQL + 'TYPE='+comboEngine.Text + CRLF
|
||||
SQL := SQL + 'TYPE='+comboEngine.Text + CRLF
|
||||
else
|
||||
Query.SQL := Query.SQL + 'ENGINE='+comboEngine.Text + CRLF;
|
||||
SQL := SQL + 'ENGINE='+comboEngine.Text + CRLF;
|
||||
end;
|
||||
if comboRowFormat.Tag = ModifiedFlag then
|
||||
Query.SQL := Query.SQL + 'ROW_FORMAT='+comboRowFormat.Text + CRLF;
|
||||
SQL := SQL + 'ROW_FORMAT='+comboRowFormat.Text + CRLF;
|
||||
if chkChecksum.Checked then
|
||||
Query.SQL := Query.SQL + 'CHECKSUM='+IntToStr(Integer(chkChecksum.Checked)) + CRLF;
|
||||
SQL := SQL + 'CHECKSUM='+IntToStr(Integer(chkChecksum.Checked)) + CRLF;
|
||||
if editAutoInc.Text <> '' then
|
||||
Query.SQL := Query.SQL + 'AUTO_INCREMENT='+editAutoInc.Text + CRLF;
|
||||
SQL := SQL + 'AUTO_INCREMENT='+editAutoInc.Text + CRLF;
|
||||
if editAvgRowLen.Text <> '' then
|
||||
Query.SQL := Query.SQL + 'AVG_ROW_LENGTH='+editAvgRowLen.Text + CRLF;
|
||||
SQL := SQL + 'AVG_ROW_LENGTH='+editAvgRowLen.Text + CRLF;
|
||||
if editMaxRows.Text <> '' then
|
||||
Query.SQL := Query.SQL + 'MAX_ROWS='+editMaxRows.Text + CRLF;
|
||||
SQL := SQL + 'MAX_ROWS='+editMaxRows.Text + CRLF;
|
||||
if memoUnionTables.Enabled and (memoUnionTables.Text <> '') then
|
||||
Query.SQL := Query.SQL + 'UNION=('+memoUnionTables.Text+')' + CRLF;
|
||||
SQL := SQL + 'UNION=('+memoUnionTables.Text+')' + CRLF;
|
||||
if comboInsertMethod.Enabled and (comboInsertMethod.Text <> '') then
|
||||
Query.SQL := Query.SQL + 'INSERT_METHOD='+comboInsertMethod.Text + CRLF;
|
||||
Query.SQL := Trim(Query.SQL);
|
||||
SQL := SQL + 'INSERT_METHOD='+comboInsertMethod.Text + CRLF;
|
||||
Result := TSQLBatch.Create;
|
||||
Result.SQL := Trim(SQL);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user