Skip to content

Commit 6397c61

Browse files
committed
carry _self_ref_order through Sync API, Queue and Dequeue
1 parent c192222 commit 6397c61

6 files changed

Lines changed: 57 additions & 15 deletions

File tree

morango/api/serializers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,5 +178,6 @@ class Meta:
178178
"profile",
179179
"rmcb_list",
180180
"_self_ref_fk",
181+
"_self_ref_order",
181182
)
182183
read_only_fields = fields

morango/sync/backends/postgres.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,10 @@ def _dequeuing_merge_conflict_rmcb(self, cursor, transfersession_id):
204204
def _dequeuing_merge_conflict_buffer(self, cursor, current_id, transfersession_id):
205205
# transfer buffer serialized into conflicting store
206206
merge_conflict_store = """UPDATE {store} as store SET (serialized, deleted, last_saved_instance, last_saved_counter, hard_deleted, model_name,
207-
profile, partition, source_id, conflicting_serialized_data, dirty_bit, _self_ref_fk, deserialization_error, last_transfer_session_id)
207+
profile, partition, source_id, conflicting_serialized_data, dirty_bit, _self_ref_fk, _self_ref_order, deserialization_error, last_transfer_session_id)
208208
= (CASE buffer.hard_deleted WHEN TRUE THEN '' ELSE store.serialized END, store.deleted OR buffer.deleted, '{current_instance_id}',
209209
{current_instance_counter}, store.hard_deleted, store.model_name, store.profile, store.partition, store.source_id,
210-
CASE buffer.hard_deleted WHEN TRUE THEN '' ELSE buffer.serialized || '\n' || store.conflicting_serialized_data END, TRUE, store._self_ref_fk,
210+
CASE buffer.hard_deleted WHEN TRUE THEN '' ELSE buffer.serialized || '\n' || store.conflicting_serialized_data END, TRUE, store._self_ref_fk, store._self_ref_order,
211211
'', '{transfer_session_id}')
212212
/*Scope to a single record.*/
213213
FROM {buffer} AS buffer
@@ -278,26 +278,26 @@ def _dequeuing_insert_remaining_buffer(self, cursor, transfersession_id):
278278
WITH new_values as
279279
(
280280
SELECT buffer.model_uuid, buffer.serialized, buffer.deleted, buffer.last_saved_instance, buffer.last_saved_counter, buffer.hard_deleted,
281-
buffer.model_name, buffer.profile, buffer.partition, buffer.source_id, buffer.conflicting_serialized_data, buffer._self_ref_fk
281+
buffer.model_name, buffer.profile, buffer.partition, buffer.source_id, buffer.conflicting_serialized_data, buffer._self_ref_fk, buffer._self_ref_order
282282
FROM {buffer} as buffer
283283
WHERE buffer.transfer_session_id = '{transfer_session_id}'
284284
),
285285
updated as
286286
(
287287
UPDATE {store} store SET (serialized, deleted, last_saved_instance, last_saved_counter, hard_deleted, model_name, profile,
288-
partition, source_id, conflicting_serialized_data, dirty_bit, _self_ref_fk, deserialization_error, last_transfer_session_id)
288+
partition, source_id, conflicting_serialized_data, dirty_bit, _self_ref_fk, _self_ref_order, deserialization_error, last_transfer_session_id)
289289
= (nv.serialized, nv.deleted, nv.last_saved_instance, nv.last_saved_counter, nv.hard_deleted,
290290
nv.model_name, nv.profile, nv.partition, nv.source_id, nv.conflicting_serialized_data, TRUE,
291-
nv._self_ref_fk, '', '{transfer_session_id}')
291+
nv._self_ref_fk, nv._self_ref_order, '', '{transfer_session_id}')
292292
FROM new_values nv
293293
WHERE nv.model_uuid = store.id
294294
returning store.*
295295
)
296296
INSERT INTO {store}(id, serialized, deleted, last_saved_instance, last_saved_counter, hard_deleted, model_name, profile,
297-
partition, source_id, conflicting_serialized_data, dirty_bit, _self_ref_fk, deserialization_error, last_transfer_session_id)
297+
partition, source_id, conflicting_serialized_data, dirty_bit, _self_ref_fk, _self_ref_order, deserialization_error, last_transfer_session_id)
298298
SELECT ut.model_uuid, ut.serialized, ut.deleted, ut.last_saved_instance, ut.last_saved_counter, ut.hard_deleted,
299299
ut.model_name, ut.profile, ut.partition, ut.source_id, ut.conflicting_serialized_data, TRUE,
300-
ut._self_ref_fk, '', '{transfer_session_id}'
300+
ut._self_ref_fk, ut._self_ref_order, '', '{transfer_session_id}'
301301
FROM new_values ut
302302
WHERE ut.model_uuid not in (SELECT id FROM updated)
303303
""".format(

morango/sync/backends/sqlite.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,10 @@ def _dequeuing_merge_conflict_rmcb(self, cursor, transfersession_id):
137137
def _dequeuing_merge_conflict_buffer(self, cursor, current_id, transfersession_id):
138138
# transfer buffer serialized into conflicting store
139139
merge_conflict_store = """REPLACE INTO {store} (id, serialized, deleted, last_saved_instance, last_saved_counter, hard_deleted, model_name, profile, partition,
140-
source_id, conflicting_serialized_data, dirty_bit, _self_ref_fk, deserialization_error, last_transfer_session_id)
140+
source_id, conflicting_serialized_data, dirty_bit, _self_ref_fk, _self_ref_order, deserialization_error, last_transfer_session_id)
141141
SELECT store.id, CASE buffer.hard_deleted WHEN 1 THEN '' ELSE store.serialized END, store.deleted OR buffer.deleted, '{current_instance_id}',
142142
{current_instance_counter}, store.hard_deleted OR buffer.hard_deleted, store.model_name, store.profile, store.partition, store.source_id,
143-
CASE buffer.hard_deleted WHEN 1 THEN '' ELSE buffer.serialized || '\n' || store.conflicting_serialized_data END, 1, store._self_ref_fk,
143+
CASE buffer.hard_deleted WHEN 1 THEN '' ELSE buffer.serialized || '\n' || store.conflicting_serialized_data END, 1, store._self_ref_fk, store._self_ref_order,
144144
'', '{transfer_session_id}'
145145
FROM {buffer} AS buffer, {store} AS store
146146
/*Scope to a single record.*/
@@ -191,10 +191,10 @@ def _dequeuing_update_rmcs_last_saved_by(
191191
def _dequeuing_insert_remaining_buffer(self, cursor, transfersession_id):
192192
# insert remaining records into store
193193
insert_remaining_buffer = """REPLACE INTO {store} (id, serialized, deleted, last_saved_instance, last_saved_counter, hard_deleted, model_name, profile, partition,
194-
source_id, conflicting_serialized_data, dirty_bit, _self_ref_fk, deserialization_error, last_transfer_session_id)
194+
source_id, conflicting_serialized_data, dirty_bit, _self_ref_fk, _self_ref_order, deserialization_error, last_transfer_session_id)
195195
SELECT buffer.model_uuid, buffer.serialized, buffer.deleted, buffer.last_saved_instance, buffer.last_saved_counter, buffer.hard_deleted,
196196
buffer.model_name, buffer.profile, buffer.partition, buffer.source_id, buffer.conflicting_serialized_data, 1,
197-
buffer._self_ref_fk, '', '{transfer_session_id}'
197+
buffer._self_ref_fk, buffer._self_ref_order, '', '{transfer_session_id}'
198198
FROM {buffer} AS buffer
199199
WHERE buffer.transfer_session_id = '{transfer_session_id}'
200200
""".format(

morango/sync/operations.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ def _queue_into_buffer_v1(transfersession):
483483
"""SELECT
484484
id, serialized, deleted, last_saved_instance, last_saved_counter, hard_deleted, model_name, profile,
485485
partition, source_id, conflicting_serialized_data,
486-
CAST ('{transfer_session_id}' AS {transfer_session_id_type}), _self_ref_fk
486+
CAST ('{transfer_session_id}' AS {transfer_session_id_type}), _self_ref_fk, _self_ref_order
487487
FROM {store} WHERE {condition}
488488
""".format(
489489
transfer_session_id=transfersession.id,
@@ -514,7 +514,7 @@ def _queue_into_buffer_v1(transfersession):
514514
"""INSERT INTO {outgoing_buffer}
515515
(model_uuid, serialized, deleted, last_saved_instance, last_saved_counter,
516516
hard_deleted, model_name, profile, partition, source_id, conflicting_serialized_data,
517-
transfer_session_id, _self_ref_fk)
517+
transfer_session_id, _self_ref_fk, _self_ref_order)
518518
{select}
519519
""".format(
520520
outgoing_buffer=Buffer._meta.db_table,
@@ -632,7 +632,7 @@ def _queue_into_buffer_v2(transfersession, chunk_size=200):
632632
"""SELECT
633633
id, serialized, deleted, last_saved_instance, last_saved_counter, hard_deleted, model_name, profile,
634634
partition, source_id, conflicting_serialized_data,
635-
CAST ('{transfer_session_id}' AS {transfer_session_id_type}), _self_ref_fk
635+
CAST ('{transfer_session_id}' AS {transfer_session_id_type}), _self_ref_fk, _self_ref_order
636636
FROM {store} WHERE {condition}
637637
""".format(
638638
transfer_session_id=transfersession.id,
@@ -661,7 +661,7 @@ def _queue_into_buffer_v2(transfersession, chunk_size=200):
661661
"""INSERT INTO {outgoing_buffer}
662662
(model_uuid, serialized, deleted, last_saved_instance, last_saved_counter,
663663
hard_deleted, model_name, profile, partition, source_id, conflicting_serialized_data,
664-
transfer_session_id, _self_ref_fk)
664+
transfer_session_id, _self_ref_fk, _self_ref_order)
665665
{select}
666666
""".format(
667667
outgoing_buffer=Buffer._meta.db_table,

tests/testapp/tests/sync/test_operations.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ def test_all_fsics(self):
8888
assertRecordsBuffered(self.data["group1_c2"])
8989
assertRecordsBuffered(self.data["group2_c1"])
9090

91+
def test_self_ref_order_propagates_to_buffer(self):
92+
Store.objects.update(_self_ref_order=42)
93+
fsics = {self.data["group1_id"].id: 1, self.data["group2_id"].id: 1}
94+
self.transfer_session.client_fsic = json.dumps(fsics)
95+
_queue_into_buffer_v1(self.transfer_session)
96+
self.assertTrue(Buffer.objects.exists())
97+
self.assertFalse(Buffer.objects.exclude(_self_ref_order=42).exists())
98+
9199
def test_very_many_fsics(self):
92100
"""
93101
Regression test against 'Expression tree is too large (maximum depth 1000)' error with many fsics
@@ -278,6 +286,18 @@ def setUp(self):
278286
capabilities=[FSIC_V2_FORMAT],
279287
)
280288

