27 |
|
|
28 |
|
{$mode objfpc}{$H+} |
29 |
|
|
30 |
– |
{$IF FPC_FULLVERSION >= 20700 } |
30 |
|
{$codepage UTF8} |
32 |
– |
{$ENDIF} |
31 |
|
|
32 |
|
interface |
33 |
|
|
34 |
< |
uses Classes, IBDatabase, IBSQL, IBHeader; |
34 |
> |
uses Classes, IBDatabase, IBSQL, IB; |
35 |
|
|
36 |
|
type |
37 |
|
TSQLSymbol = (sqNone,sqSpace,sqSemiColon,sqSingleQuotes,sqDoubleQuotes, |
38 |
|
sqEnd,sqBegin,sqCommit,sqRollback,sqString,sqCommentStart, |
39 |
|
sqCommentEnd,sqCommentLine,sqAsterisk,sqForwardSlash, |
40 |
< |
sqDeclare,sqEOL,sqTerminator, sqReconnect); |
40 |
> |
sqDeclare,sqEOL,sqTerminator, sqReconnect,sqCase); |
41 |
|
|
42 |
< |
TSQLStates = (stInit, stError, stInSQL, stNested,stInSingleQuotes, |
42 |
> |
TSQLStates = (stInit, stError, stInSQL, stNested, stInSingleQuotes, |
43 |
|
stInDoubleQuotes, stInComment, stInCommentLine, |
44 |
|
stInDeclaration, stInCommit, stInReconnect); |
45 |
|
|
122 |
|
FLastChar: char; |
123 |
|
FSQLText: string; |
124 |
|
FHasBegin: boolean; |
125 |
+ |
FInCase: boolean; |
126 |
|
FStack: array [0..16] of TSQLStates; |
127 |
|
FStackindex: integer; |
128 |
|
FGetParamValue: TGetParamValue; |
140 |
|
function GetSymbol(const Line: string; var index: integer): TSQLSymbol; |
141 |
|
function GetTransaction: TIBTransaction; |
142 |
|
procedure SetDatabase(AValue: TIBDatabase); |
143 |
< |
procedure SetParamValue(SQLVar: TIBXSQLVAR); |
143 |
> |
procedure SetParamValue(SQLVar: ISQLParam); |
144 |
|
procedure SetState(AState: TSQLStates); |
145 |
|
procedure ClearStatement; |
146 |
|
function PopState: TSQLStates; |
165 |
|
|
166 |
|
implementation |
167 |
|
|
168 |
< |
uses Sysutils, IB, RegExpr; |
168 |
> |
uses Sysutils, RegExpr; |
169 |
|
|
170 |
|
resourcestring |
171 |
|
sTerminatorUnknownState = 'Statement Terminator in unexpected state (%d)'; |
323 |
|
begin |
324 |
|
if FNested = 0 then |
325 |
|
begin |
326 |
< |
PopState; |
327 |
< |
FState := stInit; |
328 |
< |
ExecSQL |
326 |
> |
FState := PopState; |
327 |
> |
if not FInCase then |
328 |
> |
begin |
329 |
> |
FState := stInit; |
330 |
> |
ExecSQL |
331 |
> |
end |
332 |
> |
else |
333 |
> |
FInCase := false; |
334 |
|
end |
335 |
|
else |
336 |
|
Dec(FNested) |
357 |
|
end |
358 |
|
end; |
359 |
|
|
360 |
+ |
sqCase: |
361 |
+ |
if not (FState in [stInComment,stInCommentLine]) then |
362 |
+ |
begin |
363 |
+ |
AddToSQL(FString); |
364 |
+ |
case FState of |
365 |
+ |
stInSingleQuotes, |
366 |
+ |
stInDoubleQuotes: |
367 |
+ |
{Ignore}; |
368 |
+ |
stNested: |
369 |
+ |
Inc(FNested); |
370 |
+ |
|
371 |
+ |
stInSQL, |
372 |
+ |
stInit: |
373 |
+ |
begin |
374 |
+ |
FInCase := true; |
375 |
+ |
SetState(stNested); |
376 |
+ |
end; |
377 |
+ |
end |
378 |
+ |
end; |
379 |
+ |
|
380 |
|
sqDeclare: |
381 |
|
if not (FState in [stInComment,stInCommentLine]) then |
382 |
|
begin |
391 |
|
if FState = stInit then |
392 |
|
FState := stInCommit |
393 |
|
else |
394 |
< |
raise Exception.Create(sNoCommit) |
394 |
> |
AddToSQL(FString); |
395 |
|
end; |
396 |
|
|
397 |
|
sqReconnect: |
520 |
|
if not InTransaction then StartTransaction; |
521 |
|
FISQL.ParamCheck := not FHasBegin; {Probably PSQL} |
522 |
|
FISQL.Prepare; |
523 |
< |
if FISQL.SQLType in [SQLInsert, SQLUpdate, SQLDelete] then |
523 |
> |
if FISQL.SQLStatementType in [SQLInsert, SQLUpdate, SQLDelete] then |
524 |
|
begin |
525 |
|
{Interpret parameters} |
526 |
|
for I := 0 to FISQL.Params.Count - 1 do |
527 |
|
SetParamValue(FISQL.Params[I]); |
528 |
|
end; |
529 |
|
|
530 |
< |
if FISQL.SQLType = SQLSelect then |
530 |
> |
if FISQL.SQLStatementType = SQLSelect then |
531 |
|
begin |
532 |
|
if assigned(OnSelectSQL) then |
533 |
|
OnSelectSQL(self,FSQLText) |
536 |
|
end |
537 |
|
else |
538 |
|
begin |
539 |
< |
DDL := FISQL.SQLType = SQLDDL; |
539 |
> |
DDL := FISQL.SQLStatementType = SQLDDL; |
540 |
|
if not DDL or not FIgnoreGrants or (Pos('GRANT',AnsiUpperCase(Trim(FSQLText))) <> 1) then |
541 |
|
FISQL.ExecQuery; |
542 |
|
if FAutoDDL and DDL then |
653 |
|
Result := sqCommit |
654 |
|
else |
655 |
|
if CompareText(FString,'reconnect') = 0 then |
656 |
< |
Result := sqReconnect; |
656 |
> |
Result := sqReconnect |
657 |
> |
else |
658 |
> |
if CompareText(FString,'case') = 0 then |
659 |
> |
Result := sqCase; |
660 |
|
end |
661 |
|
end; |
662 |
|
|
764 |
|
end; |
765 |
|
|
766 |
|
|
767 |
< |
procedure TIBXScript.SetParamValue(SQLVar: TIBXSQLVAR); |
767 |
> |
procedure TIBXScript.SetParamValue(SQLVar: ISQLParam); |
768 |
|
var BlobID: TISC_QUAD; |
769 |
|
begin |
770 |
|
if assigned(FGetParamValue) and (SQLVar.SQLType = SQL_BLOB) then |