Index: test/helper.rb =================================================================== --- test/helper.rb (revision 323) +++ test/helper.rb (working copy) @@ -34,3 +34,16 @@ class Reflection < Struct.new(:macro, :primary_key_name, :name, :table_name) end + +module ActiveRecord + module ConnectionAdapters + class MysqlAdapter + def connect(*args) + true + end + end + + class FakeAdapter < AbstractAdapter + end + end +end Index: test/where_test.rb =================================================================== --- test/where_test.rb (revision 323) +++ test/where_test.rb (working copy) @@ -109,12 +109,12 @@ specify "simple =~ with regexp" do sql = User.select { |m| m.name =~ /chris/ }.to_sql - sql.should == "SELECT * FROM users WHERE users.name REGEXP 'chris'" + sql.should == "SELECT * FROM users WHERE users.name SIMILAR TO 'chris'" end specify "simple =~ with regexp flags" do sql = User.select { |m| m.name =~ /chris/i }.to_sql - sql.should == "SELECT * FROM users WHERE users.name REGEXP 'chris'" + sql.should == "SELECT * FROM users WHERE users.name SIMILAR TO 'chris'" end specify "simple LOWER()" do @@ -140,6 +140,65 @@ specify "inspect" do User.select { |u| u.name }.inspect.should.match %r(call #to_sql or #to_hash) end + + context "PostgreSQL specific" do + setup do + ActiveRecord::Base.connection = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.new 'fake_connection', 'fake_logger' + end + teardown do + ActiveRecord::Base.remove_connection + end + + specify "quoting of column name" do + me = 'chris' + sql = User.select { |m| m.name == me }.to_sql + sql.should == "SELECT * FROM users WHERE users.\"name\" = '#{me}'" + end + + specify "simple =~ with regexp" do + sql = User.select { |m| m.name =~ /chris/ }.to_sql + sql.should == "SELECT * FROM users WHERE users.\"name\" ~ 'chris'" + end + end + + context "MySQL specific" do + setup do + ActiveRecord::Base.connection = ActiveRecord::ConnectionAdapters::MysqlAdapter.new('connection', 'logger', 'options', 'config') + end + teardown do + ActiveRecord::Base.remove_connection + end + + specify "quoting of column name" do + me = 'chris' + sql = User.select { |m| m.name == me }.to_sql + sql.should == "SELECT * FROM users WHERE users.`name` = '#{me}'" + end + + specify "simple =~ with regexp" do + sql = User.select { |m| m.name =~ /chris/ }.to_sql + sql.should == "SELECT * FROM users WHERE users.`name` REGEXP 'chris'" + end + end + + context "Adapter without overrides" do + setup do + ActiveRecord::Base.connection = ActiveRecord::ConnectionAdapters::FakeAdapter.new('connection', 'logger') + end + teardown do + ActiveRecord::Base.remove_connection + end + + specify "quoting of column name" do + me = 'chris' + sql = User.select { |m| m.name == me }.to_sql + sql.should == "SELECT * FROM users WHERE users.name = '#{me}'" + end + + specify "simple =~ with regexp" do + should.raise{ User.select { |m| m.name =~ /chris/ }.to_sql } + end + end end context "Where (using detect)" do Index: lib/ambition/processor.rb =================================================================== --- lib/ambition/processor.rb (revision 323) +++ lib/ambition/processor.rb (working copy) @@ -3,6 +3,7 @@ module Ambition class Processor < SexpProcessor include ActiveRecord::ConnectionAdapters::Quoting + include ActiveRecord::ConnectionAdapters::DatabaseStatements attr_reader :key, :join_string, :prefix, :includes @@ -48,13 +49,25 @@ case value.to_s when 'true' then '1' when 'false' then '0' - else ActiveRecord::Base.connection.quote(value) rescue quote(value) + else ActiveRecord::Base.connection.quote(value) #rescue quote(value) end + rescue ActiveRecord::ConnectionNotEstablished + quote(value) + rescue + "'#{value}'" end def quote_column_name(value) - ActiveRecord::Base.connection.quote_column_name(value) rescue value.to_s + ActiveRecord::Base.connection.quote_column_name(value) + rescue ActiveRecord::ConnectionNotEstablished + value.to_s end + + def adapter_regexp(value) + ActiveRecord::Base.connection.ambition_regexp(value) + rescue ActiveRecord::ConnectionNotEstablished + ambition_regexp(value) + end def extract_includes(receiver, method) return unless receiver.first == :call && receiver[1].last == @receiver Index: lib/ambition/where.rb =================================================================== --- lib/ambition/where.rb (revision 323) +++ lib/ambition/where.rb (working copy) @@ -65,6 +65,7 @@ def process_match3(exp) regexp, target = exp.shift.last.inspect.gsub(/\/([^\/]+)\/\S*/, '\1'), process(exp.shift) "#{target} REGEXP '#{regexp}'" + "#{target} #{adapter_regexp(regexp)}" end def process_dvar(exp) Index: lib/ambition/active_record_overrides.rb =================================================================== --- lib/ambition/active_record_overrides.rb (revision 0) +++ lib/ambition/active_record_overrides.rb (revision 0) @@ -0,0 +1,28 @@ +module ActiveRecord + module ConnectionAdapters + + module DatabaseStatements + def ambition_regexp(value) + "SIMILAR TO #{quote(value)}" + end + end + + class AbstractAdapter + def ambition_regexp(value) + raise "#{adapter_name} does not define ambition_regexp" + end + end + + class MysqlAdapter + def ambition_regexp(value) + "REGEXP '#{value}'" + end + end + + class PostgreSQLAdapter + def ambition_regexp(value) + "~ #{quote(value)}" + end + end + end +end Index: lib/ambition.rb =================================================================== --- lib/ambition.rb (revision 323) +++ lib/ambition.rb (working copy) @@ -8,6 +8,7 @@ require 'ambition/limit' require 'ambition/count' require 'ambition/enumerable' +require 'ambition/active_record_overrides' module Ambition include Where, Order, Limit, Enumerable, Count