Home › Forums › kbmMemTable › kbmMemTable1.IsDataModified
- This topic has 3 replies, 2 voices, and was last updated 5 years, 3 months ago by
TomYU.
-
AuthorPosts
-
-
October 15, 2020 at 02:52 #55169
TomYU
ParticipantResult of kbmMemTable1.IsDataModified is not the result I expected.
Suppose a kbmMemTable has a record, when I modify a field, but the new value is the same as the original value of the field. At this time, I think the data set has not been modified. The result of the IsDataModified method should be False.
procedure TForm4.Button1Click(Sender: TObject);
begin
//init kbmMemtable1
kbmMemTable1.AppendRecord([‘1′,1]);
kbmMemTable1.CheckPoint;//modify current record ,the new value is the same as the original value of the field
kbmMemTable1.Edit;
kbmMemTable1f1.AsString:=’1′;
kbmMemTable1.Post;if kbmMemTable1.IsDataModified then
Label1.Caption:=’IsModified=True’
else
Label1.Caption:=’IsModified=False’
end; -
October 15, 2020 at 03:46 #55170
TomYU
ParticipantThis is the helper class I wrote to solve the above problem:
function TkbmMWClientQueryHelper.IsModified: Boolean;
var
i: TkbmNativeInt;
j: TkbmNativeInt;
pRec, pOrigRec, pOldRec: PkbmRecord;
aRecords: TkbmList;
st: TUpdateStatus;
aOldV, aNewV: Variant;
begin
if Self.State in [dsInsert, dsEdit] then
Self.Post;
Result := False;
with Self do
begin
aRecords := Common.Records;
for i := 0 to aRecords.Count – 1 do
begin
pRec := PkbmRecord(aRecords.Items[i]);
if pRec = nil then
begin
Continue;
end;
// Find oldest version.
pOrigRec := pRec;
while pOrigRec^.PrevRecordVersion <> nil do
begin
pOrigRec := pOrigRec^.PrevRecordVersion;
end;// Check what status to react on.
if pRec^.UpdateStatus = usDeleted then
begin
// Dont resolve inserts that were deleted again.
if pOrigRec^.UpdateStatus = usInserted then
st := usUnmodified
else
st := usDeleted;
end
else if pOrigRec^.UpdateStatus = usInserted then
st := usInserted
else
st := pRec^.UpdateStatus;
pOldRec := OverrideActiveRecordBuffer;
try
if st = usModified then
begin
OverrideActiveRecordBuffer := pRec; // 指向修改后的数据
for j := 0 to FieldCount – 1 do
begin
OverrideActiveRecordBuffer := pRec; // 指向修改后的数据
aNewV := FieldByName(Fields[j].FieldName).Value;
OverrideActiveRecordBuffer := pOrigRec; // 指向修改前的数据
aOldV := FieldByName(Fields[j].FieldName).Value;
if aNewV <> aOldV then
begin
Result := True;
Break;
end;
end;
end
else if st = usInserted then
begin
Result := True;
end
else if st = usDeleted then
begin
Result := True;
end
else if pRec.UpdateStatus = usUnmodified then
beginend;
finally
OverrideActiveRecordBuffer := pOldRec;
end;if Result then
Break;
end;
end;
end; -
October 15, 2020 at 13:15 #55171
kimbomadsen
KeymasterTechnically the memory table was change hence IsDataModified is set to true. Metadata could have changed due to your update, which would be the case if your have enabled versioning.
Let’s think about another scenario, Delete an existing record, and then Insert the exactly same data again. Should the memory table identify as changed or not? It clearly has changed, and new metadata (like a record number, unique record id, and potentially an update status) has changed.
I do understand that from an enduser point of view, the dataset may not have been changed, which is what you try to solve with your helper function, looking at update status’es etc.
However it will only be able to detect if data has been changed, as long as the developer decides not to CheckPoint or play with UpdateStatus’es or versioning, so it comes with another set of prerequisites, not to mention a healthy overhead, since it will need to probe every single record, which is not a problem for the majority of cases except those where there may be huge amounts of records in memory.
-
October 16, 2020 at 09:34 #55175
TomYU
Participanthi,
Thank you for your reply and agree with you.
If this method is added to kbmMWClientQuery, it will let me not use the helper class.
best regards.
Tom yu.
-
-
AuthorPosts
- You must be logged in to reply to this topic.
