Commit graph

33 commits

Author SHA1 Message Date
Daniel Gasienica
f36f206a01 Use IndexablePresence for hasFileAttachments and hasVisualMediaAttachments
Reduces index size, makes it easier to debug using IndexedDB inspector, and
hopefully improves lookup performance.
2018-04-25 15:25:12 -04:00
Daniel Gasienica
9d84b2f420 Index messages with attachments using a boolean
When indexing message attachment metadata using numeric indexes such as:

```javascript
{
  conversationId: '+12223334455',
  received_at: 123,
  attachments: […],
  numAttachments: 2,
},
{
  conversationId: '+12223334455',
  received_at: 456,
  attachments: [],
  numAttachments: 0,
}
{
  conversationId: '+12223334455',
  received_at: 789,
  attachments: [],
  numAttachments: 1,
}
```

It creates an index as follows:

```
[conversationId, received_at, numAttachments]
['+12223334455', 123, 2]
['+12223334455', 456, 0]
['+12223334455', 789, 1]
```

This means a query such as…

```
lowerBound: ['+12223334455', 0,                1               ]
upperBound: ['+12223334455', Number.MAX_VALUE, Number.MAX_VALUE]
```

…will return all three original entries because they span the `received_at`
from `0` through `Number.MAX_VALUE`. One workaround is to index booleans using
`1 | undefined` where `1` is included in the index and `undefined` is not, but
that way we lose the ability to query for the `false` value. Instead, we flip
adjust the index to `[conversationId, hasAttachments, received_at]` and can
then query messages with attachments using

```
[conversationId, 1 /* hasAttachments */, 0                /* received_at */]
[conversationId, 1 /* hasAttachments */, Number.MAX_VALUE /* received_at */]
```
2018-04-25 15:24:51 -04:00
Daniel Gasienica
5f220a7b2c Add migration for media gallery indices 2018-04-25 15:24:50 -04:00
Daniel Gasienica
24f4ad53bc Use single quotes for identifiers 2018-04-11 15:54:32 -04:00
Daniel Gasienica
052fb841f6 Allow database name override in migrations 2018-04-03 11:45:10 -04:00
Daniel Gasienica
1e04083813 Support database upgrades in Database.open 2018-04-03 11:44:50 -04:00
Daniel Gasienica
2e4893f4c1 Clarify implications of introducing new migrations 2018-04-02 18:54:51 -04:00
Daniel Gasienica
7413b787b6 Make migrations private 2018-04-02 18:54:28 -04:00
Daniel Gasienica
805031ade8 Conditionally run post-attachment migrations
Introduce placeholder migrations for Backbone models so they never implicitly
run migrations whenever they are `fetch`ed. We prefer to run our migrations
explicitly upon app startup and then let Backbone models be (slightly) dumb(er)
models, without inadvertently triggering migrations.
2018-04-02 17:42:04 -04:00
Daniel Gasienica
bfbeedab5c Temporarily disable post-attachment migration migrations 2018-04-02 15:26:24 -04:00
Daniel Gasienica
d9be6a0f94 Destructure Lodash requires 2018-04-02 15:12:04 -04:00
Daniel Gasienica
1f8556b049 Remove unused createCollection 2018-04-02 12:17:36 -04:00
Daniel Gasienica
efe3cd67fc Allow attachment migration run on higher database version 2018-04-02 12:17:36 -04:00
Daniel Gasienica
921c3dba7c Skip migrations that have already been applied 2018-04-02 12:17:36 -04:00
Daniel Gasienica
c5c94bc3ab Extract getMigrationVersions 2018-04-02 12:17:36 -04:00
Daniel Gasienica
6aea36240d Rename closeDatabase to closeDatabaseConnection 2018-04-02 12:17:36 -04:00
Daniel Gasienica
016432826b Extract database and settings modules 2018-04-02 12:17:36 -04:00
Daniel Gasienica
5bea894abd Close database connection via Backbone IDB adapter 2018-04-02 12:17:36 -04:00
Daniel Gasienica
4ff8bc3357 Use camelCase for non-constructors 2018-04-02 12:17:36 -04:00
Daniel Gasienica
eca930770c Remove hard-coded database connection settings 2018-04-02 12:17:36 -04:00
Daniel Gasienica
178a3cc262 Reduce work for verifying transaction completion 2018-04-02 12:17:36 -04:00
Daniel Gasienica
457bf7ab9d Add createCollection function 2018-04-02 12:17:36 -04:00
Daniel Gasienica
172616ca4f Add log message for dummy migration 18 2018-04-02 12:17:36 -04:00
Daniel Gasienica
da144edc56 Manually close database connection after migration 2018-04-02 12:17:36 -04:00
Daniel Gasienica
106ce21c49 Remove redundant log message 2018-04-02 12:17:36 -04:00
Daniel Gasienica
fcd30cd919 Close database after migration
This is not 100% reliable as database connections are closed in a separate
thread according to the documentation:
- https://developer.mozilla.org/en-US/docs/Web/API/IDBDatabase/close
- https://stackoverflow.com/a/18639298
- 80c7a06d5c/backbone-indexeddb.js (L558-L565)
2018-04-02 12:17:36 -04:00
Daniel Gasienica
e2f1339ab9 Explicitly run post-attachment migrations 2018-04-02 12:17:36 -04:00
Daniel Gasienica
d7c8d33edb Extract runMigrations 2018-04-02 12:17:36 -04:00
Daniel Gasienica
d16178638e Split database migrations into pre- and post-attachment migration
- Run light-weight migrations before attachment migration.
- Run regular migrations after attachments have been moved to disk.
2018-04-02 12:17:36 -04:00
Daniel Gasienica
c88381efe3 Use async / await to improve readability 2018-03-19 19:27:59 -04:00
Daniel Gasienica
2642844c27 Rewrite migration 17 without idb
We ran into issues when doing async operations inside of an IndexedDB
`onupgradeneeded` handler. The errors were ‘The transaction is not active’ or
‘Transaction has finished’. The following documentation confirmed that
transactions are committed/terminated when control returns to the event loop:

Spec
- https://www.w3.org/TR/IndexedDB/#transaction-lifetime-concept
- https://www.w3.org/TR/IndexedDB/#upgrade-transaction-construct

Stack Overflow
- https://stackoverflow.com/a/11059085
- https://stackoverflow.com/a/27338944

Since the initial database migration is so critical, I decided to avoid `idb`
with promise support for IndexedDB for now, but will reconsider using it for
other tasks in the future to improve readability of IndexedDB code.
2018-03-19 19:27:59 -04:00
Daniel Gasienica
5d927b73e6 Use while loop for IDB cursor iteration
Previously, I messily combined promises and callbacks because I thought we
were affected by the microtask issue:
https://github.com/gasi/idb#iteratecursor--iteratekeycursor

ESLint’s `more/no-then` encouraged me to revisit this and it works as expected.
2018-03-19 19:27:59 -04:00
Daniel Gasienica
182e6ffe10 Add version 17 migration 2018-03-19 19:27:59 -04:00