blob: 5d7738911ed1f17bb433df96df00a4adf8e3ceca [file] [log] [blame]
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
function create_sandbox() {
try {
// if possible, use evalcx (not always available)
var sandbox = evalcx('');
sandbox.emit = Views.emit;
sandbox.sum = Views.sum;
sandbox.log = log;
sandbox.toJSON = JSON.stringify;
sandbox.JSON = JSON;
sandbox.provides = Mime.provides;
sandbox.registerType = Mime.registerType;
sandbox.start = Render.start;
sandbox.send = Render.send;
sandbox.getRow = Render.getRow;
sandbox.isArray = isArray;
sandbox.index = Dreyfus.index;
} catch (e) {
var sandbox = {};
}
return sandbox;
};
function create_filter_sandbox() {
var sandbox = create_sandbox();
sandbox.emit = Filter.emit;
return sandbox;
};
// Commands are in the form of json arrays:
// ["commandname",..optional args...]\n
//
// Responses are json values followed by a new line ("\n")
var DDoc = (function() {
var ddoc_dispatch = {
"lists" : Render.list,
"shows" : Render.show,
"filters" : Filter.filter,
"views" : Filter.filter_view,
"updates" : Render.update,
"validate_doc_update" : Validate.validate,
"rewrites" : Render.rewrite
};
var ddocs = {};
return {
ddoc : function() {
var args = [];
for (var i=0; i < arguments.length; i++) {
args.push(arguments[i]);
};
var ddocId = args.shift();
if (ddocId == "new") {
// get the real ddocId.
ddocId = args.shift();
// store the ddoc, functions are lazily compiled.
ddocs[ddocId] = args.shift();
print("true");
} else {
// Couch makes sure we know this ddoc already.
var ddoc = ddocs[ddocId];
if (!ddoc) throw(["fatal", "query_protocol_error", "uncached design doc: "+ddocId]);
var funPath = args.shift();
var cmd = funPath[0];
// the first member of the fun path determines the type of operation
var funArgs = args.shift();
if (ddoc_dispatch[cmd]) {
// get the function, call the command with it
var point = ddoc;
for (var i=0; i < funPath.length; i++) {
if (i+1 == funPath.length) {
var fun = point[funPath[i]];
if (!fun) {
throw(["error","not_found",
"missing " + funPath[0] + " function " + funPath[i] +
" on design doc " + ddocId]);
}
if (typeof fun != "function") {
fun = Couch.compileFunction(fun, ddoc, funPath.join('.'));
// cache the compiled fun on the ddoc
point[funPath[i]] = fun;
};
} else {
point = point[funPath[i]];
}
};
// run the correct responder with the cmd body
ddoc_dispatch[cmd].apply(null, [fun, ddoc, funArgs]);
} else {
// unknown command, quit and hope the restarted version is better
throw(["fatal", "unknown_command", "unknown ddoc command '" + cmd + "'"]);
}
}
}
};
})();
var Loop = function() {
var line, cmd, cmdkey, dispatch = {
"ddoc" : DDoc.ddoc,
// "view" : Views.handler,
"reset" : State.reset,
"add_fun" : State.addFun,
"add_lib" : State.addLib,
"map_doc" : Views.mapDoc,
"index_doc": Dreyfus.indexDoc,
"reduce" : Views.reduce,
"rereduce" : Views.rereduce
};
function handleError(e) {
var type = e[0];
if (type == "fatal") {
e[0] = "error"; // we tell the client it was a fatal error by dying
respond(e);
quit(-1);
} else if (type == "error") {
respond(e);
} else if (e.error && e.reason) {
// compatibility with old error format
respond(["error", e.error, e.reason]);
} else if (e.name) {
respond(["error", e.name, e]);
} else {
respond(["error","unnamed_error",e.toSource ? e.toSource() : e.stack]);
}
};
while (line = readline()) {
cmd = JSON.parse(line);
State.line_length = line.length;
try {
cmdkey = cmd.shift();
if (dispatch[cmdkey]) {
// run the correct responder with the cmd body
dispatch[cmdkey].apply(null, cmd);
} else {
// unknown command, quit and hope the restarted version is better
throw(["fatal", "unknown_command", "unknown command '" + cmdkey + "'"]);
}
} catch(e) {
handleError(e);
}
};
};
// Seal all the globals to prevent modification.
seal(Couch, true);
seal(JSON, true);
seal(Mime, true);
seal(Render, true);
seal(Filter, true);
seal(Views, true);
seal(isArray, true);
seal(log, true);
Loop();