Skip to content

Commit c4a4a2a

Browse files
authored
feat: Add $setOnInsert operator to Parse.Server.database.update (#8790)
1 parent ff4639a commit c4a4a2a

File tree

3 files changed

+66
-1
lines changed

3 files changed

+66
-1
lines changed

spec/MongoStorageAdapter.spec.js

+55
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,61 @@ describe_only_db('mongo')('MongoStorageAdapter', () => {
213213
});
214214
});
215215

216+
it('upserts with $setOnInsert', async () => {
217+
const uuid = require('uuid');
218+
const uuid1 = uuid.v4();
219+
const uuid2 = uuid.v4();
220+
const schema = {
221+
className: 'MyClass',
222+
fields: {
223+
x: { type: 'Number' },
224+
count: { type: 'Number' },
225+
},
226+
classLevelPermissions: {},
227+
};
228+
229+
const myClassSchema = new Parse.Schema(schema.className);
230+
myClassSchema.setCLP(schema.classLevelPermissions);
231+
await myClassSchema.save();
232+
233+
const query = {
234+
x: 1,
235+
};
236+
const update = {
237+
objectId: {
238+
__op: 'SetOnInsert',
239+
amount: uuid1,
240+
},
241+
count: {
242+
__op: 'Increment',
243+
amount: 1,
244+
},
245+
};
246+
await Parse.Server.database.update(
247+
'MyClass',
248+
query,
249+
update,
250+
{ upsert: true },
251+
);
252+
update.objectId.amount = uuid2;
253+
await Parse.Server.database.update(
254+
'MyClass',
255+
query,
256+
update,
257+
{ upsert: true },
258+
);
259+
260+
const res = await Parse.Server.database.find(
261+
schema.className,
262+
{},
263+
{},
264+
);
265+
expect(res.length).toBe(1);
266+
expect(res[0].objectId).toBe(uuid1);
267+
expect(res[0].count).toBe(2);
268+
expect(res[0].x).toBe(1);
269+
});
270+
216271
it('handles updating a single object with array, object date', done => {
217272
const adapter = new MongoStorageAdapter({ uri: databaseURI });
218273

src/Adapters/Storage/Mongo/MongoTransform.js

+7
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,13 @@ function transformUpdateOperator({ __op, amount, objects }, flatten) {
976976
return { __op: '$inc', arg: amount };
977977
}
978978

979+
case 'SetOnInsert':
980+
if (flatten) {
981+
return amount;
982+
} else {
983+
return { __op: '$setOnInsert', arg: amount };
984+
}
985+
979986
case 'Add':
980987
case 'AddUnique':
981988
if (!(objects instanceof Array)) {

src/Controllers/DatabaseController.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,9 @@ const flattenUpdateOperatorsForCreate = object => {
272272
}
273273
object[key] = object[key].amount;
274274
break;
275+
case 'SetOnInsert':
276+
object[key] = object[key].amount;
277+
break;
275278
case 'Add':
276279
if (!(object[key].objects instanceof Array)) {
277280
throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to add must be an array');
@@ -1813,7 +1816,7 @@ class DatabaseController {
18131816
keyUpdate &&
18141817
typeof keyUpdate === 'object' &&
18151818
keyUpdate.__op &&
1816-
['Add', 'AddUnique', 'Remove', 'Increment'].indexOf(keyUpdate.__op) > -1
1819+
['Add', 'AddUnique', 'Remove', 'Increment', 'SetOnInsert'].indexOf(keyUpdate.__op) > -1
18171820
) {
18181821
// only valid ops that produce an actionable result
18191822
// the op may have happened on a keypath

0 commit comments

Comments
 (0)