Skip to content

Commit

Permalink
DelayObjectDestruction now called after PreUpdate. #20
Browse files Browse the repository at this point in the history
  • Loading branch information
bero committed Dec 6, 2024
1 parent 7bbe7e2 commit 9319d6c
Showing 1 changed file with 67 additions and 63 deletions.
130 changes: 67 additions & 63 deletions Source/BoldSystemPersistenceHandler.pas
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ procedure TBoldSystemPersistenceHandler.FetchMembersWithObjects(
aBoldObjectList: TBoldObjectList; aBoldMemberIdList: TBoldMemberIdList);
var
ListToFetch: TBoldObjectList;
vObject: TBoldObject;
vObject: TBoldObject;
i,j: integer;
begin
ListToFetch := TBoldObjectList.Create;
Expand Down Expand Up @@ -334,7 +334,7 @@ procedure TBoldSystemPersistenceHandler.FetchLinksWithObjects(ObjectList: TBoldO
ObjectList.EnsureObjects;
if ObjectList.Count > 0 then
begin
Guard := TBoldGuard.Create(FetchList, MemberIdList);
Guard := TBoldGuard.Create(FetchList, MemberIdList);
FetchList := TBoldObjectList.Create;
FetchList.SubscribeToObjectsInList := False;
MemberIdList := TBoldMemberIdList.Create;
Expand Down Expand Up @@ -524,78 +524,82 @@ procedure TBoldSystemPersistenceHandler.UpdateDatabaseWithList(ObjectList: TBold

Guard := TBoldGuard.Create(ObjectsToUpdate, aTranslationList, ObjectIdList, Precondition, FailureList);

System.DelayObjectDestruction;
try
ObjectsToUpdate := ObjectList.Clone as TBoldObjectList;
for i := ObjectsToUpdate.Count-1 downto 0 do
if not assigned(ObjectsToUpdate.Locators[i].BoldObject) or
not ObjectsToUpdate[i].BoldPersistent then
ObjectsToUpdate.RemoveByIndex(i);

ObjectsToUpdate := ObjectList.Clone as TBoldObjectList;
for i := ObjectsToUpdate.Count-1 downto 0 do
if not assigned(ObjectsToUpdate.Locators[i].BoldObject) or
not ObjectsToUpdate[i].BoldPersistent then
ObjectsToUpdate.RemoveByIndex(i);

if ObjectsToUpdate.Count > 0 then
begin
EnsureEnclosure(ObjectsToUpdate, false);
DoPreUpdate(ObjectsToUpdate);
if ObjectsToUpdate.Count > 0 then
begin
EnsureEnclosure(ObjectsToUpdate, false);
DoPreUpdate(ObjectsToUpdate);
System.IsUpdatingDatabase := True;
ObjectIdList := ObjectsToUpdate.CreateObjectIdList(true);
aTranslationList := TBoldIdTranslationList.Create;
if System.BoldSystemTypeInfo.OptimisticLocking = bolmOff then
Precondition := nil
else
begin
Precondition := TBoldOptimisticLockingPrecondition.create;
System.OptimisticLockHandler.AddOptimisticLocks(ObjectsToUpdate, PreCondition);
if not Precondition.HasOptimisticLocks then
FreeAndNil(PreCondition);
end;
System.DelayObjectDestruction;
try
System.IsUpdatingDatabase := True;
ObjectIdList := ObjectsToUpdate.CreateObjectIdList(true);
aTranslationList := TBoldIdTranslationList.Create;
if System.BoldSystemTypeInfo.OptimisticLocking = bolmOff then
Precondition := nil
else
begin
Precondition := TBoldOptimisticLockingPrecondition.create;
System.OptimisticLockHandler.AddOptimisticLocks(ObjectsToUpdate, PreCondition);
if not Precondition.HasOptimisticLocks then
FreeAndNil(PreCondition);
end;

//TODO: in the future, call another function to add optimistic locking data for optimistic region locking
//TODO: If the model wants optimistic locking, but none of the classes of objects to be updated,
// the precondition should be freed.
//TODO: in the future, call another function to add optimistic locking data for optimistic region locking
//TODO: If the model wants optimistic locking, but none of the classes of objects to be updated,
// the precondition should be freed.

if assigned(System.PessimisticLockHandler) and not System.PessimisticLockHandler.EnsureLocks then
raise EBold.CreateFmt(sRequiredLocksNotHeld, [classname]);
BoldClearLastfailure;
if assigned(System.PessimisticLockHandler) and not System.PessimisticLockHandler.EnsureLocks then
raise EBold.CreateFmt(sRequiredLocksNotHeld, [classname]);
BoldClearLastfailure;

try
if not StartUpdateForAll(ObjectsToUpdate) then
BoldRaiseLastFailure(System, 'UpdateDatabaseWithList', sStartUpdateFailed); // do not localize
try
if not StartUpdateForAll(ObjectsToUpdate) then
BoldRaiseLastFailure(System, 'UpdateDatabaseWithList', sStartUpdateFailed); // do not localize

PersistenceController.PMUpdate(ObjectIdList, System.AsIBoldvalueSpace[bdepPMOut], System.OptimisticLockHandler.OldValues, Precondition, aTranslationList, fTimeStampOfLatestUpdate, fTimeOfLatestUpdate, NOTVALIDCLIENTID);
if assigned(Precondition) and Precondition.Failed then
begin
if assigned(system.OnOptimisticLockingFailed) then
PersistenceController.PMUpdate(ObjectIdList, System.AsIBoldvalueSpace[bdepPMOut], System.OptimisticLockHandler.OldValues, Precondition, aTranslationList, fTimeStampOfLatestUpdate, fTimeOfLatestUpdate, NOTVALIDCLIENTID);
if assigned(Precondition) and Precondition.Failed then
begin
FailureList := TBoldObjectList.Create;
FailureList.FillFromIDList(Precondition.FailureList, System);
system.OnOptimisticLockingFailed(ObjectsToUpdate, FailureList, Precondition.FailureReason);
end
else
raise EBoldOperationFailedForObjectList.Create(Precondition.FailureReason, [], Precondition.FailureList, System);
end else
begin
for i := 0 to ObjectsToUpdate.Count - 1 do
ObjectsToUpdate[i].AsIBoldObjectContents[bdepPMIn].TimeStamp := TimeStampOfLatestUpdate;
EndUpdateForAll(ObjectsToUpdate, aTranslationList);
if Assigned(System.UndoHandler) then
System.UndoHandler.PrepareUpdate(ObjectList);
end;
DoPostUpdate(ObjectList);
except
on e: Exception do
begin
if GetBoldLastFailureReason <> nil then
BoldRaiseLastFailure(System, 'UpdateDatabaseWithlist', e.message)
else
raise;
if assigned(system.OnOptimisticLockingFailed) then
begin
FailureList := TBoldObjectList.Create;
FailureList.FillFromIDList(Precondition.FailureList, System);
system.OnOptimisticLockingFailed(ObjectsToUpdate, FailureList, Precondition.FailureReason);
end
else
raise EBoldOperationFailedForObjectList.Create(Precondition.FailureReason, [], Precondition.FailureList, System);
end else
begin
for i := 0 to ObjectsToUpdate.Count - 1 do
ObjectsToUpdate[i].AsIBoldObjectContents[bdepPMIn].TimeStamp := TimeStampOfLatestUpdate;
EndUpdateForAll(ObjectsToUpdate, aTranslationList);
if Assigned(System.UndoHandler) then
System.UndoHandler.PrepareUpdate(ObjectList);
end;
DoPostUpdate(ObjectList);
except
on e: Exception do
begin
if GetBoldLastFailureReason <> nil then
BoldRaiseLastFailure(System, 'UpdateDatabaseWithlist', e.message)
else
raise;
end;
end;
finally
if assigned(System.PessimisticLockHandler) then
System.PessimisticLockHandler.ReleaseUnneededRegions;
System.AllowObjectDestruction;
System.IsUpdatingDatabase := false;
end;
end;
finally
if assigned(System.PessimisticLockHandler) then
System.PessimisticLockHandler.ReleaseUnneededRegions;
System.AllowObjectDestruction;
System.IsUpdatingDatabase := false;
end;
end;

Expand Down

0 comments on commit 9319d6c

Please sign in to comment.