couchdb-python icon indicating copy to clipboard operation
couchdb-python copied to clipboard

More sophisticated behaviour for View.define decorator

Open djc opened this issue 10 years ago • 14 comments

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

djc avatar Jul 12 '14 14:07 djc

From djc.ochtman on December 14, 2009 02:32:19

Labels: -Type-Defect Type-Enhancement

djc avatar Jul 12 '14 14:07 djc

From kxepal on June 27, 2010 06:05:27

Will this enhancement ever be applied?

djc avatar Jul 12 '14 14:07 djc

From djc.ochtman on June 27, 2010 06:31:20

Can someone attach the/a patch?

djc avatar Jul 12 '14 14:07 djc

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

djc avatar Jul 12 '14 14:07 djc

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.

djc avatar Jul 12 '14 14:07 djc

From djc.ochtman on June 27, 2010 09:28:33

It would definitely need tests, but I can write the docs.

djc avatar Jul 12 '14 14:07 djc

From [email protected] on June 28, 2010 22:05:56

I'll look at writing some tests this week.

djc avatar Jul 12 '14 14:07 djc

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

djc avatar Jul 12 '14 14:07 djc

From kxepal on September 13, 2010 05:14:49

What the status of this issue?

djc avatar Jul 12 '14 14:07 djc

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?

djc avatar Jul 12 '14 14:07 djc

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?

djc avatar Jul 12 '14 14:07 djc

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).

djc avatar Jul 12 '14 14:07 djc

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?

djc avatar Jul 12 '14 14:07 djc

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.

twheys avatar Jul 16 '17 20:07 twheys