[Checkins] SVN: Sandbox/J1m/dozodb/s Updated tests to test both the client and server code.

Jim Fulton jim at zope.com
Tue Jan 11 19:03:49 EST 2011


Log message for revision 119518:
  Updated tests to test both the client and server code.
  
  Added a separate webob module with a webob-based helper function that
  can be used by webob-based applications (like bobo), and a webob-based
  wsgi application.
  

Changed:
  U   Sandbox/J1m/dozodb/setup.py
  U   Sandbox/J1m/dozodb/src/zc/dozodb/__init__.py
  U   Sandbox/J1m/dozodb/src/zc/dozodb/dozodb.js
  D   Sandbox/J1m/dozodb/src/zc/dozodb/dozodb.js.test
  A   Sandbox/J1m/dozodb/src/zc/dozodb/dozodb.test
  U   Sandbox/J1m/dozodb/src/zc/dozodb/test_setup.js
  U   Sandbox/J1m/dozodb/src/zc/dozodb/tests.py
  A   Sandbox/J1m/dozodb/src/zc/dozodb/webob.py

-=-
Modified: Sandbox/J1m/dozodb/setup.py
===================================================================
--- Sandbox/J1m/dozodb/setup.py	2011-01-11 23:54:00 UTC (rev 119517)
+++ Sandbox/J1m/dozodb/setup.py	2011-01-12 00:03:48 UTC (rev 119518)
@@ -14,7 +14,9 @@
 name, version = 'zc.dozodb', '0'
 
 install_requires = ['setuptools', 'ZODB3']
-extras_require = dict(test=['zope.testing', 'python-spidermonkey', 'manuel'])
+extras_require = dict(
+    test=['zope.testing', 'python-spidermonkey', 'manuel', 'webtest'],
+    )
 
 entry_points = """
 """

Modified: Sandbox/J1m/dozodb/src/zc/dozodb/__init__.py
===================================================================
--- Sandbox/J1m/dozodb/src/zc/dozodb/__init__.py	2011-01-11 23:54:00 UTC (rev 119517)
+++ Sandbox/J1m/dozodb/src/zc/dozodb/__init__.py	2011-01-12 00:03:48 UTC (rev 119518)
@@ -1,3 +1,16 @@
+##############################################################################
+#
+# Copyright (c) 2011 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
 try:
     import simplejson as json
 except ImportError:
@@ -44,8 +57,8 @@
         item=_serialize(connection.get(_p_oid.decode('hex')))
         )
 
-def fetched(items):
-    return _result(items=[_serialize(item) for item in items])
+def fetched(size, items):
+    return _result(items=[_serialize(item) for item in items], size=size)
 
 otypes = list, dict
 def save(app, json_string):
@@ -129,18 +142,3 @@
                             ))
 
     return json.dumps(dict(updates=updates))
-
-
-def webob(app, request):
-    import time; time.sleep(1)
-    try:
-        if request.method == 'GET':
-            if '_p_oid' in request.str_GET:
-                return load(app.connection, request.str_GET.get('_p_oid'))
-            return fetched(app.query())
-
-        assert(request.method == 'POST')
-        assert request.content_type.startswith('application/json')
-        return save(app, request.body)
-    except Exception, e:
-        return json.dumps(dict(error=unicode(e)))

Modified: Sandbox/J1m/dozodb/src/zc/dozodb/dozodb.js
===================================================================
--- Sandbox/J1m/dozodb/src/zc/dozodb/dozodb.js	2011-01-11 23:54:00 UTC (rev 119517)
+++ Sandbox/J1m/dozodb/src/zc/dozodb/dozodb.js	2011-01-12 00:03:48 UTC (rev 119518)
@@ -1,3 +1,17 @@
+/*
+
+ Copyright (c) 2011 Zope Foundation and Contributors.
+ All Rights Reserved.
+
+ This software is subject to the provisions of the Zope Public License,
+ Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+ WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+ FOR A PARTICULAR PURPOSE.
+
+*/
+
 dojo.provide('zc.dozodb');
 
 if (zc === undefined)

