From b035b912fbe924f1b5aef15084a88609df287f2f Mon Sep 17 00:00:00 2001 From: Joshua Kifer Date: Tue, 26 Oct 2010 20:58:10 +0000 Subject: [PATCH] Document changes are now flushed to the database in sequential order --- lib/congo.coffee | 58 ++++++++++++++++++++++++++++-------------- lib/mongo.coffee | 2 +- test/mongo.test.coffee | 10 ++++---- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/lib/congo.coffee b/lib/congo.coffee index ec906e2..e46eea0 100644 --- a/lib/congo.coffee +++ b/lib/congo.coffee @@ -214,41 +214,61 @@ class Collection extends Model _id: __type__.Identity constructor: (initial, next) -> + @__flushing__ = false + @__store_queue__ = [] if initial instanceof Function next = initial initial = null super initial if not @__values__._id? - Congo.db.insert @constructor.name, @__dehydrate__(), (id) => - @__values__._id = id - next @ + document = @__dehydrate__() + @__queue_store__ (qnext) => + log '[ Creating ] ' + @constructor.name if process.env.DEBUG? + Congo.db.insert @constructor.name, document, (id) => + # log 'ID: ' + id + @__values__._id = id + next @ if next? + qnext() else if next? next @ __ascend_push__: (key, val, next) -> - @__store_push__ key, val, next - - __store_push__: (key, val, next) -> - log '[ Storing ] ' + @constructor.name + '.' + key if process.env.DEBUG? - doc = {} + document = {} if val instanceof Model - doc[key] = val.__dehydrate__() + document[key] = val.__dehydrate__() else - doc[key] = val - Congo.db.update @constructor.name, { _id: @__values__._id }, { $push: doc }, next + document[key] = val + @__queue_store__ (qnext) => + log '[ Storing ] ' + @constructor.name + '.' + key if process.env.DEBUG? + Congo.db.update @constructor.name, { _id: @__values__._id }, { $push: document }, -> + next() if next? + qnext() __ascend_set__: (key, val, next) -> - @__store_set__ key, val, next - - __store_set__: (key, val, next) -> return if key == '_id' - log '[ Storing ] ' + @constructor.name + '.' + key if process.env.DEBUG? - doc = {} + document = {} if val instanceof Model - doc[key] = val.__dehydrate__() + document[key] = val.__dehydrate__() + else + document[key] = val + @__queue_store__ (qnext) => + log '[ Storing ] ' + @constructor.name + '.' + key if process.env.DEBUG? + Congo.db.update @constructor.name, { _id: @__values__._id }, { $set: document }, -> + next() if next? + qnext() + + __queue_store__: (op) -> + @__store_queue__.push op + if not @__flushing__ + @__flushing__ = true + @__flush_store_queue__() + + __flush_store_queue__: -> + if @__store_queue__.length == 0 + @__flushing__ = false else - doc[key] = val - Congo.db.update @constructor.name, { _id: @__values__._id }, { $set: doc }, next + @__store_queue__.shift()(=> + @__flush_store_queue__()) __save__: (next) -> Congo.db.update @constructor.name, { _id: @__values__._id }, @__dehydrate__(), next diff --git a/lib/mongo.coffee b/lib/mongo.coffee index 640bfda..ea5a420 100644 --- a/lib/mongo.coffee +++ b/lib/mongo.coffee @@ -3,7 +3,7 @@ try catch error util = require 'sys' log = (args...) -> util.puts(a) for a in args -inspect = (args...) -> log(util.inspect(a)) for a in args +inspect = (args...) -> log(util.inspect(a, true, null)) for a in args _bson = require './vendor/bson' binary = require './vendor/binary' net = require 'net' diff --git a/test/mongo.test.coffee b/test/mongo.test.coffee index 008c813..d5d7823 100644 --- a/test/mongo.test.coffee +++ b/test/mongo.test.coffee @@ -75,7 +75,7 @@ Account.clear -> result = account.__dehydrate__() result._id = test_result._id assert.ok _.isEqual(test_result, result) - setTimeout go, 200 + setTimeout go, 400 new Account {}, (account) -> new Person { name: 'Andrew Jackson' }, (person) -> @@ -95,12 +95,12 @@ Account.clear -> go1 = -> new Provider { name: 'FedEx', account: 'FEDXXX' }, (provider) -> person.addresses[0].shipping[0].providers[1] = provider - setTimeout go2, 200 + setTimeout go2, 400 go2 = -> Account.load account._id, (loaded_account) -> log '--- Setting scalars via assignment' assert.ok _.isEqual(account.__dehydrate__(), loaded_account.__dehydrate__()) - setTimeout go2, 200 + setTimeout go2, 400 new Account {}, (account) -> new Person { name: 'Andrew Jackson' }, (person) -> @@ -115,5 +115,5 @@ Account.clear -> Account.load account._id, (loaded2) -> log '--- Setting properties after hydration' assert.ok _.isEqual(loaded1.__dehydrate__(), loaded2.__dehydrate__()) - setTimeout go2, 200 - setTimeout go, 200 + setTimeout go2, 400 + setTimeout go, 400