From 75878c80a8bf71f43763b3346eb81694e526f515 Mon Sep 17 00:00:00 2001 From: azivner Date: Sun, 28 Jan 2018 20:52:05 -0500 Subject: [PATCH] migration script to camel case --- db/schema.sql | 2 +- .../0070__rename_columns_to_camel_case.sql | 207 ++++++++++++++++++ public/javascripts/note_tree.js | 2 +- routes/api/login.js | 2 +- routes/api/recent_notes.js | 2 +- routes/api/tree.js | 2 +- routes/index.js | 2 +- services/app_info.js | 2 +- services/options.js | 30 ++- services/script_context.js | 2 +- services/source_id.js | 2 +- services/sql.js | 18 +- services/sync.js | 2 +- services/sync_table.js | 2 +- 14 files changed, 258 insertions(+), 19 deletions(-) create mode 100644 migrations/0070__rename_columns_to_camel_case.sql diff --git a/db/schema.sql b/db/schema.sql index 1e6005c52..209d23ae9 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -28,7 +28,7 @@ CREATE TABLE IF NOT EXISTS "notes" ( `is_protected` INT NOT NULL DEFAULT 0, `is_deleted` INT NOT NULL DEFAULT 0, `date_created` TEXT NOT NULL, - `date_modified` TEXT NOT NULL, type TEXT NOT NULL DEFAULT 'text', mime TEXT NOT NULL DEFAULT 'text', + `date_modified` TEXT NOT NULL, type TEXT NOT NULL DEFAULT 'text', mime TEXT NOT NULL DEFAULT 'text/html', PRIMARY KEY(`note_id`) ); CREATE INDEX `IDX_notes_is_deleted` ON `notes` ( diff --git a/migrations/0070__rename_columns_to_camel_case.sql b/migrations/0070__rename_columns_to_camel_case.sql new file mode 100644 index 000000000..d8340bd66 --- /dev/null +++ b/migrations/0070__rename_columns_to_camel_case.sql @@ -0,0 +1,207 @@ +CREATE TABLE "options_mig" ( + `name` TEXT NOT NULL PRIMARY KEY, + `value` TEXT, + `dateModified` INT, + isSynced INTEGER NOT NULL DEFAULT 0); + +INSERT INTO options_mig (name, value, dateModified, isSynced) + SELECT opt_name, opt_value, date_modified, is_synced FROM options; + +DROP TABLE options; +ALTER TABLE options_mig RENAME TO options; + +CREATE TABLE "sync_mig" ( + `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + `entityName` TEXT NOT NULL, + `entityId` TEXT NOT NULL, + `sourceId` TEXT NOT NULL, + `syncDate` TEXT NOT NULL); + +INSERT INTO sync_mig (id, entityName, entityId, sourceId, syncDate) + SELECT id, entity_name, entity_id, source_id, sync_date FROM sync; + +DROP TABLE sync; +ALTER TABLE sync_mig RENAME TO sync; + +CREATE UNIQUE INDEX `IDX_sync_entityName_entityId` ON `sync` ( + `entityName`, + `entityId` +); + +CREATE INDEX `IDX_sync_syncDate` ON `sync` ( + `syncDate` +); + +CREATE TABLE `source_ids_mig` ( + `sourceId` TEXT NOT NULL, + `dateCreated` TEXT NOT NULL, + PRIMARY KEY(`sourceId`) +); + +INSERT INTO source_ids_mig (sourceId, dateCreated) + SELECT source_id, date_created FROM source_ids; + +DROP TABLE source_ids; +ALTER TABLE source_ids_mig RENAME TO source_ids; + +CREATE TABLE "notes_mig" ( + `noteId` TEXT NOT NULL, + `title` TEXT, + `content` TEXT, + `isProtected` INT NOT NULL DEFAULT 0, + `isDeleted` INT NOT NULL DEFAULT 0, + `dateCreated` TEXT NOT NULL, + `dateModified` TEXT NOT NULL, + type TEXT NOT NULL DEFAULT 'text', + mime TEXT NOT NULL DEFAULT 'text/html', + PRIMARY KEY(`noteId`) +); + +INSERT INTO notes_mig (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified, type, mime) + SELECT note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified, type, mime FROM notes; + +DROP TABLE notes; +ALTER TABLE notes_mig RENAME TO notes; + +CREATE INDEX `IDX_notes_isDeleted` ON `notes` ( + `isDeleted` +); + +CREATE TABLE `event_log_mig` ( + `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + `noteId` TEXT, + `comment` TEXT, + `dateAdded` TEXT NOT NULL, + FOREIGN KEY(noteId) REFERENCES notes(noteId) +); + +INSERT INTO event_log_mig (id, noteId, comment, dateAdded) + SELECT id, note_id, comment, date_added FROM event_log; + +DROP TABLE event_log; +ALTER TABLE event_log_mig RENAME TO event_log; + +CREATE TABLE "note_tree" ( + `noteTreeId` TEXT NOT NULL, + `noteId` TEXT NOT NULL, + `parentNoteId` TEXT NOT NULL, + `notePosition` INTEGER NOT NULL, + `prefix` TEXT, + `isExpanded` BOOLEAN, + `isDeleted` INTEGER NOT NULL DEFAULT 0, + `dateModified` TEXT NOT NULL, + PRIMARY KEY(`noteTreeId`) +); + +INSERT INTO note_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) + SELECT note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified FROM notes_tree; + +DROP TABLE notes_tree; + +CREATE INDEX `IDX_note_tree_noteId` ON `note_tree` ( + `noteId` +); + +CREATE INDEX `IDX_note_tree_noteId_parentNoteId` ON `note_tree` ( + `noteId`, + `parentNoteId` +); + +CREATE TABLE "note_revisions" ( + `noteRevisionId` TEXT NOT NULL PRIMARY KEY, + `noteId` TEXT NOT NULL, + `title` TEXT, + `content` TEXT, + `isProtected` INT NOT NULL DEFAULT 0, + `dateModifiedFrom` TEXT NOT NULL, + `dateModifiedTo` TEXT NOT NULL +); + +INSERT INTO note_revisions (noteRevisionId, noteId, title, content, isProtected, dateModifiedFrom, dateModifiedTo) + SELECT note_history_id, note_id, note_title, note_text, is_protected, date_modified_from, date_modified_to FROM notes_history; + +DROP TABLE notes_history; + +CREATE INDEX `IDX_note_revisions_noteId` ON `note_revisions` ( + `noteId` +); + +CREATE INDEX `IDX_note_revisions_dateModifiedFrom` ON `note_revisions` ( + `dateModifiedFrom` +); + +CREATE INDEX `IDX_note_revisions_dateModifiedTo` ON `note_revisions` ( + `dateModifiedTo` +); + +CREATE TABLE `recent_notes_mig` ( + `noteTreeId` TEXT NOT NULL PRIMARY KEY, + `notePath` TEXT NOT NULL, + `dateAccessed` TEXT NOT NULL, + isDeleted INT +); + +INSERT INTO recent_notes_mig (noteTreeId, notePath, dateAccessed, isDeleted) + SELECT note_tree_id, note_path, date_accessed, is_deleted FROM recent_notes; + +DROP TABLE recent_notes; +ALTER TABLE recent_notes_mig RENAME TO recent_notes; + +CREATE TABLE images_mig +( + imageId TEXT PRIMARY KEY NOT NULL, + format TEXT NOT NULL, + checksum TEXT NOT NULL, + name TEXT NOT NULL, + data BLOB, + isDeleted INT NOT NULL DEFAULT 0, + dateModified TEXT NOT NULL, + dateCreated TEXT NOT NULL +); + +INSERT INTO images_mig (imageId, format, checksum, name, data, isDeleted, dateModified, dateCreated) + SELECT image_id, format, checksum, name, data, is_deleted, date_modified, date_created FROM images; + +DROP TABLE images; +ALTER TABLE images_mig RENAME TO images; + +CREATE TABLE note_images +( + noteImageId TEXT PRIMARY KEY NOT NULL, + noteId TEXT NOT NULL, + imageId TEXT NOT NULL, + isDeleted INT NOT NULL DEFAULT 0, + dateModified TEXT NOT NULL, + dateCreated TEXT NOT NULL +); + +INSERT INTO note_images (noteImageId, noteId, imageId, isDeleted, dateModified, dateCreated) + SELECT note_image_id, note_id, image_id, is_deleted, date_modified, date_created FROM notes_image; + +DROP TABLE notes_image; + +CREATE INDEX IDX_note_images_noteId ON note_images (noteId); + +CREATE INDEX IDX_note_images_imageId ON note_images (imageId); + +CREATE INDEX IDX_note_images_noteId_imageId ON note_images (noteId, imageId); + +CREATE TABLE attributes_mig +( + attributeId TEXT PRIMARY KEY NOT NULL, + noteId TEXT NOT NULL, + name TEXT NOT NULL, + value TEXT, + dateCreated TEXT NOT NULL, + dateModified TEXT NOT NULL +); + +INSERT INTO attributes_mig (attributeId, noteId, name, value, dateCreated, dateModified) + SELECT attribute_id, note_id, name, value, date_created, date_modified FROM attributes; + +DROP TABLE attributes; +ALTER TABLE attributes_mig RENAME TO attributes; + +CREATE INDEX IDX_attributes_noteId ON attributes (noteId); + +CREATE UNIQUE INDEX IDX_attributes_noteId_name ON attributes (noteId, name); diff --git a/public/javascripts/note_tree.js b/public/javascripts/note_tree.js index e599ea924..6c3ed1e61 100644 --- a/public/javascripts/note_tree.js +++ b/public/javascripts/note_tree.js @@ -642,7 +642,7 @@ const noteTree = (function() { function loadTree() { return server.get('tree').then(resp => { - startNotePath = resp.start_notePath; + startNotePath = resp.start_note_path; if (document.location.hash) { startNotePath = getNotePathFromAddress(); diff --git a/routes/api/login.js b/routes/api/login.js index cadcf4dc7..3c21531cf 100644 --- a/routes/api/login.js +++ b/routes/api/login.js @@ -4,7 +4,7 @@ const express = require('express'); const router = express.Router(); const options = require('../../services/options'); const utils = require('../../services/utils'); -const sourceId = require('../../services/sourceId'); +const sourceId = require('../../services/source_id'); const auth = require('../../services/auth'); const password_encryption = require('../../services/password_encryption'); const protected_session = require('../../services/protected_session'); diff --git a/routes/api/recent_notes.js b/routes/api/recent_notes.js index bfb0d81f8..3f946d63c 100644 --- a/routes/api/recent_notes.js +++ b/routes/api/recent_notes.js @@ -28,7 +28,7 @@ router.put('/:noteTreeId/:notePath', auth.checkApiAuth, wrap(async (req, res, ne await sync_table.addRecentNoteSync(noteTreeId, sourceId); - await options.setOption('start_notePath', notePath, sourceId); + await options.setOption('start_note_path', notePath, sourceId); }); res.send(await getRecentNotes()); diff --git a/routes/api/tree.js b/routes/api/tree.js index 13c4a1174..03e1f7dfa 100644 --- a/routes/api/tree.js +++ b/routes/api/tree.js @@ -31,7 +31,7 @@ router.get('/', auth.checkApiAuth, wrap(async (req, res, next) => { res.send({ notes: notes, - start_notePath: await options.getOption('start_notePath') + start_note_path: await options.getOption('start_note_path') }); })); diff --git a/routes/index.js b/routes/index.js index 5d7871bc5..2928f80b5 100644 --- a/routes/index.js +++ b/routes/index.js @@ -3,7 +3,7 @@ const express = require('express'); const router = express.Router(); const auth = require('../services/auth'); -const sourceId = require('../services/sourceId'); +const sourceId = require('../services/source_id'); const sql = require('../services/sql'); const wrap = require('express-promise-wrap').wrap; diff --git a/services/app_info.js b/services/app_info.js index 9bd16f895..5e30423ea 100644 --- a/services/app_info.js +++ b/services/app_info.js @@ -3,7 +3,7 @@ const build = require('./build'); const packageJson = require('../package'); -const APP_DB_VERSION = 69; +const APP_DB_VERSION = 70; module.exports = { app_version: packageJson.version, diff --git a/services/options.js b/services/options.js index c2d608a94..799f55be1 100644 --- a/services/options.js +++ b/services/options.js @@ -4,7 +4,12 @@ const sync_table = require('./sync_table'); const app_info = require('./app_info'); async function getOptionOrNull(name) { - return await sql.getFirstOrNull("SELECT value FROM options WHERE name = ?", [name]); + try { + return await sql.getFirstOrNull("SELECT value FROM options WHERE name = ?", [name]); + } + catch (e) { + return await sql.getFirstOrNull("SELECT opt_value FROM options WHERE opt_name = ?", [name]); + } } async function getOption(name) { @@ -14,11 +19,18 @@ async function getOption(name) { throw new Error("Option " + name + " doesn't exist"); } - return row['value']; + return row['value'] ? row['value'] : row['opt_value']; } async function setOption(name, value, sourceId = null) { - const opt = await sql.getFirst("SELECT * FROM options WHERE name = ?", [name]); + let opt; + + try { + opt = await sql.getFirst("SELECT * FROM options WHERE name = ?", [name]); + } + catch (e) { + opt = await sql.getFirst("SELECT * FROM options WHERE opt_name = ?", [name]); + } if (!opt) { throw new Error(`Option ${name} doesn't exist`); @@ -28,8 +40,14 @@ async function setOption(name, value, sourceId = null) { await sync_table.addOptionsSync(name, sourceId); } - await sql.execute("UPDATE options SET value = ?, dateModified = ? WHERE name = ?", - [value, utils.nowDate(), name]); + try { + await sql.execute("UPDATE options SET value = ?, dateModified = ? WHERE name = ?", + [value, utils.nowDate(), name]); + } + catch (e) { + await sql.execute("UPDATE options SET opt_value = ?, date_modified = ? WHERE opt_name = ?", + [value, utils.nowDate(), name]); + } } async function createOption(name, value, isSynced, sourceId = null) { @@ -56,7 +74,7 @@ async function initOptions(startNotePath) { await createOption('encrypted_data_key', '', true); await createOption('encrypted_data_key_iv', '', true); - await createOption('start_notePath', startNotePath, false); + await createOption('start_note_path', startNotePath, false); await createOption('protected_session_timeout', 600, true); await createOption('history_snapshot_time_interval', 600, true); await createOption('last_backup_date', utils.nowDate(), false); diff --git a/services/script_context.js b/services/script_context.js index fa2bd3358..76b2ec78a 100644 --- a/services/script_context.js +++ b/services/script_context.js @@ -61,7 +61,7 @@ function ScriptContext(noteId, dataKey) { if (!note.type) { note.type = "text"; - note.mime = ""; + note.mime = "text/html"; } const noteId = (await notes.createNewNote(parentNoteId, note)).noteId; diff --git a/services/source_id.js b/services/source_id.js index dec46a0aa..47d2352a2 100644 --- a/services/source_id.js +++ b/services/source_id.js @@ -4,7 +4,7 @@ const sql = require('./sql'); async function saveSourceId(sourceId) { await sql.doInTransaction(async () => { - await sql.insert("sourceIds", { + await sql.insert("source_ids", { sourceId: sourceId, dateCreated: utils.nowDate() }); diff --git a/services/sql.js b/services/sql.js index 16034f510..514ff3e69 100644 --- a/services/sql.js +++ b/services/sql.js @@ -226,7 +226,14 @@ async function doInTransaction(func) { } async function isDbUpToDate() { - const dbVersion = parseInt(await getFirstValue("SELECT value FROM options WHERE name = 'db_version'")); + let dbVersion; + + try { + dbVersion = parseInt(await getFirstValue("SELECT value FROM options WHERE name = 'db_version'")); + } + catch (e) { + dbVersion = parseInt(await getFirstValue("SELECT opt_value FROM options WHERE opt_name = 'db_version'")); + } const upToDate = dbVersion >= app_info.db_version; @@ -238,7 +245,14 @@ async function isDbUpToDate() { } async function isUserInitialized() { - const username = await getFirstValue("SELECT value FROM options WHERE name = 'username'"); + let username; + + try { + username = await getFirstValue("SELECT value FROM options WHERE name = 'username'"); + } + catch (e) { + username = await getFirstValue("SELECT opt_value FROM options WHERE opt_name = 'username'"); + } return !!username; } diff --git a/services/sync.js b/services/sync.js index b585608d5..9bb77fe0c 100644 --- a/services/sync.js +++ b/services/sync.js @@ -5,7 +5,7 @@ const rp = require('request-promise'); const sql = require('./sql'); const options = require('./options'); const utils = require('./utils'); -const sourceId = require('./sourceId'); +const sourceId = require('./source_id'); const notes = require('./notes'); const syncUpdate = require('./sync_update'); const content_hash = require('./content_hash'); diff --git a/services/sync_table.js b/services/sync_table.js index 8cf4aec3f..63623b8b4 100644 --- a/services/sync_table.js +++ b/services/sync_table.js @@ -1,5 +1,5 @@ const sql = require('./sql'); -const sourceId = require('./sourceId'); +const sourceId = require('./source_id'); const utils = require('./utils'); const sync_setup = require('./sync_setup'); const log = require('./log');