Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Pagination & Recursion #87

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 109 additions & 7 deletions lib/Resource/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
var util = require('util');
var pluralize = require('pluralize');
var pathToRegex = require('path-to-regexp');
var Promise = require('bluebird');

var procure = require('procure');
var slugify = require('speakingurl');
Expand All @@ -23,6 +24,7 @@ var Resource = function( name , options ) {
if (!options.templates) options.templates = {};
if (!options.plugins) options.plugins = [];
if (!options.requires) options.requires = [];
if (!options.recursive) options.recursive = [];
if (!options.handlers) options.handlers = {};
if (!options.attributes) options.attributes = {};
if (!options.names) options.names = {};
Expand Down Expand Up @@ -264,6 +266,7 @@ Resource.prototype.attach = function( maki ) {
return {
exec: function( cb ) {
Object.keys( self.props ).forEach(function(prop) {
console.log(self.props);
self.data.forEach(function( el , i ) {
self.data[ i ][ prop ] = self.props[ prop ].apply( self.data[ i ] );
});
Expand Down Expand Up @@ -328,6 +331,7 @@ Resource.prototype.query = function( q , opts , complete ) {
}
var self = this;
var Model = self.Model;
console.log(opts);

async.waterfall([
executePreFunctions,
Expand All @@ -339,15 +343,113 @@ Resource.prototype.query = function( q , opts , complete ) {
});

function executeMethod( q , done ) {
var query = Model.find( q ).sort('-_id');
if (opts.populate) {
query.populate( opts.populate );

function execQuery(q, done, pageInfo){
var query = Model.find( q ).sort('-_id');
console.log("TOP LEVEL QUERY");
console.log(q);

if(pageInfo){
if(pageInfo.skip){
query = query.skip( pageInfo.skip );
}
if(pageInfo.limit){
query = query.limit( pageInfo.limit );
}
}

if (opts.populate) {
console.log('MODEL NAME');
console.log(Model.modelName);
console.log("POPULATE:");
console.log(opts.populate);
query.populate( opts.populate );
}

console.log("OPTS:");
console.log(opts);

var collections = [];

query.exec(function(err, collection) {
if (err) return complete(err);


collections.push(collection);

console.log("POPULATING CHILDREN");
if(!opts.recursive){
opts.recursive = {};
}
async.each( Object.keys(opts.recursive), function(propName, doneWithProp) {

var recursionInfo = opts.recursive[propName];
console.log(recursionInfo);

function loadItemRecursively(item, doneWithItem){
subq = {};
subq[recursionInfo.parentId] = item.id;
console.log("SUB Q");
console.log(subq);
Model.find(subq).exec(function(err, subItems){
item[propName] = subItems;

console.log("SUBCOMMENTS");
console.log(propName);
console.log("=");
console.log(subItems);
collections.push(subItems);

async.each(subItems, loadItemRecursively, function(err){
doneWithItem(null);
});

});
}

async.each(collection, loadItemRecursively, function(err){
doneWithProp(null);
});
}, function(err) {
var resultCollection = collections.length > 1 ? _.flatten(collections) : collection;

if(pageInfo){
return done( err, {collection:resultCollection, isArrayWrapper:true, pageInfo:pageInfo});
}else{
return done( err , resultCollection );
}
})




});
}

query.exec(function(err, collection) {
if (err) return complete(err);
return done( err , collection );
});
if(opts.pagination && opts.pagination.usePagination){
var pagination = opts.pagination;

var pageSize = pagination.pageSize;
console.log("PAGINATION: ");
console.log(pagination);

Model.count( q ).exec(function(err, count){
if(count > pagination.pageSize){
var pageInfo = {
skip: pagination.pageSize * pagination.page,
limit: pageSize,
pageCount: count / pagination.pageSize,
page: pagination.page
};
execQuery(q, done, pageInfo);
}else{
execQuery(q, done, null);
}
});
}else{
console.log("PAGINATION OFF");
execQuery(q, done, null, null);
}
}

function executePreFunctions( done ) {
Expand Down
48 changes: 42 additions & 6 deletions lib/Service/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ var HTTP = function() {

require('util').inherits( HTTP , Service );

function getPagination(req){
var pagination = {lol:'hi', usePagination:false, pageSize:1};
if(req.param('page')) {
pagination['page'] = parseInt( req.param('page') );
}
return pagination;
}

HTTP.prototype.pre = function( event , binding ) {
if (!~['query', 'get', 'update', 'delete', 'create'].indexOf( event )) {
throw new Error('event "'+event+'" is not a valid method.');
Expand Down Expand Up @@ -90,11 +98,17 @@ HTTP.prototype.provide = function() {
}

var resource = self.maki.resources[ r ];

resource.query( filter , {
populate: requirement.populate
populate: requirement.populate,
recursive: requirement.recursive,
pagination: getPagination(req)
}, function(err, obj) {
var element = {};

//console.log("OBJ");
//console.log(obj);

if (requirement.single) {
element[ resource.names.get ] = (obj) ? obj[0] : {};
} else {
Expand Down Expand Up @@ -123,6 +137,10 @@ HTTP.prototype.provide = function() {

locals = _.merge( locals , always );

console.log("LOCALS:");
console.log(locals);
console.log("RENDERING:" + resource.templates[ req.m ]);

res.render( resource.templates[ req.m ] , locals , function( err , body , next ) {
if (self.maki.debug) console.log('render callback', err );
if (err && err.view && err.view.path) return res.render('error'); // TODO: replace with Error handler
Expand All @@ -142,11 +160,24 @@ HTTP.prototype.provide = function() {
var subject = data;

if (subject && !Array.isArray(subject)) {
return res.render('resource', _.merge( always , {
resource: resource,
item: subject
}) );
if(subject.isArrayWrapper){
console.log("RENDERING ARRAY WRAPPER");
var collection = subject.collection;
subject.collection = null;
console.log(resource);
return res.render('resource', _.merge( always, subject , {
resource: resource,
collection: collection
}) );
}else{
console.log("RENDERING SINGLE");
return res.render('resource', _.merge( always , {
resource: resource,
item: subject
}) );
}
} else {
console.log("RENDERING ARRAY");
return res.render('resource', _.merge( always , {
resource: resource,
collection: subject
Expand Down Expand Up @@ -596,9 +627,14 @@ HTTP.prototype.attach = function( maki ) {
var q = {};

resource[ p ]( q , {
populate: methodPopulationMap[ p ]
populate: methodPopulationMap[ p ],
pagination: getPagination(req)
}, function(err, instance) {
if (err) return res.error( err );

//console.log("OBJ");
//console.log(instance);

res.provide( resource.name , instance , handlers );
});
}
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@
"spdy": "^1.28.1",
"speakingurl": "^1.1.0",
"streamifier": "^0.1.0",
"ws": "~0.4.31"
"ws": "~0.4.31",
"bluebird": "^2.9.34"
},
"devDependencies": {
"chai": "^1.9.1",
Expand Down
9 changes: 8 additions & 1 deletion views/modules/collection.jade
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,14 @@ table.ui.table.segment.sortable

tfoot
tr
td #{collection.length} items
td
if (pageInfo)
div.ui.pagination.menu
- var i = 0
while i < pageInfo.pageCount
a.active.item(href="/#{resource.plural.toLowerCase()}?page=#{i}")= i++
else
td #{collection.length} items

script.
$(window).load(function() {
Expand Down