2013-08-09 06:10:19 -04:00
|
|
|
{db, ObjectId} = require "./mongojs"
|
|
|
|
ConcatManager = require "./ConcatManager"
|
|
|
|
|
|
|
|
module.exports = ConversionManager =
|
|
|
|
OPS_TO_LEAVE: 10
|
|
|
|
|
2013-08-09 08:27:35 -04:00
|
|
|
popLatestCompressedUpdate: (doc_id, callback = (error, update) ->) ->
|
|
|
|
db.docHistory.findAndModify
|
|
|
|
query: { doc_id: ObjectId(doc_id) }
|
|
|
|
fields: { docOps: { $slice: -1 } }
|
|
|
|
update: { $pop: { docOps: 1 } }
|
|
|
|
, (error, history = { docOps: [] }) ->
|
2013-08-09 06:10:19 -04:00
|
|
|
return callback(error) if error?
|
2013-08-09 08:27:35 -04:00
|
|
|
callback null, history.docOps[0]
|
2013-08-09 06:10:19 -04:00
|
|
|
|
|
|
|
insertCompressedUpdates: (doc_id, updates, callback = (error) ->) ->
|
|
|
|
db.docHistory.update { doc_id: ObjectId(doc_id) }, { $push: { docOps: { $each: updates } } }, { upsert: true }, callback
|
|
|
|
|
2013-08-09 08:27:35 -04:00
|
|
|
popOldRawUpdates: (doc_id, callback = (error, updates) ->) ->
|
|
|
|
db.docOps.find { doc_id: ObjectId(doc_id) }, { version: true, tailVersion: true }, (error, docs) ->
|
2013-08-09 06:10:19 -04:00
|
|
|
return callback(error) if error?
|
|
|
|
return callback(new Error("doc not found")) if docs.length == 0
|
|
|
|
doc = docs[0]
|
2013-08-09 08:27:35 -04:00
|
|
|
currentVersion = doc.version
|
|
|
|
tailVersion = doc.tailVersion or 0
|
2013-08-09 06:36:19 -04:00
|
|
|
if currentVersion - tailVersion > ConversionManager.OPS_TO_LEAVE
|
2013-08-09 08:27:35 -04:00
|
|
|
db.docOps.findAndModify
|
|
|
|
query: { doc_id: ObjectId(doc_id), version: currentVersion }
|
|
|
|
update: {
|
|
|
|
$push: { docOps: { $each: [], $slice: - ConversionManager.OPS_TO_LEAVE } }
|
|
|
|
$set: tailVersion: currentVersion - ConversionManager.OPS_TO_LEAVE,
|
|
|
|
}
|
|
|
|
fields: { docOps: $slice: currentVersion - tailVersion - ConversionManager.OPS_TO_LEAVE }
|
|
|
|
, (error, doc) ->
|
2013-08-09 06:10:19 -04:00
|
|
|
return callback(error) if error?
|
2013-08-09 08:27:35 -04:00
|
|
|
if !doc?
|
|
|
|
# Version was modified since so try again
|
|
|
|
return ConversionManager.popOldRawUpdates doc_id, callback
|
|
|
|
else
|
|
|
|
return callback null, doc.docOps
|
2013-08-09 06:10:19 -04:00
|
|
|
|
|
|
|
else
|
2013-08-09 08:27:35 -04:00
|
|
|
callback null, []
|
2013-08-09 06:36:19 -04:00
|
|
|
|
2013-08-09 08:27:35 -04:00
|
|
|
convertOldRawUpdates: (doc_id, callback = (error) ->) ->
|
|
|
|
ConversionManager.popOldRawUpdates doc_id, (error, rawUpdates) ->
|
2013-08-09 06:36:19 -04:00
|
|
|
return callback(error) if error?
|
2013-08-09 08:27:35 -04:00
|
|
|
|
|
|
|
length = rawUpdates.length
|
|
|
|
|
|
|
|
normalizedRawUpdates = []
|
|
|
|
for rawUpdate in rawUpdates
|
|
|
|
normalizedRawUpdates = normalizedRawUpdates.concat ConcatManager.normalizeUpdate(rawUpdate)
|
|
|
|
rawUpdates = normalizedRawUpdates
|
|
|
|
|
|
|
|
ConversionManager.popLatestCompressedUpdate doc_id, (error, lastCompressedUpdate) ->
|
|
|
|
return callback(error) if error?
|
|
|
|
|
|
|
|
if !lastCompressedUpdate?
|
|
|
|
lastCompressedUpdate = rawUpdates.shift()
|
|
|
|
|
2013-08-09 08:46:03 -04:00
|
|
|
if !lastCompressedUpdate?
|
|
|
|
# No saved versions, no raw updates, nothing to do
|
2013-08-09 08:51:02 -04:00
|
|
|
return callback()
|
2013-08-09 08:46:03 -04:00
|
|
|
|
2013-08-09 08:27:35 -04:00
|
|
|
compressedUpdates = [lastCompressedUpdate]
|
|
|
|
for rawUpdate in rawUpdates
|
|
|
|
lastCompressedUpdate = compressedUpdates.pop()
|
|
|
|
if lastCompressedUpdate?
|
|
|
|
compressedUpdates = compressedUpdates.concat ConcatManager.concatTwoUpdates lastCompressedUpdate, rawUpdate
|
|
|
|
else
|
|
|
|
compressedUpdates.push rawUpdate
|
|
|
|
ConversionManager.insertCompressedUpdates doc_id, compressedUpdates, (error) ->
|
|
|
|
return callback(error) if error?
|
|
|
|
console.log doc_id, "Pushed doc ops", length
|
2013-08-09 08:46:03 -04:00
|
|
|
callback()
|
2013-08-09 08:27:35 -04:00
|
|
|
|