Skip to content

Commit

Permalink
Merge pull request #825 from orbitjs/backport-823
Browse files Browse the repository at this point in the history
Backport PR 823 to v0.16
  • Loading branch information
dgeb authored Mar 7, 2021
2 parents 51f5eab + 74804bf commit 2d56e4c
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 12 deletions.
18 changes: 17 additions & 1 deletion packages/@orbit/indexeddb/src/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ export default class IndexedDBCache extends AsyncRecordCache {
objectStore.createIndex('recordIdentity', 'recordIdentity', {
unique: false
});
objectStore.createIndex('relatedIdentity', 'relatedIdentity', {
unique: false
});
}

/**
Expand Down Expand Up @@ -464,7 +467,20 @@ export default class IndexedDBCache extends AsyncRecordCache {
const keyRange = Orbit.globals.IDBKeyRange.only(
serializeRecordIdentity(recordIdentity)
);
const request = objectStore.index('recordIdentity').openCursor(keyRange);

let index;
try {
index = objectStore.index('relatedIdentity');
} catch (e) {
console.error(
`[@orbit/indexeddb] The 'relatedIdentity' index is missing from the ${INVERSE_RELS} object store in IndexedDB. ` +
'Please add this index using a DB migration as described in https://github.com/orbitjs/orbit/pull/825'
);
resolve([]);
return;
}

const request = index.openCursor(keyRange);

request.onerror = function(/* event */) {
// console.error('error - getRecords', request.error);
Expand Down
4 changes: 3 additions & 1 deletion packages/@orbit/indexeddb/src/source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ export default class IndexedDBSource extends Source

super(settings);

let cacheSettings: IndexedDBCacheSettings = settings.cacheSettings || {};
let cacheSettings: IndexedDBCacheSettings = settings.cacheSettings || {
schema: settings.schema
};
cacheSettings.schema = settings.schema;
cacheSettings.keyMap = settings.keyMap;
cacheSettings.queryBuilder =
Expand Down
163 changes: 153 additions & 10 deletions packages/@orbit/indexeddb/test/cache-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,15 @@ module('Cache', function(hooks) {
assert.deepEqual(await cache.getRecordsAsync([jupiter, io, europa]), []);
});

test('sets/gets inverse relationships', async function(assert) {
test('sets/gets inverse relationships for a single record', async function(assert) {
const jupiter = { type: 'planet', id: 'jupiter' };
const io = { type: 'moon', id: 'io' };
const europa = { type: 'moon', id: 'europa' };
const callisto = { type: 'moon', id: 'callisto' };

const earth = { type: 'planet', id: 'earth' };
const earthMoon = { type: 'moon', id: 'earthMoon' };

await cache.openDB();

assert.deepEqual(
Expand All @@ -145,32 +148,46 @@ module('Cache', function(hooks) {
);

await cache.addInverseRelationshipsAsync([
{ record: jupiter, relationship: 'moons', relatedRecord: io },
{ record: jupiter, relationship: 'moons', relatedRecord: europa },
{ record: jupiter, relationship: 'moons', relatedRecord: callisto }
{ record: callisto, relationship: 'planet', relatedRecord: jupiter },
{ record: earthMoon, relationship: 'planet', relatedRecord: earth },
{ record: europa, relationship: 'planet', relatedRecord: jupiter },
{ record: io, relationship: 'planet', relatedRecord: jupiter }
]);

assert.deepEqual(
await cache.getInverseRelationshipsAsync(jupiter),
[
{ record: jupiter, relationship: 'moons', relatedRecord: callisto },
{ record: jupiter, relationship: 'moons', relatedRecord: europa },
{ record: jupiter, relationship: 'moons', relatedRecord: io }
{ record: callisto, relationship: 'planet', relatedRecord: jupiter },
{ record: europa, relationship: 'planet', relatedRecord: jupiter },
{ record: io, relationship: 'planet', relatedRecord: jupiter }
],
'inverse relationships have been added'
);

assert.deepEqual(
await cache.getInverseRelationshipsAsync(earth),
[{ record: earthMoon, relationship: 'planet', relatedRecord: earth }],
'inverse relationships have been added'
);

await cache.removeInverseRelationshipsAsync([
{ record: jupiter, relationship: 'moons', relatedRecord: io },
{ record: jupiter, relationship: 'moons', relatedRecord: europa },
{ record: jupiter, relationship: 'moons', relatedRecord: callisto }
{ record: callisto, relationship: 'planet', relatedRecord: jupiter },
{ record: earthMoon, relationship: 'planet', relatedRecord: earth },
{ record: europa, relationship: 'planet', relatedRecord: jupiter },
{ record: io, relationship: 'planet', relatedRecord: jupiter }
]);

assert.deepEqual(
await cache.getInverseRelationshipsAsync(jupiter),
[],
'inverse relationships have been removed'
);

assert.deepEqual(
await cache.getInverseRelationshipsAsync(earth),
[],
'inverse relationships have been removed'
);
});

test('#patch - addRecord', async function(assert) {
Expand Down Expand Up @@ -997,4 +1014,130 @@ module('Cache', function(hooks) {
'key has been mapped'
);
});

test('#patch tracks refs and clears them from hasOne relationships when a referenced record is removed', async function(assert) {
const jupiter: Record = {
type: 'planet',
id: 'p1',
attributes: { name: 'Jupiter' },
relationships: { moons: { data: undefined } }
};
const io: Record = {
type: 'moon',
id: 'm1',
attributes: { name: 'Io' },
relationships: { planet: { data: { type: 'planet', id: 'p1' } } }
};
const europa: Record = {
type: 'moon',
id: 'm2',
attributes: { name: 'Europa' },
relationships: { planet: { data: { type: 'planet', id: 'p1' } } }
};

await cache.patch(t => [
t.addRecord(jupiter),
t.addRecord(io),
t.addRecord(europa)
]);

assert.deepEqual(
((await cache.getRecordAsync({ type: 'moon', id: 'm1' })) as Record)
.relationships.planet.data,
{ type: 'planet', id: 'p1' },
'Jupiter has been assigned to Io'
);
assert.deepEqual(
((await cache.getRecordAsync({ type: 'moon', id: 'm2' })) as Record)
.relationships.planet.data,
{ type: 'planet', id: 'p1' },
'Jupiter has been assigned to Europa'
);

await cache.patch(t => t.removeRecord(jupiter));

assert.equal(
await cache.getRecordAsync({ type: 'planet', id: 'p1' }),
undefined,
'Jupiter is GONE'
);

assert.equal(
((await cache.getRecordAsync({ type: 'moon', id: 'm1' })) as Record)
.relationships.planet.data,
undefined,
'Jupiter has been cleared from Io'
);
assert.equal(
((await cache.getRecordAsync({ type: 'moon', id: 'm2' })) as Record)
.relationships.planet.data,
undefined,
'Jupiter has been cleared from Europa'
);
});

test('#patch tracks refs and clears them from hasMany relationships when a referenced record is removed', async function(assert) {
const io: Record = {
type: 'moon',
id: 'm1',
attributes: { name: 'Io' },
relationships: { planet: { data: null } }
};
const europa: Record = {
type: 'moon',
id: 'm2',
attributes: { name: 'Europa' },
relationships: { planet: { data: null } }
};
const jupiter: Record = {
type: 'planet',
id: 'p1',
attributes: { name: 'Jupiter' },
relationships: {
moons: {
data: [{ type: 'moon', id: 'm1' }, { type: 'moon', id: 'm2' }]
}
}
};

await cache.patch(t => [
t.addRecord(io),
t.addRecord(europa),
t.addRecord(jupiter)
]);

assert.deepEqual(
((await cache.getRecordAsync({ type: 'planet', id: 'p1' })) as Record)
.relationships.moons.data,
[{ type: 'moon', id: 'm1' }, { type: 'moon', id: 'm2' }],
'Jupiter has been assigned to Io and Europa'
);
assert.deepEqual(
await cache.getRelatedRecordsAsync(jupiter, 'moons'),
[{ type: 'moon', id: 'm1' }, { type: 'moon', id: 'm2' }],
'Jupiter has been assigned to Io and Europa'
);

await cache.patch(t => t.removeRecord(io));

assert.equal(
await cache.getRecordAsync({ type: 'moon', id: 'm1' }),
null,
'Io is GONE'
);

await cache.patch(t => t.removeRecord(europa));

assert.equal(
await cache.getRecordAsync({ type: 'moon', id: 'm2' }),
null,
'Europa is GONE'
);

assert.deepEqual(
await cache.getRelatedRecordsAsync({ type: 'planet', id: 'p1' }, 'moons'),
[],
'moons have been cleared from Jupiter'
);
});
});

0 comments on commit 2d56e4c

Please sign in to comment.