Skip to content

Commit 839bb9a

Browse files
authored
Merge pull request #1149 from strongloop/near_loaded_oh
Add support for `loaded` operation hook for DAO.find() when near is used
2 parents fc4ea43 + 54d0f5b commit 839bb9a

File tree

2 files changed

+90
-9
lines changed

2 files changed

+90
-9
lines changed

lib/dao.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1821,7 +1821,7 @@ DataAccessObject.find = function find(query, options, cb) {
18211821
}
18221822

18231823
function queryGeo(query) {
1824-
function geoCallback(err, data) {
1824+
function geoCallbackWithoutNotify(err, data) {
18251825
var memory = new Memory();
18261826
var modelName = self.modelName;
18271827

@@ -1847,6 +1847,29 @@ DataAccessObject.find = function find(query, options, cb) {
18471847
}
18481848
}
18491849

1850+
function geoCallbackWithNotify(err, data) {
1851+
if (err) return cb(err);
1852+
1853+
async.map(data, function(item, next) {
1854+
var context = {
1855+
Model: self,
1856+
data: item,
1857+
isNewInstance: false,
1858+
hookState: hookState,
1859+
options: options,
1860+
};
1861+
1862+
self.notifyObserversOf('loaded', context, function(err) {
1863+
if (err) return next(err);
1864+
next(null, context.data);
1865+
});
1866+
}, function(err, results) {
1867+
if (err) return cb(err);
1868+
geoCallbackWithoutNotify(null, results);
1869+
});
1870+
}
1871+
1872+
var geoCallback = options.notify === false ? geoCallbackWithoutNotify : geoCallbackWithNotify;
18501873
if (connector.all.length === 4) {
18511874
connector.all(self.modelName, {}, options, geoCallback);
18521875
} else {

test/persistence-hooks.suite.js

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
'use strict';
77
var ValidationError = require('../').ValidationError;
88

9+
var async = require('async');
910
var contextTestHelpers = require('./helpers/context-test-helpers');
1011
var ContextRecorder = contextTestHelpers.ContextRecorder;
1112
var deepCloneToObject = contextTestHelpers.deepCloneToObject;
1213
var aCtxForModel = contextTestHelpers.aCtxForModel;
14+
var GeoPoint = require('../lib/geo.js').GeoPoint;
1315

1416
var uid = require('./helpers/uid-generator');
1517
var getLastGeneratedUid = uid.last;
@@ -24,7 +26,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
2426
}
2527
describe('Persistence hooks', function() {
2628
var ctxRecorder, hookMonitor, expectedError;
27-
var TestModel, existingInstance;
29+
var TestModel, existingInstance, GeoModel;
2830
var migrated = false;
2931

3032
var undefinedValue = undefined;
@@ -41,12 +43,25 @@ module.exports = function(dataSource, should, connectorCapabilities) {
4143
extra: {type: String, required: false},
4244
});
4345

46+
GeoModel = dataSource.createModel('GeoModel', {
47+
id: {type: String, id: true},
48+
name: {type: String, required: false},
49+
location: {type: GeoPoint, required: false},
50+
});
51+
4452
uid.reset();
4553

4654
if (migrated) {
47-
TestModel.deleteAll(done);
55+
async.series([
56+
function(cb) {
57+
TestModel.deleteAll(cb);
58+
},
59+
function(cb) {
60+
GeoModel.deleteAll(cb);
61+
},
62+
], done);
4863
} else {
49-
dataSource.automigrate(TestModel.modelName, function(err) {
64+
dataSource.automigrate([TestModel.modelName, 'GeoModel'], function(err) {
5065
migrated = true;
5166
done(err);
5267
});
@@ -64,7 +79,12 @@ module.exports = function(dataSource, should, connectorCapabilities) {
6479

6580
TestModel.create({name: 'second'}, function(err) {
6681
if (err) return done(err);
67-
done();
82+
var location1 = new GeoPoint({lat: 10.2, lng: 6.7});
83+
GeoModel.create([
84+
{name: 'Rome', location: location1},
85+
], function(err) {
86+
done(err);
87+
});
6888
});
6989
});
7090
});
@@ -100,13 +120,51 @@ module.exports = function(dataSource, should, connectorCapabilities) {
100120
});
101121

102122
it('triggers correct hooks when near filter is used', function(done) {
103-
monitorHookExecution();
123+
var hookMonitorGeoModel;
124+
hookMonitorGeoModel = new HookMonitor({includeModelName: false});
125+
126+
function monitorHookExecutionGeoModel(hookNames) {
127+
hookMonitorGeoModel.install(GeoModel, hookNames);
128+
}
129+
130+
monitorHookExecutionGeoModel();
131+
104132
var query = {
105-
where: {location: {near: '10,20', maxDistance: '10', unit: 'meters'}},
133+
where: {location: {near: '10,5'}},
106134
};
107-
TestModel.find(query, function(err, list) {
135+
GeoModel.find(query, function(err, list) {
136+
if (err) return done(err);
137+
hookMonitorGeoModel.names.should.eql(['access', 'loaded']);
138+
done();
139+
});
140+
});
141+
142+
it('applies updates from `loaded` hook when near filter is used', function(done) {
143+
GeoModel.observe('loaded', function(ctx, next) {
144+
ctx.data.name = 'Berlin';
145+
next();
146+
});
147+
148+
var query = {
149+
where: {location: {near: '10,5'}},
150+
};
151+
152+
GeoModel.find(query, function(err, list) {
153+
if (err) return done(err);
154+
list.map(get('name')).should.eql(['Berlin']);
155+
done();
156+
});
157+
});
158+
159+
it('applies updates from `loaded` hook when near filter is not used', function(done) {
160+
TestModel.observe('loaded', function(ctx, next) {
161+
ctx.data.name = 'Paris';
162+
next();
163+
});
164+
165+
TestModel.find(function(err, list) {
108166
if (err) return done(err);
109-
hookMonitor.names.should.eql(['access']);
167+
list.map(get('name')).should.eql(['Paris', 'Paris']);
110168
done();
111169
});
112170
});

0 commit comments

Comments
 (0)