From 30d320f8d97fdb150c7f4cf6a7c808e60333673c Mon Sep 17 00:00:00 2001 From: Max Ogden Date: Thu, 21 Jul 2011 18:52:52 -0700 Subject: [PATCH] refactoring costco to support bulk deletions and better functional transform error handling --- attachments/pages/index.html | 1 + attachments/script/costco.js | 121 +++++++++++++++++++++++++--------- attachments/script/recline.js | 7 +- attachments/script/site.js | 15 ++--- 4 files changed, 103 insertions(+), 41 deletions(-) diff --git a/attachments/pages/index.html b/attachments/pages/index.html index 89485159..fb5426c9 100644 --- a/attachments/pages/index.html +++ b/attachments/pages/index.html @@ -69,6 +69,7 @@ diff --git a/attachments/script/costco.js b/attachments/script/costco.js index 1ca8dd4a..dcc7c478 100644 --- a/attachments/script/costco.js +++ b/attachments/script/costco.js @@ -3,60 +3,117 @@ var costco = function() { function handleEditorChange(e) { - mapDocs(app.cache, e.target.value, true); - } - - function mapDocs(docs, funcString, preview) { - if(preview) var errors = $('.expression-preview-parsing-status'); - try { - eval("var editFunc = " + funcString); - if(preview) errors.text('No syntax error.'); - } catch(e) { - if(preview) errors.text(e+""); + var editFunc = evalFunction(e.target.value); + var errors = $('.expression-preview-parsing-status'); + if (_.isFunction(editFunc)) { + errors.text('No syntax error.'); + } else { + errors.text(editFunc); return; } + previewTransform(app.cache, editFunc); + } + + function evalFunction(funcString) { + try { + eval("var editFunc = " + funcString); + return editFunc; + } catch(e) { + return e+""; + } + } + + function previewTransform(docs, editFunc) { + var preview = []; + var updated = mapDocs(docs, editFunc); + for (var i = 0; i < updated.docs.length; i++) { + var before = docs[i] + , after = updated.docs[i] + ; + if (!after) after = {}; + preview.push({before: JSON.stringify(before[app.currentColumn]), after: JSON.stringify(after[app.currentColumn])}); + } + util.render('editPreview', 'expression-preview-container', {rows: preview}); + } - var toUpdate = [] - , deleted = 0 - , edited = 0 - , failed = 0 + function mapDocs(docs, editFunc) { + var edited = [] + , deleted = [] + , failed = [] ; - if(preview) var preview = []; - - _.each(docs, function(doc) { + var updatedDocs = _.map(docs, function(doc) { try { var updated = editFunc(_.clone(doc)); } catch(e) { - failed++; // ignore if it throws on this doc + failed.push(doc); return; } if(updated === null) { - doc._deleted = true; - toUpdate.push(doc); - deleted++; + updated = {_deleted: true}; + edited.push(updated); + deleted.push(doc); } else if(updated && !_.isEqual(updated, doc)) { - toUpdate.push(updated); - edited++; + edited.push(updated); } - - if(preview) preview.push({before: JSON.stringify(doc[app.currentColumn]), after: JSON.stringify(updated[app.currentColumn])}); + return updated; }); - if(preview) util.render('editPreview', 'expression-preview-container', {rows: preview}); - return toUpdate; + return { + edited: edited, + docs: updatedDocs, + deleted: deleted, + failed: failed + }; + } + + function updateDocs(editFunc) { + var dfd = $.Deferred(); + util.notify("Updating documents...", {persist: true, loader: true}); + couch.request({url: app.baseURL + "api/json"}).then(function(docs) { + var toUpdate = costco.mapDocs(docs.docs, editFunc).edited; + costco.uploadDocs(toUpdate).then( + function(updatedDocs) { + util.notify(updatedDocs.length + " documents updated successfully"); + recline.fetchRows(false, app.offset); + dfd.resolve(updatedDocs); + }, + function(err) { + util.notify("Errorz! " + err); + dfd.reject(err); + } + ); + }); + return dfd.promise(); } - function updateDocs(docs, callback) { - if(!docs.length) - return callback("Failed to update"); - couch.request({url: app.baseURL + "api/_bulk_docs", type: "POST", data: JSON.stringify({docs: docs})}).then(callback); + function uploadDocs(docs) { + var dfd = $.Deferred(); + if(!docs.length) dfd.resolve("Failed to update"); + couch.request({url: app.baseURL + "api/_bulk_docs", type: "POST", data: JSON.stringify({docs: docs})}) + .then( + dfd.resolve, + function(err) { dfd.reject(err.responseText) } + ); + return dfd.promise(); + } + + function deleteColumn(name) { + var deleteFunc = function(doc) { + delete doc[name]; + return doc; + } + return updateDocs(deleteFunc); } return { handleEditorChange: handleEditorChange, + evalFunction: evalFunction, + previewTransform: previewTransform, mapDocs: mapDocs, - updateDocs: updateDocs + updateDocs: updateDocs, + uploadDocs: uploadDocs, + deleteColumn: deleteColumn }; }(); \ No newline at end of file diff --git a/attachments/script/recline.js b/attachments/script/recline.js index 59630985..aefbae01 100644 --- a/attachments/script/recline.js +++ b/attachments/script/recline.js @@ -23,7 +23,12 @@ var recline = function() { json: function() { window.location.href = "_rewrite/api/json" }, urlImport: function() { showDialog('urlImport') }, pasteImport: function() { showDialog('pasteImport') }, - uploadImport: function() { showDialog('uploadImport') } + uploadImport: function() { showDialog('uploadImport') }, + deleteColumn: function() { + var msg = "Are you sure? This will delete '" + app.currentColumn + "' from all documents."; + if (confirm(msg)) costco.deleteColumn(app.currentColumn); + util.hide('menu'); + } } actions[$(e.target).attr('data-action')](); diff --git a/attachments/script/site.js b/attachments/script/site.js index d2f639a7..87309771 100644 --- a/attachments/script/site.js +++ b/attachments/script/site.js @@ -113,15 +113,13 @@ app.after = { $('.dialog-content .okButton').click(function(e) { var funcText = $('.expression-preview-code').val(); + var editFunc = costco.evalFunction(funcText); + if (!_.isFunction(editFunc)) { + util.notify("Error with function! " + editFunc); + return; + } util.hide('dialog'); - util.notify("Updating documents...", {persist: true, loader: true}); - couch.request({url: app.baseURL + "api/json"}).then(function(docs) { - var toUpdate = costco.mapDocs(docs.docs, funcText); - costco.updateDocs(toUpdate, function(msg) { - util.notify(msg.length + " documents updated successfully"); - recline.fetchRows(false, app.offset); - }); - }); + costco.updateDocs(editFunc); }) var editor = $('.expression-preview-code'); @@ -160,5 +158,6 @@ app.sammy = $.sammy(function () { }); $(function() { + util.traverse = require('traverse'); app.sammy.run(); }) \ No newline at end of file