Err the Blog Atom Feed Icon
Err the Blog
Rubyisms and Railities
  • “Even More Ambitious”
    – Chris on September 12, 2007

    Things are really looking up for Ambition. It’s been almost two weeks since the initial release and I thought I would catch y’all up on the progress we’ve made.

    The current version is 0.2.2, so grab that while you can and follow along. Supplies are limited.

    $ sudo gem install ambition -y

    Databasein’

    Ambition has gone from generating generic SQL to respecting your database of choice (as long as it’s MySQL or PostgreSQL).

    Check it:

    # Postgres
    User.select { |m| m.name =~ /chris/ }
    SELECT * FROM users WHERE users."name" ~ 'chris'
    
    # MySQL
    User.select { |m| m.name =~ /chris/ }
    SELECT * FROM users WHERE users.`name` REGEXP 'chris'
    

    How cool is that? And because Postgres supports case insensitive regular expressions, so do we:

    User.select { |m| m.name =~ /chris/i }
    SELECT * FROM users WHERE users."name" ~* 'chris'
    

    Escaping is also DB-specific, whether you like it or not. Oh, and OFFSET works with Postgres now.

    Don’t see your database of choice on our (short) list? Feel free to send patches—we happily accept them.

    Toyin’

    If you just want to dip your toe in, we’ve added a test/console inspired by will_paginate’s.

    You have to create the database yourself, but once that’s setup this irbish script will create a schema and load it with fixtures for you to play with and enjoy.

    $ mysqladmin create ambition_development
    $ cd GEMS/ambition-0.2.2
    $ ruby test/console
    >> Developer.select { |u| u.salary > 80_000 }.size
    => 9
    >> Developer.select { |u| u.salary > 80_000 }.entries
    => [#<Developer:0x271f370 ...> ...]
    

    There might be some rough spots as far as the associations go, but overall it should work pretty nicely.

    To use a different database, set an ADAPTER environment variable, e.g.

    $ ADAPTER=sqlite3 ruby test/console

    Speedin’

    Some people have been asking about performance. You know how it goes. “Oh, that’s cool, but it’s slow.” “It doesn’t scale.” “Who owns the trademark?”

    In the interest of appeasing the unappeasable, I spent some time with ruby-prof. Below are the fruits of my labor, comparing the first and latest versions of Ambition.

    Each case runs 10,000 times. The benchmark I used is here. I had to fix some bugs in 0.1.0 to get it to work, but that shouldn’t affect anything.

    # Ambition 0.1.0
                               user     system      total        real
    simple select          7.030000   0.020000   7.050000 (  7.052899)
    dual select            8.050000   0.010000   8.060000 (  8.094917)
    join select            7.890000   0.030000   7.920000 (  8.003906)
    dual select w/ sort   13.390000   0.040000  13.430000 ( 13.529581)
    dual select w/ stuff  13.600000   0.050000  13.650000 ( 14.107565)
    it's complicated      16.030000   0.070000  16.100000 ( 16.213238)
    
    # Ambition 0.2.2
                              user     system      total        real
    simple select         0.910000   0.010000   0.920000 (  0.921048)
    dual select           1.380000   0.010000   1.390000 (  1.398235)
    join select           1.950000   0.020000   1.970000 (  1.981603)
    dual select w/ sort   1.960000   0.000000   1.960000 (  1.964018)
    dual select w/ stuff  2.080000   0.010000   2.090000 (  2.111435)
    it's complicated      2.820000   0.000000   2.820000 (  2.831330)
    

    So, that’s pretty cool. We’re definitely not slowing anything down—Ambition happily leaves that task up to your app. Zing!

    Stubbin’

    This is an experimental feature, but that’s what we’re all about. Observe:

    User.ambition_source = fixtures(:chris, :pj, :_why)
    User.detect { |u| u.name == 'Chris' }
    

    If an ambition_source is set, Ambition will run all it instead of the database. The above example runs select on the fixtures array rather than building and executing SQL. Could be cool for functional / unit tests.

    Gitin’

    Development is now riding Git rather than Subversion. Follow along:

    $ git clone git://errtheblog.com/git/ambition

    If you haven’t already tried Git, this could be a golden opportunity for us both. Other projects like Rubinius, god, and CouchObject are already using this up and coming tool for development, so give it a shot.

    Us using Git or Subversion should not affect your ability to use Ambition in a Rails app. You can either require the gem or run gem unpack ambition in your vendor/plugins directory to get it working.

    Contributin’

    Thanks to Matthew King, David Chelimsky, Pratik Naik, Loïc, Louis Rose, John Topley, and François Beausoleil for bug reports, feature requests, and their contributions.

    If you didn’t catch the updates on the last post, we added empty?, downcase, upcase, any?, all?, and slice thanks to their hard work.

    As always, you can add bugs, make requests, and participate in general over at the Lighthouse bug tracker.

    We now have a mailing list, too: http://groups.google.com/group/ambition-rb

    Prospectin’

    We’ve moved our sights from Rack to LINQ. That is, we don’t want to only support other ORMs—we want Ambition to be a query language for SQL, LDAP, XPath, the works. The 1.0 release will be backend-agnostic. Maybe then we’ll change the name to Hubris? Time will tell.

  • Fawn, about 3 hours later:

  • Matthijs Langenberg, about 5 hours later:

    Uhm, the link to the Lighthouse bug tracker actually points to “http://git.errtheblog.com/”. This is some great stuff though, thumbs up!

  • Chris, about 5 hours later:

    Matthijs: Whoops, thanks. I fixed it.

  • Robby Russell, about 9 hours later:

    Sweet, I was wondering about how you’d handle REGEX support for PostgreSQL. :-)

  • weepy, about 10 hours later:

    Wow – great stuff. How far off is evaluating ruby within the block ?

  • josh, about 10 hours later:

    Nifty. And I believe the new name you are looking for is “panacea”. :-)

  • Vrensk, about 11 hours later:

    And because Postgres supports case insensitive regular expressions, so do we

    Well, so does MySQL. In fact, it’s the default (on char/varchar/text that has not been declared binary). So to do a case sensitive search, you need to add BINARY. Snippet from the manual:

    mysql> SELECT 'a' REGEXP 'A', 'a' REGEXP BINARY 'A';
    -> 1  0
  • Steve, 2 days later:

    What are the Rails benchmarks for doing these operations without Ambition. The speed improvement between the two Ambition versions is definitely improved, but I’m curious as to the impact on vanilla Rails.

  • Chris, 2 days later:

    Well it takes 3 seconds to build a complicated query 10,000 times, so if we do some simple math… 3 / 10_000 = .0003. There you go, .0003 seconds for a complicated query. That’s the impact on “vanilla” Rails—less than a millisecond.

  • Thorben, 3 days later:

    Shouldn’t this be the same:

    user = User.select {|user| user.age > 25}
    user.first #ok, the first user of the set of users who's age is above 25
    user[0] #user with the id 0?! Where is my age > 25 clause?
    

    I think this is quite strange.

    Thanks,

    Thorben

  • Henrik N, 6 days later:

    I love the logo type thing.

  • Max Lapshin, 8 days later:

    Everything is nice, but Macports have no git. I failed to check it out.

  • Chris, 8 days later:

    Max: Macports does indeed have git, that’s how I installed it!

    $ sudo port install git-core

  • Brian, 8 days later:

    You guys is smart.

  • David Mathers, 19 days later:

    also:

    $ sudo port install cogito

    for more git stuff in macports

  • jonelf, about 1 month later:

    No news for so long. Did you leave us and the blog behind and totally caved in git?

  • maciej, 2 months later:

    I have noticed that sum is broken.

    Currency.column_names => [“id”, “value”] Currency.sum(:value) SQL (0.000575) SELECT count(*) AS count_all FROM currencies => :value

  • Seventeen people have commented.
    Chime in.
    Sorry, no more comments :(
This is Err, the weblog of PJ Hyett and Chris Wanstrath.
All original content copyright ©2006-2008 the aforementioned.