cult-of-coders / redis-oplog

Redis Oplog implementation to fully replace MongoDB Oplog in Meteor
MIT License
376 stars 81 forks source link

collection.update with options.upsert set to true is returning an object rather than a number #375

Closed wkeithchau closed 1 year ago

wkeithchau commented 3 years ago

There is a bug with using collection.update with upsert:true. collection.update should always be return the number of matched documents. When redis-oplog is in use, using collection.update with options.upsert set tot true returns an object with numberAffected and insertedId (this is an output similar to when using collection.upsert).

I did some digging and it looks like when upsert is true for an update, it will call Mutator._handleUpsert, this explains why it returns like an upsert. A possible fix is to attach _returnObject: false to the config that is passed into _handleUpsert and switch around how the config fields are merged together for the Originals.update.call in _handleUpsert.

Here are some basic assertions that can be used to verify the fix:

const fooCollection = new Mongo.Collection('foo')

const updateRes = fooCollection.update(
    { name: 'Test 0' },
    { $set: { colour: 'white' } },
)
expect(updateRes).to.be.a('number')

const updateUpsertRes = fooCollection.update(
    { name: 'Test 1' },
    { $set: { colour: 'red' } },
    { upsert: true },
)
expect(updateUpsertRes).to.be.a('number')

const upsertRes = fooCollection.upsert(
    { name: 'Test 2' },
    { $set: { colour: 'blue' } },
)
expect(upsertRes).to.be.an('object')
expect(upsertRes).to.have.property('numberAffected')
expect(upsertRes).to.have.property('insertedId')