Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions bin/migrate_mongodb_flatten_opdata
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env node

# The MongoDb driver used to create an unnecessary "opData" key in op documents.
# Future ops now do not create this key. This script fixes all existing ops.

require('coffee-script');

var createdb = require('../src/server/db');
var options = require('./options');
if (options.db.type !== 'mongo') {
console.error('You must configure your server to use mongodb before using this script');
process.exit(1);
}

var db = createdb(options.db);
db.migrateFlattenOpData(function(error) {
if(error) {
throw new Error(error.toString());
} else {
console.log("DB migrated successfully");
}
db.close();
});

48 changes: 44 additions & 4 deletions src/server/db/mongo.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,17 @@ module.exports = MongoDb = (options) ->
console.warn "failed to get ops for #{docName}: #{err}" if err
return callback? err if err

callback? null, (doc.opData for doc in docs)
result = []
for doc in docs
# This is to support an old schema where ops were stored within an
# "opData" object.
if doc.opData
result.push doc.opData
else
delete doc._id
result.push doc

callback? null, result

# Write an op to a document.
#
Expand All @@ -125,9 +135,8 @@ module.exports = MongoDb = (options) ->
return callback? err if err

doc =
opData:
op: opData.op
meta: opData.meta
op: opData.op
meta: opData.meta

if options.opsCollectionPerDoc
doc._id = opData.v
Expand Down Expand Up @@ -201,6 +210,37 @@ module.exports = MongoDb = (options) ->
opsCollection.remove { '_id.doc': docName }, (err, count) ->
callback? err

flattenOpDataCollection = (name, callback) ->
client.collection name, (err, collection) ->
collection.update {}, {$rename: {"opData.op": "op", "opData.meta": "meta"}}, {multi: true}, (err) ->
return callback(err) if err
collection.update {}, {$unset: {opData: ""}}, {multi: true}, (err) ->
callback(err)

# A migration to flatten the unnecessary "opdata" key
@migrateFlattenOpData = (callback = ->) ->
if options.opsCollectionPerDoc
client.collection 'docs', (err, docsCollection) ->
return callback(err) if err

docCount = 0
docDoneCount = 0

docsCollection.find({}).each (err, doc) ->
return callback(err) if err
return if not doc?._id
docCount += 1
flattenOpDataCollection opsCollectionForDoc(doc._id), (err) ->
return callback(err) if err
docDoneCount += 1
if docDoneCount == docCount
callback()

else
flattenOpDataCollection 'ops', callback



# Close the connection to the database
@close = ->
client.close()
Expand Down