A few changes for upcoming db refactoring

This commit is contained in:
Ben Gotow 2016-07-14 15:48:48 -07:00
parent 0c900b072d
commit ea497f7ea2
13 changed files with 54 additions and 51 deletions

View file

@ -19,7 +19,7 @@ function inflateTransactions(db, transactionModels = []) {
const ModelKlass = db[modelConstructorName] const ModelKlass = db[modelConstructorName]
let includes = []; let includes = [];
if (ModelKlass.requiredAssociationsForJSON) { if (ModelKlass.requiredAssociationsForJSON) {
includes = ModelKlass.requiredAssociationsForJSON() includes = ModelKlass.requiredAssociationsForJSON(db)
} }
return ModelKlass.findAll({where: {id: ids}, include: includes}) return ModelKlass.findAll({where: {id: ids}, include: includes})
.then((models = []) => { .then((models = []) => {

View file

@ -1,5 +1,5 @@
module.exports = (sequelize, Sequelize) => { module.exports = (sequelize, Sequelize) => {
const Contact = sequelize.define('contact', { return sequelize.define('contact', {
accountId: { type: Sequelize.STRING, allowNull: false }, accountId: { type: Sequelize.STRING, allowNull: false },
version: Sequelize.INTEGER, version: Sequelize.INTEGER,
name: Sequelize.STRING, name: Sequelize.STRING,
@ -17,6 +17,4 @@ module.exports = (sequelize, Sequelize) => {
}, },
}, },
}) })
return Contact;
} }

View file

@ -2,7 +2,7 @@ const PromiseUtils = require('../../promise-utils')
const IMAPConnection = require('../../imap-connection') const IMAPConnection = require('../../imap-connection')
module.exports = (sequelize, Sequelize) => { module.exports = (sequelize, Sequelize) => {
const File = sequelize.define('file', { return sequelize.define('file', {
accountId: { type: Sequelize.STRING, allowNull: false }, accountId: { type: Sequelize.STRING, allowNull: false },
version: Sequelize.INTEGER, version: Sequelize.INTEGER,
filename: Sequelize.STRING(500), filename: Sequelize.STRING(500),
@ -11,7 +11,7 @@ module.exports = (sequelize, Sequelize) => {
size: Sequelize.INTEGER, size: Sequelize.INTEGER,
}, { }, {
classMethods: { classMethods: {
associate: ({Message}) => { associate: ({File, Message}) => {
File.belongsTo(Message) File.belongsTo(Message)
}, },
}, },
@ -52,6 +52,4 @@ module.exports = (sequelize, Sequelize) => {
}, },
}, },
}); });
return File;
}; };

View file

@ -1,7 +1,7 @@
const {JSONType} = require('../../database-types'); const {JSONType} = require('../../database-types');
module.exports = (sequelize, Sequelize) => { module.exports = (sequelize, Sequelize) => {
const Folder = sequelize.define('folder', { return sequelize.define('folder', {
accountId: { type: Sequelize.STRING, allowNull: false }, accountId: { type: Sequelize.STRING, allowNull: false },
version: Sequelize.INTEGER, version: Sequelize.INTEGER,
name: Sequelize.STRING, name: Sequelize.STRING,
@ -9,7 +9,7 @@ module.exports = (sequelize, Sequelize) => {
syncState: JSONType('syncState'), syncState: JSONType('syncState'),
}, { }, {
classMethods: { classMethods: {
associate: ({Message, Thread}) => { associate: ({Folder, Message, Thread}) => {
Folder.hasMany(Message) Folder.hasMany(Message)
Folder.belongsToMany(Thread, {through: 'thread_folders'}) Folder.belongsToMany(Thread, {through: 'thread_folders'})
}, },
@ -26,6 +26,4 @@ module.exports = (sequelize, Sequelize) => {
}, },
}, },
}); });
return Folder;
}; };

View file

@ -1,14 +1,14 @@
module.exports = (sequelize, Sequelize) => { module.exports = (sequelize, Sequelize) => {
const Label = sequelize.define('label', { return sequelize.define('label', {
accountId: { type: Sequelize.STRING, allowNull: false }, accountId: { type: Sequelize.STRING, allowNull: false },
version: Sequelize.INTEGER, version: Sequelize.INTEGER,
name: Sequelize.STRING, name: Sequelize.STRING,
role: Sequelize.STRING, role: Sequelize.STRING,
}, { }, {
classMethods: { classMethods: {
associate: ({Message, Thread}) => { associate: ({Label, Message, MessageLabel, Thread, ThreadLabel}) => {
Label.belongsToMany(Message, {through: 'message_labels'}) Label.belongsToMany(Message, {through: MessageLabel})
Label.belongsToMany(Thread, {through: 'thread_labels'}) Label.belongsToMany(Thread, {through: ThreadLabel})
}, },
}, },
instanceMethods: { instanceMethods: {
@ -23,6 +23,4 @@ module.exports = (sequelize, Sequelize) => {
}, },
}, },
}); });
return Label;
}; };

