mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-07 18:50:33 +01:00
* Use TFieldDef descendent to implement updateable enums
git-svn-id: trunk@26781 -
This commit is contained in:
parent
948f40f24b
commit
b1fc595d17
@ -31,12 +31,17 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
{ TPQCursor }
|
{ TPQCursor }
|
||||||
|
// TField and TFieldDef only support a limited amount of fields.
|
||||||
|
// TFieldBinding and TExtendedFieldType can be used to map PQ types
|
||||||
|
// on standard fields and retain mapping info.
|
||||||
TExtendedFieldType = (eftNone,eftEnum);
|
TExtendedFieldType = (eftNone,eftEnum);
|
||||||
|
|
||||||
TFieldBinding = record
|
TFieldBinding = record
|
||||||
Index : Integer;
|
FieldDef : TSQLDBFieldDef; // FieldDef this is associated with
|
||||||
TypeOID : oid;
|
Index : Integer; // Tuple index
|
||||||
TypeName : String;
|
TypeOID : oid; // Filled with type OID if it is not standard.
|
||||||
ExtendedFieldType: TExtendedFieldType;
|
TypeName : String; // Filled with type name by getextendedfieldInfo
|
||||||
|
ExtendedFieldType: TExtendedFieldType; //
|
||||||
end;
|
end;
|
||||||
PFieldBinding = ^TFieldBinding;
|
PFieldBinding = ^TFieldBinding;
|
||||||
TFieldBindings = Array of TFieldBinding;
|
TFieldBindings = Array of TFieldBinding;
|
||||||
@ -49,6 +54,7 @@ type
|
|||||||
res : PPGresult;
|
res : PPGresult;
|
||||||
CurTuple : integer;
|
CurTuple : integer;
|
||||||
FieldBinding : TFieldBindings;
|
FieldBinding : TFieldBindings;
|
||||||
|
Function GetFieldBinding(F : TFieldDef): PFieldBinding;
|
||||||
Public
|
Public
|
||||||
Destructor Destroy; override;
|
Destructor Destroy; override;
|
||||||
end;
|
end;
|
||||||
@ -84,6 +90,7 @@ type
|
|||||||
procedure ExecuteDirectPG(const Query : String);
|
procedure ExecuteDirectPG(const Query : String);
|
||||||
Procedure GetExtendedFieldInfo(cursor: TPQCursor; Bindings : TFieldBindings);
|
Procedure GetExtendedFieldInfo(cursor: TPQCursor; Bindings : TFieldBindings);
|
||||||
protected
|
protected
|
||||||
|
procedure ApplyFieldUpdate(C : TSQLCursor; P: TSQLDBParam; F: TField; UseOldValue: Boolean); override;
|
||||||
Function ErrorOnUnknownType : Boolean;
|
Function ErrorOnUnknownType : Boolean;
|
||||||
// Add connection to pool.
|
// Add connection to pool.
|
||||||
procedure AddConnection(T: TPQTranConnection);
|
procedure AddConnection(T: TPQTranConnection);
|
||||||
@ -150,10 +157,7 @@ ResourceString
|
|||||||
SErrCommitFailed = 'Commit transaction failed';
|
SErrCommitFailed = 'Commit transaction failed';
|
||||||
SErrConnectionFailed = 'Connection to database failed';
|
SErrConnectionFailed = 'Connection to database failed';
|
||||||
SErrTransactionFailed = 'Start of transacion failed';
|
SErrTransactionFailed = 'Start of transacion failed';
|
||||||
SErrClearSelection = 'Clear of selection failed';
|
|
||||||
SErrExecuteFailed = 'Execution of query failed';
|
SErrExecuteFailed = 'Execution of query failed';
|
||||||
SErrFieldDefsFailed = 'Can not extract field information from query';
|
|
||||||
SErrFetchFailed = 'Fetch of data failed';
|
|
||||||
SErrPrepareFailed = 'Preparation of query failed.';
|
SErrPrepareFailed = 'Preparation of query failed.';
|
||||||
SErrUnPrepareFailed = 'Unpreparation of query failed.';
|
SErrUnPrepareFailed = 'Unpreparation of query failed.';
|
||||||
|
|
||||||
@ -223,6 +227,29 @@ end;
|
|||||||
|
|
||||||
{ TPQCursor }
|
{ TPQCursor }
|
||||||
|
|
||||||
|
function TPQCursor.GetFieldBinding(F: TFieldDef): PFieldBinding;
|
||||||
|
|
||||||
|
Var
|
||||||
|
I : Integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result:=Nil;
|
||||||
|
if (F=Nil) then exit;
|
||||||
|
// This is an optimization: it is so for 99% of cases (FieldNo-1=array index)
|
||||||
|
if F is TSQLDBFieldDef then
|
||||||
|
Result:=PFieldBinding(TSQLDBFieldDef(F).SQLDBData)
|
||||||
|
else If (FieldBinding[F.FieldNo-1].FieldDef=F) then
|
||||||
|
Result:=@FieldBinding[F.FieldNo-1]
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
I:=Length(FieldBinding)-1;
|
||||||
|
While (I>=0) and (FieldBinding[i].FieldDef<>F) do
|
||||||
|
Dec(I);
|
||||||
|
if I>=0 then
|
||||||
|
Result:=@FieldBinding[i];
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
destructor TPQCursor.Destroy;
|
destructor TPQCursor.Destroy;
|
||||||
begin
|
begin
|
||||||
if Assigned(tr) then
|
if Assigned(tr) then
|
||||||
@ -342,6 +369,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPQConnection.ApplyFieldUpdate(C : TSQLCursor; P: TSQLDBParam; F: TField;
|
||||||
|
UseOldValue: Boolean);
|
||||||
|
begin
|
||||||
|
inherited ApplyFieldUpdate(C,P, F, UseOldValue);
|
||||||
|
if (C is TPQCursor) then
|
||||||
|
P.SQLDBData:=TPQCursor(C).GetFieldBinding(F.FieldDef);
|
||||||
|
end;
|
||||||
|
|
||||||
function TPQConnection.ErrorOnUnknownType: Boolean;
|
function TPQConnection.ErrorOnUnknownType: Boolean;
|
||||||
begin
|
begin
|
||||||
Result:=False;
|
Result:=False;
|
||||||
@ -802,8 +837,11 @@ const TypeStrings : array[TFieldType] of string =
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
var s : string;
|
var
|
||||||
i : integer;
|
s,ts : string;
|
||||||
|
i : integer;
|
||||||
|
P : TParam;
|
||||||
|
PQ : TSQLDBParam;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
with (cursor as TPQCursor) do
|
with (cursor as TPQCursor) do
|
||||||
@ -824,8 +862,21 @@ begin
|
|||||||
begin
|
begin
|
||||||
s := s + '(';
|
s := s + '(';
|
||||||
for i := 0 to AParams.Count-1 do
|
for i := 0 to AParams.Count-1 do
|
||||||
if TypeStrings[AParams[i].DataType] <> 'Unknown' then
|
begin
|
||||||
s := s + TypeStrings[AParams[i].DataType] + ','
|
P:=AParams[i];
|
||||||
|
If (P is TSQLDBParam) then
|
||||||
|
PQ:=TSQLDBParam(P)
|
||||||
|
else
|
||||||
|
PQ:=Nil;
|
||||||
|
TS:=TypeStrings[P.DataType];
|
||||||
|
if (TS<>'Unknown') then
|
||||||
|
begin
|
||||||
|
If Assigned(PQ)
|
||||||
|
and Assigned(PQ.SQLDBData)
|
||||||
|
and (PFieldBinding(PQ.SQLDBData)^.ExtendedFieldType=eftEnum) then
|
||||||
|
ts:='unknown';
|
||||||
|
s := s + ts + ','
|
||||||
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
if AParams[i].DataType = ftUnknown then
|
if AParams[i].DataType = ftUnknown then
|
||||||
@ -838,6 +889,7 @@ begin
|
|||||||
else
|
else
|
||||||
DatabaseErrorFmt(SUnsupportedParameter,[Fieldtypenames[AParams[i].DataType]],self);
|
DatabaseErrorFmt(SUnsupportedParameter,[Fieldtypenames[AParams[i].DataType]],self);
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
s[length(s)] := ')';
|
s[length(s)] := ')';
|
||||||
buf := AParams.ParseSQL(buf,false,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions,psPostgreSQL);
|
buf := AParams.ParseSQL(buf,false,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions,psPostgreSQL);
|
||||||
end;
|
end;
|
||||||
@ -992,8 +1044,9 @@ var
|
|||||||
nFields : integer;
|
nFields : integer;
|
||||||
b : Boolean;
|
b : Boolean;
|
||||||
Q : TPQCursor;
|
Q : TPQCursor;
|
||||||
FD : TFieldDef;
|
FD : TSQLDBFieldDef;
|
||||||
FB : PFieldBinding;
|
FB : PFieldBinding;
|
||||||
|
C : TFieldDefClass;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
B:=False;
|
B:=False;
|
||||||
@ -1005,10 +1058,13 @@ begin
|
|||||||
for i := 0 to nFields-1 do
|
for i := 0 to nFields-1 do
|
||||||
begin
|
begin
|
||||||
fieldtype := TranslateFldType(Res, i,size, aoid );
|
fieldtype := TranslateFldType(Res, i,size, aoid );
|
||||||
with TFieldDef.Create(FieldDefs, FieldDefs.MakeNameUnique(PQfname(Res, i)), fieldtype,size, False, (i + 1)) do
|
FD:=FieldDefs.Add(FieldDefs.MakeNameUnique(PQfname(Res, i)),fieldtype,Size,False,I+1) as TSQLDBFieldDef;
|
||||||
|
With FD do
|
||||||
begin
|
begin
|
||||||
FieldBinding[FieldNo-1].Index := i;
|
SQLDBData:=@FieldBinding[i];
|
||||||
FieldBinding[FieldNo-1].TypeOID:=aOID;
|
FieldBinding[i].Index:=i;
|
||||||
|
FieldBinding[i].FieldDef:=FD;
|
||||||
|
FieldBinding[i].TypeOID:=aOID;
|
||||||
B:=B or (aOID>0);
|
B:=B or (aOID>0);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1023,13 +1079,13 @@ begin
|
|||||||
FB:=@Q.FieldBinding[i];
|
FB:=@Q.FieldBinding[i];
|
||||||
if (FB^.TypeOID>0) then
|
if (FB^.TypeOID>0) then
|
||||||
begin
|
begin
|
||||||
FD:=FieldDefs[FB^.Index];
|
FD:=FB^.FieldDef;
|
||||||
Case FB^.ExtendedFieldType of
|
Case FB^.ExtendedFieldType of
|
||||||
eftEnum :
|
eftEnum :
|
||||||
begin
|
begin
|
||||||
FD.DataType:=ftString;
|
FD.DataType:=ftString;
|
||||||
FD.Size:=64;
|
FD.Size:=64;
|
||||||
FD.Attributes:=FD.Attributes+[faReadonly];
|
//FD.Attributes:=FD.Attributes+[faReadonly];
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if ErrorOnUnknownType then
|
if ErrorOnUnknownType then
|
||||||
@ -1133,7 +1189,7 @@ begin
|
|||||||
Createblob := False;
|
Createblob := False;
|
||||||
with cursor as TPQCursor do
|
with cursor as TPQCursor do
|
||||||
begin
|
begin
|
||||||
x := FieldBinding[FieldDef.FieldNo-1].Index;
|
x := GetFieldBinding(FieldDef)^.Index;
|
||||||
|
|
||||||
// Joost, 5 jan 2006: I disabled the following, since it's useful for
|
// Joost, 5 jan 2006: I disabled the following, since it's useful for
|
||||||
// debugging, but it also slows things down. In principle things can only go
|
// debugging, but it also slows things down. In principle things can only go
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user