Hey Chris, great work, thanks. Can you update http://wiki.apache.org/couchdb/Breaking_changes? :)
Cheers Jan -- On 25 Jan 2010, at 16:12, [email protected] wrote: > Author: jchris > Date: Tue Jan 26 00:11:59 2010 > New Revision: 903023 > > URL: http://svn.apache.org/viewvc?rev=903023&view=rev > Log: > Replace the old JavaScript query server JSON library with json2.js > > This change makes us interoperate better with other JSON implementations. It > also means we can use the native JSON handlers in JavaScript runtimes that > support them. Should be faster right away on new Spidermonkeys. > > There are some potential breaking changes for apps that depend on Couch > blowing up on 'undefined'. json2.js serialized undefined as 'null' instead of > crashing. > > This change will also affect people using E4X, as you can't just return an > XML object and have it serialized to a string for you. Calling .toXMLString() > on these is all you need to do. > > Added: > couchdb/trunk/share/server/json2.js > - copied, changed from r902422, couchdb/trunk/share/www/script/json2.js > Modified: > couchdb/trunk/share/Makefile.am > couchdb/trunk/share/server/util.js > couchdb/trunk/share/www/script/json2.js > couchdb/trunk/share/www/script/test/show_documents.js > couchdb/trunk/share/www/script/test/update_documents.js > couchdb/trunk/share/www/script/test/view_errors.js > > Modified: couchdb/trunk/share/Makefile.am > URL: > http://svn.apache.org/viewvc/couchdb/trunk/share/Makefile.am?rev=903023&r1=903022&r2=903023&view=diff > ============================================================================== > --- couchdb/trunk/share/Makefile.am (original) > +++ couchdb/trunk/share/Makefile.am Tue Jan 26 00:11:59 2010 > @@ -13,6 +13,7 @@ > JS_FILE = server/main.js > > JS_FILE_COMPONENTS = \ > + server/json2.js \ > server/filter.js \ > server/mimeparse.js \ > server/render.js \ > > Copied: couchdb/trunk/share/server/json2.js (from r902422, > couchdb/trunk/share/www/script/json2.js) > URL: > http://svn.apache.org/viewvc/couchdb/trunk/share/server/json2.js?p2=couchdb/trunk/share/server/json2.js&p1=couchdb/trunk/share/www/script/json2.js&r1=902422&r2=903023&rev=903023&view=diff > ============================================================================== > --- couchdb/trunk/share/www/script/json2.js [utf-8] (original) > +++ couchdb/trunk/share/server/json2.js [utf-8] Tue Jan 26 00:11:59 2010 > @@ -1,6 +1,6 @@ > /* > http://www.JSON.org/json2.js > - 2009-08-17 > + 2009-09-29 > > Public Domain. > > @@ -8,6 +8,14 @@ > > See http://www.JSON.org/js.html > > + > + This code should be minified before deployment. > + See http://javascript.crockford.com/jsmin.html > + > + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU > DO > + NOT CONTROL. > + > + > This file creates a global JSON object containing two methods: stringify > and parse. > > @@ -136,15 +144,9 @@ > > This is a reference implementation. You are free to copy, modify, or > redistribute. > - > - This code should be minified before deployment. > - See http://javascript.crockford.com/jsmin.html > - > - USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU > DO > - NOT CONTROL. > */ > > -/*jslint evil: true */ > +/*jslint evil: true, strict: false */ > > /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, > call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, > @@ -153,7 +155,6 @@ > test, toJSON, toString, valueOf > */ > > -"use strict"; > > // Create a JSON object only if one does not already exist. We create the > // methods in a closure to avoid creating global variables. > > Modified: couchdb/trunk/share/server/util.js > URL: > http://svn.apache.org/viewvc/couchdb/trunk/share/server/util.js?rev=903023&r1=903022&r2=903023&view=diff > ============================================================================== > --- couchdb/trunk/share/server/util.js (original) > +++ couchdb/trunk/share/server/util.js Tue Jan 26 00:11:59 2010 > @@ -13,14 +13,7 @@ > var Couch = { > // moving this away from global so we can move to json2.js later > toJSON : function (val) { > - if (typeof(val) == "undefined") { > - throw "Cannot encode 'undefined' value as JSON"; > - } > - if (typeof(val) == "xml") { // E4X support > - val = val.toXMLString(); > - } > - if (val === null) { return "null"; } > - return (Couch.toJSON.dispatcher[val.constructor.name])(val); > + return JSON.stringify(val); > }, > compileFunction : function(source) { > if (!source) throw(["error","not_found","missing function"]); > @@ -47,55 +40,6 @@ > } > } > > -Couch.toJSON.subs = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', > - '\r': '\\r', '"' : '\\"', '\\': '\\\\'}; > -Couch.toJSON.dispatcher = { > - "Array": function(v) { > - var buf = []; > - for (var i = 0; i < v.length; i++) { > - buf.push(Couch.toJSON(v[i])); > - } > - return "[" + buf.join(",") + "]"; > - }, > - "Boolean": function(v) { > - return v.toString(); > - }, > - "Date": function(v) { > - var f = function(n) { return n < 10 ? '0' + n : n }; > - return '"' + v.getUTCFullYear() + '-' + > - f(v.getUTCMonth() + 1) + '-' + > - f(v.getUTCDate()) + 'T' + > - f(v.getUTCHours()) + ':' + > - f(v.getUTCMinutes()) + ':' + > - f(v.getUTCSeconds()) + 'Z"'; > - }, > - "Number": function(v) { > - return isFinite(v) ? v.toString() : "null"; > - }, > - "Object": function(v) { > - //if (v === null) return "null"; > - var buf = []; > - for (var k in v) { > - if (!v.hasOwnProperty(k) || typeof(k) !== "string" || v[k] === > undefined) { > - continue; > - } > - buf.push(Couch.toJSON(k) + ": " + Couch.toJSON(v[k])); > - } > - return "{" + buf.join(",") + "}"; > - }, > - "String": function(v) { > - if (/["\\\x00-\x1f]/.test(v)) { > - v = v.replace(/([\x00-\x1f\\"])/g, function(a, b) { > - var c = Couch.toJSON.subs[b]; > - if (c) return c; > - c = b.charCodeAt(); > - return '\\u00' + Math.floor(c / 16).toString(16) + (c % > 16).toString(16); > - }); > - } > - return '"' + v + '"'; > - } > -}; > - > // prints the object as JSON, and rescues and logs any toJSON() related errors > function respond(obj) { > try { > @@ -107,10 +51,8 @@ > }; > > function log(message) { > - // return; // idea: query_server_config option for log level > - if (typeof message == "undefined") { > - message = "Error: attempting to log message of 'undefined'."; > - } else if (typeof message != "string") { > + // idea: query_server_config option for log level > + if (typeof message != "string") { > message = Couch.toJSON(message); > } > respond(["log", message]); > > Modified: couchdb/trunk/share/www/script/json2.js > URL: > http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/json2.js?rev=903023&r1=903022&r2=903023&view=diff > ============================================================================== > --- couchdb/trunk/share/www/script/json2.js [utf-8] (original) > +++ couchdb/trunk/share/www/script/json2.js [utf-8] Tue Jan 26 00:11:59 2010 > @@ -1,6 +1,6 @@ > /* > http://www.JSON.org/json2.js > - 2009-08-17 > + 2009-09-29 > > Public Domain. > > @@ -8,6 +8,14 @@ > > See http://www.JSON.org/js.html > > + > + This code should be minified before deployment. > + See http://javascript.crockford.com/jsmin.html > + > + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU > DO > + NOT CONTROL. > + > + > This file creates a global JSON object containing two methods: stringify > and parse. > > @@ -136,15 +144,9 @@ > > This is a reference implementation. You are free to copy, modify, or > redistribute. > - > - This code should be minified before deployment. > - See http://javascript.crockford.com/jsmin.html > - > - USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU > DO > - NOT CONTROL. > */ > > -/*jslint evil: true */ > +/*jslint evil: true, strict: false */ > > /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, > call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, > @@ -153,7 +155,6 @@ > test, toJSON, toString, valueOf > */ > > -"use strict"; > > // Create a JSON object only if one does not already exist. We create the > // methods in a closure to avoid creating global variables. > > Modified: couchdb/trunk/share/www/script/test/show_documents.js > URL: > http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/show_documents.js?rev=903023&r1=903022&r2=903023&view=diff > ============================================================================== > --- couchdb/trunk/share/www/script/test/show_documents.js (original) > +++ couchdb/trunk/share/www/script/test/show_documents.js Tue Jan 26 00:11:59 > 2010 > @@ -61,7 +61,7 @@ > "headers" : { > "Content-Type" : "application/xml" > }, > - "body" : new XML('<xml><node foo="bar"/></xml>') > + "body" : new XML('<xml><node foo="bar"/></xml>').toXMLString() > } > }), > "no-set-etag" : stringFun(function(doc, req) { > @@ -114,7 +114,8 @@ > // E4X outside of a string. Outside of tests you > // can just use E4X literals. > eval('xml.no...@foo = doc.word'); > - return xml; > + log('xml: '+xml.toSource()); > + return xml.toXMLString(); > }); > > provides("foo", function() { > > Modified: couchdb/trunk/share/www/script/test/update_documents.js > URL: > http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/update_documents.js?rev=903023&r1=903022&r2=903023&view=diff > ============================================================================== > --- couchdb/trunk/share/www/script/test/update_documents.js (original) > +++ couchdb/trunk/share/www/script/test/update_documents.js Tue Jan 26 > 00:11:59 2010 > @@ -68,7 +68,7 @@ > "headers" : { > "Content-Type" : "application/xml" > }, > - "body" : xml > + "body" : xml.toXMLString() > }; > > return [doc, resp]; > > Modified: couchdb/trunk/share/www/script/test/view_errors.js > URL: > http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/view_errors.js?rev=903023&r1=903022&r2=903023&view=diff > ============================================================================== > --- couchdb/trunk/share/www/script/test/view_errors.js (original) > +++ couchdb/trunk/share/www/script/test/view_errors.js Tue Jan 26 00:11:59 > 2010 > @@ -16,8 +16,6 @@ > db.createDb(); > if (debug) debugger; > > - > - > run_on_modified_server( > [{section: "couchdb", > key: "os_process_timeout", > @@ -26,12 +24,13 @@ > var doc = {integer: 1, string: "1", array: [1, 2, 3]}; > T(db.save(doc).ok); > > - // emitting a key value that is undefined should result in that row not > - // being included in the view results > + // emitting a key value that is undefined should result in that row > + // being included in the view results as null > var results = db.query(function(doc) { > emit(doc.undef, null); > }); > - T(results.total_rows == 0); > + T(results.total_rows == 1); > + T(results.rows[0].key == null); > > // if a view function throws an exception, its results are not included > in > // the view index, but the view does not itself raise an error > @@ -41,13 +40,13 @@ > T(results.total_rows == 0); > > // if a view function includes an undefined value in the emitted key or > - // value, an error is logged and the result is not included in the view > - // index, and the view itself does not raise an error > + // value, it is treated as null > var results = db.query(function(doc) { > emit([doc._id, doc.undef], null); > }); > - T(results.total_rows == 0); > - > + T(results.total_rows == 1); > + T(results.rows[0].key[1] == null); > + > // querying a view with invalid params should give a resonable error > message > var xhr = CouchDB.request("POST", > "/test_suite_db/_temp_view?startkey=foo", { > headers: {"Content-Type": "application/json"}, > >
