Skip to content

Commit

Permalink
bugfix metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
Lars-Erik Roald committed May 31, 2023
1 parent 86849bc commit 40a978e
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 73 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Based on promises.
[Documentation and examples](https://github.com/alfateam/rdb/blob/master/docs/docs.md)

## Release notes
__3.1.18__
Bugfix patching without metadata
__3.1.17__
Another Buffer workaround in browser
__3.1.16__
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rdb",
"version": "3.1.17",
"version": "3.1.18",
"main": "./src/index.js",
"browser": "./src/client/index.mjs",
"bin": {
Expand Down
4 changes: 2 additions & 2 deletions src/client/createPatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ module.exports = function createPatch(original, dto, options) {
map[stringify(key)] = i;
}
else if ('id' in element)
map[stringify(element.id)] = i;
map[stringify([element.id])] = i;
else
map[i] = i;
return map;
Expand All @@ -84,7 +84,7 @@ module.exports = function createPatch(original, dto, options) {
copy[stringify(key)] = element;
}
else if (element === Object(element) && 'id' in element)
copy[stringify(element.id)] = element;
copy[stringify([element.id])] = element;
else
copy[i] = element;
}
Expand Down
5 changes: 4 additions & 1 deletion src/patchTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ async function patchTableCore(table, patches, { strategy = undefined, deduceStra
let property = path[0];
path = path.slice(1);
if (!row && path.length > 0) {
row = row || await table.tryGetById.apply(null, toKey(property), strategy);
const key = toKey(property);
row = await table.tryGetById.apply(null, toKey(property), strategy);
if (!row)
throw new Error(`Row ${table._dbName} with id ${key} was not found.`);
}
if (path.length === 0) {
if (dryrun) {
Expand Down
94 changes: 55 additions & 39 deletions tests/concurrencyAndPatch.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ describe('patch single row', () => {

async function verify({ pool }) {

const db = _db({ db: pool});
const db = _db({ db: pool });

let row = await db.customer.getOne();
const original = JSON.parse(JSON.stringify(row));
Expand Down Expand Up @@ -96,9 +96,9 @@ describe('patch array', () => {

async function verify({ pool }) {

const db = _db({ db: pool});
const db = _db({ db: pool });

const strategy = {deliveryAddress: true, lines: true, customer: true};
const strategy = { deliveryAddress: true, lines: true, customer: true };
let rows = await db.order.getAll(strategy);
const original = JSON.parse(JSON.stringify(rows));

Expand Down Expand Up @@ -171,7 +171,7 @@ describe('concurrency default', () => {

async function verify({ pool }) {

const db = _db({ db: pool});
const db = _db({ db: pool });

let row = await db.customer.getOne();

Expand All @@ -185,7 +185,7 @@ describe('concurrency default', () => {
row.name = name;
await row.saveChanges();
}
catch(e) {
catch (e) {
error = e;
}

Expand All @@ -199,7 +199,7 @@ describe('concurrency skipOnConflict', () => {

async function verify({ pool }) {

const db = _db({ db: pool, concurrency: 'skipOnConflict'});
const db = _db({ db: pool, concurrency: 'skipOnConflict' });

let row = await db.customer.getOne();
let changedRow = await db.customer.getOne();
Expand All @@ -219,7 +219,7 @@ describe('concurrency overwrite', () => {

async function verify({ pool }) {

const db = _db({ db: pool, concurrency: 'overwrite'});
const db = _db({ db: pool, concurrency: 'overwrite' });

let row = await db.customer.getOne();
let changedRow = await db.customer.getOne();
Expand All @@ -238,8 +238,8 @@ describe('concurrency join, no conflict', () => {
test('pg', async () => await verify(pg()));

async function verify({ pool }) {
const db = _db({ db: pool});
let row = await db.order.getOne(null, {customer: true});
const db = _db({ db: pool });
let row = await db.order.getOne(null, { customer: true });
row.customer = null;
await row.saveChanges();
expect(row.customerId).toEqual(null);
Expand All @@ -252,10 +252,10 @@ describe('concurrency join, null conflict', () => {
test('pg', async () => await verify(pg()));

async function verify({ pool }) {
const db = _db({ db: pool});
let row = await db.order.getOne(null, {customer: true});
const db = _db({ db: pool });
let row = await db.order.getOne(null, { customer: true });

let changedRow = await db.order.getOne(null, {customer: true});
let changedRow = await db.order.getOne(null, { customer: true });
changedRow.customer = null;
await changedRow.saveChanges();

Expand All @@ -264,7 +264,7 @@ describe('concurrency join, null conflict', () => {
try {
await row.saveChanges();
}
catch(e) {
catch (e) {
error = e;
}
expect(error?.message).toEqual('The field customerId was changed by another user. Expected 1, but was null.');
Expand All @@ -276,10 +276,10 @@ describe('concurrency join, conflict', () => {
test('pg', async () => await verify(pg()));

async function verify({ pool }) {
const db = _db({ db: pool});
let row = await db.order.getOne(null, {customer: true});
const db = _db({ db: pool });
let row = await db.order.getOne(null, { customer: true });

let changedRow = await db.order.getOne(null, {customer: true});
let changedRow = await db.order.getOne(null, { customer: true });
changedRow.customerId = customer2Id;
await changedRow.saveChanges();

Expand All @@ -288,7 +288,7 @@ describe('concurrency join, conflict', () => {
try {
await row.saveChanges();
}
catch(e) {
catch (e) {
error = e;
}
expect(error?.message).toEqual('The field customerId was changed by another user. Expected 1, but was 2.');
Expand All @@ -300,10 +300,10 @@ describe('concurrency join, conflict alternative syntax', () => {
test('pg', async () => await verify(pg()));

async function verify({ pool }) {
const db = _db({ db: pool});
let row = await db.order.getOne(null, {customer: true});
const db = _db({ db: pool });
let row = await db.order.getOne(null, { customer: true });

let changedRow = await db.order.getOne(null, {customer: true});
let changedRow = await db.order.getOne(null, { customer: true });
changedRow.customerId = customer2Id;
await changedRow.saveChanges();

Expand All @@ -312,7 +312,7 @@ describe('concurrency join, conflict alternative syntax', () => {
try {
await row.saveChanges();
}
catch(e) {
catch (e) {
error = e;
}
expect(error?.message).toEqual('The field customerId was changed by another user. Expected 1, but was 2.');
Expand All @@ -324,10 +324,10 @@ describe('concurrency join, conflict overwrite', () => {
test('pg', async () => await verify(pg()));

async function verify({ pool }) {
const db = _db({ db: pool, order: {customerId: {concurrency: 'overwrite'}}});
let row = await db.order.getOne(null, {customer: true});
const db = _db({ db: pool, order: { customerId: { concurrency: 'overwrite' } } });
let row = await db.order.getOne(null, { customer: true });

let changedRow = await db.order.getOne(null, {customer: true});
let changedRow = await db.order.getOne(null, { customer: true });
changedRow.customerId = null;
await changedRow.saveChanges();

Expand All @@ -342,10 +342,10 @@ describe('concurrency join, conflict skipOnConflict', () => {
test('pg', async () => await verify(pg()));

async function verify({ pool }) {
const db = _db({ db: pool, order: {customerId: {concurrency: 'skipOnConflict'}}});
let row = await db.order.getOne(null, {customer: true});
const db = _db({ db: pool, order: { customerId: { concurrency: 'skipOnConflict' } } });
let row = await db.order.getOne(null, { customer: true });

let changedRow = await db.order.getOne(null, {customer: true});
let changedRow = await db.order.getOne(null, { customer: true });
changedRow.customerId = null;
await changedRow.saveChanges();

Expand All @@ -361,10 +361,10 @@ describe('concurrency join, conflict undefined syntax', () => {
test('pg', async () => await verify(pg()));

async function verify({ pool }) {
const db = _db({ db: pool});
let row = await db.order.getOne(null, {customer: true});
const db = _db({ db: pool });
let row = await db.order.getOne(null, { customer: true });

let changedRow = await db.order.getOne(null, {customer: true});
let changedRow = await db.order.getOne(null, { customer: true });
delete changedRow.customerId;
await changedRow.saveChanges();

Expand All @@ -373,7 +373,7 @@ describe('concurrency join, conflict undefined syntax', () => {
try {
await row.saveChanges();
}
catch(e) {
catch (e) {
error = e;
}
expect(error?.message).toEqual('The field customerId was changed by another user. Expected 1, but was null.');
Expand All @@ -385,9 +385,9 @@ describe('concurrency delete join', () => {
test('pg', async () => await verify(pg()));

async function verify({ pool }) {
const db = _db({ db: pool});
let row = await db.order.getOne(null, {customer: true});
let changedRow = await db.order.getOne(null, {customer: true});
const db = _db({ db: pool });
let row = await db.order.getOne(null, { customer: true });
let changedRow = await db.order.getOne(null, { customer: true });
delete changedRow.customer;
await changedRow.saveChanges();

Expand All @@ -396,7 +396,7 @@ describe('concurrency delete join', () => {
try {
await row.saveChanges();
}
catch(e) {
catch (e) {
error = e;
}
expect(error?.message).toEqual('The field customerId was changed by another user. Expected 1, but was null.');
Expand All @@ -408,9 +408,9 @@ describe('concurrency delete join, alternative syntax', () => {
test('pg', async () => await verify(pg()));

async function verify({ pool }) {
const db = _db({ db: pool});
let row = await db.order.getOne(null, {customer: true});
let changedRow = await db.order.getOne(null, {customer: true});
const db = _db({ db: pool });
let row = await db.order.getOne(null, { customer: true });
let changedRow = await db.order.getOne(null, { customer: true });
delete changedRow.customer;
await changedRow.saveChanges();

Expand All @@ -419,14 +419,30 @@ describe('concurrency delete join, alternative syntax', () => {
try {
await row.saveChanges();
}
catch(e) {
catch (e) {
error = e;
}
expect(error?.message).toEqual('The field customerId was changed by another user. Expected 1, but was null.');
}
});


describe('createPatch', () => {

test('pg', async () => await verify(pg()));

async function verify({ pool }) {
const db = _db({ db: pool });
const original = {id:'12a2f0e4-d657-47ea-a96a-0b2fff0090b2', husNummer: 2};
const modified = {id:'12a2f0e4-d657-47ea-a96a-0b2fff0090b2', husNummer: 4};
const patch = db.createPatch(original, modified);
const expected = [{ 'op': 'replace', 'path': '/["12a2f0e4-d657-47ea-a96a-0b2fff0090b2"]/husNummer', 'value': 4, 'oldValue': 2 }];
expect(patch).toEqual(expected);
}
});



function pg() {
return { pool: rdb.pg('postgres://postgres:postgres@postgres/postgres'), init: initPg };
}
60 changes: 30 additions & 30 deletions tests/createPatch.array.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,63 +4,63 @@ let createPatch = require('../src/client/createPatch');

test('updateAndInsertArray should order patches by insert, update with position, delete', () => {
let a = { id: 2, date: 'original' };
let aChanged = { id: 2, date: 'changed' , too: 'yes'};
let aChanged = { id: 2, date: 'changed', too: 'yes' };
let b = { id: 1, date: 'originalb' };
let bChanged = { id: 1, date: 'changedb' , too: 'yesb'};
let bChanged = { id: 1, date: 'changedb', too: 'yesb' };
let cInserted = { id: 'c', date: 'someDateC' };
let dInserted = { id: 'd', date: 'someDateD' };
let eDeleted = { id: 0, date: 'delete me' };
let fDeleted = { id: -1, date: 'delete me too' };
let updatePatch = createPatch([eDeleted, a, b, fDeleted], [dInserted, aChanged, bChanged, cInserted]);
expect(updatePatch).toEqual([
{ 'op': 'add', 'path': '/"d"', 'value': { 'date': 'someDateD', 'id': 'd' } },
{ 'op': 'add', 'path': '/"c"', 'value': { 'date': 'someDateC', 'id': 'c' } },
{ 'op': 'replace', 'path': '/2/date', 'value': 'changed', 'oldValue': 'original' },
{ 'op': 'add', 'path': '/2/too', 'value': 'yes' },
{ 'op': 'replace', 'path': '/1/date', 'value': 'changedb', 'oldValue': 'originalb' },
{ 'op': 'add', 'path': '/1/too', 'value': 'yesb' },
{ 'op': 'remove', 'path': '/-1', 'oldValue': { 'id': -1, 'date': 'delete me too' } },
{ 'op': 'remove', 'path': '/0', 'oldValue': { 'id': 0, 'date': 'delete me' } },
{ 'op': 'add', 'path': '/["d"]', 'value': { 'date': 'someDateD', 'id': 'd' } },
{ 'op': 'add', 'path': '/["c"]', 'value': { 'date': 'someDateC', 'id': 'c' } },
{ 'op': 'replace', 'path': '/[1]/date', 'value': 'changedb', 'oldValue': 'originalb' },
{ 'op': 'add', 'path': '/[1]/too', 'value': 'yesb' },
{ 'op': 'replace', 'path': '/[2]/date', 'value': 'changed', 'oldValue': 'original' },
{ 'op': 'add', 'path': '/[2]/too', 'value': 'yes' },
{ 'op': 'remove', 'path': '/[-1]', 'oldValue': { 'id': -1, 'date': 'delete me too' } },
{ 'op': 'remove', 'path': '/[0]', 'oldValue': { 'id': 0, 'date': 'delete me' } },
]
);

});

test('updateArray', () => {
let a = {id: 1, date: 'original'};
let b = {id: 1, date: 'changed'};
test('updateArray', () => {
let a = { id: 1, date: 'original' };
let b = { id: 1, date: 'changed' };
let updatePatch = createPatch([a], [b]);
expect(updatePatch).toEqual([{'op': 'replace', 'path': '/1/date', 'value': 'changed', 'oldValue': 'original'}]);
expect(updatePatch).toEqual([{ 'op': 'replace', 'path': '/[1]/date', 'value': 'changed', 'oldValue': 'original' }]);
});

test('update non-id pk', () => {
let a = {otherPk: 1, date: 'original'};
let b = {otherPk: 1, date: 'changed'};
let updatePatch = createPatch([a], [b], {keys: [{name: 'otherPk'}]});
expect(updatePatch).toEqual([{'op': 'replace', 'path': '/[1]/date', 'value': 'changed', 'oldValue': 'original'}]);
let a = { otherPk: 1, date: 'original' };
let b = { otherPk: 1, date: 'changed' };
let updatePatch = createPatch([a], [b], { keys: [{ name: 'otherPk' }] });
expect(updatePatch).toEqual([{ 'op': 'replace', 'path': '/[1]/date', 'value': 'changed', 'oldValue': 'original' }]);
});

test('update nested composite pk', () => {
let a = {otherPk: 1, date: 'original', lines: [{linePk: 22, otherPk: 1, foo: '_foo'}, {linePk: 23, otherPk: 1, foo: 'original'}]};
let b = {otherPk: 1, date: 'original', lines: [{linePk: 22, otherPk: 1, foo: '_foo'}, {linePk: 23, otherPk: 1, foo: 'changed'}]};
let updatePatch = createPatch([a], [b], {keys: [{name: 'otherPk'}], relations: {lines: {keys: [{name: 'otherPk'}, {name: 'linePk'}]}}});
expect(updatePatch).toEqual([{'op': 'replace', 'path': '/[1]/lines/[1,23]/foo', 'value': 'changed', 'oldValue': 'original'}]);
let a = { otherPk: 1, date: 'original', lines: [{ linePk: 22, otherPk: 1, foo: '_foo' }, { linePk: 23, otherPk: 1, foo: 'original' }] };
let b = { otherPk: 1, date: 'original', lines: [{ linePk: 22, otherPk: 1, foo: '_foo' }, { linePk: 23, otherPk: 1, foo: 'changed' }] };
let updatePatch = createPatch([a], [b], { keys: [{ name: 'otherPk' }], relations: { lines: { keys: [{ name: 'otherPk' }, { name: 'linePk' }] } } });
expect(updatePatch).toEqual([{ 'op': 'replace', 'path': '/[1]/lines/[1,23]/foo', 'value': 'changed', 'oldValue': 'original' }]);
});

test('insert sequence', () => {
let a = {otherPk: 2, some: 'a'};
let b = {otherPk: 1, some: 'b'};
let updatePatch = createPatch([], [a,b], {keys: [{name: 'otherPk'}], relations: {lines: {keys: [{name: 'otherPk'}, {name: 'linePk'}]}}});
expect(updatePatch).toEqual([{'op': 'add', 'path': '/[2]', 'value': a}, {'op': 'add', 'path': '/[1]', 'value': b}]);
let a = { otherPk: 2, some: 'a' };
let b = { otherPk: 1, some: 'b' };
let updatePatch = createPatch([], [a, b], { keys: [{ name: 'otherPk' }], relations: { lines: { keys: [{ name: 'otherPk' }, { name: 'linePk' }] } } });
expect(updatePatch).toEqual([{ 'op': 'add', 'path': '/[2]', 'value': a }, { 'op': 'add', 'path': '/[1]', 'value': b }]);
});

test('updateDate', () => {
let a = {id: 1, date: new Date('2020-10-13')};
let b = {id: 1, date: new Date('2020-10-12')};
test('updateDate', () => {
let a = { id: 1, date: new Date('2020-10-13') };
let b = { id: 1, date: new Date('2020-10-12') };
let aIso = toIsoString(a.date);
let bIso = toIsoString(b.date);
let updatePatch = createPatch([a], [b]);
expect(updatePatch).toEqual([{'op': 'replace', 'path': '/1/date', 'value': bIso, 'oldValue': aIso}]);
expect(updatePatch).toEqual([{ 'op': 'replace', 'path': '/[1]/date', 'value': bIso, 'oldValue': aIso }]);
});

function toIsoString(date) {
Expand Down
Loading

0 comments on commit 40a978e

Please sign in to comment.