mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	fix DB setup
This commit is contained in:
		| @@ -1,7 +1,7 @@ | |||||||
| "use strict"; | "use strict"; | ||||||
|  |  | ||||||
| const repository = require('../../services/repository'); | const repository = require('../../services/repository'); | ||||||
| const noteCacheService = require('../../services/note_cache/note_cache.js'); | const noteCacheService = require('../../services/note_cache/note_cache_service'); | ||||||
| const protectedSessionService = require('../../services/protected_session'); | const protectedSessionService = require('../../services/protected_session'); | ||||||
| const noteRevisionService = require('../../services/note_revisions'); | const noteRevisionService = require('../../services/note_revisions'); | ||||||
| const utils = require('../../services/utils'); | const utils = require('../../services/utils'); | ||||||
|   | |||||||
| @@ -146,7 +146,7 @@ function update(req) { | |||||||
| function syncFinished() { | function syncFinished() { | ||||||
|     // after first sync finishes, the application is ready to be used |     // after first sync finishes, the application is ready to be used | ||||||
|     // this is meaningless but at the same time harmless (idempotent) for further syncs |     // this is meaningless but at the same time harmless (idempotent) for further syncs | ||||||
|     sqlInit.dbInitialized(); |     sqlInit.setDbAsInitialized(); | ||||||
| } | } | ||||||
|  |  | ||||||
| function queueSector(req) { | function queueSector(req) { | ||||||
|   | |||||||
| @@ -80,6 +80,8 @@ function apiRoute(method, path, routeHandler) { | |||||||
|  |  | ||||||
| function route(method, path, middleware, routeHandler, resultHandler, transactional = true) { | function route(method, path, middleware, routeHandler, resultHandler, transactional = true) { | ||||||
|     router[method](path, ...middleware, (req, res, next) => { |     router[method](path, ...middleware, (req, res, next) => { | ||||||
|  |         const start = Date.now(); | ||||||
|  |  | ||||||
|         try { |         try { | ||||||
|             cls.namespace.bindEmitter(req); |             cls.namespace.bindEmitter(req); | ||||||
|             cls.namespace.bindEmitter(res); |             cls.namespace.bindEmitter(res); | ||||||
| @@ -103,6 +105,12 @@ function route(method, path, middleware, routeHandler, resultHandler, transactio | |||||||
|  |  | ||||||
|             res.sendStatus(500); |             res.sendStatus(500); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         const time = Date.now() - start; | ||||||
|  |  | ||||||
|  |         if (time >= 10) { | ||||||
|  |             console.log(`Slow request: ${time}ms - ${method} ${path}`); | ||||||
|  |         } | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -126,10 +126,12 @@ if (!fs.existsSync(dataDir.BACKUP_DIR)) { | |||||||
|     fs.mkdirSync(dataDir.BACKUP_DIR, 0o700); |     fs.mkdirSync(dataDir.BACKUP_DIR, 0o700); | ||||||
| } | } | ||||||
|  |  | ||||||
| setInterval(cls.wrap(regularBackup), 4 * 60 * 60 * 1000); | sqlInit.dbReady.then(() => { | ||||||
|  |     setInterval(cls.wrap(regularBackup), 4 * 60 * 60 * 1000); | ||||||
|  |  | ||||||
| // kickoff first backup soon after start up |     // kickoff first backup soon after start up | ||||||
| setTimeout(cls.wrap(regularBackup), 5 * 60 * 1000); |     setTimeout(cls.wrap(regularBackup), 5 * 60 * 1000); | ||||||
|  | }); | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|     backupNow, |     backupNow, | ||||||
|   | |||||||
| @@ -699,10 +699,12 @@ function runOnDemandChecks(autoFix) { | |||||||
|     consistencyChecks.runChecks(); |     consistencyChecks.runChecks(); | ||||||
| } | } | ||||||
|  |  | ||||||
| setInterval(cls.wrap(runPeriodicChecks), 60 * 60 * 1000); | sqlInit.dbReady.then(() => { | ||||||
|  |     setInterval(cls.wrap(runPeriodicChecks), 60 * 60 * 1000); | ||||||
|  |  | ||||||
| // kickoff checks soon after startup (to not block the initial load) |     // kickoff checks soon after startup (to not block the initial load) | ||||||
| setTimeout(cls.wrap(runPeriodicChecks), 20 * 1000); |     setTimeout(cls.wrap(runPeriodicChecks), 20 * 1000); | ||||||
|  | }); | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|     runOnDemandChecks |     runOnDemandChecks | ||||||
|   | |||||||
| @@ -9,4 +9,6 @@ eventService.subscribe(eventService.ENTITY_CHANGED, ({entityName, entity}) => { | |||||||
|     } |     } | ||||||
| }); | }); | ||||||
|  |  | ||||||
| hoistedNote.setHoistedNoteId(optionService.getOption('hoistedNoteId')); | sqlInit.dbReady.then(() => { | ||||||
|  |     hoistedNote.setHoistedNoteId(optionService.getOption('hoistedNoteId')); | ||||||
|  | }); | ||||||
|   | |||||||
| @@ -296,7 +296,7 @@ function importZip(taskContext, fileBuffer, importRootNote) { | |||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|  |  | ||||||
|             if(noteMeta) { |             if (noteMeta) { | ||||||
|                 const includeNoteLinks = (noteMeta.attributes || []) |                 const includeNoteLinks = (noteMeta.attributes || []) | ||||||
|                     .filter(attr => attr.type === 'relation' && attr.name === 'includeNoteLink'); |                     .filter(attr => attr.type === 'relation' && attr.name === 'includeNoteLink'); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,23 +3,31 @@ | |||||||
| const sql = require('../sql.js'); | const sql = require('../sql.js'); | ||||||
| const eventService = require('../events.js'); | const eventService = require('../events.js'); | ||||||
| const noteCache = require('./note_cache'); | const noteCache = require('./note_cache'); | ||||||
|  | const sqlInit = require('../sql_init'); | ||||||
| const Note = require('./entities/note'); | const Note = require('./entities/note'); | ||||||
| const Branch = require('./entities/branch'); | const Branch = require('./entities/branch'); | ||||||
| const Attribute = require('./entities/attribute'); | const Attribute = require('./entities/attribute'); | ||||||
|  |  | ||||||
|  | sqlInit.dbReady.then(() => { | ||||||
|  |     load(); | ||||||
|  | }); | ||||||
|  |  | ||||||
| function load() { | function load() { | ||||||
|     noteCache.reset(); |     noteCache.reset(); | ||||||
|  |  | ||||||
|     sql.getRows(`SELECT noteId, title, type, mime, isProtected, dateCreated, dateModified, utcDateCreated, utcDateModified, contentLength FROM notes WHERE isDeleted = 0`, []) |     for (const row of sql.iterateRows(`SELECT noteId, title, type, mime, isProtected, dateCreated, dateModified, utcDateCreated, utcDateModified, contentLength FROM notes WHERE isDeleted = 0`, [])) { | ||||||
|         .map(row => new Note(noteCache, row)); |         new Note(noteCache, row); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     sql.getRows(`SELECT branchId, noteId, parentNoteId, prefix FROM branches WHERE isDeleted = 0`, []) |     for (const row of sql.iterateRows(`SELECT branchId, noteId, parentNoteId, prefix FROM branches WHERE isDeleted = 0`, [])) { | ||||||
|         .map(row => new Branch(noteCache, row)); |         new Branch(noteCache, row); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     sql.getRows(`SELECT attributeId, noteId, type, name, value, isInheritable FROM attributes WHERE isDeleted = 0`, []).map(row => new Attribute(noteCache, row)); |     for (const row of sql.iterateRows(`SELECT attributeId, noteId, type, name, value, isInheritable FROM attributes WHERE isDeleted = 0`, [])) { | ||||||
|  |         new Attribute(noteCache, row); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     noteCache.loaded = true; |     noteCache.loaded = true; | ||||||
|     noteCache.loadedResolve(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| eventService.subscribe([eventService.ENTITY_CHANGED, eventService.ENTITY_DELETED, eventService.ENTITY_SYNCED],  ({entityName, entity}) => { | eventService.subscribe([eventService.ENTITY_CHANGED, eventService.ENTITY_DELETED, eventService.ENTITY_SYNCED],  ({entityName, entity}) => { | ||||||
| @@ -144,7 +152,5 @@ eventService.subscribe([eventService.ENTITY_CHANGED, eventService.ENTITY_DELETED | |||||||
| }); | }); | ||||||
|  |  | ||||||
| eventService.subscribe(eventService.ENTER_PROTECTED_SESSION, () => { | eventService.subscribe(eventService.ENTER_PROTECTED_SESSION, () => { | ||||||
|     noteCache.loadedPromise.then(() => noteCache.decryptProtectedNotes()); |     noteCache.decryptProtectedNotes(); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| load(); |  | ||||||
|   | |||||||
| @@ -154,7 +154,7 @@ function getNotePath(noteId) { | |||||||
|  |  | ||||||
|         return { |         return { | ||||||
|             noteId: noteId, |             noteId: noteId, | ||||||
|             branchId: getBranch(noteId, parentNote.noteId).branchId, |             branchId: noteCache.getBranch(noteId, parentNote.noteId).branchId, | ||||||
|             title: noteTitle, |             title: noteTitle, | ||||||
|             notePath: retPath, |             notePath: retPath, | ||||||
|             path: retPath.join('/') |             path: retPath.join('/') | ||||||
|   | |||||||
| @@ -762,10 +762,12 @@ function duplicateNote(noteId, parentNoteId) { | |||||||
|     }; |     }; | ||||||
| } | } | ||||||
|  |  | ||||||
| // first cleanup kickoff 5 minutes after startup | sqlInit.dbReady.then(() => { | ||||||
| setTimeout(cls.wrap(eraseDeletedNotes), 5 * 60 * 1000); |     // first cleanup kickoff 5 minutes after startup | ||||||
|  |     setTimeout(cls.wrap(eraseDeletedNotes), 5 * 60 * 1000); | ||||||
|  |  | ||||||
| setInterval(cls.wrap(eraseDeletedNotes), 4 * 3600 * 1000); |     setInterval(cls.wrap(eraseDeletedNotes), 4 * 3600 * 1000); | ||||||
|  | }); | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|     createNewNote, |     createNewNote, | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| const scriptService = require('./script'); | const scriptService = require('./script'); | ||||||
| const repository = require('./repository'); | const repository = require('./repository'); | ||||||
| const cls = require('./cls'); | const cls = require('./cls'); | ||||||
|  | const sqlInit = require('./sql_init'); | ||||||
|  |  | ||||||
| function runNotesWithLabel(runAttrValue) { | function runNotesWithLabel(runAttrValue) { | ||||||
|     const notes = repository.getEntities(` |     const notes = repository.getEntities(` | ||||||
| @@ -20,8 +21,10 @@ function runNotesWithLabel(runAttrValue) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| setTimeout(cls.wrap(() => runNotesWithLabel('backendStartup')), 10 * 1000); | sqlInit.dbReady.then(() => { | ||||||
|  |     setTimeout(cls.wrap(() => runNotesWithLabel('backendStartup')), 10 * 1000); | ||||||
|  |  | ||||||
| setInterval(cls.wrap(() => runNotesWithLabel('hourly')), 3600 * 1000); |     setInterval(cls.wrap(() => runNotesWithLabel('hourly')), 3600 * 1000); | ||||||
|  |  | ||||||
| setInterval(cls.wrap(() => runNotesWithLabel('daily')), 24 * 3600 * 1000); |     setInterval(cls.wrap(() => runNotesWithLabel('daily')), 24 * 3600 * 1000); | ||||||
|  | }); | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ function triggerSync() { | |||||||
|     // it's ok to not wait for it here |     // it's ok to not wait for it here | ||||||
|     syncService.sync().then(res => { |     syncService.sync().then(res => { | ||||||
|         if (res.success) { |         if (res.success) { | ||||||
|             sqlInit.dbInitialized(); |             sqlInit.setDbAsInitialized(); | ||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -47,8 +47,10 @@ function isLocalSourceId(srcId) { | |||||||
|  |  | ||||||
| const currentSourceId = createSourceId(); | const currentSourceId = createSourceId(); | ||||||
|  |  | ||||||
| // this will also refresh source IDs | // very ugly | ||||||
| cls.wrap(() => saveSourceId(currentSourceId)); | setTimeout(() => { | ||||||
|  |     sqlInit.dbReady.then(cls.wrap(() => saveSourceId(currentSourceId))); | ||||||
|  | }, 1000); | ||||||
|  |  | ||||||
| function getCurrentSourceId() { | function getCurrentSourceId() { | ||||||
|     return currentSourceId; |     return currentSourceId; | ||||||
|   | |||||||
| @@ -2,12 +2,11 @@ | |||||||
|  |  | ||||||
| const log = require('./log'); | const log = require('./log'); | ||||||
| const cls = require('./cls'); | const cls = require('./cls'); | ||||||
|  | const Database = require('better-sqlite3'); | ||||||
|  | const dataDir = require('./data_dir'); | ||||||
|  |  | ||||||
| let dbConnection; | const dbConnection = new Database(dataDir.DOCUMENT_PATH); | ||||||
|  | dbConnection.pragma('journal_mode = WAL'); | ||||||
| function setDbConnection(connection) { |  | ||||||
|     dbConnection = connection; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| [`exit`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `SIGTERM`].forEach(eventType => { | [`exit`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `SIGTERM`].forEach(eventType => { | ||||||
|     process.on(eventType, () => { |     process.on(eventType, () => { | ||||||
| @@ -88,7 +87,7 @@ function rollback() { | |||||||
| } | } | ||||||
|  |  | ||||||
| function getRow(query, params = []) { | function getRow(query, params = []) { | ||||||
|     return wrap(() => stmt(query).get(params), query); |     return wrap(query, s => s.get(params)); | ||||||
| } | } | ||||||
|  |  | ||||||
| function getRowOrNull(query, params = []) { | function getRowOrNull(query, params = []) { | ||||||
| @@ -135,7 +134,11 @@ function getManyRows(query, params) { | |||||||
| } | } | ||||||
|  |  | ||||||
| function getRows(query, params = []) { | function getRows(query, params = []) { | ||||||
|     return wrap(() => stmt(query).all(params), query); |     return wrap(query, s => s.all(params)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function iterateRows(query, params = []) { | ||||||
|  |     return stmt(query).iterate(params); | ||||||
| } | } | ||||||
|  |  | ||||||
| function getMap(query, params = []) { | function getMap(query, params = []) { | ||||||
| @@ -171,7 +174,7 @@ function getColumn(query, params = []) { | |||||||
| function execute(query, params = []) { | function execute(query, params = []) { | ||||||
|     startTransactionIfNecessary(); |     startTransactionIfNecessary(); | ||||||
|  |  | ||||||
|     return wrap(() => stmt(query).run(params), query); |     return wrap(query, s => s.run(params)); | ||||||
| } | } | ||||||
|  |  | ||||||
| function executeWithoutTransaction(query, params = []) { | function executeWithoutTransaction(query, params = []) { | ||||||
| @@ -181,57 +184,39 @@ function executeWithoutTransaction(query, params = []) { | |||||||
| function executeMany(query, params) { | function executeMany(query, params) { | ||||||
|     startTransactionIfNecessary(); |     startTransactionIfNecessary(); | ||||||
|  |  | ||||||
|     // essentially just alias |  | ||||||
|     getManyRows(query, params); |     getManyRows(query, params); | ||||||
| } | } | ||||||
|  |  | ||||||
| function executeScript(query) { | function executeScript(query) { | ||||||
|     startTransactionIfNecessary(); |     startTransactionIfNecessary(); | ||||||
|  |  | ||||||
|     return wrap(() => stmt.run(query), query); |     return dbConnection.exec(query); | ||||||
| } | } | ||||||
|  |  | ||||||
| function wrap(func, query) { | function wrap(query, func) { | ||||||
|     if (!dbConnection) { |     const startTimestamp = Date.now(); | ||||||
|         throw new Error("DB connection not initialized yet"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const thisError = new Error(); |     const result = func(stmt(query)); | ||||||
|  |  | ||||||
|     try { |     const milliseconds = Date.now() - startTimestamp; | ||||||
|         const startTimestamp = Date.now(); |  | ||||||
|  |  | ||||||
|         const result = func(dbConnection); |     if (milliseconds >= 100) { | ||||||
|  |         if (query.includes("WITH RECURSIVE")) { | ||||||
|         const milliseconds = Date.now() - startTimestamp; |             log.info(`Slow recursive query took ${milliseconds}ms.`); | ||||||
|         if (milliseconds >= 300) { |         } | ||||||
|             if (query.includes("WITH RECURSIVE")) { |         else { | ||||||
|                 log.info(`Slow recursive query took ${milliseconds}ms.`); |             log.info(`Slow query took ${milliseconds}ms: ${query}`); | ||||||
|             } |  | ||||||
|             else { |  | ||||||
|                 log.info(`Slow query took ${milliseconds}ms: ${query}`); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return result; |  | ||||||
|     } |     } | ||||||
|     catch (e) { |  | ||||||
|         log.error("Error executing query. Inner exception: " + e.stack + thisError.stack); |  | ||||||
|  |  | ||||||
|         thisError.message = e.stack; |     return result; | ||||||
|  |  | ||||||
|         throw thisError; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| function startTransactionIfNecessary() { | function startTransactionIfNecessary() { | ||||||
|     if (!cls.get('isTransactional') |     if (!cls.get('isTransactional') || dbConnection.inTransaction) { | ||||||
|         || cls.get('isInTransaction')) { |  | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     cls.set('isInTransaction', true); |  | ||||||
|  |  | ||||||
|     beginTransaction(); |     beginTransaction(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -246,7 +231,7 @@ function transactional(func) { | |||||||
|     try { |     try { | ||||||
|         const ret = func(); |         const ret = func(); | ||||||
|  |  | ||||||
|         if (cls.get('isInTransaction')) { |         if (dbConnection.inTransaction) { | ||||||
|             commit(); |             commit(); | ||||||
|  |  | ||||||
|             // note that sync rows sent from this action will be sent again by scheduled periodic ping |             // note that sync rows sent from this action will be sent again by scheduled periodic ping | ||||||
| @@ -256,7 +241,7 @@ function transactional(func) { | |||||||
|         return ret; |         return ret; | ||||||
|     } |     } | ||||||
|     catch (e) { |     catch (e) { | ||||||
|         if (cls.get('isInTransaction')) { |         if (dbConnection.inTransaction) { | ||||||
|             rollback(); |             rollback(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -264,22 +249,17 @@ function transactional(func) { | |||||||
|     } |     } | ||||||
|     finally { |     finally { | ||||||
|         cls.namespace.set('isTransactional', false); |         cls.namespace.set('isTransactional', false); | ||||||
|  |  | ||||||
|         if (cls.namespace.get('isInTransaction')) { |  | ||||||
|             cls.namespace.set('isInTransaction', false); |  | ||||||
|             // resolving even for rollback since this is just semaphore for allowing another write transaction to proceed |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|     setDbConnection, |  | ||||||
|     insert, |     insert, | ||||||
|     replace, |     replace, | ||||||
|     getValue, |     getValue, | ||||||
|     getRow, |     getRow, | ||||||
|     getRowOrNull, |     getRowOrNull, | ||||||
|     getRows, |     getRows, | ||||||
|  |     iterateRows, | ||||||
|     getManyRows, |     getManyRows, | ||||||
|     getMap, |     getMap, | ||||||
|     getColumn, |     getColumn, | ||||||
|   | |||||||
| @@ -1,28 +1,21 @@ | |||||||
| const log = require('./log'); | const log = require('./log'); | ||||||
| const dataDir = require('./data_dir'); |  | ||||||
| const fs = require('fs'); | const fs = require('fs'); | ||||||
| const resourceDir = require('./resource_dir'); | const resourceDir = require('./resource_dir'); | ||||||
| const appInfo = require('./app_info'); | const appInfo = require('./app_info'); | ||||||
| const sql = require('./sql'); | const sql = require('./sql'); | ||||||
| const cls = require('./cls'); |  | ||||||
| const utils = require('./utils'); | const utils = require('./utils'); | ||||||
| const optionService = require('./options'); | const optionService = require('./options'); | ||||||
| const port = require('./port'); | const port = require('./port'); | ||||||
| const Option = require('../entities/option'); | const Option = require('../entities/option'); | ||||||
| const TaskContext = require('./task_context.js'); | const TaskContext = require('./task_context.js'); | ||||||
| const Database = require('better-sqlite3'); |  | ||||||
|  |  | ||||||
| const dbConnection = new Database(dataDir.DOCUMENT_PATH); | const dbReady = utils.deferred(); | ||||||
| dbConnection.pragma('journal_mode = WAL'); |  | ||||||
|  |  | ||||||
| sql.setDbConnection(dbConnection); | initDbConnection(); | ||||||
|  |  | ||||||
| const dbReady = initDbConnection(); |  | ||||||
|  |  | ||||||
| function schemaExists() { | function schemaExists() { | ||||||
|     const tableResults = sql.getRows("SELECT name FROM sqlite_master WHERE type='table' AND name='options'"); |     return !!sql.getValue(`SELECT name FROM sqlite_master | ||||||
|  |                                  WHERE type = 'table' AND name = 'options'`); | ||||||
|     return tableResults.length === 1; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| function isDbInitialized() { | function isDbInitialized() { | ||||||
| @@ -32,35 +25,34 @@ function isDbInitialized() { | |||||||
|  |  | ||||||
|     const initialized = sql.getValue("SELECT value FROM options WHERE name = 'initialized'"); |     const initialized = sql.getValue("SELECT value FROM options WHERE name = 'initialized'"); | ||||||
|  |  | ||||||
|     // !initialized may be removed in the future, required only for migration |     return initialized === 'true'; | ||||||
|     return !initialized || initialized === 'true'; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| function initDbConnection() { | function initDbConnection() { | ||||||
|     cls.init(() => { |     if (!isDbInitialized()) { | ||||||
|         if (!isDbInitialized()) { |         log.info(`DB not initialized, please visit setup page` + (utils.isElectron() ? '' : ` - http://[your-server-host]:${port} to see instructions on how to initialize Trilium.`)); | ||||||
|             log.info(`DB not initialized, please visit setup page` + (utils.isElectron() ? '' : ` - http://[your-server-host]:${port} to see instructions on how to initialize Trilium.`)); |  | ||||||
|  |  | ||||||
|             return; |         return; | ||||||
|         } |     } | ||||||
|  |  | ||||||
|         const currentDbVersion = getDbVersion(); |     const currentDbVersion = getDbVersion(); | ||||||
|  |  | ||||||
|         if (currentDbVersion > appInfo.dbVersion) { |     if (currentDbVersion > appInfo.dbVersion) { | ||||||
|             log.error(`Current DB version ${currentDbVersion} is newer than app db version ${appInfo.dbVersion} which means that it was created by newer and incompatible version of Trilium. Upgrade to latest version of Trilium to resolve this issue.`); |         log.error(`Current DB version ${currentDbVersion} is newer than app db version ${appInfo.dbVersion} which means that it was created by newer and incompatible version of Trilium. Upgrade to latest version of Trilium to resolve this issue.`); | ||||||
|  |  | ||||||
|             utils.crash(); |         utils.crash(); | ||||||
|         } |     } | ||||||
|  |  | ||||||
|         if (!isDbUpToDate()) { |     if (!isDbUpToDate()) { | ||||||
|             // avoiding circular dependency |         // avoiding circular dependency | ||||||
|             const migrationService = require('./migration'); |         const migrationService = require('./migration'); | ||||||
|  |  | ||||||
|             migrationService.migrate(); |         migrationService.migrate(); | ||||||
|         } |     } | ||||||
|  |  | ||||||
|         require('./options_init').initStartupOptions(); |     require('./options_init').initStartupOptions(); | ||||||
|     }); |  | ||||||
|  |     dbReady.resolve(); | ||||||
| } | } | ||||||
|  |  | ||||||
| function createInitialDatabase(username, password, theme) { | function createInitialDatabase(username, password, theme) { | ||||||
| @@ -156,7 +148,7 @@ function isDbUpToDate() { | |||||||
|     return upToDate; |     return upToDate; | ||||||
| } | } | ||||||
|  |  | ||||||
| function dbInitialized() { | function setDbAsInitialized() { | ||||||
|     if (!isDbInitialized()) { |     if (!isDbInitialized()) { | ||||||
|         optionService.setOption('initialized', 'true'); |         optionService.setOption('initialized', 'true'); | ||||||
|  |  | ||||||
| @@ -174,5 +166,5 @@ module.exports = { | |||||||
|     isDbUpToDate, |     isDbUpToDate, | ||||||
|     createInitialDatabase, |     createInitialDatabase, | ||||||
|     createDatabaseForSync, |     createDatabaseForSync, | ||||||
|     dbInitialized |     setDbAsInitialized | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -368,12 +368,14 @@ function getMaxSyncId() { | |||||||
|     return sql.getValue('SELECT MAX(id) FROM sync'); |     return sql.getValue('SELECT MAX(id) FROM sync'); | ||||||
| } | } | ||||||
|  |  | ||||||
| setInterval(cls.wrap(sync), 60000); | sqlInit.dbReady.then(() => { | ||||||
|  |     setInterval(cls.wrap(sync), 60000); | ||||||
|  |  | ||||||
| // kickoff initial sync immediately |     // kickoff initial sync immediately | ||||||
| setTimeout(cls.wrap(sync), 3000); |     setTimeout(cls.wrap(sync), 3000); | ||||||
|  |  | ||||||
| setInterval(cls.wrap(updatePushStats), 1000); |     setInterval(cls.wrap(updatePushStats), 1000); | ||||||
|  | }); | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|     sync, |     sync, | ||||||
|   | |||||||
| @@ -5,7 +5,6 @@ const repository = require('./repository'); | |||||||
| const Branch = require('../entities/branch'); | const Branch = require('../entities/branch'); | ||||||
| const syncTableService = require('./sync_table'); | const syncTableService = require('./sync_table'); | ||||||
| const protectedSessionService = require('./protected_session'); | const protectedSessionService = require('./protected_session'); | ||||||
| const noteCacheService = require('./note_cache/note_cache.js'); |  | ||||||
|  |  | ||||||
| function getNotes(noteIds) { | function getNotes(noteIds) { | ||||||
|     // we return also deleted notes which have been specifically asked for |     // we return also deleted notes which have been specifically asked for | ||||||
| @@ -23,8 +22,6 @@ function getNotes(noteIds) { | |||||||
|  |  | ||||||
|     protectedSessionService.decryptNotes(notes); |     protectedSessionService.decryptNotes(notes); | ||||||
|  |  | ||||||
|     noteCacheService.loadedPromise; |  | ||||||
|  |  | ||||||
|     notes.forEach(note => { |     notes.forEach(note => { | ||||||
|         note.isProtected = !!note.isProtected |         note.isProtected = !!note.isProtected | ||||||
|     }); |     }); | ||||||
|   | |||||||
| @@ -259,6 +259,22 @@ function timeLimit(promise, limitMs) { | |||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function deferred() { | ||||||
|  |     return (() => { | ||||||
|  |         let resolve, reject; | ||||||
|  |  | ||||||
|  |         let promise = new Promise((res, rej) => { | ||||||
|  |             resolve = res; | ||||||
|  |             reject = rej; | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         promise.resolve = resolve; | ||||||
|  |         promise.reject = reject; | ||||||
|  |  | ||||||
|  |         return promise; | ||||||
|  |     })(); | ||||||
|  | } | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|     randomSecureToken, |     randomSecureToken, | ||||||
|     randomString, |     randomString, | ||||||
| @@ -290,5 +306,6 @@ module.exports = { | |||||||
|     getNoteTitle, |     getNoteTitle, | ||||||
|     removeTextFileExtension, |     removeTextFileExtension, | ||||||
|     formatDownloadTitle, |     formatDownloadTitle, | ||||||
|     timeLimit |     timeLimit, | ||||||
|  |     deferred | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -127,10 +127,10 @@ function closeSetupWindow() { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| function registerGlobalShortcuts() { | async function registerGlobalShortcuts() { | ||||||
|     const {globalShortcut} = require('electron'); |     const {globalShortcut} = require('electron'); | ||||||
|  |  | ||||||
|     sqlInit.dbReady; |     await sqlInit.dbReady; | ||||||
|  |  | ||||||
|     const allActions = keyboardActionsService.getKeyboardActions(); |     const allActions = keyboardActionsService.getKeyboardActions(); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user