View file

@ -5,11 +5,11 @@ const {JSONType, JSONARRAYType} = require('../../database-types');
module.exports = (sequelize, Sequelize) => { module.exports = (sequelize, Sequelize) => {
const Message = sequelize.define('message', { return sequelize.define('message', {
accountId: { type: Sequelize.STRING, allowNull: false }, accountId: { type: Sequelize.STRING, allowNull: false },
version: Sequelize.INTEGER, version: Sequelize.INTEGER,
headerMessageId: Sequelize.STRING, headerMessageId: Sequelize.STRING,
body: Sequelize.TEXT, body: Sequelize.TEXT('long'),
headers: JSONType('headers'), headers: JSONType('headers'),
subject: Sequelize.STRING(500), subject: Sequelize.STRING(500),
snippet: Sequelize.STRING(255), snippet: Sequelize.STRING(255),
@ -33,10 +33,10 @@ module.exports = (sequelize, Sequelize) => {
}, },
], ],
classMethods: { classMethods: {
associate: ({Folder, Label, File, Thread}) => { associate: ({Message, Folder, Label, File, Thread, MessageLabel}) => {
Message.belongsTo(Thread) Message.belongsTo(Thread)
Message.belongsTo(Folder) Message.belongsTo(Folder)
Message.belongsToMany(Label, {through: 'message_labels'}) Message.belongsToMany(Label, {through: MessageLabel})
Message.hasMany(File) Message.hasMany(File)
}, },
hashForHeaders: (headers) => { hashForHeaders: (headers) => {
@ -44,13 +44,12 @@ module.exports = (sequelize, Sequelize) => {
}, },
}, },
instanceMethods: { instanceMethods: {
setLabelsFromXGM(xGmLabels, {preloadedLabels} = {}) { setLabelsFromXGM(xGmLabels, {Label, preloadedLabels} = {}) {
if (!xGmLabels) { if (!xGmLabels) {
return Promise.resolve(); return Promise.resolve();
} }
const labelNames = xGmLabels.filter(l => l[0] !== '\\') const labelNames = xGmLabels.filter(l => l[0] !== '\\')
const labelRoles = xGmLabels.filter(l => l[0] === '\\').map(l => l.substr(1).toLowerCase()) const labelRoles = xGmLabels.filter(l => l[0] === '\\').map(l => l.substr(1).toLowerCase())
const Label = sequelize.models.label;
let getLabels = null; let getLabels = null;
if (preloadedLabels) { if (preloadedLabels) {
@ -101,6 +100,4 @@ module.exports = (sequelize, Sequelize) => {
}, },
}, },
}); });
return Message;
}; };

View file

@ -0,0 +1,5 @@
module.exports = (sequelize, Sequelize) => {
return sequelize.define('messageLabel', {
}, {
});
};

View file

@ -1,10 +1,10 @@
const {JSONARRAYType} = require('../../database-types'); const {JSONARRAYType} = require('../../database-types');
module.exports = (sequelize, Sequelize) => { module.exports = (sequelize, Sequelize) => {
const Thread = sequelize.define('thread', { return sequelize.define('thread', {
accountId: { type: Sequelize.STRING, allowNull: false }, accountId: { type: Sequelize.STRING, allowNull: false },
version: Sequelize.INTEGER, version: Sequelize.INTEGER,
threadId: Sequelize.STRING, remoteThreadId: Sequelize.STRING,
subject: Sequelize.STRING(500), subject: Sequelize.STRING(500),
snippet: Sequelize.STRING(255), snippet: Sequelize.STRING(255),
unreadCount: Sequelize.INTEGER, unreadCount: Sequelize.INTEGER,
@ -17,22 +17,22 @@ module.exports = (sequelize, Sequelize) => {
}, { }, {
indexes: [ indexes: [
{ fields: ['subject'] }, { fields: ['subject'] },
{ fields: ['threadId'] }, { fields: ['remoteThreadId'] },
], ],
classMethods: { classMethods: {
requiredAssociationsForJSON: () => { requiredAssociationsForJSON: ({Folder, Label, Message}) => {
return [ return [
{model: sequelize.models.folder}, {model: Folder},
{model: sequelize.models.label}, {model: Label},
{ {
model: sequelize.models.message, model: Message,
attributes: ['id'], attributes: ['id'],
}, },
] ]
}, },
associate: ({Folder, Label, Message}) => { associate: ({Thread, Folder, ThreadFolder, Label, ThreadLabel, Message}) => {
Thread.belongsToMany(Folder, {through: 'thread_folders'}) Thread.belongsToMany(Folder, {through: ThreadFolder})
Thread.belongsToMany(Label, {through: 'thread_labels'}) Thread.belongsToMany(Label, {through: ThreadLabel})
Thread.hasMany(Message) Thread.hasMany(Message)
}, },
}, },
@ -75,6 +75,4 @@ module.exports = (sequelize, Sequelize) => {
}, },
}, },
}); });
return Thread;
}; };

