mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 11:59:19 +02:00
* Allow parameter-names between double-quotes
* Place parameter-names between double-quotes in TBufDataset.ApplyUpdates +tests (bug 12275) git-svn-id: trunk@12284 -
This commit is contained in:
parent
e9976b6ced
commit
a7086e7164
@ -1,4 +1,27 @@
|
|||||||
|
|
||||||
|
procedure SkipQuotesString(var p : pchar; QuoteChar : char; EscapeSlash, EscapeRepeat : Boolean);
|
||||||
|
var notRepeatEscaped : boolean;
|
||||||
|
begin
|
||||||
|
Inc(p);
|
||||||
|
repeat
|
||||||
|
notRepeatEscaped := True;
|
||||||
|
while not (p^ in [#0, QuoteChar]) do
|
||||||
|
begin
|
||||||
|
if EscapeSlash and (p^='\') and (p[1] <> #0) then Inc(p,2) // make sure we handle \' and \\ correct
|
||||||
|
else Inc(p);
|
||||||
|
end;
|
||||||
|
if p^=QuoteChar then
|
||||||
|
begin
|
||||||
|
Inc(p); // skip final '
|
||||||
|
if (p^=QuoteChar) and EscapeRepeat then // Handle escaping by ''
|
||||||
|
begin
|
||||||
|
notRepeatEscaped := False;
|
||||||
|
inc(p);
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
until notRepeatEscaped;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TParams }
|
{ TParams }
|
||||||
|
|
||||||
Function TParams.GetItem(Index: Integer): TParam;
|
Function TParams.GetItem(Index: Integer): TParam;
|
||||||
@ -177,36 +200,20 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function SkipComments(var p: PChar; EscapeSlash, EscapeRepeat : Boolean) : Boolean;
|
function SkipComments(var p: PChar; EscapeSlash, EscapeRepeat : Boolean) : Boolean;
|
||||||
var notRepeatEscaped : boolean;
|
|
||||||
|
|
||||||
procedure SkipQuotesString(QuoteChar : char);
|
|
||||||
begin
|
|
||||||
Inc(p);
|
|
||||||
Result := True;
|
|
||||||
repeat
|
|
||||||
notRepeatEscaped := True;
|
|
||||||
while not (p^ in [#0, QuoteChar]) do
|
|
||||||
begin
|
|
||||||
if EscapeSlash and (p^='\') and (p[1] <> #0) then Inc(p,2) // make sure we handle \' and \\ correct
|
|
||||||
else Inc(p);
|
|
||||||
end;
|
|
||||||
if p^=QuoteChar then
|
|
||||||
begin
|
|
||||||
Inc(p); // skip final '
|
|
||||||
if (p^=QuoteChar) and EscapeRepeat then // Handle escaping by ''
|
|
||||||
begin
|
|
||||||
notRepeatEscaped := False;
|
|
||||||
inc(p);
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
until notRepeatEscaped;
|
|
||||||
end;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
result := false;
|
result := false;
|
||||||
case p^ of
|
case p^ of
|
||||||
'''': SkipQuotesString(''''); // single quote delimited string
|
'''':
|
||||||
'"': SkipQuotesString('"'); // double quote delimited string
|
begin
|
||||||
|
SkipQuotesString(p,'''',EscapeSlash,EscapeRepeat); // single quote delimited string
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
'"':
|
||||||
|
begin
|
||||||
|
SkipQuotesString(p,'"',EscapeSlash,EscapeRepeat); // double quote delimited string
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
'-': // possible start of -- comment
|
'-': // possible start of -- comment
|
||||||
begin
|
begin
|
||||||
Inc(p);
|
Inc(p);
|
||||||
@ -295,10 +302,21 @@ begin
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
ParamNameStart:=p;
|
if p^='"' then // Check if the parameter-name is between quotes
|
||||||
while not (p^ in (SQLDelimiterCharacters+[#0,'=','+','-','*','\','/','[',']','|'])) do
|
begin
|
||||||
Inc(p);
|
ParamNameStart:=p;
|
||||||
ParamName:=Copy(ParamNameStart,1,p-ParamNameStart);
|
SkipQuotesString(p,'"',EscapeSlash,EscapeRepeat);
|
||||||
|
// Do not include the quotes in ParamName, but they must be included
|
||||||
|
// when the parameter is replaced by some place-holder.
|
||||||
|
ParamName:=Copy(ParamNameStart+1,1,p-ParamNameStart-2);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
ParamNameStart:=p;
|
||||||
|
while not (p^ in (SQLDelimiterCharacters+[#0,'=','+','-','*','\','/','[',']','|'])) do
|
||||||
|
Inc(p);
|
||||||
|
ParamName:=Copy(ParamNameStart,1,p-ParamNameStart);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -1366,7 +1366,7 @@ var FieldNamesQuoteChar : char;
|
|||||||
if (pfInKey in Fields[x].ProviderFlags) or
|
if (pfInKey in Fields[x].ProviderFlags) or
|
||||||
((FUpdateMode = upWhereAll) and (pfInWhere in Fields[x].ProviderFlags)) or
|
((FUpdateMode = upWhereAll) and (pfInWhere in Fields[x].ProviderFlags)) or
|
||||||
((FUpdateMode = UpWhereChanged) and (pfInWhere in Fields[x].ProviderFlags) and (fields[x].value <> fields[x].oldvalue)) then
|
((FUpdateMode = UpWhereChanged) and (pfInWhere in Fields[x].ProviderFlags) and (fields[x].value <> fields[x].oldvalue)) then
|
||||||
sql_where := sql_where + '(' + FieldNamesQuoteChar + fields[x].FieldName + FieldNamesQuoteChar + '= :OLD_' + fields[x].FieldName + ') and ';
|
sql_where := sql_where + '(' + FieldNamesQuoteChar + fields[x].FieldName + FieldNamesQuoteChar + '= :' + FieldNamesQuoteChar + 'OLD_' + fields[x].FieldName + FieldNamesQuoteChar +') and ';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ModifyRecQuery : string;
|
function ModifyRecQuery : string;
|
||||||
@ -1383,7 +1383,7 @@ var FieldNamesQuoteChar : char;
|
|||||||
UpdateWherePart(sql_where,x);
|
UpdateWherePart(sql_where,x);
|
||||||
|
|
||||||
if (pfInUpdate in Fields[x].ProviderFlags) then
|
if (pfInUpdate in Fields[x].ProviderFlags) then
|
||||||
sql_set := sql_set +FieldNamesQuoteChar + fields[x].FieldName + FieldNamesQuoteChar +'=:' + fields[x].FieldName + ',';
|
sql_set := sql_set +FieldNamesQuoteChar + fields[x].FieldName + FieldNamesQuoteChar +'=:' + FieldNamesQuoteChar + fields[x].FieldName + FieldNamesQuoteChar + ',';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if length(sql_set) = 0 then DatabaseErrorFmt(sNoUpdateFields,['update'],self);
|
if length(sql_set) = 0 then DatabaseErrorFmt(sNoUpdateFields,['update'],self);
|
||||||
@ -1408,7 +1408,7 @@ var FieldNamesQuoteChar : char;
|
|||||||
if (not fields[x].IsNull) and (pfInUpdate in Fields[x].ProviderFlags) then
|
if (not fields[x].IsNull) and (pfInUpdate in Fields[x].ProviderFlags) then
|
||||||
begin
|
begin
|
||||||
sql_fields := sql_fields + FieldNamesQuoteChar + fields[x].FieldName + FieldNamesQuoteChar + ',';
|
sql_fields := sql_fields + FieldNamesQuoteChar + fields[x].FieldName + FieldNamesQuoteChar + ',';
|
||||||
sql_values := sql_values + ':' + fields[x].FieldName + ',';
|
sql_values := sql_values + ':' + FieldNamesQuoteChar + fields[x].FieldName + FieldNamesQuoteChar +',';
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if length(sql_fields) = 0 then DatabaseErrorFmt(sNoUpdateFields,['insert'],self);
|
if length(sql_fields) = 0 then DatabaseErrorFmt(sNoUpdateFields,['insert'],self);
|
||||||
|
@ -37,6 +37,7 @@ var Params : TParams;
|
|||||||
pb : TParamBinding;
|
pb : TParamBinding;
|
||||||
begin
|
begin
|
||||||
Params := TParams.Create;
|
Params := TParams.Create;
|
||||||
|
|
||||||
AssertEquals( 'select * from table where id = $1',
|
AssertEquals( 'select * from table where id = $1',
|
||||||
params.ParseSQL('select * from table where id = :id',true,True,True,psPostgreSQL));
|
params.ParseSQL('select * from table where id = :id',true,True,True,psPostgreSQL));
|
||||||
|
|
||||||
@ -95,6 +96,14 @@ begin
|
|||||||
AssertEquals( 'select * from table where "id = :id\',
|
AssertEquals( 'select * from table where "id = :id\',
|
||||||
params.ParseSQL('select * from table where "id = :id\',true,True,True,psInterbase));
|
params.ParseSQL('select * from table where "id = :id\',true,True,True,psInterbase));
|
||||||
|
|
||||||
|
// Test strange-field names
|
||||||
|
AssertEquals( 'select * from table where "field-name" = ?',
|
||||||
|
params.ParseSQL('select * from table where "field-name" = :"field-name"',true,True,True,psInterbase));
|
||||||
|
AssertEquals('field-name',Params.Items[0].Name);
|
||||||
|
|
||||||
|
AssertEquals( 'select * from table where "field-name" = ?',
|
||||||
|
params.ParseSQL('select * from table where "field-name" = :"field-name',true,True,True,psInterbase));
|
||||||
|
|
||||||
Params.Free;
|
Params.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ type
|
|||||||
procedure TestParseUnion; // bug 8442
|
procedure TestParseUnion; // bug 8442
|
||||||
procedure TestInsertLargeStrFields; // bug 9600
|
procedure TestInsertLargeStrFields; // bug 9600
|
||||||
procedure TestNumericNames; // Bug9661
|
procedure TestNumericNames; // Bug9661
|
||||||
|
procedure TestApplyUpdFieldnames; // Bug 12275;
|
||||||
procedure Test11Params;
|
procedure Test11Params;
|
||||||
procedure TestRowsAffected; // bug 9758
|
procedure TestRowsAffected; // bug 9758
|
||||||
procedure TestStringsReplace;
|
procedure TestStringsReplace;
|
||||||
@ -1132,6 +1133,35 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestFieldTypes.TestApplyUpdFieldnames;
|
||||||
|
begin
|
||||||
|
with TSQLDBConnector(DBConnector) do
|
||||||
|
begin
|
||||||
|
AssertEquals(-1,query.RowsAffected);
|
||||||
|
Connection.ExecuteDirect('create table FPDEV2 ( ' +
|
||||||
|
' ID INT NOT NULL , ' +
|
||||||
|
' "NAME-TEST" VARCHAR(250), ' +
|
||||||
|
' PRIMARY KEY (ID) ' +
|
||||||
|
') ');
|
||||||
|
// Firebird/Interbase need a commit after a DDL statement. Not necessary for the other connections
|
||||||
|
TSQLDBConnector(DBConnector).Transaction.CommitRetaining;
|
||||||
|
Connection.ExecuteDirect('insert into FPDEV2(ID,"NAME-TEST") values (1,''test1'')');
|
||||||
|
Query.SQL.Text := 'select * from fpdev2';
|
||||||
|
Query.Open;
|
||||||
|
AssertEquals(1,Query.FieldByName('ID').AsInteger);
|
||||||
|
AssertEquals('test1',Query.FieldByName('NAME-TEST').AsString);
|
||||||
|
Query.Edit;
|
||||||
|
Query.FieldByName('NAME-TEST').AsString:='Edited';
|
||||||
|
Query.Post;
|
||||||
|
Query.ApplyUpdates;
|
||||||
|
Query.Close;
|
||||||
|
Query.Open;
|
||||||
|
AssertEquals(1,Query.FieldByName('ID').AsInteger);
|
||||||
|
AssertEquals('Edited',Query.FieldByName('NAME-TEST').AsString);
|
||||||
|
Query.Close;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestFieldTypes.TestRowsAffected;
|
procedure TTestFieldTypes.TestRowsAffected;
|
||||||
begin
|
begin
|
||||||
with TSQLDBConnector(DBConnector) do
|
with TSQLDBConnector(DBConnector) do
|
||||||
|
Loading…
Reference in New Issue
Block a user