Skip to content

Commit

Permalink
FIX bulk inserting 2 docs with same primary key should throw #6589 (#…
Browse files Browse the repository at this point in the history
…6595)

* FIX bulk inserting 2 docs with same primary key should throw #6589

* FIX error meta
  • Loading branch information
pubkey authored Nov 17, 2024
1 parent 33fccc8 commit dcc3297
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 1 deletion.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<!-- CHANGELOG NEWEST -->

- FIX findByIds not working with modify and patch [#6592](https://github.com/pubkey/rxdb/pull/6592)

- FIX bulk inserting 2 docs with same primary key should throw [#6589](https://github.com/pubkey/rxdb/pull/6589)
<!-- ADD new changes here! -->

<!-- /CHANGELOG NEWEST -->
Expand Down
1 change: 1 addition & 0 deletions src/plugins/dev-mode/error-messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export const ERROR_MESSAGES = {
COL20: 'Storage write error',
COL21: 'The RxCollection is destroyed or removed already, either from this JavaScript realm or from another, like a browser tab',
CONFLICT: 'Document update conflict. When changing a document you must work on the previous revision',
COL22: '.bulkInsert() and .bulkUpsert() cannot be run with multiple documents that have the same primary key',

// rx-document.js
DOC1: 'RxDocument.get$ cannot get observable of in-array fields because order cannot be guessed',
Expand Down
13 changes: 13 additions & 0 deletions src/rx-collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ export class RxCollectionBase<

const primaryPath = this.schema.primaryPath;

const ids = new Set<string>();

/**
* This code is a bit redundant for better performance.
Expand All @@ -386,6 +387,7 @@ export class RxCollectionBase<
if (this.hasHooks('pre', 'insert')) {
insertRows = await Promise.all(
docsData.map(docData => {
ids.add((docData as any)[primaryPath]);
const useDocData = fillObjectDataBeforeInsert(this.schema, docData);
return this._runHooks('pre', 'insert', useDocData)
.then(() => {
Expand All @@ -398,11 +400,22 @@ export class RxCollectionBase<
const schema = this.schema;
for (let index = 0; index < docsData.length; index++) {
const docData = docsData[index];
ids.add((docData as any)[primaryPath]);
const useDocData = fillObjectDataBeforeInsert(schema, docData);
insertRows[index] = { document: useDocData };
}
}


if (ids.size !== docsData.length) {
throw newRxError('COL22', {
collection: this.name,
args: {
documents: docsData
}
});
}

const results = await this.storageInstance.bulkWrite(
insertRows,
'rx-collection-bulk-insert'
Expand Down
56 changes: 56 additions & 0 deletions test/unit/rx-collection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,29 @@ describe('rx-collection.test.ts', () => {
assert.strictEqual(ret.error.length, 1);
db.destroy();
});
/**
* @link https://github.com/pubkey/rxdb/pull/6589
*/
it('should throw on duplicate ids', async () => {
const db = await createRxDatabase({
name: randomCouchString(10),
storage: config.storage.getStorage(),
});
const collections = await db.addCollections({
human: { schema: schemas.primaryHuman }
});

const human1 = schemaObjects.humanData('same-id');
const human2 = schemaObjects.humanData('same-id');

await assertThrows(
() => collections.human.bulkInsert([human1, human2]),
'RxError',
'COL22'
);

db.destroy();
});
});
});
describe('.find()', () => {
Expand Down Expand Up @@ -1528,6 +1551,39 @@ describe('rx-collection.test.ts', () => {

c.database.destroy();
});
/**
* @link https://github.com/pubkey/rxdb/pull/6589
*/
it('should throw on duplicate ids', async () => {
const db = await createRxDatabase({
name: randomCouchString(10),
storage: config.storage.getStorage(),
});
const collections = await db.addCollections({
human: { schema: schemas.primaryHuman }
});

const human1 = schemaObjects.humanData('same-id');
const human2 = schemaObjects.humanData('same-id');

await assertThrows(
() => collections.human.bulkUpsert([human1, human2]),
'RxError',
'COL22'
);

// should be the same behavior even if the document already exists
await collections.human.insert(human1);
await assertThrows(
() => collections.human.bulkUpsert([human1, human2]),
'RxError',
'COL22'
);



db.destroy();
});
});
describeParallel('.upsert()', () => {
describe('positive', () => {
Expand Down

0 comments on commit dcc3297

Please sign in to comment.