mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 11:26:33 +02:00
* postgres part of sqldb returning support, fixes Mantis #20133
Patch by Lacak2 git-svn-id: trunk@19008 -
This commit is contained in:
parent
3401a3be83
commit
b1c0d35dbe
@ -24,10 +24,10 @@ type
|
|||||||
TPQCursor = Class(TSQLCursor)
|
TPQCursor = Class(TSQLCursor)
|
||||||
protected
|
protected
|
||||||
Statement : string;
|
Statement : string;
|
||||||
|
StmtName : string;
|
||||||
tr : TPQTrans;
|
tr : TPQTrans;
|
||||||
res : PPGresult;
|
res : PPGresult;
|
||||||
CurTuple : integer;
|
CurTuple : integer;
|
||||||
Nr : string;
|
|
||||||
FieldBinding : array of integer;
|
FieldBinding : array of integer;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -516,16 +516,16 @@ begin
|
|||||||
with (cursor as TPQCursor) do
|
with (cursor as TPQCursor) do
|
||||||
begin
|
begin
|
||||||
FPrepared := False;
|
FPrepared := False;
|
||||||
nr := inttostr(FCursorcount);
|
|
||||||
inc(FCursorCount);
|
|
||||||
// Prior to v8 there is no support for cursors and parameters.
|
// Prior to v8 there is no support for cursors and parameters.
|
||||||
// So that's not supported.
|
// So that's not supported.
|
||||||
if FStatementType in [stInsert,stUpdate,stDelete, stSelect] then
|
if FStatementType in [stInsert,stUpdate,stDelete, stSelect] then
|
||||||
begin
|
begin
|
||||||
|
StmtName := 'prepst'+inttostr(FCursorCount);
|
||||||
|
inc(FCursorCount);
|
||||||
tr := TPQTrans(aTransaction.Handle);
|
tr := TPQTrans(aTransaction.Handle);
|
||||||
// Only available for pq 8.0, so don't use it...
|
// Only available for pq 8.0, so don't use it...
|
||||||
// Res := pqprepare(tr,'prepst'+name+nr,pchar(buf),params.Count,pchar(''));
|
// Res := pqprepare(tr,'prepst'+name+nr,pchar(buf),params.Count,pchar(''));
|
||||||
s := 'prepare prepst'+nr+' ';
|
s := 'prepare '+StmtName+' ';
|
||||||
if Assigned(AParams) and (AParams.count > 0) then
|
if Assigned(AParams) and (AParams.count > 0) then
|
||||||
begin
|
begin
|
||||||
s := s + '(';
|
s := s + '(';
|
||||||
@ -548,6 +548,15 @@ begin
|
|||||||
pqclear(res);
|
pqclear(res);
|
||||||
DatabaseError(SErrPrepareFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.PGConn) + ')',self)
|
DatabaseError(SErrPrepareFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.PGConn) + ')',self)
|
||||||
end;
|
end;
|
||||||
|
// if statement is INSERT, UPDATE, DELETE with RETURNING clause, then
|
||||||
|
// override the statement type derrived by parsing the query.
|
||||||
|
if (FStatementType in [stInsert,stUpdate,stDelete]) and (pos('RETURNING', upcase(s)) > 0) then
|
||||||
|
begin
|
||||||
|
PQclear(res);
|
||||||
|
res := PQdescribePrepared(tr.PGConn,pchar(StmtName));
|
||||||
|
if (PQresultStatus(res) = PGRES_COMMAND_OK) and (PQnfields(res) > 0) then
|
||||||
|
FStatementType := stSelect;
|
||||||
|
end;
|
||||||
FPrepared := True;
|
FPrepared := True;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -563,7 +572,7 @@ begin
|
|||||||
if not tr.ErrorOccured then
|
if not tr.ErrorOccured then
|
||||||
begin
|
begin
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
res := pqexec(tr.PGConn,pchar('deallocate prepst'+nr));
|
res := pqexec(tr.PGConn,pchar('deallocate '+StmtName));
|
||||||
if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
|
if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
|
||||||
begin
|
begin
|
||||||
pqclear(res);
|
pqclear(res);
|
||||||
@ -630,12 +639,12 @@ begin
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
FreeAndNil(ar[i]);
|
FreeAndNil(ar[i]);
|
||||||
res := PQexecPrepared(tr.PGConn,pchar('prepst'+nr),Aparams.count,@Ar[0],@Lengths[0],@Formats[0],1);
|
res := PQexecPrepared(tr.PGConn,pchar(StmtName),Aparams.count,@Ar[0],@Lengths[0],@Formats[0],1);
|
||||||
for i := 0 to AParams.count -1 do
|
for i := 0 to AParams.count -1 do
|
||||||
FreeMem(ar[i]);
|
FreeMem(ar[i]);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
res := PQexecPrepared(tr.PGConn,pchar('prepst'+nr),0,nil,nil,nil,1);
|
res := PQexecPrepared(tr.PGConn,pchar(StmtName),0,nil,nil,nil,1);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
|
@ -1171,15 +1171,15 @@ end;
|
|||||||
|
|
||||||
procedure TTestFieldTypes.TestInsertReturningQuery;
|
procedure TTestFieldTypes.TestInsertReturningQuery;
|
||||||
begin
|
begin
|
||||||
if (SQLDbType <> interbase) then Ignore('This test does only apply to Firebird.');
|
if not(SQLDbType in [postgresql,interbase,oracle]) then Ignore('This test does not apply to this db-engine');
|
||||||
with TSQLDBConnector(DBConnector) do
|
with TSQLDBConnector(DBConnector) do
|
||||||
begin
|
begin
|
||||||
// This only works with databases that supports 'insert into .. returning'
|
// This only works with databases that supports 'insert into .. returning'
|
||||||
// for example, Firebird version 2.0 and up
|
// for example: PostgreSQL, Oracle, Firebird version 2.0 and up
|
||||||
CreateTableWithFieldType(ftInteger,'int');
|
CreateTableWithFieldType(ftInteger,'int');
|
||||||
Query.SQL.Text:='insert into FPDEV2 values(154) returning FT';
|
Query.SQL.Text:='insert into FPDEV2 values(154) returning FT';
|
||||||
Query.Open;
|
Query.Open;
|
||||||
AssertEquals('FT',Query.fields[0].FieldName);
|
AssertTrue(CompareText('FT',Query.Fields[0].FieldName)=0);
|
||||||
AssertEquals(154,Query.fields[0].AsInteger);
|
AssertEquals(154,Query.fields[0].AsInteger);
|
||||||
Query.Close;
|
Query.Close;
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user