Skip to content
This repository has been archived by the owner on Nov 14, 2017. It is now read-only.

Commit

Permalink
chainable view api
Browse files Browse the repository at this point in the history
  • Loading branch information
garrensmith committed Oct 24, 2012
1 parent 032e4ed commit 645194b
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 39 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
@@ -1,3 +1,5 @@
language: node_js
env:
- NODE_ENV="travis"
node_js:
- "0.8"
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -6,7 +6,7 @@ site:
&& echo "done"

test:
@NODE_ENV=test mocha specs/* --reporter spec --require should --ignore-leaks --timeout 20000
mocha specs/* --reporter spec --require should --ignore-leaks --timeout 20000


.PHONY: site
70 changes: 70 additions & 0 deletions lib/chainview.js
@@ -0,0 +1,70 @@
var querystring = require('querystring');


var ChainViewAble = function (Model, view_name) {
var self = this,
view_options = {reduce: false, include_docs: true},
Model = Model,
view_name = view_name;

function add_option (name, option) {
view_options[name] = option;
}

function execute(cb) {
Model.view(view_name, view_options, cb);
}

function check_cb(cb) {
if (cb) {
return execute(cb);
}

return self;
}

this.key = function (inputs, cb) {
add_option('key',inputs);

return check_cb(cb);
}

this.startkey = function (inputs, cb) {
add_option('startkey',inputs);

return check_cb(cb);
}

this.endkey = function (inputs, cb) {
add_option('endkey',inputs);
return check_cb(cb);
}

this.limit = function (limit, cb) {
add_option('limit',limit);
return check_cb(cb);
}

this.skip = function (skip, cb) {
add_option('skip',skip);
return check_cb(cb);
}

this.descending = function (cb) {
add_option('descending',true);
return check_cb(cb);
}

this.dont_include_docs = function (cb) {
add_option('include_docs', 'false');
return check_cb(cb);
}


this.stale = function (cb) {
add_option('stale','ok');
return check_cb(cb);
}
}

module.exports = ChainViewAble;
17 changes: 12 additions & 5 deletions lib/model.js
Expand Up @@ -3,6 +3,7 @@ var fs = require('fs'),
async = require('async'),
Document = require('./document'),
Queriable = require('./query'),
ChainViewAble = require('./chainview'),
db_helper = require('./connection');

var defined_models = {};
Expand Down Expand Up @@ -50,13 +51,19 @@ var ModelDocument = function (model_type, schema, views) {
self.methods[method_name] = method;
};


this.view = function (view_name, options, cb) {
if (cb) {
this._view(self.model_type + '/' + view_name, options, cb);
} else {
this._view(self.model_type + '/' + view_name, options);
var _cb = cb;

if (arguments.length == 1) {
return new ChainViewAble(self, view_name);
}

if (arguments.length < 3) {
_cb = options;
options = {};
}

this._view(self.model_type + '/' + view_name, options, _cb);
};

self.load = function (model_data) {
Expand Down
24 changes: 5 additions & 19 deletions lib/query.js
Expand Up @@ -29,23 +29,13 @@ var Queriable = function () {
});
};

this._view = function (view_name, view_options, cb) {
var _cb,
options,
db = db_helper.connection(),
this._view = function (view_name, options, cb) {
var db = db_helper.connection(),
self = this;

if (cb) {
_cb = cb;
options = view_options;
} else {
_cb = arguments[arguments.length - 1]
}


db.view(view_name, options, function (err, docs) {
if (err) {
return _cb(err, null);
return cb(err, null);
}

var model_collection = [];
Expand All @@ -54,16 +44,13 @@ var Queriable = function () {
model_collection.push(self.onDocLoadFn(doc));
});

return _cb(null, model_collection);
return cb(null, model_collection);
});


};


this.all = function (cb) {

this._view(this.model_type + '/all',cb);
this._view(this.model_type + '/all', {}, cb);

};

Expand All @@ -75,7 +62,6 @@ var Queriable = function () {

module.exports = Queriable;


function dumpError(err) {
if (typeof err === 'object') {
if (err.message) {
Expand Down
79 changes: 79 additions & 0 deletions specs/chainable_views_spec.js
@@ -0,0 +1,79 @@
var db = require('./spec_helper').db,
Model = require('../lib/index');

describe("Custom views", function () {

before(function (done) {
var RankingThing = Model.define("RankingThing",{rank: Number, name: String});

RankingThing.addView('ByRankAndName',{
map: function (doc) {
if (doc.model_type === 'RankingThing') {
emit([doc.rank, doc.name],1);
}
}
});

RankingThing.addView('ByName',{
map: function (doc) {
if (doc.model_type === 'RankingThing') {
emit(doc.name,1);
}
}
});



Model.load(function () {

RankingThing.create({name: "Thing1", rank: 5}).save();
RankingThing.create({name: "Thing2", rank: 1}).save();
RankingThing.create({name: "Thing3", rank: 3}).save();
RankingThing.create({name: "Thing4", rank: 5}).save();
RankingThing.create({name: "Thing5", rank: 2}).save();
RankingThing.create({name: "Thing6", rank: 3}).save();
RankingThing.create({name: "Thing7", rank: 5}).save(function () {
done();

});
});

});

it("Should have chainable start and end key", function (done) {
var RankingThing = Model('RankingThing');
RankingThing.view('ByRankAndName').startkey([2, "Thing"]).endkey([3, {}], function (err, things) {
things.length.should.equal(3);
done();
});
});

it("Should descend", function (done) {
var RankingThing = Model('RankingThing');
RankingThing.view('ByName').descending(function (err, things) {
things[0].name.should === "Thing1"
things[3].name.should === "Thing4"
things[6].name.should === "Thing7"
done();
});
});

it("Should limit", function (done) {
var RankingThing = Model('RankingThing');
RankingThing.view('ByName').limit(2, function (err, things) {
things.length.should.equal(2);
done();
});
});

it("Should skip", function (done) {
var RankingThing = Model('RankingThing');
RankingThing.view('ByName').skip(2, function (err, things) {
things.length.should.equal(5);
things[0].name.should === "Thing3"
done();
});
});
});


21 changes: 10 additions & 11 deletions specs/custom_views_spec.js
Expand Up @@ -14,6 +14,16 @@ describe("Custom views", function () {
}
});


Album.addView('ByRatingAndBand',{
map: function (doc) {
if (doc.model_type === 'Album' && doc.band === 'Incubus') {
emit([doc.rating, doc.band],1);
}
}
});


Model.load(function () {

var Album = Model('Album');
Expand All @@ -31,25 +41,14 @@ describe("Custom views", function () {

});




it("Should be able to define custom view for model", function (done) {
var Album = Model('Album');
Album.view('BestIncubusAlbums', function (err, albums) {
albums.length.should.equal(3);
done();
});

});

/*it("Should run some in parallel", function (done) {
Album.parallel_views(['BestIncubusAlbums'], ['WorstIncubusAlbums', {startkey:[1], :endkey[3}], function (err, results) {
});
});*/

});

11 changes: 8 additions & 3 deletions specs/spec_helper.js
@@ -1,10 +1,15 @@
process.env.NODE_ENV = process.env.NODE_ENV || "test"

var db_connection = require('../lib/connection.js'),
cradle = require('cradle'),
async = require('async');

db_connection.create_connection('lazyboy_tests');
//db_connection.create_connection({url: 'https://garrensmith.iriscouch.com', port: '443', secure:true, db:'lazyboy_test'});
//db_connection.create_connection({url: 'https://garrensmith.cloudant.com', port: '443', cache: true, secure:true, db:'lazyboy_tests'});
if (process.env.NODE_ENV === "test") {
db_connection.create_connection('lazyboy_tests');
} else {
//db_connection.create_connection({url: 'https://garrensmith.iriscouch.com', port: '443', secure:true, db:'lazyboy_test'});
db_connection.create_connection({url: 'https://garrensmith.cloudant.com', port: '443', cache: true, secure:true, db:'lazyboy_tests'});
}

var db = module.exports.db = db_connection.connection();

Expand Down

0 comments on commit 645194b

Please sign in to comment.