Make q and other query parameters not mutually exclusive

This commit is contained in:
Typicode
2015-07-17 02:39:21 +02:00
parent 29469cc21f
commit 3056b963cb
2 changed files with 47 additions and 42 deletions

View File

@ -62,28 +62,30 @@ module.exports = function (source) {
// Filters list // Filters list
var filters = {} var filters = {}
// Result array // Resource chain
var array var chain = db(req.params.resource).chain()
// Remove _start, _end and _limit from req.query to avoid filtering using those // Remove q, _start, _end, ... from req.query to avoid filtering using those
// parameters // parameters
var q = req.query.q
var _start = req.query._start var _start = req.query._start
var _end = req.query._end var _end = req.query._end
var _sort = req.query._sort var _sort = req.query._sort
var _order = req.query._order var _order = req.query._order
var _limit = req.query._limit var _limit = req.query._limit
delete req.query.q
delete req.query._start delete req.query._start
delete req.query._end delete req.query._end
delete req.query._sort delete req.query._sort
delete req.query._order delete req.query._order
delete req.query._limit delete req.query._limit
if (req.query.q) { if (q) {
// Full-text search // Full-text search
var q = req.query.q.toLowerCase() q = q.toLowerCase()
array = db(req.params.resource).filter(function (obj) { chain = chain.filter(function (obj) {
for (var key in obj) { for (var key in obj) {
var value = obj[key] var value = obj[key]
if (db._.deepQuery(value, q)) { if (db._.deepQuery(value, q)) {
@ -92,7 +94,7 @@ module.exports = function (source) {
} }
}) })
} else { }
// Add :parentId filter in case URL is like /:parent/:parentId/:resource // Add :parentId filter in case URL is like /:parent/:parentId/:resource
if (req.params.parent) { if (req.params.parent) {
@ -111,34 +113,29 @@ module.exports = function (source) {
} }
// Filter // Filter
if (_(filters).isEmpty()) { if (!_(filters).isEmpty()) {
array = db(req.params.resource).value()
} else {
var chain = db(req.params.resource).chain()
for (var f in filters) { for (var f in filters) {
// This syntax allow for deep filtering using lodash (i.e. a.b.c[0]) // This syntax allow for deep filtering using lodash (i.e. a.b.c[0])
chain = chain.filter(f, filters[f]) chain = chain.filter(f, filters[f])
} }
array = chain.value()
}
} }
// Sort // Sort
if (_sort) { if (_sort) {
_order = _order || 'ASC' _order = _order || 'ASC'
array = _.sortBy(array, function (element) { chain = chain.sortBy(function (element) {
return element[_sort] return element[_sort]
}) })
if (_order === 'DESC') { if (_order === 'DESC') {
array.reverse() chain = chain.reverse()
} }
} }
// Slice result // Slice result
if (_end || _limit) { if (_end || _limit) {
res.setHeader('X-Total-Count', array.length) res.setHeader('X-Total-Count', chain.size())
res.setHeader('Access-Control-Expose-Headers', 'X-Total-Count') res.setHeader('Access-Control-Expose-Headers', 'X-Total-Count')
} }
@ -146,13 +143,13 @@ module.exports = function (source) {
if (_end) { if (_end) {
_end = parseInt(_end, 10) _end = parseInt(_end, 10)
array = array.slice(_start, _end) chain = chain.slice(_start, _end)
} else if (_limit) { } else if (_limit) {
_limit = parseInt(_limit, 10) _limit = parseInt(_limit, 10)
array = array.slice(_start, _start + _limit) chain = chain.slice(_start, _start + _limit)
} }
res.locals.data = array res.locals.data = chain.value()
next() next()
} }

View File

@ -25,11 +25,11 @@ describe('Server', function () {
] ]
db.comments = [ db.comments = [
{id: 1, published: true, postId: 1}, {id: 1, body: 'foo', published: true, postId: 1},
{id: 2, published: false, postId: 1}, {id: 2, body: 'bar', published: false, postId: 1},
{id: 3, published: false, postId: 2}, {id: 3, body: 'baz', published: false, postId: 2},
{id: 4, published: false, postId: 2}, {id: 4, body: 'qux', published: true, postId: 2},
{id: 5, published: false, postId: 2} {id: 5, body: 'quux', published: false, postId: 2}
] ]
db.refs = [ db.refs = [
@ -122,6 +122,14 @@ describe('Server', function () {
.expect([]) .expect([])
.expect(200, done) .expect(200, done)
}) })
it('should support other query parameters', function (done) {
request(server)
.get('/comments?q=qu&published=true')
.expect('Content-Type', /json/)
.expect([db.comments[3]])
.expect(200, done)
})
}) })
describe('GET /:resource?_end=', function () { describe('GET /:resource?_end=', function () {