refactoring costco to support bulk deletions and better functional transform error handling
This commit is contained in:
@@ -69,6 +69,7 @@
|
|||||||
|
|
||||||
<script type='text/mustache' class="columnActionsTemplate">
|
<script type='text/mustache' class="columnActionsTemplate">
|
||||||
<li><a data-action="bulkEdit" class="menuAction" href="JavaScript:void(0);">Transform...</a></li>
|
<li><a data-action="bulkEdit" class="menuAction" href="JavaScript:void(0);">Transform...</a></li>
|
||||||
|
<li><a data-action="deleteColumn" class="menuAction" href="JavaScript:void(0);">Delete this column</a></li>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type='text/mustache' class="titleTemplate"><span id="project-name-button" class="app-path-section">{{db_name}}</span></script>
|
<script type='text/mustache' class="titleTemplate"><span id="project-name-button" class="app-path-section">{{db_name}}</span></script>
|
||||||
|
|||||||
@@ -3,60 +3,117 @@
|
|||||||
var costco = function() {
|
var costco = function() {
|
||||||
|
|
||||||
function handleEditorChange(e) {
|
function handleEditorChange(e) {
|
||||||
mapDocs(app.cache, e.target.value, true);
|
var editFunc = evalFunction(e.target.value);
|
||||||
}
|
var errors = $('.expression-preview-parsing-status');
|
||||||
|
if (_.isFunction(editFunc)) {
|
||||||
function mapDocs(docs, funcString, preview) {
|
errors.text('No syntax error.');
|
||||||
if(preview) var errors = $('.expression-preview-parsing-status');
|
} else {
|
||||||
try {
|
errors.text(editFunc);
|
||||||
eval("var editFunc = " + funcString);
|
|
||||||
if(preview) errors.text('No syntax error.');
|
|
||||||
} catch(e) {
|
|
||||||
if(preview) errors.text(e+"");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
previewTransform(app.cache, editFunc);
|
||||||
|
}
|
||||||
|
|
||||||
var toUpdate = []
|
function evalFunction(funcString) {
|
||||||
, deleted = 0
|
try {
|
||||||
, edited = 0
|
eval("var editFunc = " + funcString);
|
||||||
, failed = 0
|
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});
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapDocs(docs, editFunc) {
|
||||||
|
var edited = []
|
||||||
|
, deleted = []
|
||||||
|
, failed = []
|
||||||
;
|
;
|
||||||
|
|
||||||
if(preview) var preview = [];
|
var updatedDocs = _.map(docs, function(doc) {
|
||||||
|
|
||||||
_.each(docs, function(doc) {
|
|
||||||
try {
|
try {
|
||||||
var updated = editFunc(_.clone(doc));
|
var updated = editFunc(_.clone(doc));
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
failed++; // ignore if it throws on this doc
|
failed.push(doc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(updated === null) {
|
if(updated === null) {
|
||||||
doc._deleted = true;
|
updated = {_deleted: true};
|
||||||
toUpdate.push(doc);
|
edited.push(updated);
|
||||||
deleted++;
|
deleted.push(doc);
|
||||||
}
|
}
|
||||||
else if(updated && !_.isEqual(updated, doc)) {
|
else if(updated && !_.isEqual(updated, doc)) {
|
||||||
toUpdate.push(updated);
|
edited.push(updated);
|
||||||
edited++;
|
|
||||||
}
|
}
|
||||||
|
return updated;
|
||||||
if(preview) preview.push({before: JSON.stringify(doc[app.currentColumn]), after: JSON.stringify(updated[app.currentColumn])});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if(preview) util.render('editPreview', 'expression-preview-container', {rows: preview});
|
return {
|
||||||
return toUpdate;
|
edited: edited,
|
||||||
|
docs: updatedDocs,
|
||||||
|
deleted: deleted,
|
||||||
|
failed: failed
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateDocs(docs, callback) {
|
function updateDocs(editFunc) {
|
||||||
if(!docs.length)
|
var dfd = $.Deferred();
|
||||||
return callback("Failed to update");
|
util.notify("Updating documents...", {persist: true, loader: true});
|
||||||
couch.request({url: app.baseURL + "api/_bulk_docs", type: "POST", data: JSON.stringify({docs: docs})}).then(callback);
|
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 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 {
|
return {
|
||||||
handleEditorChange: handleEditorChange,
|
handleEditorChange: handleEditorChange,
|
||||||
|
evalFunction: evalFunction,
|
||||||
|
previewTransform: previewTransform,
|
||||||
mapDocs: mapDocs,
|
mapDocs: mapDocs,
|
||||||
updateDocs: updateDocs
|
updateDocs: updateDocs,
|
||||||
|
uploadDocs: uploadDocs,
|
||||||
|
deleteColumn: deleteColumn
|
||||||
};
|
};
|
||||||
}();
|
}();
|
||||||
@@ -23,7 +23,12 @@ var recline = function() {
|
|||||||
json: function() { window.location.href = "_rewrite/api/json" },
|
json: function() { window.location.href = "_rewrite/api/json" },
|
||||||
urlImport: function() { showDialog('urlImport') },
|
urlImport: function() { showDialog('urlImport') },
|
||||||
pasteImport: function() { showDialog('pasteImport') },
|
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')]();
|
actions[$(e.target).attr('data-action')]();
|
||||||
|
|||||||
@@ -113,15 +113,13 @@ app.after = {
|
|||||||
|
|
||||||
$('.dialog-content .okButton').click(function(e) {
|
$('.dialog-content .okButton').click(function(e) {
|
||||||
var funcText = $('.expression-preview-code').val();
|
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.hide('dialog');
|
||||||
util.notify("Updating documents...", {persist: true, loader: true});
|
costco.updateDocs(editFunc);
|
||||||
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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
|
|
||||||
var editor = $('.expression-preview-code');
|
var editor = $('.expression-preview-code');
|
||||||
@@ -160,5 +158,6 @@ app.sammy = $.sammy(function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
|
util.traverse = require('traverse');
|
||||||
app.sammy.run();
|
app.sammy.run();
|
||||||
})
|
})
|
||||||
Reference in New Issue
Block a user