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