* Reworked pool to a thread list

git-svn-id: trunk@25249 -
This commit is contained in:
michael 2013-08-12 07:48:08 +00:00
parent ae19359a7c
commit abae19b553

View File

@ -50,12 +50,11 @@ type
TPQConnection = class (TSQLConnection) TPQConnection = class (TSQLConnection)
private private
FConnectionPool : array of TPQTranConnection; FConnectionPool : TThreadList;
FCursorCount : dword; FCursorCount : dword;
FConnectString : string; FConnectString : string;
FIntegerDateTimes : boolean; FIntegerDateTimes : boolean;
FVerboseErrors : Boolean; FVerboseErrors : Boolean;
FPool : TRTLCriticalSection;
procedure CheckConnectionStatus(var conn: PPGconn); procedure CheckConnectionStatus(var conn: PPGconn);
procedure CheckResultError(var res: PPGresult; conn:PPGconn; ErrMsg: string); procedure CheckResultError(var res: PPGresult; conn:PPGconn; ErrMsg: string);
function TranslateFldType(res : PPGresult; Tuple : integer; out Size : integer) : TFieldType; function TranslateFldType(res : PPGresult; Tuple : integer; out Size : integer) : TFieldType;
@ -167,12 +166,12 @@ begin
FConnOptions := FConnOptions + [sqSupportParams] + [sqEscapeRepeat] + [sqEscapeSlash]; FConnOptions := FConnOptions + [sqSupportParams] + [sqEscapeRepeat] + [sqEscapeSlash];
FieldNameQuoteChars:=DoubleQuotes; FieldNameQuoteChars:=DoubleQuotes;
VerboseErrors:=True; VerboseErrors:=True;
InitCriticalSection(FPool); FConnectionPool:=TThreadlist.Create;
end; end;
destructor TPQConnection.destroy; destructor TPQConnection.destroy;
begin begin
DoneCriticalSection(FPool); FreeAndNil(FConnectionPool);
inherited destroy; inherited destroy;
end; end;
@ -223,41 +222,34 @@ end;
procedure TPQConnection.AddConnection(T: TPQTranConnection); procedure TPQConnection.AddConnection(T: TPQTranConnection);
Var
I : Integer;
begin begin
// make connection available in pool FConnectionPool.Add(T);
EnterCriticalSection(FPool);
try
I:=Length(FConnectionPool);
SetLength(FConnectionPool,I+1);
FConnectionPool[i]:=T;
finally
EnterCriticalSection(FPool);
end;
end; end;
procedure TPQConnection.ReleaseConnection(Conn: PPGConn; DoClear: Boolean); procedure TPQConnection.ReleaseConnection(Conn: PPGConn; DoClear: Boolean);
Var Var
I : Integer; I : Integer;
L : TList;
T : TPQTranConnection;
begin begin
L:=FConnectionPool.LockList;
// make connection available in pool // make connection available in pool
EnterCriticalSection(FPool);
try try
for i:=0 to length(FConnectionPool)-1 do for i:=0 to L.Count-1 do
if (FConnectionPool[i].FPGConn=Conn) then begin
T:=TPQTranConnection(L[i]);
if (T.FPGConn=Conn) then
begin begin
T.FTranActive:=false;
FConnectionPool[i].FTranActive:=false;
if DoClear then if DoClear then
FConnectionPool[i].FPGConn:=Nil; T.FPGConn:=Nil;
break; break;
end; end;
end
finally finally
EnterCriticalSection(FPool); FConnectionPool.UnlockList;
end; end;
end; end;
@ -311,17 +303,19 @@ var
tr : TPQTrans; tr : TPQTrans;
i : Integer; i : Integer;
t : TPQTranConnection; t : TPQTranConnection;
L : TList;
begin begin
result:=false; result:=false;
tr := trans as TPQTrans; tr := trans as TPQTrans;
//find an unused connection in the pool //find an unused connection in the pool
i:=0; i:=0;
EnterCriticalSection(FPool); t:=Nil;
L:=FConnectionPool.LockList;
try try
while i<length(FConnectionPool) do while (I<L.Count-1) do
begin begin
T:=FConnectionPool[i]; T:=TPQTranConnection(L[i]);
if (T.FPGConn=nil) or not T.FTranActive then if (T.FPGConn=nil) or not T.FTranActive then
break break
else else
@ -333,7 +327,7 @@ begin
if Assigned(T) then if Assigned(T) then
T.FTranActive:=true; T.FTranActive:=true;
finally finally
LeaveCriticalSection(FPool); FConnectionPool.UnLockList;
end; end;
if (T=Nil) then if (T=Nil) then
begin begin
@ -428,20 +422,25 @@ begin
end; end;
procedure TPQConnection.DoInternalDisconnect; procedure TPQConnection.DoInternalDisconnect;
var i:integer; var
i:integer;
L : TList;
T : TPQTranConnection;
begin begin
Inherited; Inherited;
EnterCriticalSection(FPool); L:=FConnectionPool.LockList;
try try
for i:=0 to length(FConnectionPool)-1 do for i:=0 to L.Count-1 do
begin begin
if assigned(FConnectionPool[i].FPGConn) then T:=TPQTranConnection(L[i]);
PQfinish(FConnectionPool[i].FPGConn); if assigned(T.FPGConn) then
FConnectionPool[i].Free; PQfinish(T.FPGConn);
T.Free;
end; end;
Setlength(FConnectionPool,0); L.Clear;
finally finally
LeaveCriticalSection(FPool); FConnectionPool.UnLockList;
end; end;
{$IfDef LinkDynamically} {$IfDef LinkDynamically}
ReleasePostgres3; ReleasePostgres3;
@ -863,26 +862,39 @@ end;
function TPQConnection.GetHandle: pointer; function TPQConnection.GetHandle: pointer;
var var
i:integer; i:integer;
L : TList;
T : TPQTranConnection;
begin begin
result:=nil; result:=nil;
if not Connected then if not Connected then
exit; exit;
//Get any handle that is (still) connected //Get any handle that is (still) connected
for i:=0 to length(FConnectionPool)-1 do L:=FConnectionPool.LockList;
if assigned(FConnectionPool[i].FPGConn) and (PQstatus(FConnectionPool[i].FPGConn)<>CONNECTION_BAD) then try
I:=L.Count-1;
While (I>=0) and (Result=Nil) do
begin begin
Result :=FConnectionPool[i].FPGConn; T:=TPQTranConnection(L[i]);
exit; if assigned(T.FPGConn) and (PQstatus(T.FPGConn)<>CONNECTION_BAD) then
Result:=T.FPGConn;
Dec(I);
end; end;
finally
FConnectionPool.UnLockList;
end;
if Result<>Nil then
exit;
//Nothing connected!! Reconnect //Nothing connected!! Reconnect
if assigned(FConnectionPool[0].FPGConn) then // T is element 0 after loop
PQreset(FConnectionPool[0].FPGConn) if assigned(T.FPGConn) then
PQreset(T.FPGConn)
else else
FConnectionPool[0].FPGConn := PQconnectdb(pchar(FConnectString)); T.FPGConn := PQconnectdb(pchar(FConnectString));
CheckConnectionStatus(FConnectionPool[0].FPGConn); CheckConnectionStatus(T.FPGConn);
if CharSet <> '' then if CharSet <> '' then
PQsetClientEncoding(FConnectionPool[0].FPGConn, pchar(CharSet)); PQsetClientEncoding(T.FPGConn, pchar(CharSet));
result:=FConnectionPool[0].FPGConn; result:=T.FPGConn;
end; end;
function TPQConnection.Fetch(cursor : TSQLCursor) : boolean; function TPQConnection.Fetch(cursor : TSQLCursor) : boolean;