Deleted: Sandbox/J1m/dozodb/src/zc/dozodb/dozodb.js.test
===================================================================
--- Sandbox/J1m/dozodb/src/zc/dozodb/dozodb.js.test	2011-01-11 23:54:00 UTC (rev 119517)
+++ Sandbox/J1m/dozodb/src/zc/dozodb/dozodb.js.test	2011-01-12 00:03:48 UTC (rev 119518)
@@ -1,151 +0,0 @@
-dozodb -- ZODB-based dojo storage implementation
-================================================
-
-This files tests the javascript portion of the dozodb implementation.
-
-To use, you need to require:
-
-    js> dojo.require('zc.dozodb');
-    [object Object]
-
-Create a store:
-
-    js> var store = zc.dozodb.Store({url: '/store'});
-
-    py> import sys
-    py> sys.platform
-    'linux2'
-
-where the url option names a dozodb web resource.  dozodb web
-resources support loading and saving data via GET and POST ajax
-requests. For these tests, we've stubbed out dojo's xhr interface to
-provide implementations that save xhr callbacks and print other data
-passed to xhr.
-
-In case anyone's reading this, I'll walk through a typical usage
-scenario, before I get to the boring stuff. :)
-
-Usage typically starts with a fetch call.  This is what a dojo tree or
-grid will do to get initial data.  The fetch call can pass a query and
-some callbacks.  It's up to the server to interpret the query to
-decide which data to return.
-
-    js> var request = store.fetch({
-    ...     query: {a: 1, b: 2},
-    ...     onBegin: function (n, r) {
-    ...         assert(r === request);
-    ...         console.log('onBegin '+n);
-    ...     },
-    ...     onComplete: function (items, r) {
-    ...         assert(r === request);
-    ...         pprint('onComplete items', items);
-    ...     }
-    ... });
-    xhr GET: {
-        content: {
-          a: 1,
-          b: 2 },
-        handleAs: "json",
-        preventCache: true,
-        url: "/store" }
-
-So, fetch makes an xhr get with the URL we have it, and the parameters
-passed to it.
-
-There are a number of handlers we can pass to fetch.  See the dojo
-data api.  The onBegin handler exists mainly to let the client the
-total number of items that match the query.  It can be different from
-the total number of items returned if batching parameters were
-provided.
-
-The onComplete handler behaves differently, depending on whether the
-onItem handler was used.  The onItem handler recieves each item
-individually. If it isn't used, then the onComplete handler is passed
-all of the items.
-
-We'll now emulate the server by calling the xhr load callback.
-
-    js> last_xhr.load({
-    ...     items: [{_p_oid: '1', _p_serial: '1',
-    ...              name: 'root', children: []}],
-    ...     size: 1
-    ... })
-    onBegin 1
-    onComplete items: [
-        { _p_changed: false,
-          _p_id: "1",
-          _p_oid: "1",
-          _p_serial: "1",
-          children: [],
-          name: "root" } ]
-
-The items we get have spplication-level attributes as well as _p_
-attributes used internally bu dozodb. In practice, the object ids and
-serials are 16-digit hex numbers, but the javascript implementation
-doesn't really care what they are.
-
-Now we'll do another fetch, but this time, pass an onItem handler:
-
-    js> var request = store.fetch({
-    ...     query: {a: 1, b: 2},
-    ...     onBegin: function (n, r) {
-    ...         assert(r === request);
-    ...         console.log('onBegin '+n);
-    ...     },
-    ...     onItem: function (item, r) {
-    ...         assert(r === request);
-    ...         pprint('onItem item', item);
-    ...     },
-    ...     onComplete: function (items, r) {
-    ...         assert(r === request);
-    ...         pprint('onComplete items', items);
-    ...     }
-    ... });
-    xhr GET: {
-        content: {
-          a: 1,
-          b: 2 },
-        handleAs: "json",
-        preventCache: true,
-        url: "/store" }
-
-    js> last_xhr.load({
-    ...     items: [
-    ...         {_p_oid: '2', _p_serial: '1', name: 'foo', children: []},
-    ...         {_p_oid: '3', _p_serial: '1', name: 'bar',
-    ...          children: [ {_p_oid: '4'}, {_p_oid: '5'}]
-    ...         }],
-    ...     size: 1
-    ... })
-    onBegin 1
-    onItem item: {
-        _p_changed: false,
-        _p_id: "2",
-        _p_oid: "2",
-        _p_serial: "1",
-        children: [],
-        name: "foo" }
-    onItem item: {
-        _p_changed: false,
-        _p_id: "3",
-        _p_oid: "3",
-        _p_serial: "1",
-        children: [
-          { _p_id: "4",
-            _p_oid: "4" },
-          { _p_id: "5",
-            _p_oid: "5" } ],
-        name: "bar" }
-    onComplete items: null
-
-There are a couple of interesting things to note about this:
-
-1. onItem is called for each item and onComplete is passed null,
-   rather than a list of items.
-
-2. The second item had children and the chelidren didn't have any
-   state.  The items returned directly from fetch always have
-   state. They are distinguished by having _p_changed that's false,
-   meaning they are non-ghost objects.  They also have _p_serial,
-   which is used when saving to detect conflicts.
-

