Skip to content

Commit

Permalink
moved query.js createModel private to queryhelpers.js for use in hydr…
Browse files Browse the repository at this point in the history
…ating models in streams. fixes #1792
  • Loading branch information
j committed Nov 22, 2013
1 parent 0099828 commit 94541a2
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 29 deletions.
30 changes: 2 additions & 28 deletions lib/query.js
Expand Up @@ -1038,40 +1038,14 @@ function completeMany (model, docs, fields, self, pop, promise) {
{ populated: pop }
: undefined;
for (var i=0; i < len; ++i) {
arr[i] = createModel(model, docs[i], fields);
arr[i] = helpers.createModel(model, docs[i], fields);
arr[i].init(docs[i], opts, function (err) {
if (err) return promise.error(err);
--count || promise.complete(arr);
});
}
}

/*!
* If the document is a mapped discriminator type, it returns a model instance for that type, otherwise,
* it returns an instance of the given model.
*
* @param {Model} model
* @param {Object} doc
* @param {Object} fields
*
* @return {Model}
*/
function createModel(model, doc, fields) {
var discriminatorMapping = model.schema
? model.schema.discriminatorMapping
: null;

var key = discriminatorMapping && discriminatorMapping.isRoot
? discriminatorMapping.key
: null;

if (key && doc[key] && model.discriminators && model.discriminators[doc[key]]) {
return new model.discriminators[doc[key]](undefined, fields, true);
}

return new model(undefined, fields, true);
}

/**
* Declares the query a findOne operation. When executed, the first found document is passed to the callback.
*
Expand Down Expand Up @@ -1406,7 +1380,7 @@ function completeOne (model, doc, fields, self, pop, promise) {
{ populated: pop }
: undefined;

var casted = createModel(model, doc, fields)
var casted = helpers.createModel(model, doc, fields)
casted.init(doc, opts, function (err) {
if (err) return promise.error(err);
promise.complete(casted);
Expand Down
26 changes: 26 additions & 0 deletions lib/queryhelpers.js
Expand Up @@ -40,6 +40,32 @@ exports.preparePopulationOptionsMQ = function preparePopulationOptionsMQ (query,
return pop;
}

/*!
* If the document is a mapped discriminator type, it returns a model instance for that type, otherwise,
* it returns an instance of the given model.
*
* @param {Model} model
* @param {Object} doc
* @param {Object} fields
*
* @return {Model}
*/
exports.createModel = function createModel(model, doc, fields) {
var discriminatorMapping = model.schema
? model.schema.discriminatorMapping
: null;

var key = discriminatorMapping && discriminatorMapping.isRoot
? discriminatorMapping.key
: null;

if (key && doc[key] && model.discriminators && model.discriminators[doc[key]]) {
return new model.discriminators[doc[key]](undefined, fields, true);
}

return new model(undefined, fields, true);
}

/*!
* Set each path query option to lean
*
Expand Down
3 changes: 2 additions & 1 deletion lib/querystream.js
Expand Up @@ -232,7 +232,8 @@ QueryStream.prototype._onNextObject = function _onNextObject (err, doc) {
}

function createAndEmit (self, doc) {
var instance = new self.query.model(undefined, self._fields, true);
var instance = helpers.createModel(self.query.model, doc, self._fields);

instance.init(doc, function (err) {
if (err) return self.destroy(err);
emit(self, instance);
Expand Down
43 changes: 43 additions & 0 deletions test/model.discriminator.querying.test.js
Expand Up @@ -119,6 +119,49 @@ describe('model', function() {
});
});
});

it('hydrates streams', function(done) {
var baseEvent = new BaseEvent({ name: 'Base event' });
var impressionEvent = new ImpressionEvent({ name: 'Impression event' });
var conversionEvent = new ConversionEvent({ name: 'Conversion event', revenue: 1.337 });

baseEvent.save(function(err) {
assert.ifError(err);
impressionEvent.save(function(err) {
assert.ifError(err);
conversionEvent.save(function(err) {
assert.ifError(err);
var stream = BaseEvent.find({}).sort('name').stream();

stream.on('data', function(doc) {
switch(doc.name) {
case 'Base event':
assert.ok(doc instanceof BaseEvent);
break;
case 'Impression event':
assert.ok(doc instanceof BaseEvent);
assert.ok(doc instanceof ImpressionEvent);
break;
case 'Conversion event':
assert.ok(doc instanceof BaseEvent);
assert.ok(doc instanceof ConversionEvent);
break;
default:

}
});

stream.on('error', function (err) {
assert.ifError(err);
});

stream.on('close', function() {
done();
});
});
});
});
});
});

describe('findOne', function() {
Expand Down

0 comments on commit 94541a2

Please sign in to comment.