Skip to content
Browse files

chainable view api

  • Loading branch information...
1 parent 032e4ed commit 645194be48e248096ba5b8f6df8fed32ce6fbcd7 @garrensmith committed Oct 24, 2012
Showing with 187 additions and 39 deletions.
  1. +2 −0 .travis.yml
  2. +1 −1 Makefile
  3. +70 −0 lib/chainview.js
  4. +12 −5 lib/model.js
  5. +5 −19 lib/query.js
  6. +79 −0 specs/chainable_views_spec.js
  7. +10 −11 specs/custom_views_spec.js
  8. +8 −3 specs/spec_helper.js
View
2 .travis.yml
@@ -1,3 +1,5 @@
language: node_js
+env:
+ - NODE_ENV="travis"
node_js:
- "0.8"
View
2 Makefile
@@ -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
View
70 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;
View
17 lib/model.js
@@ -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 = {};
@@ -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) {
View
24 lib/query.js
@@ -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 = [];
@@ -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);
};
@@ -75,7 +62,6 @@ var Queriable = function () {
module.exports = Queriable;
-
function dumpError(err) {
if (typeof err === 'object') {
if (err.message) {
View
79 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();
+ });
+ });
+});
+
+
View
21 specs/custom_views_spec.js
@@ -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');
@@ -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) {
-
- });
-
- });*/
});
View
11 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();

0 comments on commit 645194b

Please sign in to comment.
Something went wrong with that request. Please try again.