You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by jc...@apache.org on 2010/01/26 01:12:00 UTC

svn commit: r903023 - in /couchdb/trunk/share: Makefile.am server/json2.js server/util.js www/script/json2.js www/script/test/show_documents.js www/script/test/update_documents.js www/script/test/view_errors.js

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.node.@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"},



Re: svn commit: r903023 - in /couchdb/trunk/share: Makefile.am server/json2.js server/util.js www/script/json2.js www/script/test/show_documents.js www/script/test/update_documents.js www/script/test/view_errors.js

Posted by Chris Anderson <jc...@apache.org>.
On Mon, Jan 25, 2010 at 8:04 PM, Jan Lehnardt <ja...@apache.org> wrote:
> Hey Chris,
>
> great work, thanks. Can you update http://wiki.apache.org/couchdb/Breaking_changes? :)
>

I wouldn't mind. But with that old wiki it'll take me 15 minutes to
figure out what username I'm shooting for.

... signing up for a new account:

http://wiki.apache.org/couchdb/FrontPage?action=newaccount

gives a 500 error. try again, and

OK I seem to have fixed it. Thanks for the prodding. The wiki wasn't
that bad but it could be more fun.

http://wiki.apache.org/couchdb/Breaking_changes

Chris


> Cheers
> Jan
> --
>
> On 25 Jan 2010, at 16:12, jchris@apache.org 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.node.@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"},
>>
>>
>
>



-- 
Chris Anderson
http://jchrisa.net
http://couch.io

Re: svn commit: r903023 - in /couchdb/trunk/share: Makefile.am server/json2.js server/util.js www/script/json2.js www/script/test/show_documents.js www/script/test/update_documents.js www/script/test/view_errors.js

Posted by Jan Lehnardt <ja...@apache.org>.
Hey Chris,

great work, thanks. Can you update http://wiki.apache.org/couchdb/Breaking_changes? :)

Cheers
Jan
--

On 25 Jan 2010, at 16:12, jchris@apache.org 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.node.@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"},
> 
>