From 791314ba1a15a0f2056e49b70442fa36398c996e Mon Sep 17 00:00:00 2001 From: azivner Date: Thu, 26 Oct 2017 21:16:21 -0400 Subject: [PATCH] push sync --- routes/api/sync.js | 28 +++++----- services/sync.js | 130 +++++++++++++++++++++++++++++++++------------ 2 files changed, 110 insertions(+), 48 deletions(-) diff --git a/routes/api/sync.js b/routes/api/sync.js index b73b44aed..bc55eb7b6 100644 --- a/routes/api/sync.js +++ b/routes/api/sync.js @@ -2,32 +2,32 @@ const express = require('express'); const router = express.Router(); -const sql = require('../../services/sql'); const auth = require('../../services/auth'); -const utils = require('../../services/utils'); +const sync = require('../../services/sync'); router.get('/changed/:since', auth.checkApiAuth, async (req, res, next) => { const since = parseInt(req.params.since); - res.send({ - 'syncTimestamp': utils.nowTimestamp(), - 'tree': await sql.getResults("select * from notes_tree where date_modified >= ?", [since]), - 'notes': await sql.getFlattenedResults('note_id', "select note_id from notes where date_modified >= ?", [since]), - 'audit_log': await sql.getResults("select * from audit_log where date_modified >= ?", [since]) - }); + res.send(await sync.getChangedSince(since)); +}); + +router.put('/changed', auth.checkApiAuth, async (req, res, next) => { + await sync.putChanged(req.body); + + res.send({}); }); router.get('/note/:noteId/:since', auth.checkApiAuth, async (req, res, next) => { const noteId = req.params.noteId; const since = parseInt(req.params.since); - const detail = await sql.getSingleResult("select * from notes where note_id = ?", [noteId]); + res.send(await sync.getNoteSince(noteId, since)); +}); - res.send({ - 'detail': detail, - 'images': await sql.getResults("select * from images where note_id = ? order by note_offset", [noteId]), - 'history': await sql.getResults("select * from notes_history where note_id = ? and date_modified_to >= ?", [noteId, since]) - }); +router.put('/note', auth.checkApiAuth, async (req, res, next) => { + await sync.putNote(req.body); + + res.send({}); }); module.exports = router; \ No newline at end of file diff --git a/services/sync.js b/services/sync.js index 2e4682b3f..6059a218b 100644 --- a/services/sync.js +++ b/services/sync.js @@ -4,6 +4,7 @@ const log = require('./log'); const rp = require('request-promise'); const sql = require('./sql'); const migration = require('./migration'); +const utils = require('./utils'); const SYNC_SERVER = 'http://localhost:3000'; @@ -11,10 +12,10 @@ const SYNC_SERVER = 'http://localhost:3000'; let syncInProgress = false; async function pullSync() { - const lastSynced = parseInt(await sql.getOption('last_synced_pull')); + const lastSyncedPull = parseInt(await sql.getOption('last_synced_pull')); const resp = await rp({ - uri: SYNC_SERVER + '/api/sync/changed/' + lastSynced, + uri: SYNC_SERVER + '/api/sync/changed/' + lastSyncedPull, headers: { auth: 'sync' }, @@ -24,25 +25,11 @@ async function pullSync() { try { await sql.beginTransaction(); - for (const treeItem of resp.tree) { - delete treeItem['id']; - - await sql.insert("notes_tree", treeItem, true); - - log.info("Syncing notes_tree " + treeItem.note_id); - } - - for (const audit of resp.audit_log) { - delete audit['id']; - - await sql.insert("audit_log", audit, true); - - log.info("Syncing audit_log for noteId=" + audit.note_id); - } + await putChanged(resp); for (const noteId of resp.notes) { const note = await rp({ - uri: SYNC_SERVER + "/api/sync/note/" + noteId + "/" + lastSynced, + uri: SYNC_SERVER + "/api/sync/note/" + noteId + "/" + lastSyncedPull, headers: { auth: 'sync' }, @@ -50,21 +37,7 @@ async function pullSync() { }); - await sql.insert("notes", note.detail, true); - - await sql.remove("images", noteId); - - for (const image of note.images) { - await sql.insert("images", image); - } - - for (const history of note.history) { - delete history['id']; - - await sql.insert("notes_history", history); - } - - log.info("Syncing note" + noteId); + await putNote(note); } await sql.setOption('last_synced_pull', resp.syncTimestamp); @@ -79,7 +52,36 @@ async function pullSync() { } async function pushSync() { + const lastSyncedPush = parseInt(await sql.getOption('last_synced_push')); + const syncStarted = utils.nowTimestamp(); + const changed = await getChangedSince(lastSyncedPush); + + await rp({ + method: 'PUT', + uri: SYNC_SERVER + '/api/sync/changed', + headers: { + auth: 'sync' + }, + body: changed, + json: true + }); + + for (const noteId of changed.notes) { + const note = await getNoteSince(noteId); + + await rp({ + method: 'PUT', + uri: SYNC_SERVER + '/api/sync/note', + headers: { + auth: 'sync' + }, + body: note, + json: true + }); + } + + await sql.setOption('last_synced_pull', syncStarted); } async function sync() { @@ -106,7 +108,67 @@ async function sync() { } } +async function getChangedSince(since) { + return { + 'syncTimestamp': utils.nowTimestamp(), + 'tree': await sql.getResults("select * from notes_tree where date_modified >= ?", [since]), + 'notes': await sql.getFlattenedResults('note_id', "select note_id from notes where date_modified >= ?", [since]), + 'audit_log': await sql.getResults("select * from audit_log where date_modified >= ?", [since]) + }; +} + +async function getNoteSince(noteId, since) { + return { + 'detail': await sql.getSingleResult("select * from notes where note_id = ?", [noteId]), + 'images': await sql.getResults("select * from images where note_id = ? order by note_offset", [noteId]), + 'history': await sql.getResults("select * from notes_history where note_id = ? and date_modified_to >= ?", [noteId, since]) + }; +} + +async function putChanged(changed) { + for (const treeItem of changed.tree) { + delete treeItem['id']; + + await sql.insert("notes_tree", treeItem, true); + + log.info("Update/sync notes_tree " + treeItem.note_id); + } + + for (const audit of changed.audit_log) { + delete audit['id']; + + await sql.insert("audit_log", audit, true); + + log.info("Update/sync audit_log for noteId=" + audit.note_id); + } +} + +async function putNote(note) { + await sql.insert("notes", note.detail, true); + + await sql.remove("images", node.detail.note_id); + + for (const image of note.images) { + await sql.insert("images", image); + } + + for (const history of note.history) { + delete history['id']; + + await sql.insert("notes_history", history); + } + + log.info("Update/sync note " + note.detail.note_id); +} + setInterval(sync, 60000); // kickoff initial sync immediately -setTimeout(sync, 1000); \ No newline at end of file +setTimeout(sync, 1000); + +module.exports = { + getChangedSince, + getNoteSince, + putChanged, + putNote +}; \ No newline at end of file