As mentioned in my previous post I've been playing around using
ParseTree to build queries for DataMapper.
I wanted to let everyone know I packaged up this experiment into a gem
(tentatively) called dm-ambition. Essentially this will allow you to
write queries like this:
User.select { |u| u.id == 1 && u.name == 'Dan Kubb' }
I've added support for most basic operators, like ==, =~, >=, >, etc.
I've also added some more advanced usage with Array#include?,
Range#include? and a few other primitive operators.
More examples are available here:
http://github.com/dkubb/dm-ambition/
I still need to work out how associations are handled, but it should
work just as you'd expect it if you were using Enumerable#select
normally. Also OR conditions are not supported, merely because
DataMapper does not (yet) handle them internally -- once it does it
will probably take 5 minutes to add them to this adapter. Nested AND/
OR blocks should be trivially easy to support too once the groundwork
in dm-core has been laid. (in reality, supporting OR conditions is
the only real reason to use ParseTree for this.. the current syntax
could probably be supported with some special objects)
To install do one of the following:
>From Gem:
$ sudo gem install dkubb-dm-ambition -s http://gems.github.com
With a local working copy:
$ git clone git://github.com/dkubb/dm-ambition.git
$ rake package && sudo rake install
Keep in mind this is a first draft. This release was sort of a code
spike and I wasn't too concerned about finding the optimal
abstractions for the code internally. I just attempted to "brute
force" the problem to explore it and learn more about ParseTree.
There's still a few huge methods in there to flog. I believe I'm
close to having a better picture of how to reorganize things into a
more extensible architecture for the next release.
The good news is that code coverage is in the mid-90's, so it's
relatively well tested, and I don't expect a reorganization to be too
painful. However I could still use a hand with figuring out some more
real-world use cases.
Also, I need some help naming this gem since its not really based on
the Ambition code-base. I did this for a few reasons:
1) A large part of Ambition is adding a bunch of concepts to
ActiveRecord that are already baked into the heart of DataMapper.
These include things like chaining, kickers, etc. For DM all I had to
do was write a SexpProcess to work with ParseTree and I was done.
2) When a Collection is already loaded into memory, and you use select
(), detect() or reject() I don't parse the block and execute a query,
I simply iterate over the Array and filter the records in-memory. I
figure if you've already paid the price to query all the objects into
memory, why not just iterate over those rather than re-retrieving them
from the backend data-store.
3) The way Ambition works with associations isn't really compatible
with the standard Enumerable API. You can't take an Ambition-style
block that filters on an association, and use it to filter down an
Array of Resource objects (making it incompatible with #2 above).
Sure, I could probably rewrite the block so that it does work this
way, but I wanted the simplest thing that could work, which means
using Ruby's standard Enumerable API when possible.
Anyway, please feel free to download, install and play with this and
give me your feedback and ideas.
--
Thanks,
Dan
(dkubb)
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"DataMapper" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/datamapper?hl=en
-~----------~----~----~----~------~----~------~--~---