mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-02 20:30:29 +02:00
* Fixed ROLLBACK : all statements must be unprepared
git-svn-id: trunk@25250 -
This commit is contained in:
parent
abae19b553
commit
75362b0bb8
@ -15,19 +15,33 @@ uses
|
||||
{$EndIf}
|
||||
|
||||
type
|
||||
TPQCursor = Class;
|
||||
|
||||
{ TPQTrans }
|
||||
|
||||
TPQTrans = Class(TSQLHandle)
|
||||
protected
|
||||
protected
|
||||
PGConn : PPGConn;
|
||||
FList : TThreadList;
|
||||
Procedure RegisterCursor(S : TPQCursor);
|
||||
Procedure UnRegisterCursor(S : TPQCursor);
|
||||
Public
|
||||
Constructor Create;
|
||||
Destructor Destroy; override;
|
||||
end;
|
||||
|
||||
{ TPQCursor }
|
||||
|
||||
TPQCursor = Class(TSQLCursor)
|
||||
protected
|
||||
protected
|
||||
Statement : string;
|
||||
StmtName : string;
|
||||
tr : TPQTrans;
|
||||
res : PPGresult;
|
||||
CurTuple : integer;
|
||||
FieldBinding : array of integer;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
end;
|
||||
|
||||
EPQDatabaseError = class(EDatabaseError)
|
||||
@ -158,6 +172,53 @@ const Oid_Bool = 16;
|
||||
oid_numeric = 1700;
|
||||
Oid_uuid = 2950;
|
||||
|
||||
{ TPQTrans }
|
||||
|
||||
procedure TPQTrans.RegisterCursor(S: TPQCursor);
|
||||
begin
|
||||
FList.Add(S);
|
||||
S.tr:=Self;
|
||||
end;
|
||||
|
||||
procedure TPQTrans.UnRegisterCursor(S: TPQCursor);
|
||||
begin
|
||||
S.tr:=Nil;
|
||||
FList.Remove(S);
|
||||
end;
|
||||
|
||||
constructor TPQTrans.Create;
|
||||
begin
|
||||
Flist:=TThreadList.Create;
|
||||
FList.Duplicates:=dupIgnore;
|
||||
end;
|
||||
|
||||
destructor TPQTrans.Destroy;
|
||||
|
||||
Var
|
||||
L : TList;
|
||||
I : integer;
|
||||
|
||||
begin
|
||||
L:=Flist.LockList;
|
||||
try
|
||||
For I:=0 to L.Count-1 do
|
||||
TPQCursor(L[i]).tr:=Nil;
|
||||
finally
|
||||
Flist.UnlockList;
|
||||
end;
|
||||
FreeAndNil(FList);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TPQCursor }
|
||||
|
||||
destructor TPQCursor.Destroy;
|
||||
begin
|
||||
if Assigned(tr) then
|
||||
Tr.UnRegisterCursor(Self);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
|
||||
constructor TPQConnection.Create(AOwner : TComponent);
|
||||
|
||||
@ -171,6 +232,8 @@ end;
|
||||
|
||||
destructor TPQConnection.destroy;
|
||||
begin
|
||||
// We must disconnect here. If it is done in inherited, then connection pool is gone.
|
||||
Connected:=False;
|
||||
FreeAndNil(FConnectionPool);
|
||||
inherited destroy;
|
||||
end;
|
||||
@ -264,15 +327,24 @@ var
|
||||
res : PPGresult;
|
||||
tr : TPQTrans;
|
||||
i : Integer;
|
||||
L : TList;
|
||||
|
||||
begin
|
||||
result := false;
|
||||
|
||||
tr := trans as TPQTrans;
|
||||
|
||||
L:=tr.FList.LockList;
|
||||
try
|
||||
For I:=0 to L.Count-1 do
|
||||
begin
|
||||
UnprepareStatement(TPQCursor(L[i]));
|
||||
TPQCursor(L[i]).tr:=Nil;
|
||||
end;
|
||||
L.Clear;
|
||||
finally
|
||||
tr.flist.UnlockList;
|
||||
end;
|
||||
res := PQexec(tr.PGConn, 'ROLLBACK');
|
||||
|
||||
CheckResultError(res,tr.PGConn,SErrRollbackFailed);
|
||||
|
||||
PQclear(res);
|
||||
ReleaseConnection(tr.PGCOnn,false);
|
||||
result := true;
|
||||
@ -285,12 +357,9 @@ var
|
||||
i : Integer;
|
||||
begin
|
||||
result := false;
|
||||
|
||||
tr := trans as TPQTrans;
|
||||
|
||||
res := PQexec(tr.PGConn, 'COMMIT');
|
||||
CheckResultError(res,tr.PGConn,SErrCommitFailed);
|
||||
|
||||
PQclear(res);
|
||||
//make connection available in pool
|
||||
ReleaseConnection(tr.PGConn,false);
|
||||
@ -672,7 +741,8 @@ begin
|
||||
begin
|
||||
StmtName := 'prepst'+inttostr(FCursorCount);
|
||||
InterlockedIncrement(FCursorCount);
|
||||
tr := TPQTrans(aTransaction.Handle);
|
||||
TPQTrans(aTransaction.Handle).RegisterCursor(Cursor as TPQCursor);
|
||||
|
||||
// Only available for pq 8.0, so don't use it...
|
||||
// Res := pqprepare(tr,'prepst'+name+nr,pchar(buf),params.Count,pchar(''));
|
||||
s := 'prepare '+StmtName+' ';
|
||||
@ -801,7 +871,8 @@ begin
|
||||
end
|
||||
else
|
||||
begin
|
||||
tr := TPQTrans(aTransaction.Handle);
|
||||
// Registercursor sets tr
|
||||
TPQTrans(aTransaction.Handle).RegisterCursor(Cursor as TPQCursor);
|
||||
|
||||
if Assigned(AParams) and (AParams.Count > 0) then
|
||||
begin
|
||||
|
Loading…
Reference in New Issue
Block a user