1919from morango .constants import transfer_statuses
2020from morango .constants .capabilities import ASYNC_OPERATIONS
2121from morango .constants .capabilities import FSIC_V2_FORMAT
22+ from morango .constants .capabilities import SELF_REF_ORDER
2223from morango .errors import MorangoInvalidFSICPartition
2324from morango .errors import MorangoLimitExceeded
2425from morango .errors import MorangoResumeSyncError
@@ -679,7 +680,52 @@ def _queue_into_buffer_v2(transfersession, chunk_size=200):
679680 )
680681
681682
682- def _dequeue_into_store (transfer_session , fsic , v2_format = False ):
683+ def _update_legacy_self_ref_order (transfer_session ):
684+ transferred_store_records = Store .objects .filter (
685+ last_transfer_session_id = transfer_session .id
686+ )
687+ records_by_id = {record .id : record for record in transferred_store_records }
688+ records_by_model = defaultdict (list )
689+
690+ for record in records_by_id .values ():
691+ try :
692+ Model = syncable_models .get_model (record .profile , record .model_name )
693+ except KeyError :
694+ continue
695+
696+ if self_referential_fk (Model ):
697+ records_by_model [(record .profile , record .model_name )].append (record )
698+ elif record ._self_ref_order is not None :
699+ record ._self_ref_order = None
700+ record .save (update_fields = ["_self_ref_order" ])
701+
702+ for records in records_by_model .values ():
703+ pending_record_ids = set (record .id for record in records )
704+ while pending_record_ids :
705+ updated = False
706+ for record_id in list (pending_record_ids ):
707+ record = records_by_id [record_id ]
708+ if not record ._self_ref_fk :
709+ order = 0
710+ else :
711+ parent = records_by_id .get (record ._self_ref_fk )
712+ if parent is not None and parent .id in pending_record_ids :
713+ continue
714+ order = Store .objects .filter (id = record ._self_ref_fk ).values_list (
715+ "_self_ref_order" , flat = True
716+ ).first ()
717+
718+ if record ._self_ref_order != order :
719+ record ._self_ref_order = order
720+ record .save (update_fields = ["_self_ref_order" ])
721+ pending_record_ids .remove (record_id )
722+ updated = True
723+
724+ if not updated :
725+ break
726+
727+
728+ def _dequeue_into_store (transfer_session , fsic , v2_format = False , self_ref_order = True ):
683729 """
684730 Takes data from the buffers and merges into the store and record max counters.
685731
@@ -703,6 +749,8 @@ def _dequeue_into_store(transfer_session, fsic, v2_format=False):
703749 DBBackend ._dequeuing_delete_mc_buffer (cursor , transfer_session .id )
704750 DBBackend ._dequeuing_insert_remaining_buffer (cursor , transfer_session .id )
705751 DBBackend ._dequeuing_insert_remaining_rmcb (cursor , transfer_session .id )
752+ if not self_ref_order :
753+ _update_legacy_self_ref_order (transfer_session )
706754 DBBackend ._dequeuing_delete_remaining_rmcb (cursor , transfer_session .id )
707755 DBBackend ._dequeuing_delete_remaining_buffer (cursor , transfer_session .id )
708756
@@ -1041,6 +1089,7 @@ def handle(self, context):
10411089 context .transfer_session ,
10421090 fsic ,
10431091 v2_format = FSIC_V2_FORMAT in context .capabilities ,
1092+ self_ref_order = SELF_REF_ORDER in context .capabilities ,
10441093 )
10451094
10461095 return transfer_statuses .COMPLETED
0 commit comments