From 5e7c9d2e1ad9e9935480544d9b881dccd9ccfa1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kartal=20Kaan=20Bozdo=C4=9Fan?= Date: Wed, 26 May 2021 01:33:40 +0300 Subject: [PATCH] Fixed a bug affecting updates to nested pointers (#7392) * Fixed a bug affecting updates to nested pointers Also created unit tests * Marked the regression test for #7391 as pending for postgre The issue is not fixed yet Use cont instead of var --- spec/ParseAPI.spec.js | 22 ++++++++++++++++++++ src/Adapters/Storage/Mongo/MongoTransform.js | 17 +++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/spec/ParseAPI.spec.js b/spec/ParseAPI.spec.js index 76143e0580..98f462c787 100644 --- a/spec/ParseAPI.spec.js +++ b/spec/ParseAPI.spec.js @@ -646,6 +646,28 @@ describe('miscellaneous', function () { }); }); + it_only_db('mongo')('pointer reassign on nested fields is working properly (#7391)', async () => { + const obj = new Parse.Object('GameScore'); // This object will include nested pointers + const ptr1 = new Parse.Object('GameScore'); + await ptr1.save(); // Obtain a unique id + const ptr2 = new Parse.Object('GameScore'); + await ptr2.save(); // Obtain a unique id + obj.set('data', { ptr: ptr1 }); + await obj.save(); + + obj.set('data.ptr', ptr2); + await obj.save(); + + const obj2 = await new Parse.Query('GameScore').get(obj.id); + expect(obj2.get('data').ptr.id).toBe(ptr2.id); + + const query = new Parse.Query('GameScore'); + query.equalTo('data.ptr', ptr2); + const res = await query.find(); + expect(res.length).toBe(1); + expect(res[0].get('data').ptr.id).toBe(ptr2.id); + }); + it('test afterSave get full object on create and update', function (done) { let triggerTime = 0; // Register a mock beforeSave hook diff --git a/src/Adapters/Storage/Mongo/MongoTransform.js b/src/Adapters/Storage/Mongo/MongoTransform.js index c591522479..5578077778 100644 --- a/src/Adapters/Storage/Mongo/MongoTransform.js +++ b/src/Adapters/Storage/Mongo/MongoTransform.js @@ -99,7 +99,10 @@ const transformKeyValueForUpdate = (className, restKey, restValue, parseFormatSc if ( (parseFormatSchema.fields[key] && parseFormatSchema.fields[key].type === 'Pointer') || - (!parseFormatSchema.fields[key] && restValue && restValue.__type == 'Pointer') + (!key.includes('.') && + !parseFormatSchema.fields[key] && + restValue && + restValue.__type == 'Pointer') // Do not use the _p_ prefix for pointers inside nested documents ) { key = '_p_' + key; } @@ -305,7 +308,10 @@ function transformQueryKeyValue(className, key, value, schema, count = false) { schema && schema.fields[key] && schema.fields[key].type === 'Pointer'; const field = schema && schema.fields[key]; - if (expectedTypeIsPointer || (!schema && value && value.__type === 'Pointer')) { + if ( + expectedTypeIsPointer || + (!schema && !key.includes('.') && value && value.__type === 'Pointer') + ) { key = '_p_' + key; } @@ -326,8 +332,11 @@ function transformQueryKeyValue(className, key, value, schema, count = false) { } // Handle atomic values - if (transformTopLevelAtom(value) !== CannotTransform) { - return { key, value: transformTopLevelAtom(value) }; + const transformRes = key.includes('.') + ? transformInteriorAtom(value) + : transformTopLevelAtom(value); + if (transformRes !== CannotTransform) { + return { key, value: transformRes }; } else { throw new Parse.Error( Parse.Error.INVALID_JSON,