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
5 changes: 5 additions & 0 deletions .changeset/slimy-cougars-rush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@powersync/common': patch
---

Include metadata and previous values when serializing CRUD entries to JSON.
17 changes: 15 additions & 2 deletions packages/common/src/client/sync/bucket/CrudEntry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ type CrudEntryOutputJSON = {
id: string;
tx_id?: number;
data?: Record<string, any>;
old?: Record<string, any>;
metadata?: string;
};

/**
Expand Down Expand Up @@ -132,7 +134,9 @@ export class CrudEntry {
type: this.table,
id: this.id,
tx_id: this.transactionId,
data: this.opData
data: this.opData,
old: this.previousValues,
metadata: this.metadata
};
}

Expand All @@ -154,6 +158,15 @@ export class CrudEntry {
* Generates an array for use in deep comparison operations
*/
toComparisonArray() {
return [this.transactionId, this.clientId, this.op, this.table, this.id, this.opData];
return [
this.transactionId,
this.clientId,
this.op,
this.table,
this.id,
this.opData,
this.previousValues,
this.metadata
];
}
}
25 changes: 16 additions & 9 deletions packages/node/tests/crud.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ databaseTest('include metadata', async ({ database }) => {
});
await database.updateSchema(schema);
await database.execute('INSERT INTO lists (id, name, _metadata) VALUES (uuid(), ?, ?);', ['entry', 'so meta']);

const batch = await database.getNextCrudTransaction();
expect(batch?.crud[0].metadata).toBe('so meta');
expect(JSON.stringify(batch?.crud[0])).toContain('"metadata":"so meta"');
});

databaseTest('include old values', async ({ database }) => {
Expand All @@ -30,12 +31,18 @@ databaseTest('include old values', async ({ database }) => {
)
});
await database.updateSchema(schema);
await database.execute('INSERT INTO lists (id, name) VALUES (uuid(), ?);', ['entry']);
await database.execute('INSERT INTO lists (id, name) VALUES (?, ?);', [
'a185b7e1-dffa-4a9a-888c-15c0f0cac4b3',
'entry'
]);
await database.execute('DELETE FROM ps_crud;');
await database.execute('UPDATE lists SET name = ?', ['new name']);

const batch = await database.getNextCrudTransaction();
expect(batch?.crud[0].previousValues).toStrictEqual({name: 'entry'});
expect(batch?.crud[0].previousValues).toStrictEqual({ name: 'entry' });
expect(JSON.stringify(batch?.crud[0])).toBe(
'{"op_id":2,"op":"PATCH","type":"lists","id":"a185b7e1-dffa-4a9a-888c-15c0f0cac4b3","tx_id":2,"data":{"name":"new name"},"old":{"name":"entry"}}'
);
});

databaseTest('include old values with column filter', async ({ database }) => {
Expand All @@ -53,9 +60,9 @@ databaseTest('include old values with column filter', async ({ database }) => {
await database.execute('INSERT INTO lists (id, name, content) VALUES (uuid(), ?, ?);', ['name', 'content']);
await database.execute('DELETE FROM ps_crud;');
await database.execute('UPDATE lists SET name = ?, content = ?', ['new name', 'new content']);

const batch = await database.getNextCrudTransaction();
expect(batch?.crud[0].previousValues).toStrictEqual({name: 'name'});
expect(batch?.crud[0].previousValues).toStrictEqual({ name: 'name' });
});

databaseTest('include old values when changed', async ({ database }) => {
Expand All @@ -73,9 +80,9 @@ databaseTest('include old values when changed', async ({ database }) => {
await database.execute('INSERT INTO lists (id, name, content) VALUES (uuid(), ?, ?);', ['name', 'content']);
await database.execute('DELETE FROM ps_crud;');
await database.execute('UPDATE lists SET name = ?', ['new name']);

const batch = await database.getNextCrudTransaction();
expect(batch?.crud[0].previousValues).toStrictEqual({name: 'name'});
expect(batch?.crud[0].previousValues).toStrictEqual({ name: 'name' });
});

databaseTest('ignore empty update', async ({ database }) => {
Expand All @@ -92,7 +99,7 @@ databaseTest('ignore empty update', async ({ database }) => {
await database.execute('INSERT INTO lists (id, name) VALUES (uuid(), ?);', ['name']);
await database.execute('DELETE FROM ps_crud;');
await database.execute('UPDATE lists SET name = ?', ['name']);

const batch = await database.getNextCrudTransaction();
expect(batch).toBeNull();
});