From eed589d9f11f31924a7e32955cb773dd1fe26cb9 Mon Sep 17 00:00:00 2001 From: Corey Date: Mon, 22 Nov 2021 20:31:02 -0500 Subject: [PATCH 1/7] Fix createObject for postgres --- src/Adapters/Storage/Postgres/PostgresStorageAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js index e6c2bdbb1b..1c0c58fa14 100644 --- a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -1280,7 +1280,7 @@ export class PostgresStorageAdapter implements StorageAdapter { validateKeys(object); Object.keys(object).forEach(fieldName => { - if (object[fieldName] === null) { + if (object[fieldName] === null || schema.fields[fieldName] === null) { return; } var authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/); From f083c546728f93d45f07246780ade92cd3b29ae5 Mon Sep 17 00:00:00 2001 From: Corey Date: Mon, 22 Nov 2021 20:35:13 -0500 Subject: [PATCH 2/7] Try xit CloudCode test --- spec/CloudCode.spec.js | 65 +++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index d5e6113763..36843c8c44 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -1391,44 +1391,37 @@ describe('Cloud Code', () => { }); }); - /* - TODO: fix for Postgres - trying to delete a field that doesn't exists doesn't play nice - */ - it_exclude_dbs(['postgres'])( - 'should fully delete objects when using `unset` and `set` with beforeSave (regression test for #1840)', - done => { - const TestObject = Parse.Object.extend('TestObject'); - const BeforeSaveObject = Parse.Object.extend('BeforeSaveChanged'); - - Parse.Cloud.beforeSave('BeforeSaveChanged', req => { - const object = req.object; - object.set('before', 'save'); - object.unset('remove'); - }); + it('should fully delete objects when using `unset` and `set` with beforeSave (regression test for #1840)', done => { + const TestObject = Parse.Object.extend('TestObject'); + const BeforeSaveObject = Parse.Object.extend('BeforeSaveChanged'); - let object; - const testObject = new TestObject({ key: 'value' }); - testObject - .save() - .then(() => { - object = new BeforeSaveObject(); - return object.save().then(() => { - object.set({ remove: testObject }); - return object.save(); - }); - }) - .then(objectAgain => { - expect(objectAgain.get('remove')).toBeUndefined(); - expect(object.get('remove')).toBeUndefined(); - done(); - }) - .catch(err => { - jfail(err); - done(); + Parse.Cloud.beforeSave('BeforeSaveChanged', req => { + const object = req.object; + object.set('before', 'save'); + object.unset('remove'); + }); + + let object; + const testObject = new TestObject({ key: 'value' }); + testObject + .save() + .then(() => { + object = new BeforeSaveObject(); + return object.save().then(() => { + object.set({ remove: testObject }); + return object.save(); }); - } - ); + }) + .then(objectAgain => { + expect(objectAgain.get('remove')).toBeUndefined(); + expect(object.get('remove')).toBeUndefined(); + done(); + }) + .catch(err => { + jfail(err); + done(); + }); + }); it('should not include relation op (regression test for #1606)', done => { const TestObject = Parse.Object.extend('TestObject'); From bbbd0d438f732d0619a9dd256a1bbaacb2474182 Mon Sep 17 00:00:00 2001 From: Corey Date: Mon, 22 Nov 2021 20:46:12 -0500 Subject: [PATCH 3/7] revert test --- spec/CloudCode.spec.js | 65 +++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index 36843c8c44..d5e6113763 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -1391,37 +1391,44 @@ describe('Cloud Code', () => { }); }); - it('should fully delete objects when using `unset` and `set` with beforeSave (regression test for #1840)', done => { - const TestObject = Parse.Object.extend('TestObject'); - const BeforeSaveObject = Parse.Object.extend('BeforeSaveChanged'); - - Parse.Cloud.beforeSave('BeforeSaveChanged', req => { - const object = req.object; - object.set('before', 'save'); - object.unset('remove'); - }); + /* + TODO: fix for Postgres + trying to delete a field that doesn't exists doesn't play nice + */ + it_exclude_dbs(['postgres'])( + 'should fully delete objects when using `unset` and `set` with beforeSave (regression test for #1840)', + done => { + const TestObject = Parse.Object.extend('TestObject'); + const BeforeSaveObject = Parse.Object.extend('BeforeSaveChanged'); + + Parse.Cloud.beforeSave('BeforeSaveChanged', req => { + const object = req.object; + object.set('before', 'save'); + object.unset('remove'); + }); - let object; - const testObject = new TestObject({ key: 'value' }); - testObject - .save() - .then(() => { - object = new BeforeSaveObject(); - return object.save().then(() => { - object.set({ remove: testObject }); - return object.save(); + let object; + const testObject = new TestObject({ key: 'value' }); + testObject + .save() + .then(() => { + object = new BeforeSaveObject(); + return object.save().then(() => { + object.set({ remove: testObject }); + return object.save(); + }); + }) + .then(objectAgain => { + expect(objectAgain.get('remove')).toBeUndefined(); + expect(object.get('remove')).toBeUndefined(); + done(); + }) + .catch(err => { + jfail(err); + done(); }); - }) - .then(objectAgain => { - expect(objectAgain.get('remove')).toBeUndefined(); - expect(object.get('remove')).toBeUndefined(); - done(); - }) - .catch(err => { - jfail(err); - done(); - }); - }); + } + ); it('should not include relation op (regression test for #1606)', done => { const TestObject = Parse.Object.extend('TestObject'); From 685a0898eddedc1a9e1c58640693283b921a9453 Mon Sep 17 00:00:00 2001 From: Corey Date: Wed, 24 Nov 2021 08:20:55 -0800 Subject: [PATCH 4/7] move testcase to correct place --- spec/CloudCode.spec.js | 84 ++++++++++++++----- .../Postgres/PostgresStorageAdapter.js | 9 +- src/Controllers/DatabaseController.js | 4 +- 3 files changed, 73 insertions(+), 24 deletions(-) diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index d5e6113763..3295594db5 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -1998,6 +1998,44 @@ describe('beforeFind hooks', () => { }); }); }); + /* + it('should use the modified the query.and', async () => { + Parse.Cloud.beforeFind('MyObject', req => { + const additionalQ = new Parse.Query('MyObject'); + additionalQ.equalTo('forced', true); + return Parse.Query.and(req.query, additionalQ); + }); + + const obj0 = Parse.Object.extend('MyObject'); + obj0.set('forced', false); + const obj1 = Parse.Object.extend('MyObject'); + obj1.set('forced', true); + + Parse.Object.saveAll([obj0, obj1]); + const q = new Parse.Query('MyObject'); + q.equalTo('forced', false); + const res = await q.find(); + expect(res.id).toEqual(item1.id); + });*/ + + it('should have object found with nested relational data query', async () => { + const obj1 = Parse.Object.extend('TestObject'); + const obj2 = Parse.Object.extend('TestObject2'); + let item2 = new obj2(); + item2 = await item2.save(); + let item1 = new obj1(); + const relation = item1.relation('rel'); + relation.add(item2); + item1 = await item1.save(); + Parse.Cloud.beforeFind('TestObject', req => { + const additionalQ = new Parse.Query('TestObject'); + additionalQ.equalTo('rel', item2); + return Parse.Query.and(req.query, additionalQ); + }); + const q = new Parse.Query('TestObject'); + const res = await q.first(); + expect(res.id).toEqual(item1.id); + }); it('should use the modified exclude query', async () => { Parse.Cloud.beforeFind('MyObject', req => { @@ -2421,6 +2459,33 @@ describe('afterFind hooks', () => { expect(pointer.get('foo')).toBe('bar'); }); + it('can set a pointer object in afterFind with User', async () => { + await Parse.User.signUp('tupac', 'shakur'); + const obj = new Parse.Object('MyObject'); + obj.set('xyz', 'yolo'); + await obj.save(); + Parse.Cloud.afterFind('MyObject', async ({ user, objects }) => { + const otherObject = new Parse.Object('Test'); + otherObject.set('foo', 'bar'); + otherObject.set('user', user); + for (const property in objects[0].attributes) { + if (Object.prototype.hasOwnProperty.call(objects[0].attributes, property)) { + otherObject.set(property, objects[0].attributes[property]); + } + } + await otherObject.save(null, { useMasterKey: true }); + const query = new Parse.Query('Test'); + query.equalTo('foo', 'bar'); + const obj = await query.first(); + expect(obj.get('user').id).toEqual(user.id); + expect(obj.get('xyz')).toBe('yolo'); + }); + const query = new Parse.Query('MyObject'); + query.equalTo('objectId', obj.id); + const obj2 = await query.first(); + expect(obj2.get('xyz')).toBe('yolo'); + }); + it('can set invalid object in afterFind', async () => { const obj = new Parse.Object('MyObject'); await obj.save(); @@ -3516,23 +3581,4 @@ describe('sendEmail', () => { 'Failed to send email because no mail adapter is configured for Parse Server.' ); }); - - it('should have object found with nested relational data query', async () => { - const obj1 = Parse.Object.extend('TestObject'); - const obj2 = Parse.Object.extend('TestObject2'); - let item2 = new obj2(); - item2 = await item2.save(); - let item1 = new obj1(); - const relation = item1.relation('rel'); - relation.add(item2); - item1 = await item1.save(); - Parse.Cloud.beforeFind('TestObject', req => { - const additionalQ = new Parse.Query('TestObject'); - additionalQ.equalTo('rel', item2); - return Parse.Query.and(req.query, additionalQ); - }); - const q = new Parse.Query('TestObject'); - const res = await q.first(); - expect(res.id).toEqual(item1.id); - }); }); diff --git a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js index 1c0c58fa14..80415b2215 100644 --- a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -1278,9 +1278,9 @@ export class PostgresStorageAdapter implements StorageAdapter { object = handleDotFields(object); validateKeys(object); - + console.log('*********1' + object); Object.keys(object).forEach(fieldName => { - if (object[fieldName] === null || schema.fields[fieldName] === null) { + if (object[fieldName] === null) { return; } var authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/); @@ -1294,6 +1294,7 @@ export class PostgresStorageAdapter implements StorageAdapter { columnsArray.push(fieldName); if (!schema.fields[fieldName] && className === '_User') { + console.log('********2'); if ( fieldName === '_email_verify_token' || fieldName === '_failed_login_count' || @@ -1324,6 +1325,8 @@ export class PostgresStorageAdapter implements StorageAdapter { } return; } + console.log('********3' + fieldName); + console.log('********4' + schema.fields); switch (schema.fields[fieldName].type) { case 'Date': if (object[fieldName]) { @@ -1366,7 +1369,7 @@ export class PostgresStorageAdapter implements StorageAdapter { throw `Type ${schema.fields[fieldName].type} not supported yet`; } }); - + console.log('********5'); columnsArray = columnsArray.concat(Object.keys(geoPoints)); const initialValues = valuesArray.map((val, index) => { let termination = ''; diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index 20d5c4ba66..158308ded3 100644 --- a/src/Controllers/DatabaseController.js +++ b/src/Controllers/DatabaseController.js @@ -972,9 +972,9 @@ class DatabaseController { }); } if (query['$and']) { - const ors = query['$and']; + const ands = query['$and']; return Promise.all( - ors.map((aQuery, index) => { + ands.map((aQuery, index) => { return this.reduceInRelation(className, aQuery, schema).then(aQuery => { query['$and'][index] = aQuery; }); From 56a9f5000a5cdf1808929eb851798a9366b26eed Mon Sep 17 00:00:00 2001 From: Corey Date: Wed, 24 Nov 2021 09:25:43 -0800 Subject: [PATCH 5/7] remove debug statements --- spec/CloudCode.spec.js | 19 ------------------- .../Postgres/PostgresStorageAdapter.js | 5 ----- 2 files changed, 24 deletions(-) diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index 3295594db5..c05a2d6305 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -1998,25 +1998,6 @@ describe('beforeFind hooks', () => { }); }); }); - /* - it('should use the modified the query.and', async () => { - Parse.Cloud.beforeFind('MyObject', req => { - const additionalQ = new Parse.Query('MyObject'); - additionalQ.equalTo('forced', true); - return Parse.Query.and(req.query, additionalQ); - }); - - const obj0 = Parse.Object.extend('MyObject'); - obj0.set('forced', false); - const obj1 = Parse.Object.extend('MyObject'); - obj1.set('forced', true); - - Parse.Object.saveAll([obj0, obj1]); - const q = new Parse.Query('MyObject'); - q.equalTo('forced', false); - const res = await q.find(); - expect(res.id).toEqual(item1.id); - });*/ it('should have object found with nested relational data query', async () => { const obj1 = Parse.Object.extend('TestObject'); diff --git a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js index 80415b2215..0e605d9b52 100644 --- a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -1278,7 +1278,6 @@ export class PostgresStorageAdapter implements StorageAdapter { object = handleDotFields(object); validateKeys(object); - console.log('*********1' + object); Object.keys(object).forEach(fieldName => { if (object[fieldName] === null) { return; @@ -1294,7 +1293,6 @@ export class PostgresStorageAdapter implements StorageAdapter { columnsArray.push(fieldName); if (!schema.fields[fieldName] && className === '_User') { - console.log('********2'); if ( fieldName === '_email_verify_token' || fieldName === '_failed_login_count' || @@ -1325,8 +1323,6 @@ export class PostgresStorageAdapter implements StorageAdapter { } return; } - console.log('********3' + fieldName); - console.log('********4' + schema.fields); switch (schema.fields[fieldName].type) { case 'Date': if (object[fieldName]) { @@ -1369,7 +1365,6 @@ export class PostgresStorageAdapter implements StorageAdapter { throw `Type ${schema.fields[fieldName].type} not supported yet`; } }); - console.log('********5'); columnsArray = columnsArray.concat(Object.keys(geoPoints)); const initialValues = valuesArray.map((val, index) => { let termination = ''; From a86a64979ba2f0775bcf8ad7526df8241d8746ed Mon Sep 17 00:00:00 2001 From: Corey Date: Wed, 24 Nov 2021 09:29:43 -0800 Subject: [PATCH 6/7] nits --- spec/CloudCode.spec.js | 27 ------------------- .../Postgres/PostgresStorageAdapter.js | 1 + 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index c05a2d6305..c185eac53e 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -2440,33 +2440,6 @@ describe('afterFind hooks', () => { expect(pointer.get('foo')).toBe('bar'); }); - it('can set a pointer object in afterFind with User', async () => { - await Parse.User.signUp('tupac', 'shakur'); - const obj = new Parse.Object('MyObject'); - obj.set('xyz', 'yolo'); - await obj.save(); - Parse.Cloud.afterFind('MyObject', async ({ user, objects }) => { - const otherObject = new Parse.Object('Test'); - otherObject.set('foo', 'bar'); - otherObject.set('user', user); - for (const property in objects[0].attributes) { - if (Object.prototype.hasOwnProperty.call(objects[0].attributes, property)) { - otherObject.set(property, objects[0].attributes[property]); - } - } - await otherObject.save(null, { useMasterKey: true }); - const query = new Parse.Query('Test'); - query.equalTo('foo', 'bar'); - const obj = await query.first(); - expect(obj.get('user').id).toEqual(user.id); - expect(obj.get('xyz')).toBe('yolo'); - }); - const query = new Parse.Query('MyObject'); - query.equalTo('objectId', obj.id); - const obj2 = await query.first(); - expect(obj2.get('xyz')).toBe('yolo'); - }); - it('can set invalid object in afterFind', async () => { const obj = new Parse.Object('MyObject'); await obj.save(); diff --git a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js index 0e605d9b52..6aef00186f 100644 --- a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -1365,6 +1365,7 @@ export class PostgresStorageAdapter implements StorageAdapter { throw `Type ${schema.fields[fieldName].type} not supported yet`; } }); + columnsArray = columnsArray.concat(Object.keys(geoPoints)); const initialValues = valuesArray.map((val, index) => { let termination = ''; From e820faa004a1304732d255fd96f3391430027fd0 Mon Sep 17 00:00:00 2001 From: Corey Date: Wed, 24 Nov 2021 09:31:12 -0800 Subject: [PATCH 7/7] nits --- src/Adapters/Storage/Postgres/PostgresStorageAdapter.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js index 6aef00186f..e6c2bdbb1b 100644 --- a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -1278,6 +1278,7 @@ export class PostgresStorageAdapter implements StorageAdapter { object = handleDotFields(object); validateKeys(object); + Object.keys(object).forEach(fieldName => { if (object[fieldName] === null) { return;