From 4889e9732d2458d60e2a079d3e54e128f6ce1b53 Mon Sep 17 00:00:00 2001 From: BoHong Li Date: Wed, 8 Mar 2017 18:45:51 +0800 Subject: Use JavaScript Standard Style Introduce JavaScript Standard Style as project style rule, and fixed all fail on backend code. --- lib/models/revision.js | 580 ++++++++++++++++++++++++------------------------- 1 file changed, 290 insertions(+), 290 deletions(-) (limited to 'lib/models/revision.js') diff --git a/lib/models/revision.js b/lib/models/revision.js index c7360fed..d8dab30a 100644 --- a/lib/models/revision.js +++ b/lib/models/revision.js @@ -1,306 +1,306 @@ -"use strict"; - // external modules -var Sequelize = require("sequelize"); -var async = require('async'); -var moment = require('moment'); -var childProcess = require('child_process'); -var shortId = require('shortid'); +var Sequelize = require('sequelize') +var async = require('async') +var moment = require('moment') +var childProcess = require('child_process') +var shortId = require('shortid') // core -var config = require("../config.js"); -var logger = require("../logger.js"); +var config = require('../config.js') +var logger = require('../logger.js') -var dmpWorker = createDmpWorker(); -var dmpCallbackCache = {}; +var dmpWorker = createDmpWorker() +var dmpCallbackCache = {} -function createDmpWorker() { - var worker = childProcess.fork("./lib/workers/dmpWorker.js", { - stdio: 'ignore' - }); - if (config.debug) logger.info('dmp worker process started'); - worker.on('message', function (data) { - if (!data || !data.msg || !data.cacheKey) { - return logger.error('dmp worker error: not enough data on message'); - } - var cacheKey = data.cacheKey; - switch(data.msg) { - case 'error': - dmpCallbackCache[cacheKey](data.error, null); - break; - case 'check': - dmpCallbackCache[cacheKey](null, data.result); - break; - } - delete dmpCallbackCache[cacheKey]; - }); - worker.on('close', function (code) { - dmpWorker = null; - if (config.debug) logger.info('dmp worker process exited with code ' + code); - }); - return worker; +function createDmpWorker () { + var worker = childProcess.fork('./lib/workers/dmpWorker.js', { + stdio: 'ignore' + }) + if (config.debug) logger.info('dmp worker process started') + worker.on('message', function (data) { + if (!data || !data.msg || !data.cacheKey) { + return logger.error('dmp worker error: not enough data on message') + } + var cacheKey = data.cacheKey + switch (data.msg) { + case 'error': + dmpCallbackCache[cacheKey](data.error, null) + break + case 'check': + dmpCallbackCache[cacheKey](null, data.result) + break + } + delete dmpCallbackCache[cacheKey] + }) + worker.on('close', function (code) { + dmpWorker = null + if (config.debug) logger.info('dmp worker process exited with code ' + code) + }) + return worker } -function sendDmpWorker(data, callback) { - if (!dmpWorker) dmpWorker = createDmpWorker(); - var cacheKey = Date.now() + '_' + shortId.generate(); - dmpCallbackCache[cacheKey] = callback; - data = Object.assign(data, { - cacheKey: cacheKey - }); - dmpWorker.send(data); +function sendDmpWorker (data, callback) { + if (!dmpWorker) dmpWorker = createDmpWorker() + var cacheKey = Date.now() + '_' + shortId.generate() + dmpCallbackCache[cacheKey] = callback + data = Object.assign(data, { + cacheKey: cacheKey + }) + dmpWorker.send(data) } module.exports = function (sequelize, DataTypes) { - var Revision = sequelize.define("Revision", { - id: { - type: DataTypes.UUID, - primaryKey: true, - defaultValue: Sequelize.UUIDV4 - }, - patch: { - type: DataTypes.TEXT, - get: function () { - return sequelize.processData(this.getDataValue('patch'), ""); - }, - set: function (value) { - this.setDataValue('patch', sequelize.stripNullByte(value)); - } - }, - lastContent: { - type: DataTypes.TEXT, - get: function () { - return sequelize.processData(this.getDataValue('lastContent'), ""); + var Revision = sequelize.define('Revision', { + id: { + type: DataTypes.UUID, + primaryKey: true, + defaultValue: Sequelize.UUIDV4 + }, + patch: { + type: DataTypes.TEXT, + get: function () { + return sequelize.processData(this.getDataValue('patch'), '') + }, + set: function (value) { + this.setDataValue('patch', sequelize.stripNullByte(value)) + } + }, + lastContent: { + type: DataTypes.TEXT, + get: function () { + return sequelize.processData(this.getDataValue('lastContent'), '') + }, + set: function (value) { + this.setDataValue('lastContent', sequelize.stripNullByte(value)) + } + }, + content: { + type: DataTypes.TEXT, + get: function () { + return sequelize.processData(this.getDataValue('content'), '') + }, + set: function (value) { + this.setDataValue('content', sequelize.stripNullByte(value)) + } + }, + length: { + type: DataTypes.INTEGER + }, + authorship: { + type: DataTypes.TEXT, + get: function () { + return sequelize.processData(this.getDataValue('authorship'), [], JSON.parse) + }, + set: function (value) { + this.setDataValue('authorship', value ? JSON.stringify(value) : value) + } + } + }, { + classMethods: { + associate: function (models) { + Revision.belongsTo(models.Note, { + foreignKey: 'noteId', + as: 'note', + constraints: false + }) + }, + getNoteRevisions: function (note, callback) { + Revision.findAll({ + where: { + noteId: note.id + }, + order: '"createdAt" DESC' + }).then(function (revisions) { + var data = [] + for (var i = 0, l = revisions.length; i < l; i++) { + var revision = revisions[i] + data.push({ + time: moment(revision.createdAt).valueOf(), + length: revision.length + }) + } + callback(null, data) + }).catch(function (err) { + callback(err, null) + }) + }, + getPatchedNoteRevisionByTime: function (note, time, callback) { + // find all revisions to prepare for all possible calculation + Revision.findAll({ + where: { + noteId: note.id + }, + order: '"createdAt" DESC' + }).then(function (revisions) { + if (revisions.length <= 0) return callback(null, null) + // measure target revision position + Revision.count({ + where: { + noteId: note.id, + createdAt: { + $gte: time + } }, - set: function (value) { - this.setDataValue('lastContent', sequelize.stripNullByte(value)); + order: '"createdAt" DESC' + }).then(function (count) { + if (count <= 0) return callback(null, null) + sendDmpWorker({ + msg: 'get revision', + revisions: revisions, + count: count + }, callback) + }).catch(function (err) { + return callback(err, null) + }) + }).catch(function (err) { + return callback(err, null) + }) + }, + checkAllNotesRevision: function (callback) { + Revision.saveAllNotesRevision(function (err, notes) { + if (err) return callback(err, null) + if (!notes || notes.length <= 0) { + return callback(null, notes) + } else { + Revision.checkAllNotesRevision(callback) + } + }) + }, + saveAllNotesRevision: function (callback) { + sequelize.models.Note.findAll({ + // query all notes that need to save for revision + where: { + $and: [ + { + lastchangeAt: { + $or: { + $eq: null, + $and: { + $ne: null, + $gt: sequelize.col('createdAt') + } + } + } + }, + { + savedAt: { + $or: { + $eq: null, + $lt: sequelize.col('lastchangeAt') + } + } + } + ] + } + }).then(function (notes) { + if (notes.length <= 0) return callback(null, notes) + var savedNotes = [] + async.each(notes, function (note, _callback) { + // revision saving policy: note not been modified for 5 mins or not save for 10 mins + if (note.lastchangeAt && note.savedAt) { + var lastchangeAt = moment(note.lastchangeAt) + var savedAt = moment(note.savedAt) + if (moment().isAfter(lastchangeAt.add(5, 'minutes'))) { + savedNotes.push(note) + Revision.saveNoteRevision(note, _callback) + } else if (lastchangeAt.isAfter(savedAt.add(10, 'minutes'))) { + savedNotes.push(note) + Revision.saveNoteRevision(note, _callback) + } else { + return _callback(null, null) + } + } else { + savedNotes.push(note) + Revision.saveNoteRevision(note, _callback) } - }, - content: { - type: DataTypes.TEXT, - get: function () { - return sequelize.processData(this.getDataValue('content'), ""); - }, - set: function (value) { - this.setDataValue('content', sequelize.stripNullByte(value)); + }, function (err) { + if (err) { + return callback(err, null) } - }, - length: { - type: DataTypes.INTEGER - }, - authorship: { - type: DataTypes.TEXT, - get: function () { - return sequelize.processData(this.getDataValue('authorship'), [], JSON.parse); - }, - set: function (value) { - this.setDataValue('authorship', value ? JSON.stringify(value) : value); - } - } - }, { - classMethods: { - associate: function (models) { - Revision.belongsTo(models.Note, { - foreignKey: "noteId", - as: "note", - constraints: false - }); - }, - getNoteRevisions: function (note, callback) { - Revision.findAll({ - where: { - noteId: note.id - }, - order: '"createdAt" DESC' - }).then(function (revisions) { - var data = []; - for (var i = 0, l = revisions.length; i < l; i++) { - var revision = revisions[i]; - data.push({ - time: moment(revision.createdAt).valueOf(), - length: revision.length - }); - } - callback(null, data); - }).catch(function (err) { - callback(err, null); - }); - }, - getPatchedNoteRevisionByTime: function (note, time, callback) { - // find all revisions to prepare for all possible calculation - Revision.findAll({ - where: { - noteId: note.id - }, - order: '"createdAt" DESC' - }).then(function (revisions) { - if (revisions.length <= 0) return callback(null, null); - // measure target revision position - Revision.count({ - where: { - noteId: note.id, - createdAt: { - $gte: time - } - }, - order: '"createdAt" DESC' - }).then(function (count) { - if (count <= 0) return callback(null, null); - sendDmpWorker({ - msg: 'get revision', - revisions: revisions, - count: count - }, callback); - }).catch(function (err) { - return callback(err, null); - }); + // return null when no notes need saving at this moment but have delayed tasks to be done + var result = ((savedNotes.length === 0) && (notes.length > savedNotes.length)) ? null : savedNotes + return callback(null, result) + }) + }).catch(function (err) { + return callback(err, null) + }) + }, + saveNoteRevision: function (note, callback) { + Revision.findAll({ + where: { + noteId: note.id + }, + order: '"createdAt" DESC' + }).then(function (revisions) { + if (revisions.length <= 0) { + // if no revision available + Revision.create({ + noteId: note.id, + lastContent: note.content, + length: note.content.length, + authorship: note.authorship + }).then(function (revision) { + Revision.finishSaveNoteRevision(note, revision, callback) + }).catch(function (err) { + return callback(err, null) + }) + } else { + var latestRevision = revisions[0] + var lastContent = latestRevision.content || latestRevision.lastContent + var content = note.content + sendDmpWorker({ + msg: 'create patch', + lastDoc: lastContent, + currDoc: content + }, function (err, patch) { + if (err) logger.error('save note revision error', err) + if (!patch) { + // if patch is empty (means no difference) then just update the latest revision updated time + latestRevision.changed('updatedAt', true) + latestRevision.update({ + updatedAt: Date.now() + }).then(function (revision) { + Revision.finishSaveNoteRevision(note, revision, callback) }).catch(function (err) { - return callback(err, null); - }); - }, - checkAllNotesRevision: function (callback) { - Revision.saveAllNotesRevision(function (err, notes) { - if (err) return callback(err, null); - if (!notes || notes.length <= 0) { - return callback(null, notes); - } else { - Revision.checkAllNotesRevision(callback); - } - }); - }, - saveAllNotesRevision: function (callback) { - sequelize.models.Note.findAll({ - // query all notes that need to save for revision - where: { - $and: [ - { - lastchangeAt: { - $or: { - $eq: null, - $and: { - $ne: null, - $gt: sequelize.col('createdAt') - } - } - } - }, - { - savedAt: { - $or: { - $eq: null, - $lt: sequelize.col('lastchangeAt') - } - } - } - ] - } - }).then(function (notes) { - if (notes.length <= 0) return callback(null, notes); - var savedNotes = []; - async.each(notes, function (note, _callback) { - // revision saving policy: note not been modified for 5 mins or not save for 10 mins - if (note.lastchangeAt && note.savedAt) { - var lastchangeAt = moment(note.lastchangeAt); - var savedAt = moment(note.savedAt); - if (moment().isAfter(lastchangeAt.add(5, 'minutes'))) { - savedNotes.push(note); - Revision.saveNoteRevision(note, _callback); - } else if (lastchangeAt.isAfter(savedAt.add(10, 'minutes'))) { - savedNotes.push(note); - Revision.saveNoteRevision(note, _callback); - } else { - return _callback(null, null); - } - } else { - savedNotes.push(note); - Revision.saveNoteRevision(note, _callback); - } - }, function (err) { - if (err) return callback(err, null); - // return null when no notes need saving at this moment but have delayed tasks to be done - var result = ((savedNotes.length == 0) && (notes.length > savedNotes.length)) ? null : savedNotes; - return callback(null, result); - }); + return callback(err, null) + }) + } else { + Revision.create({ + noteId: note.id, + patch: patch, + content: note.content, + length: note.content.length, + authorship: note.authorship + }).then(function (revision) { + // clear last revision content to reduce db size + latestRevision.update({ + content: null + }).then(function () { + Revision.finishSaveNoteRevision(note, revision, callback) + }).catch(function (err) { + return callback(err, null) + }) }).catch(function (err) { - return callback(err, null); - }); - }, - saveNoteRevision: function (note, callback) { - Revision.findAll({ - where: { - noteId: note.id - }, - order: '"createdAt" DESC' - }).then(function (revisions) { - if (revisions.length <= 0) { - // if no revision available - Revision.create({ - noteId: note.id, - lastContent: note.content, - length: note.content.length, - authorship: note.authorship - }).then(function (revision) { - Revision.finishSaveNoteRevision(note, revision, callback); - }).catch(function (err) { - return callback(err, null); - }); - } else { - var latestRevision = revisions[0]; - var lastContent = latestRevision.content || latestRevision.lastContent; - var content = note.content; - sendDmpWorker({ - msg: 'create patch', - lastDoc: lastContent, - currDoc: content, - }, function (err, patch) { - if (err) logger.error('save note revision error', err); - if (!patch) { - // if patch is empty (means no difference) then just update the latest revision updated time - latestRevision.changed('updatedAt', true); - latestRevision.update({ - updatedAt: Date.now() - }).then(function (revision) { - Revision.finishSaveNoteRevision(note, revision, callback); - }).catch(function (err) { - return callback(err, null); - }); - } else { - Revision.create({ - noteId: note.id, - patch: patch, - content: note.content, - length: note.content.length, - authorship: note.authorship - }).then(function (revision) { - // clear last revision content to reduce db size - latestRevision.update({ - content: null - }).then(function () { - Revision.finishSaveNoteRevision(note, revision, callback); - }).catch(function (err) { - return callback(err, null); - }); - }).catch(function (err) { - return callback(err, null); - }); - } - }); - } - }).catch(function (err) { - return callback(err, null); - }); - }, - finishSaveNoteRevision: function (note, revision, callback) { - note.update({ - savedAt: revision.updatedAt - }).then(function () { - return callback(null, revision); - }).catch(function (err) { - return callback(err, null); - }); - } - } - }); + return callback(err, null) + }) + } + }) + } + }).catch(function (err) { + return callback(err, null) + }) + }, + finishSaveNoteRevision: function (note, revision, callback) { + note.update({ + savedAt: revision.updatedAt + }).then(function () { + return callback(null, revision) + }).catch(function (err) { + return callback(err, null) + }) + } + } + }) - return Revision; -}; \ No newline at end of file + return Revision +} -- cgit v1.2.3