The whole code, which is repeated (and can be put in one place) is:
if not (State in [dsEdit, dsInsert, dsFilter, dsCalcFields]) then
begin
DatabaseErrorFmt(SNotEditing,[Name],self);
exit;
end;
if (Field.FieldNo>0) and not (State in [dsSetKey, dsFilter]) then
begin
if Read
OnlythenDatabaseErrorFmtSReadOnlyField,[Field.DisplayName],
Self);
Field.Validate(Buffer);
end;
You are right in your dislike.
I will create a 'BeforeSetFieldData' in TDataset and put the code in
there,
and the same for 'AfterSetFieldData' with the OnChange code.
OK,
Then please do not forget commit necessary changes also in other
descendants (not only in TCustomBufDataSet but also in TParadox,
TMemDataset, TFixedFormatDataSet, TDbf) to completelly fix 'missing
onvalidate call' problem.
Thanks
I am still thinking about this.
I have other solution, which is relative simple , puts base logic into
base TField methods (so all TDataSet descendants can benefit from it)
and does not negatively affect existing TDataSet descendants and does
not require introduce new methods (BeforeSetFieldData, AfterSetFieldData).
Let's distributes repeating used code as follows:
1. base checks "before" into procedure TField.SetData(Buffer: Pointer;
NativeFormat : Boolean);
820 begin
821 If Not Assigned(FDataset) then
822 DatabaseErrorFmt(SNoDataset,[FieldName]);
if not (State in [dsEdit, dsInsert, dsFilter, dsCalcFields]) then //here
should be IMO also dsNewValue
DatabaseErrorFmt(SNotEditing,[FDataSet.Name],FDataSet);
if ReadOnly and (FieldNo>0) and not (FDataSet.State in [dsSetKey,
dsFilter]) then
DatabaseErrorFmt(SReadOnlyField, [DisplayName], Self);
829 FDataSet.SetFieldData(Self,Buffer, NativeFormat);
--------------------------------------------------------------------------
2. into procedure TField.Validate(Buffer: Pointer);
892 begin
if FDataSet.State in [dsSetKey, dsFilter] then Exit;
893 If assigned(OnValidate) Then
--------------------------------------------------------------------------
3. "after call" into procedure TDataSet.SetFieldData(Field: TField; Buffer:
Pointer);
begin
if not (State in [dsCalcFields, dsFilter, dsNewValue]) then
DataEvent(deFieldChange, Ptrint(Field));
end;
--------------------------------------------------------------------------
And now all what we must do, is put into method SetFieldData in TDataSet
descendants one line:
Field.Validate(Buffer);
and one line at end:
inherited; //calls "field change" ... this is done by all TDataSet descendants
in fcl-db as a last thing
It is only draft, so some detils may be changed ... ;-)
What do you think ?
Laco.
_______________________________________________
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel