From 1eacc2a449eae32ae7f4eb34fd9a47fa42380576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Tue, 25 Jul 2017 15:26:57 +0200 Subject: [PATCH] restore: Implement storage limits for IDB --- src/plugins/RestoreFiles/IndexedDBStore.js | 43 ++++++++++++++++++++-- src/plugins/RestoreFiles/index.js | 6 ++- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/plugins/RestoreFiles/IndexedDBStore.js b/src/plugins/RestoreFiles/IndexedDBStore.js index b81fe6ece..6f5d5ab71 100644 --- a/src/plugins/RestoreFiles/IndexedDBStore.js +++ b/src/plugins/RestoreFiles/IndexedDBStore.js @@ -4,6 +4,7 @@ const isSupported = !!indexedDB const DB_NAME = 'uppy-blobs' const DB_VERSION = 1 + function connect (dbName, name) { const request = indexedDB.open(dbName, DB_VERSION) return new Promise((resolve, reject) => { @@ -34,7 +35,9 @@ class IndexedDBStore { constructor (core, opts) { this.opts = Object.assign({ dbName: DB_NAME, - storeName: 'default' + storeName: 'default', + maxFileSize: 10 * 1024 * 1024, // 10 MB + maxTotalSize: 300 * 1024 * 1024 // 300 MB }, opts) this.name = this.opts.storeName @@ -50,7 +53,6 @@ class IndexedDBStore { const request = transaction.objectStore(this.name).getAll() return waitForRequest(request) }).then((files) => { - console.log(files) const result = {} files.forEach((file) => { result[file.id] = file @@ -70,11 +72,46 @@ class IndexedDBStore { }).then((result) => result.data) } + /** + * Get the total size of all stored files. + * + * @private + */ + getSize () { + return this.ready.then((db) => { + const transaction = db.transaction([this.name], 'readonly') + const request = transaction.objectStore(this.name).openCursor() + return new Promise((resolve, reject) => { + let size = 0 + request.onsuccess = () => { + const cursor = event.target.result + if (cursor) { + size += cursor.value.data.size + cursor.continue() + } else { + resolve(size) + } + } + request.onerror = () => { + reject(new Error('Could not retrieve stored blobs size')) + } + }) + }) + } + /** * Save a file in the store. */ put (file) { - return this.ready.then((db) => { + if (file.data.size > this.opts.maxFileSize) { + return Promise.reject(new Error('File is too big to store.')) + } + return this.getSize().then((size) => { + if (size > this.opts.maxTotalSize) { + return Promise.reject(new Error('No space left')) + } + return this.ready + }).then((db) => { const transaction = db.transaction([this.name], 'readwrite') const request = transaction.objectStore(this.name).add({ id: file.id, diff --git a/src/plugins/RestoreFiles/index.js b/src/plugins/RestoreFiles/index.js index db70d391c..d534f88c1 100644 --- a/src/plugins/RestoreFiles/index.js +++ b/src/plugins/RestoreFiles/index.js @@ -79,7 +79,11 @@ module.exports = class RestoreFiles extends Plugin { this.store.list().then(this.onBlobsLoaded) this.core.on('core:file-added', (file) => { - if (!file.isRemote) this.store.put(file) + if (file.isRemote) return + this.store.put(file).catch((err) => { + console.error('Could not store file') + console.error(err) + }) }) this.core.on('core:file-removed', (fileID) => {