I came up with a solution that uses a counter. This is independent of the call to count () and does not wait for a timeout. It will close db after all documents in each () have been exhausted.
var mydb = {}; // initialize the helper object. mydb.cnt = {}; // init counter to permit multiple db objects. mydb.open = function(db) // call open to inc the counter. { if( !mydb.cnt[db.tag] ) mydb.cnt[db.tag] = 1; else mydb.cnt[db.tag]++; }; mydb.close = function(db) // close the db when the cnt reaches 0. { mydb.cnt[db.tag]--; if ( mydb.cnt[db.tag] <= 0 ) { delete mydb.cnt[db.tag]; return db.close(); } return null; };
So that every time you make a call like db.each () or db.save (), you should use these methods to ensure db is ready during operation and close when finished.
Example from OP:
foo = db.collection('foo'); mydb.open(db); // *** Add here to init the counter.** foo.find({},function(err,cursor) { if( err ) throw err; cursor.each(function (err, doc) { if( err ) throw err; if (doc != null) { doc.newkey = 'foo'; mydb.open(db); // *** Add here to prevent from closing prematurely ** foo.save(doc, function(err,count) { if( err ) throw err; mydb.close(db); // *** Add here to close when done. ** }); } else { mydb.close(db); // *** Close like this instead. ** } }); });
Now this assumes that from the second to the last callback from each one it passes through mydb.open () before the last callback from each one goes to mydb.close () .... so of course let me know if this is a problem.
So: put mydb.open (db) before calling db and put mydb.close (db) at the callback return point or after calling db (depending on the type of call).
It seems to me that this counter should be maintained inside the db object, but this is my current solution. Perhaps we could create a new object that takes db in the constructor and wraps mongodb functions to better handle the result.
JJ Stiff Feb 03 '14 at 7:48 2014-02-03 07:48
source share