View file

@ -0,0 +1,5 @@
module.exports = (sequelize, Sequelize) => {
return sequelize.define('threadFolder', {
}, {
});
};

View file

@ -0,0 +1,5 @@
module.exports = (sequelize, Sequelize) => {
return sequelize.define('threadLabel', {
}, {
});
};

View file

@ -1,12 +1,10 @@
const {JSONARRAYType} = require('../../database-types'); const {JSONARRAYType} = require('../../database-types');
module.exports = (sequelize, Sequelize) => { module.exports = (sequelize, Sequelize) => {
const Transaction = sequelize.define('transaction', { return sequelize.define('transaction', {
event: Sequelize.STRING, event: Sequelize.STRING,
object: Sequelize.STRING, object: Sequelize.STRING,
objectId: Sequelize.STRING, objectId: Sequelize.STRING,
changedFields: JSONARRAYType('changedFields'), changedFields: JSONARRAYType('changedFields'),
}); });
return Transaction;
}; };

View file

@ -32,11 +32,12 @@ class ThreadingProcessor {
return subject.replace(regex, () => ""); return subject.replace(regex, () => "");
} }
emptyThread(Thread, options = {}) { emptyThread({Thread, accountId}, options = {}) {
const t = Thread.build(options) return Thread.create(Object.assign({accountId}, options)).then((t) => {
t.folders = []; t.folders = [];
t.labels = []; t.labels = [];
return t; return t;
});
} }
findOrCreateByMatching(db, message) { findOrCreateByMatching(db, message) {
@ -57,16 +58,17 @@ class ThreadingProcessor {
limit: 10, limit: 10,
include: [{model: Label}, {model: Folder}], include: [{model: Label}, {model: Folder}],
}).then((threads) => }).then((threads) =>
this.pickMatchingThread(message, threads) || this.emptyThread(Thread) this.pickMatchingThread(message, threads) || this.emptyThread(db, {})
) )
} }
findOrCreateByThreadId({Thread, Label, Folder}, threadId) { findOrCreateByRemoteThreadId(db, remoteThreadId) {
const {Thread, Label, Folder} = db;
return Thread.find({ return Thread.find({
where: {threadId}, where: {remoteThreadId},
include: [{model: Label}, {model: Folder}], include: [{model: Label}, {model: Folder}],
}).then((thread) => { }).then((thread) => {
return thread || this.emptyThread(Thread, {threadId}) return thread || this.emptyThread(db, {remoteThreadId})
}) })
} }
@ -82,7 +84,7 @@ class ThreadingProcessor {
const {Folder, Label} = db; const {Folder, Label} = db;
let findOrCreateThread = null; let findOrCreateThread = null;
if (message.headers['x-gm-thrid']) { if (message.headers['x-gm-thrid']) {
findOrCreateThread = this.findOrCreateByThreadId(db, message.headers['x-gm-thrid']) findOrCreateThread = this.findOrCreateByRemoteThreadId(db, message.headers['x-gm-thrid'])
} else { } else {
findOrCreateThread = this.findOrCreateByMatching(db, message) findOrCreateThread = this.findOrCreateByMatching(db, message)
} }

View file

@ -14,6 +14,7 @@ apps:
watch : ["packages"] watch : ["packages"]
name : sync name : sync
env : env :
SYNC_AFTER_ERRORS : true
DB_ENCRYPTION_ALGORITHM : "aes-256-ctr" DB_ENCRYPTION_ALGORITHM : "aes-256-ctr"
DB_ENCRYPTION_PASSWORD : "d6F3Efeq" DB_ENCRYPTION_PASSWORD : "d6F3Efeq"
NODE_ENV: 'development' NODE_ENV: 'development'