Use `IndexablePresence` for `hasFileAttachments` and `hasVisualMediaAttachments`

Reduces index size, makes it easier to debug using IndexedDB inspector, and
hopefully improves lookup performance.
This commit is contained in:
Daniel Gasienica 2018-04-25 14:15:06 -04:00
parent 3a33d862c0
commit f36f206a01
9 changed files with 32 additions and 24 deletions

View File

@ -1,15 +1,18 @@
exports.run = (transaction) => {
const messagesStore = transaction.objectStore('messages');
[
console.log("Create message attachment metadata index: 'hasAttachments'");
messagesStore.createIndex(
'hasAttachments',
'hasVisualMediaAttachments',
'hasFileAttachments',
].forEach((name) => {
['conversationId', 'hasAttachments', 'received_at'],
{ unique: false }
);
['hasVisualMediaAttachments', 'hasFileAttachments'].forEach((name) => {
console.log(`Create message attachment metadata index: '${name}'`);
messagesStore.createIndex(
name,
['conversationId', name, 'received_at'],
['conversationId', 'received_at', name],
{ unique: false }
);
});

View File

@ -25,9 +25,8 @@ const PRIVATE = 'private';
// Version 5
// - Attachments: Track number and kind of attachments for media gallery
// - `hasAttachments?: 1 | 0`
// - `hasVisualMediaAttachments?: 1 | 0` (for media gallery Media view)
// - `hasFileAttachments?: 1 | 0` (for media gallery Documents view)
// - `hasVisualMediaAttachments?: 1 | undefined` (for media gallery Media view)
// - `hasFileAttachments?: 1 | undefined` (for media gallery Documents view)
const INITIAL_SCHEMA_VERSION = 0;

View File

@ -350,7 +350,7 @@ describe('Backup', () => {
]).buffer,
}],
hasAttachments: 1,
hasFileAttachments: 0,
hasFileAttachments: undefined,
hasVisualMediaAttachments: 1,
quote: {
text: "Isn't it cute?",

View File

@ -182,7 +182,7 @@ describe('Message', () => {
size: 1111,
}],
hasAttachments: 1,
hasVisualMediaAttachments: 0,
hasVisualMediaAttachments: undefined,
hasFileAttachments: 1,
schemaVersion: Message.CURRENT_SCHEMA_VERSION,
};

View File

@ -30,8 +30,8 @@ export const fetchVisualMediaAttachments = async ({
collection.fetch({
index: {
name: 'hasVisualMediaAttachments',
lower: [conversationId, hasVisualMediaAttachments, lowerReceivedAt],
upper: [conversationId, hasVisualMediaAttachments, upperReceivedAt],
lower: [conversationId, lowerReceivedAt, hasVisualMediaAttachments],
upper: [conversationId, upperReceivedAt, hasVisualMediaAttachments],
order: 'desc',
},
limit: 50,

View File

@ -40,7 +40,7 @@ describe('Message', () => {
}],
hasAttachments: 1,
hasVisualMediaAttachments: 1,
hasFileAttachments: 0,
hasFileAttachments: undefined,
};
const actual = await Message.initializeAttachmentMetadata(input);

View File

@ -3,15 +3,21 @@
*/
// IndexedDB doesnt support boolean indexes so we map `true` to 1 and `false`
// to `0`.
// to `0`, i.e. `IndexableBoolean`.
// N.B. Using `undefined` allows excluding an entry from an index. Useful
// when index size is a consideration or one only needs to query for `true`.
// when index size is a consideration or one only needs to query for `true`,
// i.e. `IndexablePresence`.
export type IndexableBoolean = IndexableFalse | IndexableTrue;
type IndexableTrue = 1;
export type IndexablePresence = undefined | IndexableTrue;
type IndexableFalse = 0;
type IndexableTrue = 1;
export const INDEXABLE_FALSE: IndexableFalse = 0;
export const INDEXABLE_TRUE: IndexableTrue = 1;
export const toIndexableBoolean = (value: boolean): IndexableBoolean =>
value ? INDEXABLE_TRUE : INDEXABLE_FALSE;
export const toIndexablePresence = (value: boolean): IndexablePresence =>
value ? INDEXABLE_TRUE : undefined;

View File

@ -2,7 +2,7 @@
* @prettier
*/
import { Attachment } from './Attachment';
import { IndexableBoolean } from './IndexedDB';
import { IndexableBoolean, IndexablePresence } from './IndexedDB';
export type Message = UserMessage | VerifiedChangeMessage;
export type UserMessage = IncomingMessage | OutgoingMessage;
@ -23,7 +23,7 @@ export type IncomingMessage = Readonly<
source?: string;
sourceDevice?: number;
} & SharedMessageProperties &
MessageSchemaVersion4 &
MessageSchemaVersion5 &
ExpirationTimerUpdate
>;
@ -49,7 +49,7 @@ export type OutgoingMessage = Readonly<
recipients?: Array<string>; // Array<PhoneNumber>
synced: boolean;
} & SharedMessageProperties &
MessageSchemaVersion4 &
MessageSchemaVersion5 &
ExpirationTimerUpdate
>;
@ -57,7 +57,7 @@ export type VerifiedChangeMessage = Readonly<
{
type: 'verified-change';
} & SharedMessageProperties &
MessageSchemaVersion4 &
MessageSchemaVersion5 &
ExpirationTimerUpdate
>;
@ -77,10 +77,10 @@ type ExpirationTimerUpdate = Partial<
}>
>;
type MessageSchemaVersion4 = Partial<
type MessageSchemaVersion5 = Partial<
Readonly<{
hasAttachments: IndexableBoolean;
hasVisualMediaAttachments: IndexableBoolean;
hasFileAttachments: IndexableBoolean;
hasVisualMediaAttachments: IndexablePresence;
hasFileAttachments: IndexablePresence;
}>
>;

View File

@ -22,7 +22,7 @@ export const initializeAttachmentMetadata = async (
Attachment.isVisualMedia
)
.map(attachments => attachments.length > 0)
.map(IndexedDB.toIndexableBoolean);
.map(IndexedDB.toIndexablePresence);
return {
...message,