Copied: Sandbox/J1m/dozodb/src/zc/dozodb/dozodb.test (from rev 119483, Sandbox/J1m/dozodb/src/zc/dozodb/dozodb.js.test)
===================================================================
--- Sandbox/J1m/dozodb/src/zc/dozodb/dozodb.test	                        (rev 0)
+++ Sandbox/J1m/dozodb/src/zc/dozodb/dozodb.test	2011-01-12 00:03:48 UTC (rev 119518)
@@ -0,0 +1,255 @@
+dozodb -- ZODB-based dojo storage implementation
+================================================
+
+To use the storage from dojo, you need to require:
+
+    js> dojo.require('zc.dozodb');
+    [object Object]
+
+Create a store:
+
+    js> var store = zc.dozodb.Store({url: '/store'});
+
+where the url option names a dozodb web resource.  dozodb web
+resources support loading and saving data via GET and POST ajax
+requests. For these tests, we've stubbed out dojo's xhr interface to
+provide implementations that save xhr callbacks and print other data
+passed to xhr.
+
+In case anyone's reading this, I'll walk through a typical usage
+scenario, before I get to the boring stuff. :)
+
+Usage typically starts with a fetch call.  This is what a dojo tree or
+grid will do to get initial data.  The fetch call can pass a query and
+some callbacks.  It's up to the server to interpret the query to
+decide which data to return.
+
+    js> var request = store.fetch({
+    ...     query: {name: 'x'},
+    ...     onBegin: function (n, r) {
+    ...         assert(r === request);
+    ...         console.log('onBegin '+n);
+    ...     },
+    ...     onComplete: function (items, r) {
+    ...         assert(r === request);
+    ...         pprint('onComplete items', items);
+    ...     }
+    ... });
+    xhr GET: {
+        content: "name=x",
+        error: ,
+        handleAs: "json",
+        load: ,
+        preventCache: true,
+        url: "/store?name=x" }
+
+So, fetch makes an xhr get with the URL we have it, and the parameters
+passed to it.
+
+For the server side, first, we'll set up our database:
+
+    py> import ZODB
+    py> db = ZODB.DB(None)
+
+Dozodb provides a Persistent class, meant to be used as a base
+class, but it can be used directly.
+
+    py> import zc.dozodb
+    py> with db.transaction() as conn:
+    ...     conn.root.x = zc.dozodb.Persistent()
+    ...     conn.root.x.name = 'x'
+
+Now, we need to make the data available to the web.  dozodb has a
+number of apis to facilitate this, one of which works with webob.  To
+use the webob interface, we need to define an application-handler
+factory.  An application-handler factory takes a database connection
+and a request and returns a handler object.  A handler object has the
+fillowing attributes:
+
+connection
+   The database connection passed to the handler
+
+query()
+   Get query results for the request.
+
+   Return the size of the query result and a list of results. Note
+   that the length of the results might be less than the size if batch
+   parameters are included in the request.
+
+factory(data)
+   Return an object with a _dozodb_new method that can be called
+   without arguments to create a new object.  The new object need not
+   be initialized, as it will have _dozodb_set_client_state called on
+   it it set its state.
+
+   Typically the object returned by the handler's factory method will
+   be a subclass of zc.dozodb.Persistent.
+
+   The method is optional, but if not provided, it won't be possible
+   to create new objects.
+
+insert(items)
+   Insert some newly created items without parentage into some
+   application-defined container.  This would typically be used by
+   dojo grids when new rows are inserted.
+
+   The insert method is optional and, if not provided, it won't be
+   possible to create new items without some sort of parentage.
+
+
+Let's start with a minimal handler class that just deals with querying.
+
+    py> class App:
+    ...
+    ...     def __init__(self, connection, request):
+    ...         self.connection = connection
+    ...         self.request = request
+    ...
+    ...     def query(self):
+    ...         name = self.request.str_GET.get('name')
+    ...         return 1, [self.connection.root()[name]]
+
+
+Now that we have our application handler, we can create a webob-based
+WSGI application:
+
+    py> import zc.dozodb.webob
+    py> dozodb_app = zc.dozodb.webob.Application(App, db)
+
+We pass an application handler and a database object. As each request
+comes in, a connection to the database will be created.
+
+Now, to make testing easier, we'll wrap our application object in a
+webtest test application:
+
+    py> import webtest
+    py> app = webtest.TestApp(dozodb_app)
+
+There are a number of javascript handlers we can pass to fetch.  See
+the dojo data api.  The onBegin handler exists mainly to let the
+client the total number of items that match the query.  It can be
+different from the total number of items returned if batching
+parameters were provided.
+
+The onComplete handler behaves differently, depending on whether the
+onItem handler was used.  The onItem handler recieves each item
+individually. If it isn't used, then the onComplete handler is passed
+all of the items.
+
+Now, we'll call our application the way our dojo storage would:
+
+    py> r = app.get(JS('last_xhr.url'))
+    py> r.status, r.content_type
+    ('200 OK', 'application/json')
+
+Now, we'll pass the resulting json data to the storage load handler,
+simulating the xhr response:
+
+    py> xhr_respond(r.body)
+    onBegin 1
+    onComplete items: [
+        { _p_changed: false,
+          _p_id: "0000000000000002",
+          _p_oid: "0000000000000002",
+          _p_serial: "038b8883c529a433",
+          name: "x" } ]
+
+
+The items we get have spplication-level attributes as well as _p_
+attributes used internally bu dozodb.
+
+Now we'll do another fetch, but this time, pass an onItem handler:
+
+    js> var request = store.fetch({
+    ...     query: {name: 'tasks', count: 2},
+    ...     onBegin: function (n, r) {
+    ...         assert(r === request);
+    ...         console.log('onBegin '+n);
+    ...     },
+    ...     onItem: function (item, r) {
+    ...         assert(r === request);
+    ...         pprint('onItem item', item);
+    ...     },
+    ...     onComplete: function (items, r) {
+    ...         assert(r === request);
+    ...         pprint('onComplete items', items);
+    ...     }
+    ... });
+    xhr GET: {
+        content: "name=tasks&count=2",
+        error: ,
+        handleAs: "json",
+        load: ,
+        preventCache: true,
+        url: "/store?name=tasks&count=2" }
+
+Let's add some tasks to our database and update our application
+handler to work with them:
+
+    py> class Task(zc.dozodb.Persistent):
+    ...     def __init__(self, title, subtasks=None):
+    ...         self.title = title
+    ...         self.subtasks = subtasks or []
+
+    py> with db.transaction() as conn:
+    ...     conn.root.tasks = [
+    ...        Task('task 1'),
+    ...        Task('task 2', [
+    ...                        Task('task 2.1'),
+    ...                        Task('task 2.2'),
+    ...                       ]),
+    ...        Task('task 3'),
+    ...        Task('task 4'),
+    ...        ]
+
+    py> def in_class(class_):
+    ...     return lambda f: setattr(class_, f.__name__, f)
+
+    py> @in_class(App)
+    ... def query(self):
+    ...     name = self.request.str_GET.get('name')
+    ...     result = self.connection.root()[name]
+    ...     if not isinstance(result, list):
+    ...         result = [result]
+    ...     size = len(result)
+    ...     if 'count' in self.request.str_GET:
+    ...         result = result[:int(self.request.str_GET.get('count'))]
+    ...
+    ...     return size, result
+
+Now, let's call our application:
+
+    py> xhr_respond(app.get(JS('last_xhr.url')).body)
+    onBegin 4
+    onItem item: {
+        _p_changed: false,
+        _p_id: "0000000000000009",
+        _p_oid: "0000000000000009",
+        _p_serial: "038b8883ce8ca033",
+        subtasks: [],
+        title: "task 1" }
+    onItem item: {
+        _p_changed: false,
+        _p_id: "000000000000000a",
+        _p_oid: "000000000000000a",
+        _p_serial: "038b8883ce8ca033",
+        subtasks: [
+          { _p_id: "000000000000000d",
+            _p_oid: "000000000000000d" },
+          { _p_id: "000000000000000e",
+            _p_oid: "000000000000000e" } ],
+        title: "task 2" }
+    onComplete items: null
+
+There are a couple of interesting things to note about this:
+
+1. onItem is called for each item and onComplete is passed null,
+   rather than a list of items.
+
+2. The second item had children and the children didn't have any
+   state.  The items returned directly from fetch always have
+   state. They are distinguished by having _p_changed that's false,
+   meaning they are non-ghost objects.  They also have _p_serial,
+   which is used when saving to detect conflicts.  But the sub-items
+   if the items returned don't have state.
+

