You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@couchdb.apache.org by Cliff Stanford <cl...@may.be> on 2010/02/09 10:43:34 UTC

Use of json2.js in HEAD

I'm a little confused about the JSON object and the toJSON() function
in shows and lists.

In 0.10 I could have a show which did this:

function(doc, req)
{
   return { body : JSON.stringify(doc, null, 2) }
}

and get a nicely formatted output.  In HEAD, I get:

{"error":"render_error","reason":"function raised error: (new 
ReferenceError(\"JSON is not defined\", \"\", 4)) \nstacktrace: ([object 
Object],[object Object])@:4\napply([object Object],[object 
Array])@:0\nrunShow(function (doc, req) {var d = new Array(1, 2, 3, 
4);return {body:JSON.stringify(doc['null'], 2)};},[object 
Object],[object 
Array])@/usr/local/share/couchdb/server/main.js:882\n(function (doc, 
req) {var d = new Array(1, 2, 3, 4);return 
{body:JSON.stringify(doc['null'], 2)};},[object Object],[object 
Array])@/usr/local/share/couchdb/server/main.js:985\napply(null,[object 
Array])@:0\n(\"_design/main\",[object Array],[object 
Array])@/usr/local/share/couchdb/server/main.js:1343\napply(null,[object 
Array])@:0\n()@/usr/local/share/couchdb/server/main.js:1385\n@/usr/local/share/couchdb/server/main.js:1396\n"}

In HEAD, if I replace the JSON.stringify() with toJSON(doc), it mostly 
gives me an unformatted version of the document.

Strings, numbers, arrays and objects seem to work OK with toJSON() however:

function (doc, req)
{
   var d = new Date();
   return { body : toJSON(d) }
}

returns {}

So it seems that the JSON object has disappeared and toJSON() is broken 
for dates.

Or am I misunderstanding what should happen?

Regards,
Cliff.

-- 
Cliff Stanford
Might Limited                           +44 845 0045 666 (Office)
Suite 67, Dorset House                  +44 7973 616 666 (Mobile)
Duke Street, Chelmsford, CM1 1TB


Re: Use of json2.js in HEAD

Posted by Cliff Stanford <cl...@may.be>.
Chris Anderson wrote:

> As far as getting the JSON object into the sandbox for show and list,
> I've got nothing against that. Tickets / patches are welcome.

I've posted a ticket for it but, as I really don't understand the inner 
workings yet, I just hope it makes some sense.

Cliff.
-- 
Cliff Stanford
Might Limited                           +44 845 0045 666 (Office)
Suite 67, Dorset House                  +44 7973 616 666 (Mobile)
Duke Street, Chelmsford, CM1 1TB


Re: Use of json2.js in HEAD

Posted by Brian Candler <B....@pobox.com>.
On Tue, Feb 09, 2010 at 09:01:06AM -0800, Chris Anderson wrote:
> On Tue, Feb 9, 2010 at 3:10 AM, Brian Candler <B....@pobox.com> wrote:
> > FWIW, I get the same with 0.10.1 so it doesn't appear to be a regression.
> > Both current and 0.10.1 were built under Ubuntu Hardy with spidermonkey
> > 1.8.1.18
> 
> On thing that could be impacting this: json2.js prefers to drop back
> to a native JSON serializer if one is available. This means
> differences in spidermonkey version could conceivably give different
> date formats.
> 
> For what it's worth, this is what I'm seeing when serializing date
> objects on my end:
> 
> "2010-02-09T06:26:44.355Z"

Ah, there appears to be a difference between new Date(n) and Date().

Here are the results again, this time built on a newer machine (Ubuntu
Karmic):

$ curl -d'{"map":"function(doc) { emit(new Date(0),null);}"}' -X POST http://127.0.0.1:5984/briantest/_temp_view
{"total_rows":1,"offset":0,"rows":[
{"id":"foo","key":"1970-01-01T00:00:00.000Z","value":null}
]}
$ curl -d'{"map":"function(doc) { emit(Date(),null);}"}' -X POST http://127.0.0.1:5984/briantest/_temp_view
{"total_rows":1,"offset":0,"rows":[
{"id":"foo","key":"Tue Feb 09 2010 18:26:08 GMT+0000 (BST)","value":null}
]}
$ curl -d'{"map":"function(doc) { emit(toJSON(Date()),null);}"}' -X POST http://127.0.0.1:5984/briantest/_temp_view
{"total_rows":1,"offset":0,"rows":[
{"id":"foo","key":"\"Tue Feb 09 2010 18:27:05 GMT+0000 (BST)\"","value":null}
]}

Is it defined that Date() always returns a string, not a Date object??

Built as follows:

$ cat build-local.sh
PREFIX=/v/build/couchdb
./bootstrap &&
LD_RUN_PATH=/usr/lib/xulrunner-1.9.1.7 ./configure --prefix=$PREFIX \
  --with-js-lib=/usr/lib/xulrunner-1.9.1.7 \
  --with-js-include=/usr/lib/xulrunner-devel-1.9.1.7/include &&
LD_RUN_PATH=/usr/lib/xulrunner-1.9.1.7 make &&
sudo rm -rf $PREFIX/couchdb/erlang/lib/couch-* &&
sudo make install &&
grep chown README | sed -e "s#/usr/local#$PREFIX#g" | sudo sh
grep chmod README | sed -e "s#/usr/local#$PREFIX#g" -e 's#0770#0775#g' |
sudo sh
sudo $PREFIX/etc/init.d/couchdb restart

