mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-10 06:05:57 +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 }
|
||||
|
||||
Function TParams.GetItem(Index: Integer): TParam;
|
||||
@ -177,36 +200,20 @@ begin
|
||||
end;
|
||||
|
||||
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
|
||||
result := false;
|
||||
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
|
||||
begin
|
||||
Inc(p);
|
||||
@ -295,10 +302,21 @@ begin
|
||||
end
|
||||
else
|
||||
begin
|
||||
ParamNameStart:=p;
|
||||
while not (p^ in (SQLDelimiterCharacters+[#0,'=','+','-','*','\','/','[',']','|'])) do
|
||||
Inc(p);
|
||||
ParamName:=Copy(ParamNameStart,1,p-ParamNameStart);
|
||||
if p^='"' then // Check if the parameter-name is between quotes
|
||||
begin
|
||||
ParamNameStart:=p;
|
||||
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
|
||||
else
|
||||
|
@ -1366,7 +1366,7 @@ var FieldNamesQuoteChar : char;
|
||||
if (pfInKey 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
|
||||
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;
|
||||
|
||||
function ModifyRecQuery : string;
|
||||
@ -1383,7 +1383,7 @@ var FieldNamesQuoteChar : char;
|
||||
UpdateWherePart(sql_where,x);
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
begin
|
||||
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;
|
||||
if length(sql_fields) = 0 then DatabaseErrorFmt(sNoUpdateFields,['insert'],self);
|
||||
|
@ -37,6 +37,7 @@ var Params : TParams;
|
||||
pb : TParamBinding;
|
||||
begin
|
||||
Params := TParams.Create;
|
||||
|
||||
AssertEquals( 'select * from table where id = $1',
|
||||
params.ParseSQL('select * from table where id = :id',true,True,True,psPostgreSQL));
|
||||
|
||||
@ -95,6 +96,14 @@ begin
|
||||
AssertEquals( 'select * from table where "id = :id\',
|
||||
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;
|
||||
end;
|
||||
|
||||
|
@ -34,6 +34,7 @@ type
|
||||
procedure TestParseUnion; // bug 8442
|
||||
procedure TestInsertLargeStrFields; // bug 9600
|
||||
procedure TestNumericNames; // Bug9661
|
||||
procedure TestApplyUpdFieldnames; // Bug 12275;
|
||||
procedure Test11Params;
|
||||
procedure TestRowsAffected; // bug 9758
|
||||
procedure TestStringsReplace;
|
||||
@ -1132,6 +1133,35 @@ begin
|
||||
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;
|
||||
begin
|
||||
with TSQLDBConnector(DBConnector) do
|
||||
|
Loading…
Reference in New Issue
Block a user