Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- TEST add reproduction for composite primary key auto-fill when only `name` and `number` are set in a `preInsert` hook without `id` (https://github.com/pubkey/rxdb/pull/8527)
1 change: 1 addition & 0 deletions orga/changelog/fix-composite-primary-preinsert-hook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- FIX allow `preInsert` hooks to set composite primary key fields (for example `name` and `number`) without manually setting `id`, so RxDB computes the composite primary key afterwards (https://github.com/pubkey/rxdb/pull/8527)
5 changes: 3 additions & 2 deletions src/rx-collection-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ import { newRxError } from './rx-error.ts';
*/
export function fillObjectDataBeforeInsert<RxDocType>(
schema: RxSchema<RxDocType>,
data: Partial<RxDocumentData<RxDocType>> | any
data: Partial<RxDocumentData<RxDocType>> | any,
skipPrimaryKeyFill: boolean = false
): RxDocumentData<RxDocType> {
data = flatClone(data);
data = fillObjectWithDefaults(schema, data);
if (typeof schema.jsonSchema.primaryKey !== 'string') {
if (!skipPrimaryKeyFill && typeof schema.jsonSchema.primaryKey !== 'string') {
data = fillPrimaryKey(
schema.primaryPath,
schema.jsonSchema,
Expand Down
10 changes: 9 additions & 1 deletion src/rx-collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import {
runAsyncPluginHooks,
runPluginHooks
} from './hooks.ts';
import { fillPrimaryKey } from './rx-schema-helper.ts';

import {
Subscription,
Expand Down Expand Up @@ -443,9 +444,16 @@ export class RxCollectionBase<
if (this.hasHooks('pre', 'insert')) {
insertRows = await Promise.all(
docsData.map(docData => {
const useDocData = fillObjectDataBeforeInsert(this.schema, docData);
const useDocData = fillObjectDataBeforeInsert(this.schema, docData, true);
return this._runHooks('pre', 'insert', useDocData)
.then(() => {
if (typeof this.schema.jsonSchema.primaryKey !== 'string') {
fillPrimaryKey(
this.schema.primaryPath as any,
this.schema.jsonSchema as any,
useDocData as any
);
}
ids.add((useDocData as any)[primaryPath]);
return { document: useDocData };
});
Expand Down
53 changes: 53 additions & 0 deletions test/unit/hooks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -559,5 +559,58 @@ describe('hooks.test.js', () => {
assert.strictEqual(allDocs.length, 0);
c.database.close();
});
it('should auto-generate composite primary key when set in preInsert hook', async () => {
const db = await createRxDatabase({
name: randomToken(10),
storage: config.storage.getStorage(),
multiInstance: true
});
const collections = await db.addCollections({
humans: {
schema: {
version: 0,
primaryKey: {
key: 'id',
fields: ['name', 'number'],
separator: '|'
},
type: 'object',
properties: {
id: {
type: 'string',
maxLength: 100
},
name: {
type: 'string',
maxLength: 100
},
number: {
type: 'integer',
minimum: 0,
maximum: 9999
}
},
required: [
'id',
'name',
'number'
]
}
}
});
const collection = collections.humans;

collection.preInsert((docData) => {
docData.name = 'alice';
docData.number = 5;
}, false);

const doc = await collection.insert({} as any);
assert.strictEqual(doc.id, 'alice|5');
assert.strictEqual(doc.name, 'alice');
assert.strictEqual(doc.number, 5);

db.close();
});
});
});
Loading