Convert parsesql to use wide strings and characters.

This commit is contained in:
rosenfield.albert
2008-06-17 11:56:37 +00:00
parent ff71f59fee
commit be831f11b7

View File

@ -10,7 +10,7 @@ interface
uses Classes, SysUtils, Graphics, db, clipbrd, dialogs, uses Classes, SysUtils, Graphics, db, clipbrd, dialogs,
forms, controls, ShellApi, checklst, windows, ZDataset, ZAbstractDataset, forms, controls, ShellApi, checklst, windows, ZDataset, ZAbstractDataset,
shlobj, ActiveX, StrUtils, VirtualTrees, SynRegExpr, Messages; shlobj, ActiveX, StrUtils, WideStrUtils, VirtualTrees, SynRegExpr, Messages, WideStrings;
type type
@ -34,9 +34,9 @@ type
function explode(separator, a: String) :TStringList; function explode(separator, a: String) :TStringList;
procedure ensureValidIdentifier(name: String); procedure ensureValidIdentifier(name: String);
function getEnumValues(str: WideString): WideString; function getEnumValues(str: WideString): WideString;
function IsValidDelimiter(var s: string): string; function IsValidDelimiter(var s: WideString): WideString;
type TParseSQLProcessCommand = procedure(command: String; parameter: String) of object; type TParseSQLProcessCommand = procedure(command: WideString; parameter: WideString) of object;
function parsesql(sql: String; delimiter: String; processcommand: TParseSQLProcessCommand = nil) : TStringList; function parsesql(sql: WideString; delimiter: WideString; processcommand: TParseSQLProcessCommand = nil) : TWideStringList;
function sstr(str: String; len: Integer) : String; function sstr(str: String; len: Integer) : String;
function encrypt(str: String): String; function encrypt(str: String): String;
function decrypt(str: String): String; function decrypt(str: String): String;
@ -325,11 +325,11 @@ end;
@param string to enclose added string in (use %s) @param string to enclose added string in (use %s)
@return void @return void
} }
procedure addResult(list: TStringList; s: string; enclose: string = ''); procedure addResult(list: TWideStringList; s: WideString; enclose: WideString = '');
begin begin
s := trim(s); s := trim(s);
if length(s) > 0 then begin if length(s) > 0 then begin
if enclose <> '' then s := Format(enclose, [s]); if enclose <> '' then s := WideFormat(enclose, [s]);
list.Add(s); list.Add(s);
end; end;
// Avoid memory leak // Avoid memory leak
@ -344,7 +344,7 @@ end;
@param s a string to be trimmed and tested. @param s a string to be trimmed and tested.
@return s an error message if validation fails, a nil string if it succeeds. @return s an error message if validation fails, a nil string if it succeeds.
} }
function IsValidDelimiter(var s: string): string; function IsValidDelimiter(var s: WideString): WideString;
begin begin
result := ''; result := '';
s := Trim(s); s := Trim(s);
@ -367,7 +367,7 @@ begin
then result := 'String literal markers disallowed in DELIMITER (because it would be ignored)'; then result := 'String literal markers disallowed in DELIMITER (because it would be ignored)';
if result <> '' then begin if result <> '' then begin
result := Format('Invalid delimiter %s: %s.', [s, result]); result := WideFormat('Invalid delimiter %s: %s.', [s, result]);
end; end;
end; end;
@ -378,7 +378,7 @@ end;
Limitations: only recognizes ANSI whitespace. Limitations: only recognizes ANSI whitespace.
Eligible for inlining, hope the compiler does this automatically. Eligible for inlining, hope the compiler does this automatically.
} }
function isWhitespace(const c: char): boolean; function isWhitespace(const c: WideChar): boolean;
begin begin
result := result :=
(c = #9) or (c = #9) or
@ -395,9 +395,9 @@ end;
Limitations: only recognizes ANSI numerals. Limitations: only recognizes ANSI numerals.
Eligible for inlining, hope the compiler does this automatically. Eligible for inlining, hope the compiler does this automatically.
} }
function isNumber(const c: char): boolean; function isNumber(const c: WideChar): boolean;
var var
b: byte; b: word;
begin begin
b := ord(c); b := ord(c);
result := result :=
@ -413,17 +413,17 @@ end;
Limitations: in case insensitive mode, input must be ANSI and lower case (for speed). Limitations: in case insensitive mode, input must be ANSI and lower case (for speed).
Eligible for inlining, hope the compiler does this automatically. Eligible for inlining, hope the compiler does this automatically.
} }
function scanReverse(const haystack: string; hayIndex: integer; const needle: string; needleEnd: integer; insensitive: boolean): boolean; function scanReverse(const haystack: WideString; hayIndex: integer; const needle: WideString; needleEnd: integer; insensitive: boolean): boolean;
var var
b: byte; b: word;
c: char; c: widechar;
begin begin
while (hayIndex > 0) and (needleEnd > 0) do begin while (hayIndex > 0) and (needleEnd > 0) do begin
// Lowercase ANSI A-Z if requested. // Lowercase ANSI A-Z if requested.
if insensitive then begin if insensitive then begin
b := Ord(haystack[hayIndex]); b := Ord(haystack[hayIndex]);
if (b > 64) and (b < 91) then b := b - 65 + 97; if (b > 64) and (b < 91) then b := b - 65 + 97;
c := Chr(b); c := WideChar(b);
end else c := haystack[hayIndex]; end else c := haystack[hayIndex];
if c <> needle[needleEnd] then begin if c <> needle[needleEnd] then begin
result := false; result := false;
@ -445,22 +445,22 @@ end;
@param TParseSQLProcessCommand Method that execute actions relative to an object @param TParseSQLProcessCommand Method that execute actions relative to an object
@return TStringList Separated statements @return TStringList Separated statements
} }
function parsesql(sql: String; delimiter: String; processcommand: TParseSQLProcessCommand = nil) : TStringList; function parsesql(sql: WideString; delimiter: WideString; processcommand: TParseSQLProcessCommand = nil) : TWideStringList;
var var
i, j, start, len : Integer; i, j, start, len : Integer;
tmp : String; tmp : WideString;
instring, backslash, incomment : Boolean; instring, backslash, incomment : Boolean;
inconditional, condterminated : Boolean; inconditional, condterminated : Boolean;
inbigcomment, indelimiter : Boolean; inbigcomment, indelimiter : Boolean;
delimiter_length : Integer; delimiter_length : Integer;
encloser, secchar, thdchar : Char; encloser, secchar, thdchar : WideChar;
conditional : String; conditional : WideString;
msg : String; msg : WideString;
{*** {***
If a callback for processing client SQL etc was given, invoke it. If a callback for processing client SQL etc was given, invoke it.
} }
procedure CallProcessCommand(command: String; parameter: String); procedure CallProcessCommand(command: WideString; parameter: WideString);
begin begin
if Assigned(processcommand) then processcommand(command, parameter); if Assigned(processcommand) then processcommand(command, parameter);
end; end;
@ -476,7 +476,7 @@ begin
end; end;
begin begin
result := TStringList.Create; result := TWideStringList.Create;
sql := trim(sql); sql := trim(sql);
instring := false; instring := false;
start := 1; start := 1;
@ -519,7 +519,7 @@ begin
if start = i then start := start + 1; if start = i then start := start + 1;
i := i + 1; i := i + 1;
end; end;
if incomment and (not inbigcomment) and (sql[i] in [#13, #10]) then begin if incomment and (not inbigcomment) and (sql[i] in [WideChar(#13), WideChar(#10)]) then begin
incomment := false; incomment := false;
end; end;
if inbigcomment and (sql[i] + secchar = '*/') then begin if inbigcomment and (sql[i] + secchar = '*/') then begin
@ -541,7 +541,7 @@ begin
end; end;
// Avoid parsing stuff inside string literals. // Avoid parsing stuff inside string literals.
if (sql[i] in ['''', '"', '`']) and (not (backslash and instring)) and (not incomment) and (not indelimiter) then begin if (sql[i] in [WideChar(''''), WideChar('"'), WideChar('`')]) and (not (backslash and instring)) and (not incomment) and (not indelimiter) then begin
if instring and (sql[i] = encloser) then begin if instring and (sql[i] = encloser) then begin
if secchar = encloser then if secchar = encloser then
i := i + 1 // encoded encloser-char i := i + 1 // encoded encloser-char
@ -570,7 +570,7 @@ begin
end; end;
if indelimiter then begin if indelimiter then begin
if (sql[i] in [#13, #10]) or (i = len) then begin if (sql[i] in [WideChar(#13), WideChar(#10)]) or (i = len) then begin
if (i = len) then j := 1 else j := 0; if (i = len) then j := 1 else j := 0;
tmp := copy(sql, start + 10, i + j - (start + 10)); tmp := copy(sql, start + 10, i + j - (start + 10));
msg := IsValidDelimiter(tmp); msg := IsValidDelimiter(tmp);