It’s funny, really. All these people walking around, talking about Ambition. “Oh, Ambition? Yeah, pretty cool.” “Ambition? Impedance mismatch.” “I’m happy with SQL-92 the way it is, thank you very much.” Outrageous!
I know, I know. We’ve said some crazy things ourselves. Like how we wanted Ambition to be a Rack for databases. Or, far fetched as it sounds, how we hoped Ambition could evolve into something akin to LINQ. But we’re done talking.
Today we want to show you some plain jane Ruby and how Ambition empowers it to leverage its inherent synergy. Er, I mean, we want to show you something kickass.
New School
This is what we’re used to:
>> SQL::User.select { |m| m.name == 'jon' && m.age == 21 }.to_s => "SELECT * FROM users WHERE users.name = 'jon' AND users.age = 21"
This is what’s new:
>> LDAP::User.select { |m| m.name == 'jon' && m.age == 21 }.to_s => "(&(name=jon)(age=21))"
Adapter School
As of 0.5, Ambition is no longer a SQL wrapper. Rather, it is an API for writing your own adapters. If you’d like to continue using the ActiveRecord version of Ambition, please install the ambitious-activerecord gem:
$ gem install ambitious-activerecord
Then, of course, use it:
require 'rubygems' require 'ambition/adapters/active_record'
You can, too, install and use the older 0.3 series:
$ gem install ambition -v 0.3.2
Anyway, you heard right: Ambition now supports arbitrary data stores. Anything. Ambition adapters are just gems which depend on ambition and use its amazing API powers for the greater good.
What other adapters are underway? Oh, I dunno. How about ActiveLDAP, CouchDB, Facebook FQL, XPath, and DataMapper, to name a few. Why, just the other night the Boston.rb guys started working on a Sphinx adapter. Check it out with git:
$ git clone git://technicalpickles.com/ambitious_sphinx.git
We’ve also got two example gems: ambitious-activeldap and ambitious-activerecord.
There’s basic documentation for Ambition’s API over at ambition.rubyforge.org, which you are free to peruse as well.
We’re just starting out, but it’s not a bad start. Got an idea? Something crazy? We’re all about it. Jump on the mailing list or join #ambition on irc.freenode.net then chime in.
Dream School
Let’s take the youtube-g gem, as an example. There’s no finished adapter for it yet so we’re going to pretend.
Using the new Ambition, we could (behind the scenes) turn a query like this:
Videos.select { |video| video.user == 'liz' }
Into this:
YouTubeG::Client.new.videos_by(:user => 'liz')
We could turn a query like this:
Videos.select { |video| video.tags.include? 'apple' }
Into this:
YouTubeG::Client.new.videos_by(:tags => 'apple')
And we could even turn a query like this:
Videos.select do |video| video.tags.include?('football') && !video.tags.include?('soccer') end
Into this:
YouTubeG::Client.new.videos_by :tags => { :include => ['football'], :exclude => ['soccer'] }
Not bad. It even comes with a generator, courtesy of Dr Nic, for spitting out an adapter scaffold:
$ ambition_adapter ambitious_youtube
Future School
Got an idea for an adapter, or some code to show? Throw it in the comments. You better believe we’ll keep the rest of you abreast of cool adapters, fancy tricks, and new features.
Want to get involved? Like I said, there’s always the list and the GitHub repo. Bugs can go to Lighthouse and you can clone my repo thisaways:
$ git clone git://github.com/defunkt/ambition.git
Ah, how far we’ve come. And how far we’ll go! Here’s to it.
leetness overwhelming. wow.
Hmm, perhaps an adapter for acts_as_solr requests might be nice. I keep forgetting its syntax.
Concentrated awesome.
Way too trippy ;)
Your feed keeps resetting in Google Reader, man.
It would be nice to see ThruDB adapter :-)
Any chance you could link to more information about the ambition adapters? Specifically I’m interested in helping out with the DataMapper adapter.
Ya, 2nd what Evan says. Told me I had 11 new posts from err today.
Are you aware of the work on Skynet? see http://www.infoq.com/news/2008/01/ruby-mapreduce-skynet
It might be really cool to integrate with that for distributed data fetching/processing.
EugZol: I’ll be looking at this for ActiveDocument, a ruby ORM using thrudb. You’re more than welcome to jump in and help out too of course.
An adapter for Ferret anyone?
Oh, please sort out your fucking RSS feed! I’m sick of getting a billion updated articles every time you post an entry!
I concur with the comments on the feed. Also, why do your posts link to http://independent.netguru.com.pl/posts/xxx in the feed?
Dan Kubb:
http://ambition.rubyforge.org/adapters.html
I haven’t found the time to play with DataMapper yet, but it seems that it has a find_by_sql method. Thus most of the code in the ActiveRecord ambition adapter could be copied. The main differences will be in query.rb, where you define the methods that create the SQL string and kick off the actual query.
My feed reader (Brief for Firefox) also shows all your posts as new when you write a post.
Dr. Nic, Evgeny, and anyone else who is looking to write adapters for full-text search engines: drop me a line. We’ve learned a few things in the process of developing ambitious-sphinx but still have unanswered questions about how we want the API to feel. It’d be cool if ambitious-sphinx, ambitious-ferret, and ambitious-solr had similar APIs.
Some thoughts about ambition adapters while Dan and I were working on this…
I can’t place a finger on it yet, but the ambition adapter api doesn’t seem to apply as cleanly to sphinx queries as it does for SQL. Although, this could just as easily be a product of me learning ambition, sphinx, and ultrasphinx all the same time.
Sphinx is a little annoying because the order of precendence for && and || is the exact opposite of Ruby, ie | binds more closely. We haven’t really tried to deal with this quite yet.
I seem to think you can really only use one adapter with a particular class. So, because we’re using ultrasphinx which has hooks for converting query results into a list of ActiveRecord objects, we end up mixing in our module into ActiveRecord::Base, and setting it to use our adapter. The end result is that you can only use ambitious-activerecord OR ambitious-sphinx, but not both.
Yes, an (acts_as_)Solr adapter would be cool.
With adapters for both your DBMS and your search server, it seems you could create SQL fallbacks for if the search server goes down, with little duplication.
One thing I noticed about the directory layout generated by ambition_adapter was that autotest doesn’t seem to play nice with it. It just kind of sits there when you run it.
Chime In! There is no one sql! Why? GG.
Nice. As far as I can see from the API, it’s read only?
I’m hoping that we can base our service integration stuff on this, eg. REST::Basecamp::User.select and so on.
Since select could execute a REST HTTP call, that may as well be an implicit write.
Is there an easy way to use Ambition and will_paginate?, I know that’s ActiveRecord specific, but I kinda need this right now
This is indeed way awesome.
It’s awesome with a pile of awesome.
Well, it looks like something finally has not only caught up with, but surpassed the powers of EOF (Enterprise Objects Framework from NeXT, developed in the early ‘90s, and a part of WO since day 1 [1995]).
Honestly, this is great.
DBpedia SPARQL interface and Freebase MQL come to mind (nothing urgent, though).
Chime in.