about photos bookshelf portfolio blog home
Begin main content

Mysql stupidity and overriding ruby methods

I *knew* I would regret using mysql for this project instead of postgresql. "But it's only got 3 tables" I said to myself...

Who knew that by default mysql selects were case insensitive?! I'm not talking about LIKE being case insensitive (although they are case insensitive too, just like in my nemesis Sybase), I'm talking about select * from foo where bar = 'aaa' finding a record where bar = 'AAA'. That's cruel and unusual.

The solution, in this particular incarnation of mysql anyway, is to make the column a "binary varchar" column. I'm not sure how that differs to a normal varchar (perhaps normal varchars are stored as analog vector data instead of binary data) but it works just like a normal varchar, and select matching is case sensitive. Phew, off the hook.

Except... Active Record (from Ruby on Rails) says "aha - it's a binary column, so it must be a blob. I'll pack the data in using some mysql binary quoting syntax that your particular version of mysql doesn't support." And you get this:

.../active_record/connection_adapters/ abstract_adapter.rb:88:in `log': Mysql::Error: You have an error in your SQL syntax near ''333630204465677265657320466f637573' WHERE id = 1' at line 1: UPDATE customers SET `username` = NULL, `password` = NULL, `name` = x'333630204465677265657320466f637573' WHERE id = 1 (ActiveRecord::StatementInvalid)

Right... :(

Thankfully, overriding a method in the symbol table (or whatever the ruby runtime nomenclature for the Ruby equivalent is) is just as easy as in Perl. In the model ruby file in question, I just added:

module ActiveRecord
  module ConnectionAdapters
    class MysqlAdapter
      def quote(value, column = nil)
        super
      end
    end
  end
end
and all is well. Sigh.

12:54 AM, 14 Feb 2006 by Mark Aufflick Permalink

Add comment