Skip to content

Commit

Permalink
FIX #3498 Query returns outdated result in second subscription
Browse files Browse the repository at this point in the history
  • Loading branch information
pubkey committed Nov 23, 2021
1 parent 4f56a47 commit 21efd35
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 9 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Bugfixes:
- LokiJS: Do not call `saveDatabase()` when no persistence adapter is given.

- Query returns outdated result in second subscription [#3498](https://github.com/pubkey/rxdb/issues/3498) Thanks [@swnf](https://github.com/swnf)
### 10.5.3 (19 November 2021)

Bugfixes:
Expand Down
17 changes: 10 additions & 7 deletions src/rx-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
mergeMap,
filter,
map,
tap
tap,
shareReplay
} from 'rxjs/operators';
import {
sortObject,
Expand Down Expand Up @@ -46,7 +47,7 @@ import {
} from './rx-document-prototype-merge';
import { calculateNewResults } from './event-reduce';
import { triggerCacheReplacement } from './query-cache';
import { getStateSet, QueryMatcher } from 'event-reduce-js';
import type { QueryMatcher } from 'event-reduce-js';
import { _handleToStorageInstance } from './rx-collection-helper';

let _queryCount = 0;
Expand Down Expand Up @@ -105,7 +106,10 @@ export class RxQueryBase<
}
});
}),
filter((docs: any[]) => !!docs), // not if previous returned false
// not if previous returned false
filter((docs: any[]) => !!docs),
// copy the array so it wont matter if the user modifies it
map((docs: any[]) => docs.slice(0)),
map((docs: any[]) => {
if (this.op === 'findOne') {
// findOne()-queries emit document or null
Expand All @@ -116,10 +120,9 @@ export class RxQueryBase<
return docs;
}
}),
map(docs => {
// copy the array so it wont matter if the user modifies it
const ret = Array.isArray(docs) ? docs.slice() : docs;
return ret;
shareReplay({
bufferSize: 1,
refCount: true
})
).asObservable();

Expand Down
2 changes: 1 addition & 1 deletion test/unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import './unit/rx-schema.test.js';
import './unit/key-compression.test.js';
import './unit/bug-report.test.js';
import './unit/rx-database.test.js';
import './unit/event-reduce.test.js'; // TODO move down under idle queue
import './unit/rx-collection.test.js';
import './unit/rx-document.test.js';
import './unit/primary.test.js';
Expand All @@ -20,6 +19,7 @@ import './unit/cache-replacement-policy.test';
import './unit/rx-query.test.js';
import './unit/query-builder.test.js';
import './unit/idle-queue.test.js';
import './unit/event-reduce.test.js';
import './unit/reactive-collection.test.js';
import './unit/reactive-query.test.js';
import './unit/reactive-document.test.js';
Expand Down
54 changes: 54 additions & 0 deletions test/unit/rx-query.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1456,6 +1456,60 @@ config.parallel('rx-query.test.js', () => {
assert.ok(res2);
assert.strictEqual(resOne2.age, 42);

db.destroy();
});
it('#3498 RxQuery returns outdated result in second subscription', async () => {
const schema = {
version: 0,
primaryKey: 'id',
type: 'object',
properties: {
id: {
type: 'string'
},
field: {
type: 'boolean'
}
}
};
const db = await createRxDatabase({
name: randomCouchString(10),
storage: getRxStoragePouch('memory'),
eventReduce: true,
ignoreDuplicate: true
});
const collection = (await db.addCollections({
collection: {
schema
}
})).collection;

const doc = await collection.insert({ id: 'testid', field: false });

// Bug only happens the second time the query is used
const result1 = await collection.find({ selector: { field: false } }).exec();
assert.strictEqual(result1.length, 1);

await doc.update({
$set: {
field: true
}
});

const obs = collection.find({ selector: { field: false } }).$;
const result2a: any[][] = [];
const result2b: any[][] = [];
const sub2 = obs.subscribe((d) => result2b.push(d));
const sub1 = obs.subscribe((d) => result2a.push(d));

await promiseWait(5);

sub1.unsubscribe();
sub2.unsubscribe();

assert.strictEqual(Math.max(...result2a.map(r => r.length)), 0);
assert.strictEqual(Math.max(...result2b.map(r => r.length)), 0);

db.destroy();
});
});
Expand Down

0 comments on commit 21efd35

Please sign in to comment.