Skip to content

Commit

Permalink
fix: add newly created models to IDB during migration (aws-amplify#9754)
Browse files Browse the repository at this point in the history
  • Loading branch information
dpilch authored Apr 21, 2022
1 parent 84c94fd commit 58d7e00
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 93 deletions.
55 changes: 12 additions & 43 deletions packages/datastore/__tests__/__snapshots__/indexeddb.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -404,50 +404,14 @@ Object {
},
Object {
"inbound": false,
"rows": Array [
Object {
"$": Array [
1,
Object {
"_deleted": null,
"_lastChangedAt": null,
"_version": null,
"commentPostId": "d129800d-679f-4df2-92cd-2b96573a618e",
"content": "c2",
"id": "007ea314-6645-486f-88a9-d1aaa4fddb9e",
},
],
"$types": Object {
"$": Object {
"1._deleted": "undef",
"1._lastChangedAt": "undef",
"1._version": "undef",
},
},
},
Object {
"$": Array [
2,
Object {
"_deleted": null,
"_lastChangedAt": null,
"_version": null,
"commentPostId": "d129800d-679f-4df2-92cd-2b96573a618e",
"content": "c1",
"id": "13c99f5f-1fbb-4088-aaf9-63b789e68574",
},
],
"$types": Object {
"$": Object {
"1._deleted": "undef",
"1._lastChangedAt": "undef",
"1._version": "undef",
},
},
},
],
"rows": Array [],
"tableName": "user_Comment",
},
Object {
"inbound": false,
"rows": Array [],
"tableName": "user_Person",
},
Object {
"inbound": false,
"rows": Array [
Expand Down Expand Up @@ -537,7 +501,12 @@ Object {
},
Object {
"name": "user_Comment",
"rowCount": 2,
"rowCount": 0,
"schema": "++,&id,commentPostId",
},
Object {
"name": "user_Person",
"rowCount": 0,
"schema": "++,&id",
},
Object {
Expand Down
10 changes: 8 additions & 2 deletions packages/datastore/__tests__/indexeddb.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -550,8 +550,14 @@ describe('DB versions migration', () => {
// Open V2
db = await idb.openDB('amplify-datastore', 2);

expect(db.objectStoreNames).toMatchObject(
v1Data.data.tables.map(({ name }) => name)
expect([...db.objectStoreNames].sort()).toMatchObject(
[
...v1Data.data.tables.map(({ name }) => name),
// Simulate Comment model added after IndexedDB was created,
// but before migration
`${USER}_Comment`,
`${USER}_Person`,
].sort()
);

for (const storeName of db.objectStoreNames) {
Expand Down
37 changes: 0 additions & 37 deletions packages/datastore/__tests__/v1schema.data.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@
"schema": "id",
"rowCount": 9
},
{
"name": "user_Comment",
"schema": "id,commentPostId",
"rowCount": 2
},
{
"name": "user_Post",
"schema": "id,postBlogId,referencePostId",
Expand Down Expand Up @@ -328,38 +323,6 @@
}
]
},
{
"tableName": "user_Comment",
"inbound": true,
"rows": [
{
"content": "c2",
"id": "007ea314-6645-486f-88a9-d1aaa4fddb9e",
"_version": null,
"_lastChangedAt": null,
"_deleted": null,
"commentPostId": "d129800d-679f-4df2-92cd-2b96573a618e",
"$types": {
"_version": "undef",
"_lastChangedAt": "undef",
"_deleted": "undef"
}
},
{
"content": "c1",
"id": "13c99f5f-1fbb-4088-aaf9-63b789e68574",
"_version": null,
"_lastChangedAt": null,
"_deleted": null,
"commentPostId": "d129800d-679f-4df2-92cd-2b96573a618e",
"$types": {
"_version": "undef",
"_lastChangedAt": "undef",
"_deleted": "undef"
}
}
]
},
{
"tableName": "user_Post",
"inbound": true,
Expand Down
59 changes: 48 additions & 11 deletions packages/datastore/src/storage/adapter/IndexedDBAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,17 +117,12 @@ class IndexedDBAdapter implements Adapter {

Object.keys(namespace.models).forEach(modelName => {
const storeName = this.getStorename(namespaceName, modelName);
const store = db.createObjectStore(storeName, {
autoIncrement: true,
});

const indexes =
this.schema.namespaces[namespaceName].relationships[
modelName
].indexes;
indexes.forEach(index => store.createIndex(index, index));

store.createIndex('byId', 'id', { unique: true });
this.createObjectStoreForModel(
db,
namespaceName,
storeName,
modelName
);
});
});

Expand Down Expand Up @@ -168,6 +163,31 @@ class IndexedDBAdapter implements Adapter {

logger.debug(`${count} ${storeName} records migrated`);
}

// add new models created after IndexedDB, but before migration
// this case may happen when a user has not opened an app for
// some time and a new model is added during that time
Object.keys(theSchema.namespaces).forEach(namespaceName => {
const namespace = theSchema.namespaces[namespaceName];
const objectStoreNames = new Set(txn.objectStoreNames);

Object.keys(namespace.models)
.map(modelName => {
return [
modelName,
this.getStorename(namespaceName, modelName),
];
})
.filter(([, storeName]) => !objectStoreNames.has(storeName))
.forEach(([modelName, storeName]) => {
this.createObjectStoreForModel(
db,
namespaceName,
storeName,
modelName
);
});
});
} catch (error) {
logger.error('Error migrating IndexedDB data', error);
txn.abort();
Expand Down Expand Up @@ -835,6 +855,23 @@ class IndexedDBAdapter implements Adapter {

return result;
}

private async createObjectStoreForModel(
db: idb.IDBPDatabase,
namespaceName: string,
storeName: string,
modelName: string
) {
const store = db.createObjectStore(storeName, {
autoIncrement: true,
});

const indexes =
this.schema.namespaces[namespaceName].relationships[modelName].indexes;
indexes.forEach(index => store.createIndex(index, index));

store.createIndex('byId', 'id', { unique: true });
}
}

export default new IndexedDBAdapter();

0 comments on commit 58d7e00

Please sign in to comment.