289+
def test_self_ref_order_propagates_to_buffer(self):
290+
Store.objects.update(_self_ref_order=42)
291+
fsics = {
292+
"super": {},
293+
"sub": {"": {self.data["group1_id"].id: 1, self.data["group2_id"].id: 1}},
294+
}
295+
self.transfer_session.client_fsic = json.dumps(fsics)
296+
self.transfer_session.server_fsic = json.dumps({"super": {}, "sub": {}})
297+
_queue_into_buffer_v2(self.transfer_session)
298+
self.assertTrue(Buffer.objects.exists())
299+
self.assertFalse(Buffer.objects.exclude(_self_ref_order=42).exists())
300+
281301
# @pytest.mark.skip("Takes 30+ seconds, manual run only")
282302
def test_very_many_instances_in_fsic(self):
283303
"""
@@ -788,6 +808,14 @@ def test_dequeuing_merge_conflict_hard_delete(self):
788808
self.assertEqual(store.serialized, "")
789809
self.assertEqual(store.conflicting_serialized_data, "")
790810

811+
def test_dequeuing_merge_conflict_buffer__self_ref_order_preserved(self):
812+
Store.objects.filter(id=self.data["model2"]).update(_self_ref_order=11)
813+
Buffer.objects.filter(model_uuid=self.data["model2"]).update(_self_ref_order=99)
814+
with connection.cursor() as cursor:
815+
current_id = InstanceIDModel.get_current_instance_and_increment_counter()
816+
DBBackend._dequeuing_merge_conflict_buffer(cursor, current_id, self.transfer_session.id)
817+
self.assertEqual(Store.objects.get(id=self.data["model2"])._self_ref_order, 11)
818+
791819
def test_dequeuing_update_rmcs_last_saved_by(self):
792820
self.assertFalse(RecordMaxCounter.objects.filter(instance_id=self.current_id.id).exists())
793821
with connection.cursor() as cursor:
@@ -842,6 +870,13 @@ def test_dequeuing_insert_remaining_buffer(self):
842870
self.assertEqual(Store.objects.get(id=self.data["model3"]).serialized, "buffer")
843871
self.assertTrue(Store.objects.filter(id=self.data["model4"]).exists())
844872

873+
def test_dequeuing_insert_remaining_buffer__self_ref_order_propagates(self):
874+
Buffer.objects.filter(model_uuid=self.data["model4"]).update(_self_ref_order=7)
875+
self.assertFalse(Store.objects.filter(id=self.data["model4"]).exists())
876+
with connection.cursor() as cursor:
877+
DBBackend._dequeuing_insert_remaining_buffer(cursor, self.transfer_session.id)
878+
self.assertEqual(Store.objects.get(id=self.data["model4"])._self_ref_order, 7)
879+
845880
def test_dequeuing_insert_remaining_rmcb(self):
846881
for i in self.data["model4_rmcb_ids"]:
847882
self.assertFalse(

tests/testapp/tests/test_api.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,12 @@ def test_buffer_serializer_makes_no_transfer_session_query(self):
986986
for q in ctx.captured_queries:
987987
self.assertFalse("morango_transfersession" in q["sql"])
988988

989+
def test_buffer_serializer_includes_self_ref_order(self):
990+
transfer_session_id = self.create_records_for_pulling()
991+
Buffer.objects.filter(transfer_session_id=transfer_session_id).update(_self_ref_order=4)
992+
buffer = Buffer.objects.filter(transfer_session_id=transfer_session_id).first()
993+
self.assertEqual(BufferSerializer(instance=buffer).data["_self_ref_order"], 4)
994+
989995
def test_pull_valid_buffer_list(self):
990996

991997
transfer_session_id = self.create_records_for_pulling()

0 commit comments

Comments
 (0)