From a2f1c945866e38586f01481d2af0836819faa541 Mon Sep 17 00:00:00 2001 From: Timothy Farrell Date: Fri, 12 Jan 2018 11:50:56 -0600 Subject: [PATCH] Manage order with sorts and indexing rather than keys The jury is still out on this. Indexes are the "right" way to do this but are actually slower in some circumstances. --- packages/gallery/src/data/image.js | 6 ++-- packages/gallery/src/interface/focus.js | 30 ++++++++++++++++--- packages/gallery/src/interface/sectionView.js | 2 ++ packages/gallery/src/services/db.js | 27 ++++++++--------- 4 files changed, 43 insertions(+), 22 deletions(-) diff --git a/packages/gallery/src/data/image.js b/packages/gallery/src/data/image.js index 7ce6909..a74a144 100644 --- a/packages/gallery/src/data/image.js +++ b/packages/gallery/src/data/image.js @@ -25,10 +25,6 @@ class ImageSpec extends TypeSpec { return doc.digest.substr(0, 16); } - static getSequence(doc) { - return new Date(doc.originalDate).getTime(); - } - async delete(cascade = true) { if (cascade) { new Set(Object.keys(this.sizes)).forEach(async key => { @@ -126,4 +122,6 @@ const processImportables = backgroundTask(async function _processImportables(ima export const ImageType = PouchDB.registerType('Image', ImageSpec); +ImageType.index('originalDate', ['originalDate', 'id']); + ImageType.find({ importing: true }).then(results => results.forEach(processImportables)); diff --git a/packages/gallery/src/interface/focus.js b/packages/gallery/src/interface/focus.js index 404fe9f..f2ced47 100644 --- a/packages/gallery/src/interface/focus.js +++ b/packages/gallery/src/interface/focus.js @@ -107,10 +107,32 @@ export function FocusView(vm, params) { } doc(await ImageType.find(_id)); - const n = await ImageType.next(_id); - nextLink(n.length ? router.href('focus', { id: n[0].id }) : null); - const p = await ImageType.next(_id, true); - prevLink(p.length ? router.href('focus', { id: p[0].id }) : null); + const n = await ImageType.find( + { + originalDate: { $gte: doc().originalDate } + }, + { + limit: 1, + skip: 1, + index: 'originalDate', + sort: [{ originalDate: 'asc' }] + } + ); + + const p = await ImageType.find( + { + originalDate: { $lte: doc().originalDate } + }, + { + limit: 1, + skip: 1, + index: 'originalDate', + sort: [{ originalDate: 'desc' }] + } + ); + + nextLink(n.length ? router.href('focus', { id: n[0]._id }) : null); + prevLink(p.length ? router.href('focus', { id: p[0]._id }) : null); }) ], true diff --git a/packages/gallery/src/interface/sectionView.js b/packages/gallery/src/interface/sectionView.js index 0551889..e990f54 100644 --- a/packages/gallery/src/interface/sectionView.js +++ b/packages/gallery/src/interface/sectionView.js @@ -60,6 +60,8 @@ export function SectionView(vm, params, key) { [photoArray, availableViewportSize] ); + photos.sort((a, b) => a.originalDate.localeCompare(b.originalDate)); + subscribeToRender(vm, [sections]); return function render(vm, params) { diff --git a/packages/gallery/src/services/db.js b/packages/gallery/src/services/db.js index aa523d2..5d0ddc4 100644 --- a/packages/gallery/src/services/db.js +++ b/packages/gallery/src/services/db.js @@ -23,10 +23,6 @@ export class TypeSpec { Object.assign(this, { $links: {} }, props, { type: this._prefix }); } - static getSequence(doc) { - return ''; - } - static getUniqueID(doc) { throw 'NotImplemented'; } @@ -39,7 +35,7 @@ export class TypeSpec { _populateId(doc) { if (!doc._id) { - doc._id = `${this._prefix}_${this._cls.getSequence(doc)}_${this._cls.getUniqueID(doc)}`; + doc._id = `${this._prefix}_${this._cls.getUniqueID(doc)}`; } return doc; } @@ -116,6 +112,10 @@ export function PouchORM(PouchDB) { isSelector && idOrSelector._deleted ? { _deleted: true } : { _deleted: { exists: false } }, isSelector ? idOrSelector : _baseSelector ); + if (opts.index) { + opts.use_index = [prefix, opts.index]; + delete opts.index; + } if (opts.live) { opts.mapper = instantiate; return LiveArray(_db, idOrSelector, opts); @@ -148,15 +148,14 @@ export function PouchORM(PouchDB) { } } - async function next(key, previous = false, limit = 1, inclusive = false) { - const res = await _db.allDocs({ - startkey: key, - descending: previous, - sort: ['id'], - skip: inclusive ? 0 : 1, - limit + async function _index(name, fields) { + return _db.createIndex({ + index: { + ddoc: prefix, + fields, + name + } }); - return res.rows; } Object.defineProperties(cls.prototype, { @@ -170,7 +169,7 @@ export function PouchORM(PouchDB) { Object.defineProperties(cls, { getOrCreate: { value: getOrCreate }, find: { value: find }, - next: { value: next }, + index: { value: _index }, delete: { value: _delete }, subscribe: { value: watch }, db: { value: _db },