From 00846a0cece9d475bb0daee2b105008c8781bdc0 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 31 Jul 2017 15:09:16 -0700 Subject: [PATCH] Support compressed resources for sync --- app/sync/index.js | 23 ++++++++++++++++++++++- app/sync/storage.js | 4 ++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/app/sync/index.js b/app/sync/index.js index 612532d98..8c2b6f2fb 100644 --- a/app/sync/index.js +++ b/app/sync/index.js @@ -6,6 +6,7 @@ import * as store from './storage'; import * as misc from '../common/misc'; import Logger from './logger'; import {trackEvent} from '../analytics/index'; +import * as zlib from 'zlib'; export const START_DELAY = 1E3; export const PULL_PERIOD = 15E3; @@ -542,6 +543,7 @@ async function _handleChangeAndPush (event, doc, timestamp) { */ const _fetchResourceGroupPromises = {}; const _resourceGroupCache = {}; + export async function fetchResourceGroup (resourceGroupId, invalidateCache = false) { if (invalidateCache) { delete _resourceGroupCache[resourceGroupId]; @@ -630,7 +632,14 @@ async function _getResourceGroupSymmetricKey (resourceGroupId) { export async function encryptDoc (resourceGroupId, doc) { try { const symmetricKey = await _getResourceGroupSymmetricKey(resourceGroupId); + + // TODO: Turn on compression once enough users are on version >= 5.7.0 + // const jsonStr = JSON.stringify(doc); + // const docStr = zlib.gzipSync(jsonStr); + + // Don't use compression for now const docStr = JSON.stringify(doc); + const message = crypt.encryptAES(symmetricKey, docStr); return JSON.stringify(message); } catch (e) { @@ -650,6 +659,12 @@ export async function decryptDoc (resourceGroupId, messageJSON) { throw e; } + try { + decrypted = zlib.gunzipSync(decrypted); + } catch (err) { + // It's not compressed (legacy), which is okay for now + } + try { return JSON.parse(decrypted); } catch (e) { @@ -730,7 +745,13 @@ export async function createResourceForDoc (doc) { } export async function getOrCreateResourceForDoc (doc) { - let resource = await store.getResourceByDocId(doc._id); + let [resource, ...extras] = await store.findResourcesByDocId(doc._id); + + // Sometimes there may be multiple resources created by accident for + // the same doc. Let's delete the extras here if there are any. + for (const resource of extras) { + await store.removeResource(resource); + } if (resource) { return resource; diff --git a/app/sync/storage.js b/app/sync/storage.js index ab386832f..b04b2add7 100644 --- a/app/sync/storage.js +++ b/app/sync/storage.js @@ -99,12 +99,12 @@ export async function insertResource (resource) { export async function updateResource (resource, ...patches) { const newDoc = Object.assign({}, resource, ...patches); - await _execDB(TYPE_RESOURCE, 'update', {_id: resource._id}, newDoc); + await _execDB(TYPE_RESOURCE, 'update', {_id: resource._id}, newDoc, {multi: true}); return newDoc; } export function removeResource (resource) { - return _execDB(TYPE_RESOURCE, 'remove', {_id: resource._id}); + return _execDB(TYPE_RESOURCE, 'remove', {_id: resource._id}, {multi: true}); } // ~~~~~~ //