You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ga...@apache.org on 2013/05/23 17:42:31 UTC
[09/10] git commit: updated refs/heads/fauxton-view-improvements to
2171e16
previews working with views
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/9eba40bf
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/9eba40bf
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/9eba40bf
Branch: refs/heads/fauxton-view-improvements
Commit: 9eba40bf3e5ac7cfd933078466f7067e1dde2552
Parents: 642343c
Author: Garren Smith <ga...@gmail.com>
Authored: Wed May 22 19:04:19 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Thu May 23 10:26:45 2013 +0200
----------------------------------------------------------------------
src/fauxton/app/modules/documents/resources.js | 51 +++++++++
src/fauxton/app/modules/documents/routes.js | 23 ++++-
src/fauxton/app/modules/documents/views.js | 79 +++++++++++----
src/fauxton/app/modules/pouchdb/base.js | 17 ++--
.../app/modules/pouchdb/pouchdb.mapreduce.js | 50 ++++++++-
5 files changed, 185 insertions(+), 35 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9eba40bf/src/fauxton/app/modules/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/resources.js b/src/fauxton/app/modules/documents/resources.js
index 4a2a280..36820ae 100644
--- a/src/fauxton/app/modules/documents/resources.js
+++ b/src/fauxton/app/modules/documents/resources.js
@@ -289,6 +289,57 @@ function(app, FauxtonAPI) {
return this.models;
}
});
+
+ Documents.PouchIndexCollection = Backbone.Collection.extend({
+ model: Documents.ViewRow,
+
+ initialize: function(_models, options) {
+ this.database = options.database;
+ this.rows = options.rows;
+ this.view = options.view;
+ this.design = options.design.replace('_design/','');
+ this.params = _.extend({limit: 10, reduce: false}, options.params);
+ this.idxType = "_view";
+ },
+
+ url: function () {
+ return '';
+ },
+
+ fetch: function() {
+ console.log('fetching');
+ var deferred = FauxtonAPI.Deferred();
+ this.reset(this.rows, {silent: true});
+
+ this.viewMeta = {
+ total_rows: this.rows.length,
+ offest: 0,
+ update_seq: false
+ };
+
+ deferred.resolve();
+ return deferred;
+ },
+
+ totalRows: function() {
+ console.log('rows');
+ console.log(this);
+ return this.viewMeta.total_rows || "unknown";
+ },
+
+ updateSeq: function() {
+ return this.viewMeta.update_seq || false;
+ },
+
+ buildAllDocs: function(){
+ this.fetch();
+ },
+
+ allDocs: function(){
+ return this.models;
+ }
+ });
+
return Documents;
});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9eba40bf/src/fauxton/app/modules/documents/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/routes.js b/src/fauxton/app/modules/documents/routes.js
index 1facb3b..9604915 100644
--- a/src/fauxton/app/modules/documents/routes.js
+++ b/src/fauxton/app/modules/documents/routes.js
@@ -181,7 +181,8 @@ function(app, FauxtonAPI, Documents, Databases) {
},
events: {
- "route:updateAllDocs": "updateAllDocsFromView"
+ "route:updateAllDocs": "updateAllDocsFromView",
+ "route:updatePreviewDocs": "updateAllDocsFromPreview"
},
initialize: function (route, masterLayout, options) {
@@ -219,6 +220,7 @@ function(app, FauxtonAPI, Documents, Databases) {
var docOptions = app.getParams(options);
docOptions.include_docs = true;
+ console.log('doc options', docOptions);
this.data.database.buildAllDocs(docOptions);
if (docOptions.startkey && docOptions.startkey.indexOf('_design') > -1) {
@@ -267,6 +269,7 @@ function(app, FauxtonAPI, Documents, Databases) {
viewName: view,
params: params,
newView: false,
+ database: this.data.database,
ddocInfo: ddocInfo
}));
@@ -313,7 +316,6 @@ function(app, FauxtonAPI, Documents, Databases) {
var view = event.view,
ddoc = event.ddoc;
- console.log('updae', event);
this.data.indexedDocs = new Documents.IndexCollection(null, {
database: this.data.database,
design: ddoc,
@@ -323,6 +325,23 @@ function(app, FauxtonAPI, Documents, Databases) {
this.documentsView.collection = this.data.indexedDocs;
this.documentsView.forceRender();
+ },
+
+ updateAllDocsFromPreview: function (event) {
+ var view = event.view,
+ rows = event.rows,
+ ddoc = event.ddoc;
+
+ this.data.indexedDocs = new Documents.PouchIndexCollection(null, {
+ database: this.data.database,
+ design: ddoc,
+ view: view,
+ rows: rows
+ });
+
+ console.log(this.data.indexedDocs);
+ this.documentsView.collection = this.data.indexedDocs;
+ this.documentsView.forceRender();
}
});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9eba40bf/src/fauxton/app/modules/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/views.js b/src/fauxton/app/modules/documents/views.js
index c267f31..1213ce3 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -16,6 +16,7 @@ define([
"api",
"modules/documents/resources",
+ "modules/pouchdb/base",
// Libs
"codemirror",
@@ -27,7 +28,7 @@ define([
],
-function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
+function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
var Views = {};
Views.Tabs = FauxtonAPI.View.extend({
@@ -294,7 +295,7 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
},
establish: function() {
- return this.collection.fetch().error(function() {
+ return this.collection.fetch().fail(function() {
// TODO: handle error requests that slip through
// This should just throw a notification, not break the page
console.log("ERROR: ", arguments);
@@ -389,7 +390,7 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
this.model.clear({silent:true});
this.model.set(json);
notification = FauxtonAPI.addNotification({msg: "Saving document."});
- this.model.save().error(function(xhr) {
+ this.model.save().fail(function(xhr) {
var responseText = JSON.parse(xhr.responseText).reason;
notification = FauxtonAPI.addNotification({
msg: "Save failed: " + responseText,
@@ -519,6 +520,7 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
this.viewCollection = options.viewCollection;
this.viewName = options.viewName;
this.params = options.params;
+ this.database = options.database;
if (this.newView) {
//TODO: CREATE NEW HERE
} else {
@@ -547,11 +549,8 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
}
},
- updateView: function(event) {
- var $form = $(event.currentTarget);
-
- event.preventDefault();
-
+ queryParams: function () {
+ var $form = $(".view-query-update");
// Ignore params without a value
var params = _.filter($form.serializeArray(), function(param) {
return param.value;
@@ -572,6 +571,16 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
}
});
+ return {params: params, errorParams: errorParams};
+ },
+
+ updateView: function(event) {
+ event.preventDefault();
+
+ var paramInfo = this.queryParams(),
+ errorParams = paramInfo.errorParams,
+ params = paramInfo.params;
+
if (_.any(errorParams)) {
_.map(errorParams, function(param) {
@@ -638,17 +647,42 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
},
previewView: function(event) {
+ var that = this,
+ mapVal = this.mapEditor.getValue(),
+ reduceVal = this.reduceVal(),
+ paramsArr = this.queryParams().params;
+
+ var params = _.reduce(paramsArr, function (params, param) {
+ params[param.name] = param.value;
+ return params;
+ }, {reduce: false});
+
event.preventDefault();
+
FauxtonAPI.addNotification({
msg: "<strong>Warning!</strong> Preview executes the Map/Reduce functions in your browser, and may behave differently from CouchDB.",
type: "warning",
selector: "#define-view .errors-container",
- fade: false
+ fade: true
});
- FauxtonAPI.addNotification({
- msg: "Preview Functionality Coming Soon",
- type: "warning",
- selector: "#define-view .errors-container"
+
+ var promise = FauxtonAPI.Deferred();
+
+ if (!this.database.allDocs) {
+ this.database.buildAllDocs({limit: "100", include_docs: true});
+ promise = this.database.allDocs.fetch();
+ } else {
+ promise.resolve();
+ }
+
+ promise.then(function () {
+ params.docs = that.database.allDocs.map(function (model) { return model.get('doc');});
+
+ var queryPromise = pouchdb.runViewQuery({map: mapVal, reduce: reduceVal}, params);
+ queryPromise.then(function (results) {
+ console.log('promise', arguments, results);
+ FauxtonAPI.triggerRouteEvent('updatePreviewDocs', {rows: results.rows, ddoc: that.ddocID, view: that.viewName});
+ });
});
},
@@ -661,18 +695,13 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
if (this.hasValidCode()) {
var mapVal = this.mapEditor.getValue(),
reduceVal = "",
- reduceOption = this.$('#reduce-function-selector :selected').val(),
+
viewName = this.$('#index-name').val();
ddocName = this.$('#ddoc :selected').val();
this.viewName = viewName;
- if (reduceOption === 'CUSTOM') {
- reduceVal = this.reduceEditor.getValue();
- } else if ( reduceOption !== 'NONE') {
- reduceVal = reduceOption;
- }
-
+
var ddoc = this.ddocs.find(function (ddoc) {
return ddoc.id === ddocName;
}).dDocModel();
@@ -715,6 +744,16 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
},
reduceVal: function() {
+ var reduceOption = this.$('#reduce-function-selector :selected').val(),
+ reduceVal = "";
+
+ if (reduceOption === 'CUSTOM') {
+ reduceVal = this.reduceEditor.getValue();
+ } else if ( reduceOption !== 'NONE') {
+ reduceVal = reduceOption;
+ }
+
+ return reduceVal;
},
hasValidCode: function() {
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9eba40bf/src/fauxton/app/modules/pouchdb/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/pouchdb/base.js b/src/fauxton/app/modules/pouchdb/base.js
index 2b7cfc9..ddaf06d 100644
--- a/src/fauxton/app/modules/pouchdb/base.js
+++ b/src/fauxton/app/modules/pouchdb/base.js
@@ -31,8 +31,8 @@ function(app, FauxtonAPI, MapReduce) {
var Pouch = {};
Pouch.MapReduce = MapReduce;
- Pouch.runViewQuery = function(fun, docs) {
- docs = [
+ Pouch.runViewQuery = function(fun, opts) {
+ /*docs = [
{_id: 'test_doc_1', foo: 'bar-1'},
{_id: 'test_doc_2', foo: 'bar-2'},
{_id: 'test_doc_3', foo: 'bar-3'},
@@ -43,15 +43,18 @@ function(app, FauxtonAPI, MapReduce) {
{_id: 'test_doc_8', foo: 'bar-8'},
{_id: 'test_doc_9', foo: 'bar-9'},
{_id: 'test_doc_10', foo: 'bar-10'}
- ];
+ ];*/
var deferred = FauxtonAPI.Deferred();
- var complete = function(resp) {
- console.log("COMPLETE TRIGGERED", arguments);
+ var complete = function(resp, rows) {
+ deferred.resolve(rows);
};
- return Pouch.MapReduce.query(fun, {docs: docs, complete:complete});
- };
+ var options = _.extend(opts, {complete: complete});
+ Pouch.MapReduce.query(fun, options);
+ return deferred;
+ };
+ //pdb.runViewQuery({map:function(doc) { emit(doc._id, doc.foo) }})
return Pouch;
});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9eba40bf/src/fauxton/app/modules/pouchdb/pouchdb.mapreduce.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/pouchdb/pouchdb.mapreduce.js b/src/fauxton/app/modules/pouchdb/pouchdb.mapreduce.js
index b97eb7f..a2d0b91 100644
--- a/src/fauxton/app/modules/pouchdb/pouchdb.mapreduce.js
+++ b/src/fauxton/app/modules/pouchdb/pouchdb.mapreduce.js
@@ -39,6 +39,36 @@ function(app, FauxtonAPI, Collate) {
//var MapReduce = function(db) {
var MapReduce = function() {
+ var builtInReduce = {
+ "_sum": function(keys, values){
+ return sum(values);
+ },
+
+ "_count": function(keys, values, rereduce){
+ if (rereduce){
+ return sum(values);
+ } else {
+ return values.length;
+ }
+ },
+
+ "_stats": function(keys, values, rereduce){
+ return {
+ 'sum': sum(values),
+ 'min': Math.min.apply(null, values),
+ 'max': Math.max.apply(null, values),
+ 'count': values.length,
+ 'sumsqr': (function(){
+ _sumsqr = 0;
+ for(var idx in values){
+ _sumsqr += values[idx] * values[idx];
+ }
+ return _sumsqr;
+ })()
+ };
+ }
+ };
+
function viewQuery(fun, options) {
console.log("IN VIEW QUERY");
if (!options.complete) {
@@ -55,13 +85,13 @@ function(app, FauxtonAPI, Collate) {
var completed= false;
var emit = function(key, val) {
- console.log("IN EMIT: ", key, val, current);
+ //console.log("IN EMIT: ", key, val, current);
var viewRow = {
id: current.doc._id,
key: key,
value: val
};
- console.log("VIEW ROW: ", viewRow);
+ //console.log("VIEW ROW: ", viewRow);
if (options.startkey && Pouch.collate(key, options.startkey) < 0) return;
if (options.endkey && Pouch.collate(key, options.endkey) > 0) return;
@@ -95,7 +125,11 @@ function(app, FauxtonAPI, Collate) {
// ugly way to make sure references to 'emit' in map/reduce bind to the
// above emit
eval('fun.map = ' + fun.map.toString() + ';');
- if (fun.reduce) {
+ if (fun.reduce && options.reduce) {
+ if (builtInReduce[fun.reduce]) {
+ console.log('built in reduce');
+ fun.reduce = builtInReduce[fun.reduce];
+ }
eval('fun.reduce = ' + fun.reduce.toString() + ';');
}
@@ -105,6 +139,7 @@ function(app, FauxtonAPI, Collate) {
//only proceed once all documents are mapped and joined
var checkComplete= function(){
+ console.log('check');
if (completed && results.length == num_started){
results.sort(function(a, b) {
return Pouch.collate(a.key, b.key);
@@ -116,6 +151,7 @@ function(app, FauxtonAPI, Collate) {
return options.complete(null, {rows: results});
}
+ console.log('reducing', options);
var groups = [];
results.forEach(function(e) {
var last = groups[groups.length-1] || null;
@@ -130,19 +166,21 @@ function(app, FauxtonAPI, Collate) {
e.value = fun.reduce(e.key, e.value) || null;
e.key = e.key[0][0];
});
+ console.log('GROUPs', groups);
options.complete(null, {rows: groups});
}
};
if (options.docs) {
- console.log("RUNNING MR ON DOCS: ", options.docs);
+ //console.log("RUNNING MR ON DOCS: ", options.docs);
_.each(options.docs, function(doc) {
current = {doc: doc};
fun.map.call(this, doc);
}, this);
- return options.complete(null, {rows: results});
+ completed = true;
+ return checkComplete();//options.complete(null, {rows: results});
} else {
- console.log("COULD NOT FIND DOCS");
+ //console.log("COULD NOT FIND DOCS");
return false;
}