+ Fix for the postgresql transaction becoming invalid

git-svn-id: trunk@3833 -
This commit is contained in:
joost 2006-06-09 20:59:06 +00:00
parent 01edb71190
commit 22982a127d

View File

@ -17,13 +17,14 @@ uses
type
TPQTrans = Class(TSQLHandle)
protected
TransactionHandle : PPGConn;
PGConn : PPGConn;
ErrorOccured : boolean;
end;
TPQCursor = Class(TSQLCursor)
protected
Statement : string;
tr : Pointer;
tr : TPQTrans;
res : PPGresult;
CurTuple : integer;
Nr : string;
@ -112,7 +113,7 @@ end;
function TPQConnection.GetTransactionHandle(trans : TSQLHandle): pointer;
begin
Result := (trans as TPQtrans).TransactionHandle;
Result := trans;
end;
function TPQConnection.RollBack(trans : TSQLHandle) : boolean;
@ -124,17 +125,17 @@ begin
tr := trans as TPQTrans;
res := PQexec(tr.TransactionHandle, 'ROLLBACK');
res := PQexec(tr.PGConn, 'ROLLBACK');
if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
begin
PQclear(res);
result := false;
DatabaseError(SErrRollbackFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.transactionhandle) + ')',self);
DatabaseError(SErrRollbackFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.PGConn) + ')',self);
end
else
begin
PQclear(res);
PQFinish(tr.TransactionHandle);
PQFinish(tr.PGConn);
result := true;
end;
end;
@ -148,17 +149,17 @@ begin
tr := trans as TPQTrans;
res := PQexec(tr.TransactionHandle, 'COMMIT');
res := PQexec(tr.PGConn, 'COMMIT');
if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
begin
PQclear(res);
result := false;
DatabaseError(SErrCommitFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.transactionhandle) + ')',self);
DatabaseError(SErrCommitFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.PGConn) + ')',self);
end
else
begin
PQclear(res);
PQFinish(tr.TransactionHandle);
PQFinish(tr.PGConn);
result := true;
end;
end;
@ -173,23 +174,24 @@ begin
tr := trans as TPQTrans;
tr.TransactionHandle := PQconnectdb(pchar(FConnectString));
tr.PGConn := PQconnectdb(pchar(FConnectString));
if (PQstatus(tr.TransactionHandle) = CONNECTION_BAD) then
if (PQstatus(tr.PGConn) = CONNECTION_BAD) then
begin
result := false;
PQFinish(tr.TransactionHandle);
DatabaseError(SErrConnectionFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.transactionhandle) + ')',self);
PQFinish(tr.PGConn);
DatabaseError(SErrConnectionFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.PGConn) + ')',self);
end
else
begin
res := PQexec(tr.TransactionHandle, 'BEGIN');
tr.ErrorOccured := False;
res := PQexec(tr.PGConn, 'BEGIN');
if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
begin
result := false;
PQclear(res);
msg := PQerrorMessage(tr.transactionhandle);
PQFinish(tr.TransactionHandle);
msg := PQerrorMessage(tr.PGConn);
PQFinish(tr.PGConn);
DatabaseError(sErrTransactionFailed + ' (PostgreSQL: ' + msg + ')',self);
end
else
@ -207,21 +209,21 @@ var
msg : string;
begin
tr := trans as TPQTrans;
res := PQexec(tr.TransactionHandle, 'ROLLBACK');
res := PQexec(tr.PGConn, 'ROLLBACK');
if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
begin
PQclear(res);
DatabaseError(SErrRollbackFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.transactionhandle) + ')',self);
DatabaseError(SErrRollbackFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.PGConn) + ')',self);
end
else
begin
PQclear(res);
res := PQexec(tr.TransactionHandle, 'BEGIN');
res := PQexec(tr.PGConn, 'BEGIN');
if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
begin
PQclear(res);
msg := PQerrorMessage(tr.transactionhandle);
PQFinish(tr.TransactionHandle);
msg := PQerrorMessage(tr.PGConn);
PQFinish(tr.PGConn);
DatabaseError(sErrTransactionFailed + ' (PostgreSQL: ' + msg + ')',self);
end
else
@ -236,21 +238,21 @@ var
msg : string;
begin
tr := trans as TPQTrans;
res := PQexec(tr.TransactionHandle, 'COMMIT');
res := PQexec(tr.PGConn, 'COMMIT');
if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
begin
PQclear(res);
DatabaseError(SErrCommitFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.transactionhandle) + ')',self);
DatabaseError(SErrCommitFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.PGConn) + ')',self);
end
else
begin
PQclear(res);
res := PQexec(tr.TransactionHandle, 'BEGIN');
res := PQexec(tr.PGConn, 'BEGIN');
if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
begin
PQclear(res);
msg := PQerrorMessage(tr.transactionhandle);
PQFinish(tr.TransactionHandle);
msg := PQerrorMessage(tr.PGConn);
PQFinish(tr.PGConn);
DatabaseError(sErrTransactionFailed + ' (PostgreSQL: ' + msg + ')',self);
end
else
@ -396,7 +398,7 @@ begin
// So that's not supported.
if FStatementType in [stInsert,stUpdate,stDelete, stSelect] then
begin
tr := aTransaction.Handle;
tr := TPQTrans(aTransaction.Handle);
// Only available for pq 8.0, so don't use it...
// Res := pqprepare(tr,'prepst'+name+nr,pchar(buf),params.Count,pchar(''));
s := 'prepare prepst'+nr+' ';
@ -414,11 +416,11 @@ begin
buf := AParams.ParseSQL(buf,false,psPostgreSQL);
end;
s := s + ' as ' + buf;
res := pqexec(tr,pchar(s));
res := pqexec(tr.PGConn,pchar(s));
if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
begin
pqclear(res);
DatabaseError(SErrPrepareFailed + ' (PostgreSQL: ' + PQerrorMessage(tr) + ')',self)
DatabaseError(SErrPrepareFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.PGConn) + ')',self)
end;
FPrepared := True;
end
@ -432,13 +434,16 @@ procedure TPQConnection.UnPrepareStatement(cursor : TSQLCursor);
begin
with (cursor as TPQCursor) do if FPrepared then
begin
res := pqexec(tr,pchar('deallocate prepst'+nr));
if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
if not tr.ErrorOccured then
begin
res := pqexec(tr.PGConn,pchar('deallocate prepst'+nr));
if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
begin
pqclear(res);
DatabaseError(SErrPrepareFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.PGConn) + ')',self)
end;
pqclear(res);
DatabaseError(SErrPrepareFailed + ' (PostgreSQL: ' + PQerrorMessage(tr) + ')',self)
end;
pqclear(res);
FPrepared := False;
end;
end;
@ -475,27 +480,31 @@ begin
end
else
FreeAndNil(ar[i]);
res := PQexecPrepared(tr,pchar('prepst'+nr),Aparams.count,@Ar[0],nil,nil,0);
res := PQexecPrepared(tr.PGConn,pchar('prepst'+nr),Aparams.count,@Ar[0],nil,nil,0);
for i := 0 to AParams.count -1 do
FreeMem(ar[i]);
end
else
res := PQexecPrepared(tr,pchar('prepst'+nr),0,nil,nil,nil,1);
res := PQexecPrepared(tr.PGConn,pchar('prepst'+nr),0,nil,nil,nil,1);
end
else
begin
tr := aTransaction.Handle;
tr := TPQTrans(aTransaction.Handle);
s := statement;
//Should be altered, just like in TSQLQuery.ApplyRecUpdate
if assigned(AParams) then for i := 0 to AParams.count-1 do
s := stringreplace(s,':'+AParams[i].Name,AParams[i].asstring,[rfReplaceAll,rfIgnoreCase]);
res := pqexec(tr,pchar(s));
res := pqexec(tr.PGConn,pchar(s));
end;
if not (PQresultStatus(res) in [PGRES_COMMAND_OK,PGRES_TUPLES_OK]) then
begin
s := PQerrorMessage(tr.PGConn);
pqclear(res);
DatabaseError(SErrExecuteFailed + ' (PostgreSQL: ' + PQerrorMessage(tr) + ')',self);
tr.ErrorOccured := True;
atransaction.Rollback;
DatabaseError(SErrExecuteFailed + ' (PostgreSQL: ' + s + ')',self);
end;
end;
end;