@@ -232,8 +232,8 @@ private function resolveMasterRelations(Tuple $tuple, RelationMap $map): int
232232 $ deferred = false ;
233233 $ resolved = true ;
234234 foreach ($ map ->getMasters () as $ name => $ relation ) {
235- $ relationStatus = $ tuple ->state ->getRelationStatus ($ relation ->getName ());
236- if ($ relationStatus === RelationInterface::STATUS_RESOLVED ) {
235+ $ statusAfter = $ statusBefore = $ tuple ->state ->getRelationStatus ($ relation ->getName ());
236+ if ($ statusBefore === RelationInterface::STATUS_RESOLVED ) {
237237 continue ;
238238 }
239239
@@ -242,10 +242,10 @@ private function resolveMasterRelations(Tuple $tuple, RelationMap $map): int
242242 // Connected -> $parentNode->getRelationStatus()
243243 // Disconnected -> WAIT if Tuple::STATUS_PREPARING
244244 $ relation ->queue ($ this ->pool , $ tuple );
245- $ relationStatus = $ tuple ->state ->getRelationStatus ($ relation ->getName ());
245+ $ statusAfter = $ tuple ->state ->getRelationStatus ($ relation ->getName ());
246246 } else {
247247 if ($ tuple ->status === Tuple::STATUS_PREPARING ) {
248- if ($ relationStatus === RelationInterface::STATUS_PREPARE ) {
248+ if ($ statusAfter === RelationInterface::STATUS_PREPARE ) {
249249 $ entityData ??= $ tuple ->mapper ->fetchRelations ($ tuple ->entity );
250250 $ relation ->prepare (
251251 $ this ->pool ,
@@ -254,15 +254,17 @@ private function resolveMasterRelations(Tuple $tuple, RelationMap $map): int
254254 ? $ entityData [$ name ]
255255 : ($ this ->ignoreUninitializedRelations ? SpecialValue::notSet () : null ),
256256 );
257- $ relationStatus = $ tuple ->state ->getRelationStatus ($ relation ->getName ());
257+ $ statusAfter = $ tuple ->state ->getRelationStatus ($ relation ->getName ());
258258 }
259259 } else {
260260 $ relation ->queue ($ this ->pool , $ tuple );
261- $ relationStatus = $ tuple ->state ->getRelationStatus ($ relation ->getName ());
261+ $ statusAfter = $ tuple ->state ->getRelationStatus ($ relation ->getName ());
262262 }
263263 }
264- $ resolved = $ resolved && $ relationStatus >= RelationInterface::STATUS_DEFERRED ;
265- $ deferred = $ deferred || $ relationStatus === RelationInterface::STATUS_DEFERRED ;
264+
265+ $ statusAfter > $ statusBefore and $ this ->pool ->someHappens ();
266+ $ resolved = $ resolved && $ statusAfter >= RelationInterface::STATUS_DEFERRED ;
267+ $ deferred = $ deferred || $ statusAfter === RelationInterface::STATUS_DEFERRED ;
266268 }
267269
268270 // $tuple->waitKeys = array_unique(array_merge(...$waitKeys));
@@ -284,15 +286,15 @@ private function resolveSlaveRelations(Tuple $tuple, RelationMap $map): int
284286 $ relData = $ tuple ->mapper ->fetchRelations ($ tuple ->entity );
285287 }
286288 foreach ($ map ->getSlaves () as $ name => $ relation ) {
287- $ relationStatus = $ tuple ->state ->getRelationStatus ($ relation ->getName ());
288- if (!$ relation ->isCascade () || $ relationStatus === RelationInterface::STATUS_RESOLVED ) {
289+ $ statusBefore = $ statusAfter = $ tuple ->state ->getRelationStatus ($ relation ->getName ());
290+ if (!$ relation ->isCascade () || $ statusAfter === RelationInterface::STATUS_RESOLVED ) {
289291 continue ;
290292 }
291293
292294 $ innerKeys = $ relation ->getInnerKeys ();
293295 $ isWaitingKeys = \array_intersect ($ innerKeys , $ tuple ->state ->getWaitingFields (true )) !== [];
294296 $ hasChangedKeys = \array_intersect ($ innerKeys , $ changedFields ) !== [];
295- if ($ relationStatus === RelationInterface::STATUS_PREPARE ) {
297+ if ($ statusAfter === RelationInterface::STATUS_PREPARE ) {
296298 $ relData ??= $ tuple ->mapper ->fetchRelations ($ tuple ->entity );
297299 $ relation ->prepare (
298300 $ this ->pool ,
@@ -302,32 +304,35 @@ private function resolveSlaveRelations(Tuple $tuple, RelationMap $map): int
302304 : ($ this ->ignoreUninitializedRelations ? SpecialValue::notSet () : null ),
303305 $ isWaitingKeys || $ hasChangedKeys ,
304306 );
305- $ relationStatus = $ tuple ->state ->getRelationStatus ($ relation ->getName ());
307+ $ statusAfter = $ tuple ->state ->getRelationStatus ($ relation ->getName ());
306308 }
307309
308- if ($ relationStatus !== RelationInterface::STATUS_PREPARE
309- && $ relationStatus !== RelationInterface::STATUS_RESOLVED
310+ if ($ statusAfter !== RelationInterface::STATUS_PREPARE
311+ && $ statusAfter !== RelationInterface::STATUS_RESOLVED
310312 && !$ isWaitingKeys
311313 && !$ hasChangedKeys
312314 && \count (\array_intersect ($ innerKeys , \array_keys ($ transactData ))) === \count ($ innerKeys )
313315 ) {
314316 // $child ??= $tuple->state->getRelation($name);
315317 $ relation ->queue ($ this ->pool , $ tuple );
316- $ relationStatus = $ tuple ->state ->getRelationStatus ($ relation ->getName ());
318+ $ statusAfter = $ tuple ->state ->getRelationStatus ($ relation ->getName ());
317319 }
318- $ resolved = $ resolved && $ relationStatus === RelationInterface::STATUS_RESOLVED ;
319- $ deferred = $ deferred || $ relationStatus === RelationInterface::STATUS_DEFERRED ;
320+
321+ $ statusAfter > $ statusBefore and $ this ->pool ->someHappens ();
322+ $ resolved = $ resolved && $ statusAfter === RelationInterface::STATUS_RESOLVED ;
323+ $ deferred = $ deferred || $ statusAfter === RelationInterface::STATUS_DEFERRED ;
320324 }
321325
322326 return ($ deferred ? self ::RELATIONS_DEFERRED : 0 ) | ($ resolved ? self ::RELATIONS_RESOLVED : 0 );
323327 }
324328
325329 private function resolveSelfWithEmbedded (Tuple $ tuple , RelationMap $ map , bool $ hasDeferredRelations ): void
326330 {
327- if (!$ map ->hasEmbedded () && !$ tuple ->state ->hasChanges ()) {
328- $ tuple ->status = !$ hasDeferredRelations
329- ? Tuple::STATUS_PROCESSED
330- : \max (Tuple::STATUS_DEFERRED , $ tuple ->status );
331+ $ hasChanges = $ tuple ->state ->hasChanges ();
332+ if (!$ hasChanges && !$ map ->hasEmbedded ()) {
333+ $ tuple ->status = $ hasDeferredRelations
334+ ? \max (Tuple::STATUS_DEFERRED_RESOLVED , $ tuple ->status )
335+ : Tuple::STATUS_PROCESSED ;
331336
332337 return ;
333338 }
@@ -337,19 +342,22 @@ private function resolveSelfWithEmbedded(Tuple $tuple, RelationMap $map, bool $h
337342 // Not embedded but has changes
338343 $ this ->runCommand ($ command );
339344
340- $ tuple ->status = $ tuple ->status <= Tuple::STATUS_PROPOSED && $ hasDeferredRelations
341- ? Tuple::STATUS_DEFERRED
345+ $ tuple ->status = $ tuple ->status <= Tuple::STATUS_PROPOSED_RESOLVED && $ hasDeferredRelations
346+ ? Tuple::STATUS_DEFERRED_RESOLVED
342347 : Tuple::STATUS_PROCESSED ;
343348
344349 return ;
345350 }
346351
347352 $ entityData = $ tuple ->mapper ->extract ($ tuple ->entity );
353+ $ chEmb = false ;
348354 foreach ($ map ->getEmbedded () as $ name => $ relation ) {
349355 $ relationStatus = $ tuple ->state ->getRelationStatus ($ relation ->getName ());
350356 if ($ relationStatus === RelationInterface::STATUS_RESOLVED ) {
351357 continue ;
352358 }
359+
360+ $ chEmb = true ;
353361 $ tuple ->state ->setRelation ($ name , $ entityData [$ name ] ?? null );
354362 // We can use class MergeCommand here
355363 $ relation ->queue (
@@ -358,11 +366,13 @@ private function resolveSelfWithEmbedded(Tuple $tuple, RelationMap $map, bool $h
358366 $ command instanceof Sequence ? $ command ->getPrimaryCommand () : $ command ,
359367 );
360368 }
361- $ this ->runCommand ($ command );
369+
370+ // Run command if there are embedded changes or other changes
371+ $ chEmb || $ hasChanges and $ this ->runCommand ($ command );
362372
363373 $ tuple ->status = $ tuple ->status === Tuple::STATUS_PREPROCESSED || !$ hasDeferredRelations
364374 ? Tuple::STATUS_PROCESSED
365- : \max (Tuple::STATUS_DEFERRED , $ tuple ->status );
375+ : \max (Tuple::STATUS_DEFERRED_RESOLVED , $ tuple ->status );
366376 }
367377
368378 private function resolveRelations (Tuple $ tuple ): void
@@ -375,9 +385,10 @@ private function resolveRelations(Tuple $tuple): void
375385 $ isDependenciesResolved = (bool ) ($ result & self ::RELATIONS_RESOLVED );
376386 $ deferred = (bool ) ($ result & self ::RELATIONS_DEFERRED );
377387
378- // Self
379- if ($ deferred && $ tuple ->status < Tuple::STATUS_PROPOSED ) {
380- $ tuple ->status = Tuple::STATUS_DEFERRED ;
388+ // If deferred relations found, mark self as deferred
389+ if ($ deferred ) {
390+ $ tuple ->status === Tuple::STATUS_PROPOSED_RESOLVED or $ this ->pool ->someHappens ();
391+ $ tuple ->status = $ isDependenciesResolved ? Tuple::STATUS_DEFERRED_RESOLVED : Tuple::STATUS_DEFERRED ;
381392 }
382393
383394 if ($ isDependenciesResolved ) {
0 commit comments