bmuller / twistar

Twistar is an object-relational mapper (ORM) for Python that uses the Twisted library to provide asynchronous DB interaction.
http://findingscience.com/twistar
Other
132 stars 38 forks source link

Changes InteractionBase.select() to preserve where clause when id argument is provided #69

Closed nocko closed 8 years ago

nocko commented 8 years ago

This works as expected when an id is not provided to DBObject.find(where=...), but failed to work when using specifying an id DBObject.find(id, where=...). InteractionBase.select() discards the clause if an id is provided. This patch retains any provided where clause.

coveralls commented 8 years ago

Coverage Status

Coverage increased (+0.08%) to 85.863% when pulling b06fac389b819500e43338ee55caa8412b043234 on nocko:select-id-where-preserve into d9823048f82e9ee8a8a2b6dc2e0abccf4424e72c on bmuller:master.

nocko commented 8 years ago

I recently ran into a use case (permissions checking in an API); where it was convenient to let the database filter results based on permissions subquery. I doubt it's a common pattern, but it's helpful for me...

bmuller commented 8 years ago

Hey @nocko - just to be clear - you know what the unique key id is for the query but you'd like to add additional criteria (that won't affect the query results)?

nocko commented 8 years ago

It could effect the query results, instead of returning the unique key'd item, a failed where clause would return no results. This is the desired behaviour.

nocko commented 8 years ago

Example:

Zone.find(1, where=['owner_id = ANY ((select ARRAY(select org_id from users_orgs where user_id = ?) || ?)::int[])', 1, 1])

generates:

SELECT * FROM zones WHERE owner_id = ANY ((select ARRAY(select org_id from users_orgs where user_id = 1) || 1)::int[]) AND id = 1;

Explanation: Return zone row with unique id = 1, if the user or one of the user's organizations owns the zone, otherwise return no results.

This works well for filtering a collection of rows, but I'd like the same decorator to enforce access control on collections of rows (already working) and specific rows (failed because where clause is overwritten by InteractionBase.select() without falling back to adbapi.ConnectionPool methods.

bmuller commented 8 years ago

OK - makes sense. I'll merge if you make the one change I suggest in the comments. Thanks for the PR!

nocko commented 8 years ago

I've never noticed twistar.utils, those are handy. I've implemented at least two of those functions in my own code. Should spend more time reading the code. Thanks.

coveralls commented 8 years ago

Coverage Status

Coverage increased (+0.09%) to 85.872% when pulling 8098c46f71d97fa561ee0e583e0559027c292b8e on nocko:select-id-where-preserve into d9823048f82e9ee8a8a2b6dc2e0abccf4424e72c on bmuller:master.

bmuller commented 8 years ago

Thanks @nocko! I bumped the minor version on pypi as well. Let me know if anything is missing from utils.py.