$ curl http://127.0.0.1:5984
{"couchdb":"Welcome","version":"0.11.0bcc31819f-git"}

Regards,

Brian.

Re: Use of json2.js in HEAD

Posted by Chris Anderson <jc...@apache.org>.
On Tue, Feb 9, 2010 at 3:10 AM, Brian Candler <B....@pobox.com> wrote:
> FWIW, I get the same with 0.10.1 so it doesn't appear to be a regression.
> Both current and 0.10.1 were built under Ubuntu Hardy with spidermonkey
> 1.8.1.18

On thing that could be impacting this: json2.js prefers to drop back
to a native JSON serializer if one is available. This means
differences in spidermonkey version could conceivably give different
date formats.

For what it's worth, this is what I'm seeing when serializing date
objects on my end:

"2010-02-09T06:26:44.355Z"

The map fun I used to do this looks like:

function(doc) {
if (doc.created_at)
  emit(new Date(doc.created_at), null);
}

In this case doc.created_at looked just like the final string (but it
was serialized in FF, not the view server.)

I'm running a fairly old spidermonkey.

$ js --version
JavaScript-C 1.8.0 pre-release 1 2007-10-03

As far as getting the JSON object into the sandbox for show and list,
I've got nothing against that. Tickets / patches are welcome.

Chris

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

Re: Use of json2.js in HEAD

Posted by Brian Candler <B....@pobox.com>.
FWIW, I get the same with 0.10.1 so it doesn't appear to be a regression. 
Both current and 0.10.1 were built under Ubuntu Hardy with spidermonkey
1.8.1.18

$ curl http://127.0.0.1:5984
{"couchdb":"Welcome","version":"0.10.1"}
$ curl -X PUT http://127.0.0.1:5984/briantest
{"ok":true}
$ curl -d '{}' -X PUT http://127.0.0.1:5984/briantest/foo
{"ok":true,"id":"foo","rev":"1-967a00dff5e02add41819138abb3284d"}
$ curl -d '{"map":"function(doc) {}"}' -X POST http://127.0.0.1:5984/briantest/_temp_view
{"total_rows":0,"offset":0,"rows":[]}
$ curl -d '{"map":"function(doc) {emit(Date(0),null);}"}' -X POST http://127.0.0.1:5984/briantest/_temp_view
{"total_rows":1,"offset":0,"rows":[
{"id":"foo","key":"Tue Feb 09 2010 11:01:31 GMT+0000 (BST)","value":null}
]}

$ curl -d '{"map":"function(doc) {emit(JSON.stringify([]),null);}"}' -X POST http://127.0.0.1:5984/briantest/_temp_view
{"total_rows":0,"offset":0,"rows":[]}

[Tue, 09 Feb 2010 11:08:16 GMT] [info] [<0.130.0>] OS Process :: function raised exception (ReferenceError: JSON is not defined) with doc._id foo

Re: Use of json2.js in HEAD

Posted by Brian Candler <B....@pobox.com>.
On Tue, Feb 09, 2010 at 10:43:34AM +0100, Cliff Stanford wrote:
> So it seems that the JSON object has disappeared and toJSON() is
> broken for dates.
> 
> Or am I misunderstanding what should happen?

I think what you're seeing is odd too.

I notice that:

(1) Dates serialize as their useless ASCII string version, not ISO.

$ curl -X POST -d '{"map":"function(doc) { emit([Date(0)],null); }"}' http://127.0.0.1:5984/briantest/_temp_view
{"total_rows":3,"offset":0,"rows":[
{"id":"0fc1b193e778a8c0657591618c15e3f2","key":["Tue Feb 09 2010 10:10:12 GMT+0000 (BST)"],"value":null},
{"id":"0fc1b193e778a8c0657591618c15f5aa","key":["Tue Feb 09 2010 10:10:12 GMT+0000 (BST)"],"value":null},
{"id":"foo","key":["Tue Feb 09 2010 10:10:12 GMT+0000 (BST)"],"value":null}
]}

I don't have an older build to compare against, but if you used to get ISO
format dates (and there is clearly code in main.js which could generate
them) then I'd say this is a regression, and needs a test case.


(2) xxx.toJSON() isn't available in map functions

$ curl -X POST -d '{"map":"function(doc) { emit([].toJSON(),null); }"}' http://127.0.0.1:5984/briantest/_temp_view
{"total_rows":0,"offset":0,"rows":[]}

Furthermore, no error is recorded in couch.log if you try to do this.
However, toJSON(xxx) does work.

$ curl -X POST -d '{"map":"function(doc) { emit(toJSON([]),null); }"}' http://127.0.0.1:5984/briantest/_temp_view
{"total_rows":3,"offset":0,"rows":[
{"id":"0fc1b193e778a8c0657591618c15e3f2","key":"[]","value":null},
{"id":"0fc1b193e778a8c0657591618c15f5aa","key":"[]","value":null},
{"id":"foo","key":"[]","value":null}
]}


(3) JSON isn't available in map functions

$ curl -X POST -d '{"map":"function(doc) { emit(JSON.stringify([]),null); }"}' http://127.0.0.1:5984/briantest/_temp_view
{"total_rows":0,"offset":0,"rows":[]}

But in this case an error *is* recorded:

[Tue, 09 Feb 2010 10:13:04 GMT] [info] [<0.457.0>] OS Process #Port<0.1895> Log :: function raised exception (new ReferenceError("JSON is not defined", "")) with doc._id 0fc1b193e778a8c0657591618c15f5aa

It appears to be sandboxed out. With a bit of hacking to main.js I was able
to add JSON to the sandbox.

Regards,

Brian.