couchdb-python
couchdb-python copied to clipboard
More sophisticated behaviour for View.define decorator
From [email protected] on December 10, 2009 17:15:39
[formerly a comment in Issue 73 : Fix schema.View.define decorator]
I've had a go at implementing reduce functions using this decorator (after having applied the patch from issue 73 ). Basically, the fun passed to view_wrapped is a higher-order function that returns one or more functions. The first is taken to be the map_fun, and if it exists, the second is taken as the reduce_fun. fun.name is taken as the name of the view. Here is the modified define method:
@classmethod
def define(cls, design, name=None, language='python', wrapper=DEFAULT,
**defaults):
"""Factory method for use as a decorator."""
def view_wrapped(fun):
funs = fun() # extract the map & reduce functions
if type(funs) != list:
funs = [funs]
map_fun = funs[0]
reduce_fun = None
if len(funs) > 1:
reduce_fun = funs[1]
return cls(design, name=fun.__name__,
map_fun=map_fun, reduce_fun=reduce_fun,
language=language, wrapper=wrapper,
**defaults)
return view_wrapped
example usage:
@View.define('doc_name') def view_name(): def fun_map(doc): yield None, doc def fun_reduce(keys, values, rereduce): return values return [fun_map, fun_reduce]
or, without a reduce phase:
@View.define('doc_name') def view_name(): def fun_map(doc): yield None, doc return fun_map
Any thoughts? I've tested the above code, and it works as expected. I can produce a patch if necessary.
Original issue: http://code.google.com/p/couchdb-python/issues/detail?id=105
From kxepal on June 27, 2010 07:10:00
a little reworked jimsaku idea with support for such case:
@View.define('doc_name') def view_name(): def fun_map(doc): yield None, doc def fun_reduce(keys, values, rereduce): return values return fun_map, fun_reduce
Attachment: ViewField.patch
From [email protected] on June 27, 2010 07:14:26
I can sort out a patch against hg tip this afternoon if there's interest in having it applied. If I need to update the tests & docs as well it'll take a little longer.
From djc.ochtman on June 27, 2010 09:28:33
It would definitely need tests, but I can write the docs.
From kxepal on August 07, 2010 06:56:59
Ok, while we are waiting for jimsaku, my turn(:
I've improved original idea to support multiple view servers within single ViewField. See doctests and unittest for usage example. Also this removes decorator limitation "for python views only".
Attachment: viewfield.define.patch viewfield.define.tests.patch
From [email protected] on February 28, 2011 13:51:39
Seriously, comment 8 looks good. I just put together a patch & tests for the original proposal, but it seems pointless given that the modified approach accepts javascript views as well... any insight into how we get this accepted into a future release?
From kxepal on February 28, 2011 20:06:07
I suppose not, because it requires to rewrite all existed views - a lot of people who doesn't read changelogs will be shocked(: In fact of real usage, it works good, but if there is planned to setup show/list/rewrite/validate_doc_update functions there is needed another approach.
I'm thinking there will be much more better to use full power of ViewField.define decorator: reduce function definition could be done in same way as properties have. So old code will have not be rewrited and main problem will be solved.
About multilang: it's needed feature but what is better: let ViewField and future ShowField/ListField(huh, collision) store same named functions by language and on syncing retrieve set of them by language argument or define separate DesignDocument for each design language and mix it to SchemaDocument by language argument in config file?
From [email protected] on February 28, 2011 23:27:52
Agreed it may be annoying to have to rewrite views, but it's a very simple refactoring process. Given that the class this is based on has changed its name since I first wrote the patch illustrates that the core code occasionally undergoes changes that require refactoring :)
I can see this being updated in a more subtle way to make the transition easier: just add a "map_only=True" parameter to the signature of define. If True, follow the existing behaviour, if False, use the new pattern. That way it's 100% backwards-compatible, and should be a no-brainer for inclusion.
Agreed there may be a better way of supporting multilang (maybe that's a conversation for IRC or mailing lists...) but I still think there's tremendous value in this patch (either with or without javscript view support).
From [email protected] on March 22, 2012 23:37:41
Why is it that I'm unable to apply this patch to couchdb-python? I have the downloaded 0.9dev version. I tried using hg import --no-commit viewfield.define.patch but I get the folllowing errors:
mark@somecomputer$ hg import --no-commit ~/Downloads/viewfield.define.tests.patch applying /home/mark/Downloads/viewfield.define.tests.patch patching file couchdb/tests/mapping.py Hunk #1 FAILED at 203 Hunk #2 FAILED at 212 Hunk #3 FAILED at 240 3 out of 3 hunks FAILED -- saving rejects to file couchdb/tests/mapping.py.rej abort: patch failed to apply
Can someone be kind enough to teach me how to apply this patch or point to me where I can download the latest couchdb-python with all the latest patches already applied?
This would probably be better implemented in a similar fashion as the setter
function for @property
@View.define('doc_name')
def my_map_func(doc):
yield None, doc
@my_map_func.reduce
def my_reduce_func(keys, values, rereduce):
return values
This would avoid any changes to the existing implementation and would keep the interface simple to use.