Skip to content

Commit

Permalink
Migrate non-cache nedb data to SQLite (#619)
Browse files Browse the repository at this point in the history
Adds SQLite tables and Sequelize models for nedb data excluding cache. Cache can start fresh and does not need to be migrated.

Data migration is written and tested.

During migration, connection username/password is decrypted and all of driver-specific connection options are encrypted together (host, port, connection string, etc).

No actual implementation code is touched. That will follow as another PR.

I'm anticipating some of the models will need to be adjusted, but wanted to get these in to keep the PR reasonably sized.
  • Loading branch information
rickbergfalk committed Apr 24, 2020
1 parent 5e5703f commit 5fb5262
Show file tree
Hide file tree
Showing 23 changed files with 1,281 additions and 19 deletions.
3 changes: 2 additions & 1 deletion .prettierignore
Expand Up @@ -9,4 +9,5 @@ dbtest
docker-validation
scripts
server/node_modules
server/public
server/public
server/test/fixtures/**/*.json
54 changes: 54 additions & 0 deletions server/lib/migration-utils.js
@@ -0,0 +1,54 @@
/**
* Allows creating idempotentish migrations that include index creation.
* The queryInterface does not have a create index if not exists option,
* so this creates that.
*
* @param {import('sequelize').QueryInterface} queryInterface
* @param {String} tableName
* @param {String} indexName
* @param {Array<String>} fields - collection of nedb objects created in /lib/db.js
*/
async function addOrReplaceIndex(queryInterface, tableName, indexName, fields) {
const indexes = await queryInterface.showIndex(tableName);

const found = indexes.find(index => index.name === indexName);

// If not found create the index
if (!found) {
return queryInterface.addIndex(tableName, {
fields,
name: indexName
});
}

// If found, figure out if it is the *same* index
// If it is the same, do nothing
// Name and table already match, but the fields need to as well
// fields is something like [ { attribute: 'colname', length: undefined, order: undefined } ]
// Unsure if length/order are populated. They are not for sqlite.
// we'll assume order in array is order of fields
let sameIndex = true;
if (fields.length !== found.fields.length) {
sameIndex = false;
} else {
// iterate and check
fields.forEach((field, index) => {
const indexCol = found.fields[index];
if (!indexCol || field !== indexCol.attribute) {
sameIndex = false;
}
});
}

if (!sameIndex) {
await queryInterface.removeIndex(tableName, indexName);
await queryInterface.addIndex(tableName, {
fields,
name: indexName
});
}
}

module.exports = {
addOrReplaceIndex
};

0 comments on commit 5fb5262

Please sign in to comment.