Modified: Sandbox/J1m/dozodb/src/zc/dozodb/test_setup.js
===================================================================
--- Sandbox/J1m/dozodb/src/zc/dozodb/test_setup.js	2011-01-11 23:54:00 UTC (rev 119517)
+++ Sandbox/J1m/dozodb/src/zc/dozodb/test_setup.js	2011-01-12 00:03:48 UTC (rev 119518)
@@ -1,6 +1,17 @@
+/*
 
-var last_xhr;
+ Copyright (c) 2011 Zope Foundation and Contributors.
+ All Rights Reserved.
 
+ This software is subject to the provisions of the Zope Public License,
+ Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+ WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+ FOR A PARTICULAR PURPOSE.
+
+*/
+
 function pprint(pname, ob, indent) {
     var print = ! indent, out = [], i, name, names;
 
@@ -68,20 +79,29 @@
     return out;
 }
 
+var last_xhr;
+
+dojo.objectToQuery = function (ob) { // simple minded impl :)
+    var name, result = [];
+    for (name in ob) {
+        if (ob.hasOwnProperty(name)) {
+            result.push(name+'='+ob[name]);
+        }
+    }
+    return result.join('&');
+};
+
 dojo.xhr = function (method, args, hasBody) {
-    var i, name, nonfun={};
-    last_xhr = {};
-    for (name in args) {
-        if (args.hasOwnProperty(name)) {
-            if (typeof args[name] == 'function') {
-                last_xhr[name] = args[name];
-            }
-            else {
-                nonfun[name] = args[name];
-            }
+    last_xhr = args;
+    if (args.content) {
+        if (typeof args.content !== 'string') {
+            args.content = dojo.objectToQuery(args.content);
         }
+        if (method == 'GET') {
+            args.url += '?' + args.content;
+        }
     }
-    pprint('xhr '+method, nonfun);
+    pprint('xhr '+method, args);
     if (hasBody ? method !== 'POST' : method !== 'GET') {
         console.error('Bad hasBody: '+ hasBody);
     }
@@ -93,6 +113,10 @@
     return dojo.xhr("POST", args, true);
 };
 
+var xhr_respond = function(json) {
+    last_xhr.load(dojo.fromJson(json));
+};
+
 function assert(cond, message) {
     if (! cond) {
         console.error('Assertion Failed: '+message);

Modified: Sandbox/J1m/dozodb/src/zc/dozodb/tests.py
===================================================================
--- Sandbox/J1m/dozodb/src/zc/dozodb/tests.py	2011-01-11 23:54:00 UTC (rev 119517)
+++ Sandbox/J1m/dozodb/src/zc/dozodb/tests.py	2011-01-12 00:03:48 UTC (rev 119518)
@@ -1,10 +1,10 @@
 ##############################################################################
 #
-# Copyright (c) 2006 Zope Corporation and Contributors.
+# Copyright (c) 2011 Zope Foundation and Contributors.
 # All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
@@ -13,14 +13,17 @@
 ##############################################################################
 
 import doctest
+import manuel.capture
+import manuel.doctest
+import manuel.testing
 import os
 import re
 import spidermonkey
 import sys
+import time
 import unittest
-import manuel.capture
-import manuel.doctest
-import manuel.testing
+import zope.testing.module
+import zope.testing.setupstack
 
 baseUrl = None # Set by test runner.
 
@@ -66,24 +69,35 @@
         return r
 
 def setUp(test):
+    zope.testing.setupstack.setUpDirectory(test)
+    old_time = time.time
+    zope.testing.setupstack.register(test, setattr, time, 'time', old_time)
+    now = [1294777185.01]
+    def time_time():
+        now[0] += 0.1
+        return now[0]
+    time.time = time_time
 
+    zope.testing.module.setUp(test)
+    zope.testing.setupstack.register(test, zope.testing.module.tearDown, test)
+
     cx = run_time.new_context()
+    test.globs['JS'] = JS = cx.execute
     cx.add_global('line2pc', 0)
     cx.add_global('djConfig', dict(baseUrl=baseUrl))
 
     def load(name):
-        cx.execute(open(name).read(), name)
+        JS(open(name).read(), name)
 
     cx.add_global('load', load)
 
     load(baseUrl+'dojo.js.uncompressed.js')
-    cx.execute('console').log = lambda s: sys.stdout.write('%s\n' % (s, ))
-    cx.execute('console'
-               ).error = lambda s: sys.stdout.write('Error: %s\n' % (s, ))
+    JS('console').log = lambda s: sys.stdout.write('%s\n' % (s, ))
+    JS('console').error = lambda s: sys.stdout.write('Error: %s\n' % (s, ))
 
-    test.globs['JS'] = JS = cx.execute
 
     load(os.path.join(os.path.dirname(__file__), 'test_setup.js'))
+    test.globs['xhr_respond'] = JS('xhr_respond')
     JS('dojo.registerModulePath("zc.dozodb", "%s")' %
        os.path.join(os.path.dirname(__file__), 'dozodb')
        )
@@ -94,11 +108,6 @@
             manuel.doctest.Manuel(parser=DocTestJSParser()) +
             manuel.doctest.Manuel(parser=DocTestPyParser()) +
             manuel.capture.Manuel(),
-            'dozodb.js.test',
-            setUp=setUp),
-        # doctest.DocFileSuite(
-        #     'dozodb.js.test',
-        #     parser=DocTestParser(),
-        #     setUp=setUp,
-        #     ),
+            'dozodb.test',
+            setUp=setUp, tearDown=zope.testing.setupstack.tearDown),
         ))

Added: Sandbox/J1m/dozodb/src/zc/dozodb/webob.py
===================================================================
--- Sandbox/J1m/dozodb/src/zc/dozodb/webob.py	                        (rev 0)
+++ Sandbox/J1m/dozodb/src/zc/dozodb/webob.py	2011-01-12 00:03:48 UTC (rev 119518)
@@ -0,0 +1,54 @@
+##############################################################################
+#
+# Copyright (c) 2011 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+from __future__ import absolute_import
+
+try:
+    import simplejson as json
+except ImportError:
+    import json
+
+import webob
+import zc.dozodb
+
+
+def response(handler, request):
+    try:
+        if request.method == 'GET':
+            if '_p_oid' in request.str_GET:
+                return zc.dozodb.load(
+                    handler.connection, request.str_GET.get('_p_oid'))
+            body = zc.dozodb.fetched(*handler.query())
+        else:
+            assert(request.method == 'POST')
+            assert request.content_type.startswith('application/json')
+            body = zc.dozodb.save(handler, request.body)
+    except Exception, e:
+        body = json.dumps(dict(error=unicode(e)))
+
+    response = webob.Response(status = 200, content_type = 'application/json')
+    response.body = body
+    return response
+
+class Application:
+
+    def __init__(self, handler, db):
+        self.db = db
+        self.handler = handler
+
+    def __call__(self, environment, start_response):
+        request = webob.Request(environment)
+        with self.db.transaction() as connection:
+            r = response(self.handler(connection, request), request)
+            return r(environment, start_response)
+


Property changes on: Sandbox/J1m/dozodb/src/zc/dozodb/webob.py
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native



More information about the checkins mailing list