Skip to content

Instantly share code, notes, and snippets.

@atuttle
Created April 27, 2012 18:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save atuttle/2511809 to your computer and use it in GitHub Desktop.
Save atuttle/2511809 to your computer and use it in GitHub Desktop.
All I've done here is taken the pagination plugin and mashed it into the query plugin, so that we can have the awesomeness of .where(...).page(...)
// - NOT jsonPath or jsonQuery which are horrendously complex and fugly
// - simple query syntax 'its just javascript'
// - simple string interpolation
// - search then sorting
Lawnchair.plugin((function(){
//
var interpolate = function(template, args) {
var parts = template.split('?').filter(function(i) { return i != ''})
, query = ''
for (var i = 0, l = parts.length; i < l; i++) {
query += parts[i] + args[i]
}
return query
}
var sorter = function(p) {
return function(a, b) {
if (a[p] < b[p]) return -1
if (a[p] > b[p]) return 1
return 0
}
}
//
return {
// query the storage obj
where: function() {
// ever notice we do this sort thing lots?
var args = [].slice.call(arguments)
, tmpl = args.shift()
, last = args[args.length - 1]
, qs = tmpl.match(/\?/g)
, q = qs && qs.length > 0 ? interpolate(tmpl, args.slice(0, qs.length)) : tmpl
, is = new Function(this.record, 'return !!(' + q + ')')
, r = []
, cb
// iterate the entire collection
// TODO should we allow for chained where() to filter __results? (I'm thinking no b/c creates funny behvaiors w/ callbacks)
this.all(function(all){
for (var i = 0, l = all.length; i < l; i++) {
if (is(all[i])) r.push(all[i])
}
})
// overwrite working results
this.__results = r
// callback / chain
if (args.length === 1) this.fn(this.name, last).call(this, this.__results)
return this
},
// FIXME should be able to call without this.__results
// ascending sort the working storage obj on a property (or nested property)
asc: function(property, callback) {
this.fn(this.name, callback).call(this, this.__results.sort(sorter(property)))
return this
},
// descending sort on working storage object on a property
desc: function(property, callback) {
this.fn(this.name, callback).call(this, this.__results.sort(sorter(property)).reverse())
return this
},
//mash in the page method from the pagination plugin
page: function (page, callback) {
// some defaults
var objs = []
, count = 5 // TODO make this configurable
, cur = ~~page || 1
, next = cur + 1
, prev = cur - 1
, start = cur == 1 ? 0 : prev*count
, end = start >= count ? start+count : count
// grab all the records
// FIXME if this was core we could use this.__results for faster queries
objs = this.__results
// grab the metadata
var max = Math.ceil(objs.length/count)
, page = { max: max
, next: next > max ? max : next
, prev: prev == 0 ? 1 : prev
}
// reassign to the working resultset
this.__results = page[this.name] = objs.slice(start, end)
// callback / chain
if (callback) this.fn('page', callback).call(this, page)
return this
}
}
/////
})())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment