558 |
|
function TokenFound(var token: TSQLTokens): boolean; virtual; |
559 |
|
function InternalGetNextToken: TSQLTokens; virtual; |
560 |
|
procedure Reset; virtual; |
561 |
+ |
function ReadCharacters(NumOfChars: integer): AnsiString; |
562 |
|
|
563 |
|
{Token stack} |
564 |
|
procedure QueueToken(token: TSQLTokens; text:AnsiString); overload; |
649 |
|
function FormatTimeZoneOffset(EffectiveTimeOffsetMins: integer): AnsiString; |
650 |
|
function DecodeTimeZoneOffset(TZOffset: AnsiString; var dstOffset: integer): boolean; |
651 |
|
function StripLeadingZeros(Value: AnsiString): AnsiString; |
652 |
+ |
function TryStrToNumeric(S: Ansistring; out Value: int64; out scale: integer): boolean; |
653 |
+ |
function NumericToDouble(aValue: Int64; aScale: integer): double; |
654 |
+ |
|
655 |
|
|
656 |
|
implementation |
657 |
|
|
658 |
< |
uses FBMessages |
658 |
> |
uses FBMessages, Math |
659 |
|
|
660 |
|
{$IFDEF FPC} |
661 |
|
,RegExpr |
1452 |
|
ResetQueue; |
1453 |
|
end; |
1454 |
|
|
1455 |
+ |
function TSQLTokeniser.ReadCharacters(NumOfChars: integer): AnsiString; |
1456 |
+ |
var i: integer; |
1457 |
+ |
begin |
1458 |
+ |
Result := FLastChar; |
1459 |
+ |
for i := 2 to NumOfChars do |
1460 |
+ |
begin |
1461 |
+ |
if GetNext = sqltEOF then break; |
1462 |
+ |
Result := Result + FLastChar; |
1463 |
+ |
end; |
1464 |
+ |
end; |
1465 |
+ |
|
1466 |
|
function TSQLTokeniser.GetNextToken: TSQLTokens; |
1467 |
|
begin |
1468 |
|
if FQueueState = tsRelease then |
1487 |
|
GetNext; |
1488 |
|
|
1489 |
|
repeat |
1490 |
+ |
if FSkipNext then |
1491 |
+ |
begin |
1492 |
+ |
FSkipNext := false; |
1493 |
+ |
GetNext; |
1494 |
+ |
end; |
1495 |
+ |
|
1496 |
|
Result := FNextToken; |
1497 |
|
C := FLastChar; |
1498 |
|
GetNext; |
1499 |
|
|
1500 |
< |
if FSkipNext then |
1500 |
> |
if (Result = sqltCR) and (FNextToken = sqltEOL) then |
1501 |
|
begin |
1502 |
< |
FSkipNext := false; |
1503 |
< |
continue; |
1502 |
> |
FSkipNext := true; |
1503 |
> |
Result := sqltEOL; |
1504 |
> |
C := LF; |
1505 |
|
end; |
1506 |
|
|
1507 |
|
case FState of |
1514 |
|
GetNext; |
1515 |
|
end |
1516 |
|
else |
1517 |
+ |
if Result = sqltEOL then |
1518 |
+ |
FString := FString + LineEnding |
1519 |
+ |
else |
1520 |
|
FString := FString + C; |
1521 |
|
end; |
1522 |
|
|
1529 |
|
Result := sqltCommentLine; |
1530 |
|
end; |
1531 |
|
|
1507 |
– |
sqltCR: {ignore}; |
1508 |
– |
|
1532 |
|
else |
1533 |
|
FString := FString + C; |
1534 |
|
end; |
1550 |
|
end; |
1551 |
|
end |
1552 |
|
else |
1553 |
+ |
if Result = sqltEOL then |
1554 |
+ |
FString := FString + LineEnding |
1555 |
+ |
else |
1556 |
|
FString := FString + C; |
1557 |
|
end; |
1558 |
|
|
1572 |
|
end; |
1573 |
|
end |
1574 |
|
else |
1575 |
+ |
if Result = sqltEOL then |
1576 |
+ |
FString := FString + LineEnding |
1577 |
+ |
else |
1578 |
|
FString := FString + C; |
1579 |
|
end; |
1580 |
|
|
1655 |
|
sqltNumberString: |
1656 |
|
if FNextToken in [sqltNumberString,sqltPeriod] then |
1657 |
|
FState := stInNumeric; |
1658 |
+ |
|
1659 |
+ |
sqltEOL: |
1660 |
+ |
FString := LineEnding; |
1661 |
|
end; |
1662 |
|
end; |
1663 |
|
end; |
1855 |
|
end; |
1856 |
|
end; |
1857 |
|
|
1858 |
+ |
function TryStrToNumeric(S: Ansistring; out Value: int64; out scale: integer): boolean; |
1859 |
+ |
var i: integer; |
1860 |
+ |
ds: integer; |
1861 |
+ |
exponent: integer; |
1862 |
+ |
begin |
1863 |
+ |
Result := false; |
1864 |
+ |
ds := 0; |
1865 |
+ |
exponent := 0; |
1866 |
+ |
S := Trim(S); |
1867 |
+ |
Value := 0; |
1868 |
+ |
scale := 0; |
1869 |
+ |
if Length(S) = 0 then |
1870 |
+ |
Exit; |
1871 |
+ |
{$IF declared(DefaultFormatSettings)} |
1872 |
+ |
with DefaultFormatSettings do |
1873 |
+ |
{$ELSE} |
1874 |
+ |
{$IF declared(FormatSettings)} |
1875 |
+ |
with FormatSettings do |
1876 |
+ |
{$IFEND} |
1877 |
+ |
{$IFEND} |
1878 |
+ |
begin |
1879 |
+ |
for i := length(S) downto 1 do |
1880 |
+ |
begin |
1881 |
+ |
if S[i] = AnsiChar(DecimalSeparator) then |
1882 |
+ |
begin |
1883 |
+ |
if ds <> 0 then Exit; {only one allowed} |
1884 |
+ |
ds := i; |
1885 |
+ |
dec(exponent); |
1886 |
+ |
system.Delete(S,i,1); |
1887 |
+ |
end |
1888 |
+ |
else |
1889 |
+ |
if S[i] in ['+','-'] then |
1890 |
+ |
begin |
1891 |
+ |
if (i > 1) and not (S[i-1] in ['e','E']) then |
1892 |
+ |
Exit; {malformed} |
1893 |
+ |
end |
1894 |
+ |
else |
1895 |
+ |
if S[i] in ['e','E'] then {scientific notation} |
1896 |
+ |
begin |
1897 |
+ |
if ds <> 0 then Exit; {not permitted in exponent} |
1898 |
+ |
if exponent <> 0 then Exit; {only one allowed} |
1899 |
+ |
exponent := i; |
1900 |
+ |
end |
1901 |
+ |
else |
1902 |
+ |
if not (S[i] in ['0'..'9']) then |
1903 |
+ |
{Note: ThousandSeparator not allowed by Delphi specs} |
1904 |
+ |
Exit; {bad character} |
1905 |
+ |
end; |
1906 |
+ |
|
1907 |
+ |
if exponent > 0 then |
1908 |
+ |
begin |
1909 |
+ |
Result := TryStrToInt(system.copy(S,exponent+1,maxint),Scale); |
1910 |
+ |
if Result then |
1911 |
+ |
begin |
1912 |
+ |
{adjust scale for decimal point} |
1913 |
+ |
if ds <> 0 then |
1914 |
+ |
Scale := Scale - (exponent - ds); |
1915 |
+ |
Result := TryStrToInt64(system.copy(S,1,exponent-1),Value); |
1916 |
+ |
end; |
1917 |
+ |
end |
1918 |
+ |
else |
1919 |
+ |
begin |
1920 |
+ |
if ds <> 0 then |
1921 |
+ |
scale := ds - Length(S) - 1; |
1922 |
+ |
Result := TryStrToInt64(S,Value); |
1923 |
+ |
end; |
1924 |
+ |
end; |
1925 |
+ |
end; |
1926 |
+ |
|
1927 |
+ |
function NumericToDouble(aValue: Int64; aScale: integer): double; |
1928 |
+ |
begin |
1929 |
+ |
Result := aValue * IntPower(10,aScale) |
1930 |
+ |
end; |
1931 |
+ |
|
1932 |
|
end. |