mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	converted all timestamps to string representation
This commit is contained in:
		
							
								
								
									
										156
									
								
								migrations/0050__string_dates.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								migrations/0050__string_dates.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,156 @@ | ||||
| DROP TABLE migrations; | ||||
|  | ||||
| -- Sync | ||||
| CREATE TABLE `sync_mig` ( | ||||
|     `id`	INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, | ||||
|     `entity_name`	TEXT NOT NULL, | ||||
|     `entity_id`	TEXT NOT NULL, | ||||
|     `source_id` TEXT NOT NULL, | ||||
|     `sync_date`	TEXT NOT NULL); | ||||
|  | ||||
| INSERT INTO sync_mig (id, entity_name, entity_id, source_id, sync_date) | ||||
|                SELECT id, entity_name, entity_id, source_id, datetime(sync_date, 'unixepoch') || '.000' FROM sync; | ||||
|  | ||||
| DROP TABLE sync; | ||||
| ALTER TABLE sync_mig RENAME TO sync; | ||||
|  | ||||
| CREATE UNIQUE INDEX `IDX_sync_entity_name_id` ON `sync` ( | ||||
|   `entity_name`, | ||||
|   `entity_id` | ||||
| ); | ||||
|  | ||||
| CREATE INDEX `IDX_sync_sync_date` ON `sync` ( | ||||
|   `sync_date` | ||||
| ); | ||||
|  | ||||
| -- Options | ||||
|  | ||||
| UPDATE options SET opt_value = datetime(opt_value, 'unixepoch') || '.000' WHERE opt_name IN ('last_backup_date'); | ||||
| UPDATE options SET date_modified = datetime(date_modified, 'unixepoch') || '.000'; | ||||
|  | ||||
| -- Event log | ||||
|  | ||||
| CREATE TABLE `event_log_mig` ( | ||||
|   `id`	INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, | ||||
|   `note_id`	TEXT, | ||||
|   `comment`	TEXT, | ||||
|   `date_added`	TEXT NOT NULL | ||||
| ); | ||||
|  | ||||
| INSERT INTO event_log_mig (id, note_id, comment, date_added) | ||||
|                     SELECT id, note_id, comment, datetime(date_added, 'unixepoch') || '.000' FROM event_log; | ||||
|  | ||||
| DROP TABLE event_log; | ||||
| ALTER TABLE event_log_mig RENAME TO event_log; | ||||
|  | ||||
| CREATE INDEX `IDX_event_log_date_added` ON `event_log` ( | ||||
|   `date_added` | ||||
| ); | ||||
|  | ||||
| -- Notes | ||||
|  | ||||
| CREATE TABLE IF NOT EXISTS "notes_mig" ( | ||||
|   `note_id`	TEXT NOT NULL, | ||||
|   `note_title`	TEXT, | ||||
|   `note_text`	TEXT, | ||||
|   `is_protected`	INT NOT NULL DEFAULT 0, | ||||
|   `is_deleted`	INT NOT NULL DEFAULT 0, | ||||
|   `date_created`	TEXT NOT NULL, | ||||
|   `date_modified`	TEXT NOT NULL, | ||||
|   PRIMARY KEY(`note_id`) | ||||
| ); | ||||
|  | ||||
| INSERT INTO notes_mig (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) | ||||
|                 SELECT note_id, note_title, note_text, is_protected, is_deleted, | ||||
|                   datetime(date_created, 'unixepoch') || '.000', | ||||
|                   datetime(date_modified, 'unixepoch') || '.000' | ||||
|                 FROM notes; | ||||
|  | ||||
| DROP TABLE notes; | ||||
| ALTER TABLE notes_mig RENAME TO notes; | ||||
|  | ||||
| CREATE INDEX `IDX_notes_is_deleted` ON `notes` ( | ||||
|   `is_deleted` | ||||
| ); | ||||
|  | ||||
| -- note history | ||||
|  | ||||
| CREATE TABLE IF NOT EXISTS "notes_history_mig" ( | ||||
|   `note_history_id`	TEXT NOT NULL PRIMARY KEY, | ||||
|   `note_id`	TEXT NOT NULL, | ||||
|   `note_title`	TEXT, | ||||
|   `note_text`	TEXT, | ||||
|   `is_protected`	INT NOT NULL DEFAULT 0, | ||||
|   `date_modified_from` TEXT NOT NULL, | ||||
|   `date_modified_to` TEXT NOT NULL | ||||
| ); | ||||
|  | ||||
| INSERT INTO notes_history_mig (note_history_id, note_id, note_title, note_text, is_protected, date_modified_from, date_modified_to) | ||||
|   SELECT note_history_id, note_id, note_title, note_text, is_protected, | ||||
|     datetime(date_modified_from, 'unixepoch') || '.000', | ||||
|     datetime(date_modified_to, 'unixepoch') || '.000' | ||||
|   FROM notes_history; | ||||
|  | ||||
| DROP TABLE notes_history; | ||||
| ALTER TABLE notes_history_mig RENAME TO notes_history; | ||||
|  | ||||
| CREATE INDEX `IDX_notes_history_note_id` ON `notes_history` ( | ||||
|   `note_id` | ||||
| ); | ||||
| CREATE INDEX `IDX_notes_history_note_date_modified_from` ON `notes_history` ( | ||||
|   `date_modified_from` | ||||
| ); | ||||
| CREATE INDEX `IDX_notes_history_note_date_modified_to` ON `notes_history` ( | ||||
|   `date_modified_to` | ||||
| ); | ||||
|  | ||||
| -- Source IDs | ||||
|  | ||||
| DROP TABLE source_ids; | ||||
|  | ||||
| CREATE TABLE `source_ids` ( | ||||
|   `source_id`	TEXT NOT NULL, | ||||
|   `date_created`	TEXT NOT NULL, | ||||
|   PRIMARY KEY(`source_id`) | ||||
| ); | ||||
|  | ||||
| -- Recent notes | ||||
|  | ||||
| DROP TABLE recent_notes; | ||||
|  | ||||
| CREATE TABLE `recent_notes` ( | ||||
|   'note_tree_id'TEXT NOT NULL PRIMARY KEY, | ||||
|   `note_path` TEXT NOT NULL, | ||||
|   `date_accessed` TEXT NOT NULL, | ||||
|   is_deleted INT | ||||
| ); | ||||
|  | ||||
| -- Notes tree | ||||
|  | ||||
| CREATE TABLE IF NOT EXISTS "notes_tree_mig" ( | ||||
|   `note_tree_id`	TEXT NOT NULL, | ||||
|   `note_id`	TEXT NOT NULL, | ||||
|   `note_pid`	TEXT NOT NULL, | ||||
|   `note_pos`	INTEGER NOT NULL, | ||||
|   `prefix`	TEXT, | ||||
|   `is_expanded`	BOOLEAN, | ||||
|   `is_deleted`	INTEGER NOT NULL DEFAULT 0, | ||||
|   `date_modified`	TEXT NOT NULL, | ||||
|   PRIMARY KEY(`note_tree_id`) | ||||
| ); | ||||
|  | ||||
| INSERT INTO notes_tree_mig (note_tree_id, note_id, note_pid, note_pos, prefix, is_expanded, is_deleted, date_modified) | ||||
|                      SELECT note_tree_id, note_id, note_pid, note_pos, prefix, is_expanded, is_deleted, | ||||
|                             datetime(date_modified, 'unixepoch') || '.000' | ||||
|                      FROM notes_tree; | ||||
|  | ||||
| DROP TABLE notes_tree; | ||||
| ALTER TABLE notes_tree_mig RENAME TO notes_tree; | ||||
|  | ||||
| CREATE INDEX `IDX_notes_tree_note_tree_id` ON `notes_tree` ( | ||||
|   `note_tree_id` | ||||
| ); | ||||
| CREATE INDEX `IDX_notes_tree_note_id_note_pid` ON `notes_tree` ( | ||||
|   `note_id`, | ||||
|   `note_pid` | ||||
| ); | ||||
| @@ -100,7 +100,7 @@ const noteEditor = (function() { | ||||
|     } | ||||
|  | ||||
|     async function loadNoteToEditor(noteId) { | ||||
|         currentNote = await server.get('notes/' + noteId); | ||||
|         currentNote = await loadNote(noteId); | ||||
|  | ||||
|         if (isNewNoteCreated) { | ||||
|             isNewNoteCreated = false; | ||||
|   | ||||
| @@ -67,6 +67,8 @@ async function importNotes(dir, parentNoteId) { | ||||
|         const noteId = utils.newNoteId(); | ||||
|         const noteTreeId = utils.newNoteHistoryId(); | ||||
|  | ||||
|         const now = utils.nowDate(); | ||||
|  | ||||
|         await sql.insert('notes_tree', { | ||||
|             note_tree_id: noteTreeId, | ||||
|             note_id: noteId, | ||||
| @@ -74,7 +76,7 @@ async function importNotes(dir, parentNoteId) { | ||||
|             note_pos: notePos, | ||||
|             is_expanded: 0, | ||||
|             is_deleted: 0, | ||||
|             date_modified: utils.nowTimestamp() | ||||
|             date_modified: now | ||||
|         }); | ||||
|  | ||||
|         await sync_table.addNoteTreeSync(noteTreeId); | ||||
| @@ -85,8 +87,8 @@ async function importNotes(dir, parentNoteId) { | ||||
|             note_text: noteText, | ||||
|             is_deleted: 0, | ||||
|             is_protected: 0, | ||||
|             date_created: utils.nowTimestamp(), | ||||
|             date_modified: utils.nowTimestamp() | ||||
|             date_created: now, | ||||
|             date_modified: now | ||||
|         }); | ||||
|  | ||||
|         await sync_table.addNoteSync(noteId); | ||||
|   | ||||
| @@ -4,7 +4,6 @@ const express = require('express'); | ||||
| const router = express.Router(); | ||||
| const options = require('../../services/options'); | ||||
| const utils = require('../../services/utils'); | ||||
| const migration = require('../../services/migration'); | ||||
| const source_id = require('../../services/source_id'); | ||||
| const auth = require('../../services/auth'); | ||||
| const password_encryption = require('../../services/password_encryption'); | ||||
|   | ||||
| @@ -30,8 +30,7 @@ router.get('/:noteId', auth.checkApiAuth, async (req, res, next) => { | ||||
|     } | ||||
|  | ||||
|     res.send({ | ||||
|         detail: detail, | ||||
|         loadTime: utils.nowTimestamp() | ||||
|         detail: detail | ||||
|     }); | ||||
| }); | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ router.put('/:noteTreeId/move-to/:parentNoteId', auth.checkApiAuth, async (req, | ||||
|     const maxNotePos = await sql.getSingleValue('SELECT MAX(note_pos) FROM notes_tree WHERE note_pid = ? AND is_deleted = 0', [parentNoteId]); | ||||
|     const newNotePos = maxNotePos === null ? 0 : maxNotePos + 1; | ||||
|  | ||||
|     const now = utils.nowTimestamp(); | ||||
|     const now = utils.nowDate(); | ||||
|  | ||||
|     await sql.doInTransaction(async () => { | ||||
|         await sql.execute("UPDATE notes_tree SET note_pid = ?, note_pos = ?, date_modified = ? WHERE note_tree_id = ?", | ||||
| @@ -40,7 +40,7 @@ router.put('/:noteTreeId/move-before/:beforeNoteTreeId', async (req, res, next) | ||||
|  | ||||
|             await sync_table.addNoteReorderingSync(beforeNote.note_pid); | ||||
|  | ||||
|             const now = utils.nowTimestamp(); | ||||
|             const now = utils.nowDate(); | ||||
|  | ||||
|             await sql.execute("UPDATE notes_tree SET note_pid = ?, note_pos = ?, date_modified = ? WHERE note_tree_id = ?", | ||||
|                 [beforeNote.note_pid, beforeNote.note_pos, now, noteTreeId]); | ||||
| @@ -70,7 +70,7 @@ router.put('/:noteTreeId/move-after/:afterNoteTreeId', async (req, res, next) => | ||||
|             await sync_table.addNoteReorderingSync(afterNote.note_pid); | ||||
|  | ||||
|             await sql.execute("UPDATE notes_tree SET note_pid = ?, note_pos = ?, date_modified = ? WHERE note_tree_id = ?", | ||||
|                 [afterNote.note_pid, afterNote.note_pos + 1, utils.nowTimestamp(), noteTreeId]); | ||||
|                 [afterNote.note_pid, afterNote.note_pos + 1, utils.nowDate(), noteTreeId]); | ||||
|  | ||||
|             await sync_table.addNoteTreeSync(noteTreeId); | ||||
|         }); | ||||
| @@ -107,13 +107,13 @@ router.put('/:childNoteId/clone-to/:parentNoteId', auth.checkApiAuth, async (req | ||||
|  | ||||
|     await sql.doInTransaction(async () => { | ||||
|         const noteTree = { | ||||
|             'note_tree_id': utils.newNoteTreeId(), | ||||
|             'note_id': childNoteId, | ||||
|             'note_pid': parentNoteId, | ||||
|             'note_pos': newNotePos, | ||||
|             'is_expanded': 0, | ||||
|             'date_modified': utils.nowTimestamp(), | ||||
|             'is_deleted': 0 | ||||
|             note_tree_id: utils.newNoteTreeId(), | ||||
|             note_id: childNoteId, | ||||
|             note_pid: parentNoteId, | ||||
|             note_pos: newNotePos, | ||||
|             is_expanded: 0, | ||||
|             date_modified: utils.nowDate(), | ||||
|             is_deleted: 0 | ||||
|         }; | ||||
|  | ||||
|         await sql.replace("notes_tree", noteTree); | ||||
| @@ -160,13 +160,13 @@ router.put('/:noteId/clone-after/:afterNoteTreeId', async (req, res, next) => { | ||||
|         await sync_table.addNoteReorderingSync(afterNote.note_pid); | ||||
|  | ||||
|         const noteTree = { | ||||
|             'note_tree_id': utils.newNoteTreeId(), | ||||
|             'note_id': noteId, | ||||
|             'note_pid': afterNote.note_pid, | ||||
|             'note_pos': afterNote.note_pos + 1, | ||||
|             'is_expanded': 0, | ||||
|             'date_modified': utils.nowTimestamp(), | ||||
|             'is_deleted': 0 | ||||
|             note_tree_id: utils.newNoteTreeId(), | ||||
|             note_id: noteId, | ||||
|             note_pid: afterNote.note_pid, | ||||
|             note_pos: afterNote.note_pos + 1, | ||||
|             is_expanded: 0, | ||||
|             date_modified: utils.nowDate(), | ||||
|             is_deleted: 0 | ||||
|         }; | ||||
|  | ||||
|         await sql.replace("notes_tree", noteTree); | ||||
|   | ||||
| @@ -20,7 +20,7 @@ router.put('/:noteTreeId/:notePath', auth.checkApiAuth, async (req, res, next) = | ||||
|         await sql.replace('recent_notes', { | ||||
|             note_tree_id: noteTreeId, | ||||
|             note_path: notePath, | ||||
|             date_accessed: utils.nowTimestamp(), | ||||
|             date_accessed: utils.nowDate(), | ||||
|             is_deleted: 0 | ||||
|         }); | ||||
|  | ||||
| @@ -39,7 +39,7 @@ async function getRecentNotes() { | ||||
| } | ||||
|  | ||||
| async function deleteOld() { | ||||
|     const cutoffDateAccessed = utils.nowTimestamp() - 24 * 60 * 60; | ||||
|     const cutoffDateAccessed = utils.dateStr(new Date(Date.now() - 24 * 60 * 60 * 1000)); | ||||
|  | ||||
|     await sql.doInTransaction(async () => { | ||||
|         await sql.execute("DELETE FROM recent_notes WHERE date_accessed < ?", [cutoffDateAccessed]); | ||||
|   | ||||
| @@ -52,7 +52,7 @@ router.put('/:noteTreeId/set-prefix', auth.checkApiAuth, async (req, res, next) | ||||
|     const prefix = utils.isEmptyOrWhitespace(req.body.prefix) ? null : req.body.prefix; | ||||
|  | ||||
|     await sql.doInTransaction(async () => { | ||||
|         await sql.execute("UPDATE notes_tree SET prefix = ?, date_modified = ? WHERE note_tree_id = ?", [prefix, utils.nowTimestamp(), noteTreeId]); | ||||
|         await sql.execute("UPDATE notes_tree SET prefix = ?, date_modified = ? WHERE note_tree_id = ?", [prefix, utils.nowDate(), noteTreeId]); | ||||
|  | ||||
|         await sync_table.addNoteTreeSync(noteTreeId); | ||||
|     }); | ||||
|   | ||||
							
								
								
									
										30
									
								
								schema.sql
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								schema.sql
									
									
									
									
									
								
							| @@ -68,15 +68,23 @@ CREATE TABLE `source_ids` ( | ||||
| 	`date_created`	INTEGER NOT NULL, | ||||
| 	PRIMARY KEY(`source_id`) | ||||
| ); | ||||
| CREATE TABLE `recent_notes` ( | ||||
|   'note_tree_id'TEXT NOT NULL PRIMARY KEY, | ||||
|   `note_path` TEXT NOT NULL, | ||||
|   `date_accessed` INTEGER NOT NULL , | ||||
|   is_deleted INT | ||||
| ); | ||||
| CREATE TABLE IF NOT EXISTS "notes_tree" ( | ||||
|     [note_tree_id] VARCHAR(30) PRIMARY KEY NOT NULL, | ||||
|     [note_id] VARCHAR(30) NOT NULL, | ||||
|     [note_pid] VARCHAR(30) NOT NULL, | ||||
|     [note_pos] INTEGER NOT NULL, | ||||
|     [is_expanded] BOOLEAN NULL , | ||||
|     date_modified INTEGER NOT NULL DEFAULT 0, | ||||
|     is_deleted INTEGER NOT NULL DEFAULT 0 | ||||
| , `prefix` TEXT); | ||||
| 	`note_tree_id`	VARCHAR ( 30 ) NOT NULL, | ||||
| 	`note_id`	VARCHAR ( 30 ) NOT NULL, | ||||
| 	`note_pid`	VARCHAR ( 30 ) NOT NULL, | ||||
| 	`note_pos`	INTEGER NOT NULL, | ||||
| 	`is_expanded`	BOOLEAN, | ||||
| 	`date_modified`	TEXT NOT NULL DEFAULT 0, | ||||
| 	`is_deleted`	INTEGER NOT NULL DEFAULT 0, | ||||
| 	`prefix`	TEXT, | ||||
| 	PRIMARY KEY(`note_tree_id`) | ||||
| ); | ||||
| CREATE INDEX `IDX_notes_tree_note_tree_id` ON `notes_tree` ( | ||||
| 	`note_tree_id` | ||||
| ); | ||||
| @@ -84,9 +92,3 @@ CREATE INDEX `IDX_notes_tree_note_id_note_pid` ON `notes_tree` ( | ||||
| 	`note_id`, | ||||
| 	`note_pid` | ||||
| ); | ||||
| CREATE TABLE `recent_notes` ( | ||||
|   'note_tree_id'TEXT NOT NULL PRIMARY KEY, | ||||
|   `note_path` TEXT NOT NULL, | ||||
|   `date_accessed` INTEGER NOT NULL , | ||||
|   is_deleted INT | ||||
| ); | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| const build = require('./build'); | ||||
| const packageJson = require('../package'); | ||||
|  | ||||
| const APP_DB_VERSION = 49; | ||||
| const APP_DB_VERSION = 50; | ||||
|  | ||||
| module.exports = { | ||||
|     app_version: packageJson.version, | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| "use strict"; | ||||
|  | ||||
| const migration = require('./migration'); | ||||
| const sql = require('./sql'); | ||||
| const utils = require('./utils'); | ||||
| const options = require('./options'); | ||||
|  | ||||
| @@ -13,7 +14,7 @@ async function checkAuth(req, res, next) { | ||||
|     else if (!req.session.loggedIn && !utils.isElectron()) { | ||||
|         res.redirect("login"); | ||||
|     } | ||||
|     else if (!await migration.isDbUpToDate()) { | ||||
|     else if (!await sql.isDbUpToDate()) { | ||||
|         res.redirect("migration"); | ||||
|     } | ||||
|     else { | ||||
| @@ -34,7 +35,7 @@ async function checkApiAuth(req, res, next) { | ||||
|     if (!req.session.loggedIn) { | ||||
|         res.status(401).send("Not authorized"); | ||||
|     } | ||||
|     else if (await migration.isDbUpToDate()) { | ||||
|     else if (await sql.isDbUpToDate()) { | ||||
|         next(); | ||||
|     } | ||||
|     else { | ||||
|   | ||||
| @@ -8,10 +8,12 @@ const log = require('./log'); | ||||
| const sql = require('./sql'); | ||||
|  | ||||
| async function regularBackup() { | ||||
|     const now = utils.nowTimestamp(); | ||||
|     const last_backup_date = parseInt(await options.getOption('last_backup_date')); | ||||
|     const now = new Date(); | ||||
|     const lastBackupDate = utils.parseDate(await options.getOption('last_backup_date')); | ||||
|  | ||||
|     if (now - last_backup_date > 43200) { | ||||
|     console.log(lastBackupDate); | ||||
|  | ||||
|     if (now.getTime() - lastBackupDate.getTime() > 43200 * 1000) { | ||||
|         await backupNow(); | ||||
|     } | ||||
|  | ||||
| @@ -19,7 +21,7 @@ async function regularBackup() { | ||||
| } | ||||
|  | ||||
| async function backupNow() { | ||||
|     const now = utils.nowTimestamp(); | ||||
|     const now = utils.nowDate(); | ||||
|  | ||||
|     const date_str = new Date().toISOString().substr(0, 19).replace(/:/g, ''); | ||||
|  | ||||
|   | ||||
| @@ -10,7 +10,7 @@ async function addNoteEvent(noteId, comment) { | ||||
|     await sql.insert('event_log', { | ||||
|        note_id : noteId, | ||||
|        comment: comment, | ||||
|        date_added: utils.nowTimestamp() | ||||
|        date_added: utils.nowDate() | ||||
|     }); | ||||
|  | ||||
|     log.info("Event log for " + noteId + ": " + comment); | ||||
|   | ||||
| @@ -70,6 +70,8 @@ async function migrate() { | ||||
|                 await options.setOption("db_version", mig.dbVersion); | ||||
|             }); | ||||
|  | ||||
|             sql.setDbReadyAsResolved(); | ||||
|  | ||||
|             log.info("Migration to version " + mig.dbVersion + " has been successful."); | ||||
|  | ||||
|             mig['success'] = true; | ||||
| @@ -87,13 +89,6 @@ async function migrate() { | ||||
|     return migrations; | ||||
| } | ||||
|  | ||||
| async function isDbUpToDate() { | ||||
|     const dbVersion = parseInt(await options.getOption('db_version')); | ||||
|  | ||||
|     return dbVersion >= app_info.db_version; | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
|     migrate, | ||||
|     isDbUpToDate | ||||
|     migrate | ||||
| }; | ||||
| @@ -23,7 +23,7 @@ async function createNewNote(parentNoteId, note) { | ||||
|             newNotePos = afterNote.note_pos + 1; | ||||
|  | ||||
|             await sql.execute('UPDATE notes_tree SET note_pos = note_pos + 1, date_modified = ? WHERE note_pid = ? AND note_pos > ? AND is_deleted = 0', | ||||
|                 [utils.nowTimestamp(), parentNoteId, afterNote.note_pos]); | ||||
|                 [utils.nowDate(), parentNoteId, afterNote.note_pos]); | ||||
|  | ||||
|             await sync_table.addNoteReorderingSync(parentNoteId); | ||||
|         } | ||||
| @@ -31,28 +31,27 @@ async function createNewNote(parentNoteId, note) { | ||||
|             throw new Error('Unknown target: ' + note.target); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         const now = utils.nowTimestamp(); | ||||
|         const now = utils.nowDate(); | ||||
|  | ||||
|         await sql.insert("notes", { | ||||
|             'note_id': noteId, | ||||
|             'note_title': note.note_title, | ||||
|             'note_text': '', | ||||
|             'date_created': now, | ||||
|             'date_modified': now, | ||||
|             'is_protected': note.is_protected | ||||
|             note_id: noteId, | ||||
|             note_title: note.note_title, | ||||
|             note_text: '', | ||||
|             date_created: now, | ||||
|             date_modified: now, | ||||
|             is_protected: note.is_protected | ||||
|         }); | ||||
|  | ||||
|         await sync_table.addNoteSync(noteId); | ||||
|  | ||||
|         await sql.insert("notes_tree", { | ||||
|             'note_tree_id': noteTreeId, | ||||
|             'note_id': noteId, | ||||
|             'note_pid': parentNoteId, | ||||
|             'note_pos': newNotePos, | ||||
|             'is_expanded': 0, | ||||
|             'date_modified': now, | ||||
|             'is_deleted': 0 | ||||
|             note_tree_id: noteTreeId, | ||||
|             note_id: noteId, | ||||
|             note_pid: parentNoteId, | ||||
|             note_pos: newNotePos, | ||||
|             is_expanded: 0, | ||||
|             date_modified: now, | ||||
|             is_deleted: 0 | ||||
|         }); | ||||
|  | ||||
|         await sync_table.addNoteTreeSync(noteTreeId); | ||||
| @@ -142,16 +141,19 @@ async function updateNote(noteId, newNote, ctx) { | ||||
|         await encryptNote(newNote, ctx); | ||||
|     } | ||||
|  | ||||
|     const now = utils.nowTimestamp(); | ||||
|     const now = new Date(); | ||||
|  | ||||
|     const historySnapshotTimeInterval = parseInt(await options.getOption('history_snapshot_time_interval')); | ||||
|  | ||||
|     const historyCutoff = now - historySnapshotTimeInterval; | ||||
|     const historyCutoff = utils.dateStr(new Date(now.getTime() - historySnapshotTimeInterval * 1000)); | ||||
|  | ||||
|     const existingNoteHistoryId = await sql.getSingleValue("SELECT note_history_id FROM notes_history WHERE note_id = ? AND date_modified_to >= ?", [noteId, historyCutoff]); | ||||
|     const existingNoteHistoryId = await sql.getSingleValue( | ||||
|         "SELECT note_history_id FROM notes_history WHERE note_id = ? AND date_modified_to >= ?", [noteId, historyCutoff]); | ||||
|  | ||||
|     await sql.doInTransaction(async () => { | ||||
|         if (!existingNoteHistoryId && (now - newNote.detail.date_created) >= historySnapshotTimeInterval) { | ||||
|         const msSinceDateCreated = now.getTime() - utils.parseDate(newNote.detail.date_created).getTime(); | ||||
|  | ||||
|         if (!existingNoteHistoryId && msSinceDateCreated >= historySnapshotTimeInterval * 1000) { | ||||
|             const oldNote = await sql.getSingleResult("SELECT * FROM notes WHERE note_id = ?", [noteId]); | ||||
|  | ||||
|             if (oldNote.is_protected) { | ||||
| @@ -188,7 +190,7 @@ async function updateNote(noteId, newNote, ctx) { | ||||
| } | ||||
|  | ||||
| async function deleteNote(noteTreeId) { | ||||
|     const now = utils.nowTimestamp(); | ||||
|     const now = utils.nowDate(); | ||||
|  | ||||
|     await sql.execute("UPDATE notes_tree SET is_deleted = 1, date_modified = ? WHERE note_tree_id = ?", [now, noteTreeId]); | ||||
|     await sync_table.addNoteTreeSync(noteTreeId); | ||||
|   | ||||
| @@ -24,7 +24,7 @@ async function setOption(optName, optValue) { | ||||
|     await sql.replace("options", { | ||||
|         opt_name: optName, | ||||
|         opt_value: optValue, | ||||
|         date_modified: utils.nowTimestamp() | ||||
|         date_modified: utils.nowDate() | ||||
|     }); | ||||
| } | ||||
|  | ||||
| @@ -42,7 +42,7 @@ async function initOptions(startNotePath) { | ||||
|     await setOption('start_note_path', startNotePath); | ||||
|     await setOption('protected_session_timeout', 600); | ||||
|     await setOption('history_snapshot_time_interval', 600); | ||||
|     await setOption('last_backup_date', utils.nowTimestamp()); | ||||
|     await setOption('last_backup_date', utils.nowDate()); | ||||
|     await setOption('db_version', app_info.db_version); | ||||
|  | ||||
|     await setOption('last_synced_pull', app_info.db_version); | ||||
|   | ||||
| @@ -5,12 +5,12 @@ const messaging = require('./messaging'); | ||||
| const options = require('./options'); | ||||
| const sync = require('./sync'); | ||||
|  | ||||
| let startTime = utils.nowTimestamp(); | ||||
| let startTime = utils.nowDate(); | ||||
| let sentSyncId = []; | ||||
|  | ||||
| async function sendPing() { | ||||
|     const syncs = await sql.getResults("SELECT * FROM sync WHERE sync_date >= ? AND source_id != ?", [startTime, source_id.currentSourceId]); | ||||
|     startTime = utils.nowTimestamp(); | ||||
|     startTime = utils.nowDate(); | ||||
|  | ||||
|     const data = {}; | ||||
|     const syncIds = []; | ||||
|   | ||||
| @@ -13,7 +13,7 @@ sql.dbReady.then(async () => { | ||||
|         await sql.doInTransaction(async () => { | ||||
|             await sql.insert("source_ids", { | ||||
|                 source_id: currentSourceId, | ||||
|                 date_created: utils.nowTimestamp() | ||||
|                 date_created: utils.nowDate() | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|   | ||||
| @@ -5,6 +5,7 @@ const dataDir = require('./data_dir'); | ||||
| const fs = require('fs'); | ||||
| const sqlite = require('sqlite'); | ||||
| const utils = require('./utils'); | ||||
| const app_info = require('./app_info'); | ||||
|  | ||||
| async function createConnection() { | ||||
|     return await sqlite.open(dataDir.DOCUMENT_PATH, {Promise}); | ||||
| @@ -15,7 +16,11 @@ const dbConnected = createConnection(); | ||||
| let dbReadyResolve = null; | ||||
| const dbReady = new Promise((resolve, reject) => { | ||||
|     dbConnected.then(async db => { | ||||
|         dbReadyResolve = () => resolve(db); | ||||
|         dbReadyResolve = () => { | ||||
|             log.info("DB ready."); | ||||
|  | ||||
|             resolve(db); | ||||
|         }; | ||||
|  | ||||
|         const tableResults = await getResults("SELECT name FROM sqlite_master WHERE type='table' AND name='notes'"); | ||||
|         if (tableResults.length !== 1) { | ||||
| @@ -27,6 +32,7 @@ const dbReady = new Promise((resolve, reject) => { | ||||
|                 await executeScript(schema); | ||||
|  | ||||
|                 const noteId = utils.newNoteId(); | ||||
|                 const now = utils.nowDate(); | ||||
|  | ||||
|                 await insert('notes_tree', { | ||||
|                     note_tree_id: utils.newNoteTreeId(), | ||||
| @@ -34,7 +40,7 @@ const dbReady = new Promise((resolve, reject) => { | ||||
|                     note_pid: 'root', | ||||
|                     note_pos: 1, | ||||
|                     is_deleted: 0, | ||||
|                     date_modified: utils.nowTimestamp() | ||||
|                     date_modified: now | ||||
|                 }); | ||||
|  | ||||
|                 await insert('notes', { | ||||
| @@ -43,8 +49,8 @@ const dbReady = new Promise((resolve, reject) => { | ||||
|                     note_text: 'Text', | ||||
|                     is_protected: 0, | ||||
|                     is_deleted: 0, | ||||
|                     date_created: utils.nowTimestamp(), | ||||
|                     date_modified: utils.nowTimestamp() | ||||
|                     date_created: now, | ||||
|                     date_modified: now | ||||
|                 }); | ||||
|  | ||||
|                 await require('./options').initOptions(noteId); | ||||
| @@ -56,9 +62,17 @@ const dbReady = new Promise((resolve, reject) => { | ||||
|         else { | ||||
|             const username = await getSingleValue("SELECT opt_value FROM options WHERE opt_name = 'username'"); | ||||
|  | ||||
|             if (username) { | ||||
|                 resolve(db); | ||||
|             if (!username) { | ||||
|                 log.info("Login/password not initialized. DB not ready."); | ||||
|  | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             if (!await isDbUpToDate()) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             resolve(db); | ||||
|         } | ||||
|     }) | ||||
|     .catch(e => { | ||||
| @@ -202,9 +216,8 @@ async function doInTransaction(func) { | ||||
|             await rollback(); | ||||
|  | ||||
|             transactionActive = false; | ||||
|             resolve(); | ||||
|  | ||||
|             throw e; | ||||
|             reject(e); | ||||
|         } | ||||
|     }); | ||||
|  | ||||
| @@ -213,6 +226,18 @@ async function doInTransaction(func) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| async function isDbUpToDate() { | ||||
|     const dbVersion = parseInt(await getSingleValue("SELECT opt_value FROM options WHERE opt_name = 'db_version'")); | ||||
|  | ||||
|     const upToDate = dbVersion >= app_info.db_version; | ||||
|  | ||||
|     if (!upToDate) { | ||||
|         log.info("App db version is " + app_info.db_version + ", while db version is " + dbVersion + ". Migration needed."); | ||||
|     } | ||||
|  | ||||
|     return upToDate; | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
|     dbReady, | ||||
|     insert, | ||||
| @@ -226,5 +251,6 @@ module.exports = { | ||||
|     execute, | ||||
|     executeScript, | ||||
|     doInTransaction, | ||||
|     setDbReadyAsResolved | ||||
|     setDbReadyAsResolved, | ||||
|     isDbUpToDate | ||||
| }; | ||||
| @@ -37,9 +37,7 @@ async function sync() { | ||||
|     syncInProgress = true; | ||||
|  | ||||
|     try { | ||||
|         if (!await migration.isDbUpToDate()) { | ||||
|             log.info("DB not up to date"); | ||||
|  | ||||
|         if (!await sql.isDbUpToDate()) { | ||||
|             return { | ||||
|                 success: false, | ||||
|                 message: "DB not up to date" | ||||
|   | ||||
| @@ -30,7 +30,7 @@ async function addEntitySync(entityName, entityId, sourceId) { | ||||
|     await sql.replace("sync", { | ||||
|         entity_name: entityName, | ||||
|         entity_id: entityId, | ||||
|         sync_date: utils.nowTimestamp(), | ||||
|         sync_date: utils.nowDate(), | ||||
|         source_id: sourceId || source_id.currentSourceId | ||||
|     }); | ||||
| } | ||||
|   | ||||
| @@ -27,6 +27,29 @@ function nowTimestamp() { | ||||
|     return Math.floor(Date.now() / 1000); | ||||
| } | ||||
|  | ||||
| function nowDate() { | ||||
|     return dateStr(new Date()); | ||||
| } | ||||
|  | ||||
| function dateStr(date) { | ||||
|     return date.toISOString().replace("T", " ").replace("Z", ""); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @param str - needs to be in the "YYYY-MM-DD HH:MM:SS.sss" format as outputted by dateStr(). | ||||
|  *              also is assumed to be GMT time, *not* local time | ||||
|  */ | ||||
| function parseDate(str) { | ||||
|     try { | ||||
|         const isoDate = str.replace(" ", "T") + "Z"; | ||||
|  | ||||
|         return new Date(Date.parse(isoDate)); | ||||
|     } | ||||
|     catch (e) { | ||||
|         throw new Error("Can't parse date from " + str + ": " + e.stack); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function toBase64(plainText) { | ||||
|     return Buffer.from(plainText).toString('base64'); | ||||
| } | ||||
| @@ -68,6 +91,9 @@ module.exports = { | ||||
|     randomSecureToken, | ||||
|     randomString, | ||||
|     nowTimestamp, | ||||
|     nowDate, | ||||
|     dateStr, | ||||
|     parseDate, | ||||
|     newNoteId, | ||||
|     newNoteTreeId, | ||||
|     newNoteHistoryId, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user