activerecord-jdbc-adapter 1.1.3 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +22 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +42 -0
- data/History.txt +10 -3
- data/{README.txt → README.rdoc} +30 -14
- data/Rakefile +49 -0
- data/activerecord-jdbc-adapter.gemspec +23 -0
- data/bench/bench_attributes.rb +13 -0
- data/bench/bench_attributes_new.rb +14 -0
- data/bench/bench_create.rb +12 -0
- data/bench/bench_find_all.rb +12 -0
- data/bench/bench_find_all_mt.rb +25 -0
- data/bench/bench_model.rb +85 -0
- data/bench/bench_new.rb +12 -0
- data/bench/bench_new_valid.rb +12 -0
- data/bench/bench_valid.rb +13 -0
- data/lib/activerecord-jdbc-adapter.rb +1 -1
- data/lib/arel/visitors/derby.rb +5 -1
- data/lib/arjdbc.rb +12 -17
- data/lib/arjdbc/db2/adapter.rb +91 -4
- data/lib/arjdbc/derby/adapter.rb +8 -8
- data/lib/arjdbc/derby/connection_methods.rb +1 -0
- data/lib/arjdbc/firebird/adapter.rb +4 -4
- data/lib/arjdbc/h2/adapter.rb +3 -2
- data/lib/arjdbc/h2/connection_methods.rb +1 -0
- data/lib/arjdbc/hsqldb/adapter.rb +5 -2
- data/lib/arjdbc/hsqldb/connection_methods.rb +1 -0
- data/lib/arjdbc/informix/adapter.rb +2 -2
- data/lib/arjdbc/informix/connection_methods.rb +1 -0
- data/lib/arjdbc/jdbc/adapter.rb +92 -22
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/mimer/adapter.rb +4 -4
- data/lib/arjdbc/mssql/adapter.rb +10 -8
- data/lib/arjdbc/mssql/connection_methods.rb +1 -0
- data/lib/arjdbc/mssql/limit_helpers.rb +7 -4
- data/lib/arjdbc/mysql/adapter.rb +30 -6
- data/lib/arjdbc/mysql/connection_methods.rb +1 -0
- data/lib/arjdbc/oracle/adapter.rb +15 -12
- data/lib/arjdbc/oracle/connection_methods.rb +1 -0
- data/lib/arjdbc/postgresql/adapter.rb +35 -16
- data/lib/arjdbc/postgresql/connection_methods.rb +1 -0
- data/lib/arjdbc/sqlite3/adapter.rb +13 -10
- data/lib/arjdbc/sqlite3/connection_methods.rb +1 -0
- data/lib/arjdbc/version.rb +1 -1
- data/lib/generators/jdbc/USAGE +10 -0
- data/pom.xml +57 -0
- data/rakelib/rails.rake +1 -1
- data/rakelib/test.rake +20 -6
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +4 -1
- data/src/java/arjdbc/jdbc/SQLBlock.java +1 -1
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +74 -0
- data/test/abstract_db_create.rb +8 -1
- data/test/activerecord/jall.sh +7 -0
- data/test/activerecord/jtest.sh +3 -0
- data/test/jdbc_common.rb +6 -4
- data/test/models/data_types.rb +1 -1
- data/test/models/string_id.rb +2 -0
- data/test/models/thing.rb +16 -0
- data/test/mysql_index_length_test.rb +58 -0
- data/test/mysql_info_test.rb +3 -3
- data/test/postgres_db_create_test.rb +1 -1
- data/test/simple.rb +11 -3
- data/test/sqlite3_simple_test.rb +16 -2
- metadata +167 -108
- data/.gemtest +0 -0
- data/Manifest.txt +0 -187
- data/rakelib/package.rake +0 -92
- data/test/pick_rails_version.rb +0 -3
    
        data/bench/bench_new.rb
    ADDED
    
    
    
        data/lib/arel/visitors/derby.rb
    CHANGED
    
    | @@ -7,12 +7,16 @@ module Arel | |
| 7 7 | 
             
                    [
         | 
| 8 8 | 
             
                     o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join,
         | 
| 9 9 | 
             
                     ("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
         | 
| 10 | 
            -
                     ( | 
| 10 | 
            +
                     (visit_Arel_Nodes_Limit(o.limit) if o.limit),
         | 
| 11 11 | 
             
                     (visit(o.offset) if o.offset),
         | 
| 12 12 | 
             
                     (visit(o.lock) if o.lock),
         | 
| 13 13 | 
             
                    ].compact.join ' '
         | 
| 14 14 | 
             
                  end
         | 
| 15 15 |  | 
| 16 | 
            +
                  def visit_Arel_Nodes_Limit o
         | 
| 17 | 
            +
                    "FETCH FIRST #{limit_for(o)} ROWS ONLY"
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 16 20 | 
             
                  def visit_Arel_Nodes_Offset o
         | 
| 17 21 | 
             
                    "OFFSET #{visit o.value} ROWS"
         | 
| 18 22 | 
             
                  end
         | 
    
        data/lib/arjdbc.rb
    CHANGED
    
    | @@ -1,26 +1,21 @@ | |
| 1 1 | 
             
            if defined?(JRUBY_VERSION)
         | 
| 2 2 | 
             
              begin
         | 
| 3 | 
            -
                tried_gem ||= false
         | 
| 4 3 | 
             
                require 'active_record/version'
         | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
                  RAILS_CONNECTION_ADAPTERS << %q(jdbc)
         | 
| 4 | 
            +
                if ActiveRecord::VERSION::MAJOR < 2
         | 
| 5 | 
            +
                  if defined?(RAILS_CONNECTION_ADAPTERS)
         | 
| 6 | 
            +
                    RAILS_CONNECTION_ADAPTERS << %q(jdbc)
         | 
| 7 | 
            +
                  else
         | 
| 8 | 
            +
                    RAILS_CONNECTION_ADAPTERS = %w(jdbc)
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
                  if ActiveRecord::VERSION::MAJOR == 1 && ActiveRecord::VERSION::MINOR == 14
         | 
| 11 | 
            +
                    require 'arjdbc/jdbc'
         | 
| 12 | 
            +
                  end
         | 
| 15 13 | 
             
                else
         | 
| 16 | 
            -
                   | 
| 17 | 
            -
                end
         | 
| 18 | 
            -
                if ActiveRecord::VERSION::MAJOR == 1 && ActiveRecord::VERSION::MINOR == 14
         | 
| 14 | 
            +
                  require 'active_record'
         | 
| 19 15 | 
             
                  require 'arjdbc/jdbc'
         | 
| 20 16 | 
             
                end
         | 
| 21 | 
            -
               | 
| 22 | 
            -
                 | 
| 23 | 
            -
                require 'arjdbc/jdbc'
         | 
| 17 | 
            +
              rescue LoadError
         | 
| 18 | 
            +
                warn "activerecord-jdbc-adapter requires ActiveRecord at runtime"
         | 
| 24 19 | 
             
              end
         | 
| 25 20 | 
             
            else
         | 
| 26 21 | 
             
              warn "activerecord-jdbc-adapter is for use with JRuby only"
         | 
    
        data/lib/arjdbc/db2/adapter.rb
    CHANGED
    
    | @@ -1,7 +1,29 @@ | |
| 1 1 | 
             
            module ArJdbc
         | 
| 2 2 | 
             
              module DB2
         | 
| 3 | 
            +
                def self.extended(base)
         | 
| 4 | 
            +
                  if base.zos?
         | 
| 5 | 
            +
                    unless @lob_callback_added
         | 
| 6 | 
            +
                      ActiveRecord::Base.class_eval do
         | 
| 7 | 
            +
                        def after_save_with_db2zos_blob
         | 
| 8 | 
            +
                          lobfields = self.class.columns.select { |c| c.sql_type =~ /blob|clob/i }
         | 
| 9 | 
            +
                          lobfields.each do |c|
         | 
| 10 | 
            +
                            value = self[c.name]
         | 
| 11 | 
            +
                            value = value.to_yaml if unserializable_attribute?(c.name, c)
         | 
| 12 | 
            +
                            next if value.nil?
         | 
| 13 | 
            +
                            connection.write_large_object(c.type == :binary, c.name, self.class.table_name, self.class.primary_key, quote_value(id), value)
         | 
| 14 | 
            +
                          end
         | 
| 15 | 
            +
                        end
         | 
| 16 | 
            +
                      end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                      ActiveRecord::Base.after_save :after_save_with_db2zos_blob
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                      @lob_callback_added = true
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 3 25 | 
             
                def self.column_selector
         | 
| 4 | 
            -
                  [ /(db2|as400)/i,
         | 
| 26 | 
            +
                  [ /(db2|as400|zos)/i,
         | 
| 5 27 | 
             
                    lambda { |cfg, column| column.extend(::ArJdbc::DB2::Column) } ]
         | 
| 6 28 | 
             
                end
         | 
| 7 29 |  | 
| @@ -147,15 +169,53 @@ module ArJdbc | |
| 147 169 | 
             
                  'DB2'
         | 
| 148 170 | 
             
                end
         | 
| 149 171 |  | 
| 150 | 
            -
                def arel2_visitors
         | 
| 172 | 
            +
                def self.arel2_visitors(config)
         | 
| 151 173 | 
             
                  require 'arel/visitors/db2'
         | 
| 152 | 
            -
                  { | 
| 174 | 
            +
                  {}.tap {|v| %w(db2 as400).each {|a| v[a] = ::Arel::Visitors::DB2 } }
         | 
| 153 175 | 
             
                end
         | 
| 154 176 |  | 
| 155 177 | 
             
                def add_limit_offset!(sql, options)
         | 
| 156 178 | 
             
                  replace_limit_offset!(sql, options[:limit], options[:offset])
         | 
| 157 179 | 
             
                end
         | 
| 158 180 |  | 
| 181 | 
            +
             | 
| 182 | 
            +
                def create_table(name, options = {}) #:nodoc:
         | 
| 183 | 
            +
                  if zos?
         | 
| 184 | 
            +
                    table_definition = ActiveRecord::ConnectionAdapters::TableDefinition.new(self)
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                    table_definition.primary_key(options[:primary_key] || ActiveRecord::Base.get_primary_key(name)) unless options[:id] == false
         | 
| 187 | 
            +
             | 
| 188 | 
            +
                    yield table_definition
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                    # Clobs in DB2 Host have to be created after the Table with an auxiliary Table.
         | 
| 191 | 
            +
                    # First: Save them for later in Array "clobs"
         | 
| 192 | 
            +
                    clobs =table_definition.columns.select { |x| x.type == "text" }
         | 
| 193 | 
            +
             | 
| 194 | 
            +
                    # Second: and delete them from the original Colums-Array
         | 
| 195 | 
            +
                    table_definition.columns.delete_if { |x| x.type=="text" }
         | 
| 196 | 
            +
             | 
| 197 | 
            +
                    if options[:force] && table_exists?(name)
         | 
| 198 | 
            +
                      super.drop_table(name, options)
         | 
| 199 | 
            +
                    end
         | 
| 200 | 
            +
             | 
| 201 | 
            +
                    create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE "
         | 
| 202 | 
            +
                    create_sql << "#{quote_table_name(name)} ("
         | 
| 203 | 
            +
                    create_sql << table_definition.to_sql
         | 
| 204 | 
            +
                    create_sql << ") #{options[:options]}"
         | 
| 205 | 
            +
                    create_sql << " IN #{@config[:database]}.#{@config[:tablespace]}"
         | 
| 206 | 
            +
             | 
| 207 | 
            +
                    execute create_sql
         | 
| 208 | 
            +
             | 
| 209 | 
            +
                    clobs.each do |clob_column|
         | 
| 210 | 
            +
                      execute "ALTER TABLE #{name+" ADD COLUMN "+clob_column.name.to_s+" clob"}"
         | 
| 211 | 
            +
                      execute "CREATE AUXILIARY TABLE #{name+"_"+clob_column.name.to_s+"_CD_"} IN #{@config[:database]}.#{@config[:lob_tablespaces][name.split(".")[1]]} STORES #{name} COLUMN "+clob_column.name.to_s
         | 
| 212 | 
            +
                      execute "CREATE UNIQUE INDEX #{name+"_"+clob_column.name.to_s+"_CD_"} ON #{name+"_"+clob_column.name.to_s+"_CD_"};"
         | 
| 213 | 
            +
                    end
         | 
| 214 | 
            +
                  else
         | 
| 215 | 
            +
                    super(name, options)
         | 
| 216 | 
            +
                  end
         | 
| 217 | 
            +
                end
         | 
| 218 | 
            +
             | 
| 159 219 | 
             
                def replace_limit_offset!(sql, limit, offset)
         | 
| 160 220 | 
             
                  if limit
         | 
| 161 221 | 
             
                    limit = limit.to_i
         | 
| @@ -200,7 +260,11 @@ module ArJdbc | |
| 200 260 | 
             
                    if column && column.type == :binary
         | 
| 201 261 | 
             
                      "BLOB('#{quote_string(value)}')"
         | 
| 202 262 | 
             
                    else
         | 
| 203 | 
            -
                       | 
| 263 | 
            +
                      if zos? && column.type == :text
         | 
| 264 | 
            +
                        "'if_you_see_this_value_the_after_save_hook_in_db2_zos_adapter_went_wrong'"
         | 
| 265 | 
            +
                      else
         | 
| 266 | 
            +
                        "'#{quote_string(value)}'"
         | 
| 267 | 
            +
                      end
         | 
| 204 268 | 
             
                    end
         | 
| 205 269 | 
             
                  else super
         | 
| 206 270 | 
             
                  end
         | 
| @@ -228,6 +292,21 @@ module ArJdbc | |
| 228 292 | 
             
                  tables.each {|table| drop_table("#{db2_schema}.#{table}")}
         | 
| 229 293 | 
             
                end
         | 
| 230 294 |  | 
| 295 | 
            +
                def add_index(table_name, column_name, options = {})
         | 
| 296 | 
            +
                  if (!zos? || (table_name.to_s ==  ActiveRecord::Migrator.schema_migrations_table_name.to_s))
         | 
| 297 | 
            +
                    super
         | 
| 298 | 
            +
                  else
         | 
| 299 | 
            +
                    statement ="CREATE"
         | 
| 300 | 
            +
                    statement << " UNIQUE " if options[:unique]
         | 
| 301 | 
            +
                    statement << " INDEX "+"#{ActiveRecord::Base.table_name_prefix}#{options[:name]} "
         | 
| 302 | 
            +
             | 
| 303 | 
            +
                    statement << " ON #{table_name}(#{column_name})"
         | 
| 304 | 
            +
             | 
| 305 | 
            +
                    execute statement
         | 
| 306 | 
            +
                  end
         | 
| 307 | 
            +
                end
         | 
| 308 | 
            +
             | 
| 309 | 
            +
             | 
| 231 310 | 
             
                def remove_index(table_name, options = { })
         | 
| 232 311 | 
             
                  execute "DROP INDEX #{quote_column_name(index_name(table_name, options))}"
         | 
| 233 312 | 
             
                end
         | 
| @@ -311,6 +390,10 @@ module ArJdbc | |
| 311 390 | 
             
                def columns(table_name, name = nil)
         | 
| 312 391 | 
             
                  cols = @connection.columns(table_name, name, db2_schema)
         | 
| 313 392 |  | 
| 393 | 
            +
                  if zos?
         | 
| 394 | 
            +
                    # Remove the mighty db2_generated_rowid_for_lobs from the list of columns
         | 
| 395 | 
            +
                    cols = cols.reject { |col| "db2_generated_rowid_for_lobs" == col.name }
         | 
| 396 | 
            +
                  end
         | 
| 314 397 | 
             
                  # scrub out sizing info when CREATE TABLE doesn't support it
         | 
| 315 398 | 
             
                  # but JDBC reports it (doh!)
         | 
| 316 399 | 
             
                  for col in cols
         | 
| @@ -398,6 +481,10 @@ module ArJdbc | |
| 398 481 | 
             
                  definition
         | 
| 399 482 | 
             
                end
         | 
| 400 483 |  | 
| 484 | 
            +
                def zos?
         | 
| 485 | 
            +
                  @config[:driver] == "com.ibm.db2.jcc.DB2Driver"
         | 
| 486 | 
            +
                end
         | 
| 487 | 
            +
             | 
| 401 488 | 
             
                private
         | 
| 402 489 | 
             
                def as400?
         | 
| 403 490 | 
             
                    @config[:url] =~ /^jdbc:as400:/
         | 
    
        data/lib/arjdbc/derby/adapter.rb
    CHANGED
    
    | @@ -7,7 +7,7 @@ module ::ArJdbc | |
| 7 7 | 
             
                end
         | 
| 8 8 |  | 
| 9 9 | 
             
                def self.monkey_rails
         | 
| 10 | 
            -
                  unless @already_monkeyd
         | 
| 10 | 
            +
                  unless defined?(@already_monkeyd)
         | 
| 11 11 | 
             
                    # Needed because Rails is broken wrt to quoting of
         | 
| 12 12 | 
             
                    # some values. Most databases are nice about it,
         | 
| 13 13 | 
             
                    # but not Derby. The real issue is that you can't
         | 
| @@ -50,7 +50,7 @@ module ::ArJdbc | |
| 50 50 | 
             
                  def default_value(value)
         | 
| 51 51 | 
             
                    # jdbc returns column default strings with actual single quotes around the value.
         | 
| 52 52 | 
             
                    return $1 if value =~ /^'(.*)'$/
         | 
| 53 | 
            -
             | 
| 53 | 
            +
                    return nil if value == "GENERATED_BY_DEFAULT"
         | 
| 54 54 | 
             
                    value
         | 
| 55 55 | 
             
                  end
         | 
| 56 56 | 
             
                end
         | 
| @@ -59,9 +59,9 @@ module ::ArJdbc | |
| 59 59 | 
             
                  'Derby'
         | 
| 60 60 | 
             
                end
         | 
| 61 61 |  | 
| 62 | 
            -
                def arel2_visitors
         | 
| 62 | 
            +
                def self.arel2_visitors(config)
         | 
| 63 63 | 
             
                  require 'arel/visitors/derby'
         | 
| 64 | 
            -
                  { | 
| 64 | 
            +
                  {}.tap {|v| %w(derby jdbcderby).each {|a| v[a] = ::Arel::Visitors::Derby } }
         | 
| 65 65 | 
             
                end
         | 
| 66 66 |  | 
| 67 67 | 
             
                include ArJdbc::MissingFunctionalityHelper
         | 
| @@ -171,7 +171,8 @@ module ::ArJdbc | |
| 171 171 | 
             
                  execute(add_column_sql)
         | 
| 172 172 | 
             
                end
         | 
| 173 173 |  | 
| 174 | 
            -
                def execute(sql, name = nil)
         | 
| 174 | 
            +
                def execute(sql, name = nil, binds = [])
         | 
| 175 | 
            +
                  sql = extract_sql(sql)
         | 
| 175 176 | 
             
                  if sql =~ /\A\s*(UPDATE|INSERT)/i
         | 
| 176 177 | 
             
                    i = sql =~ /\swhere\s/im
         | 
| 177 178 | 
             
                    if i
         | 
| @@ -196,8 +197,7 @@ module ::ArJdbc | |
| 196 197 |  | 
| 197 198 | 
             
                  # construct a clean list of column names from the ORDER BY clause, removing
         | 
| 198 199 | 
             
                  # any asc/desc modifiers
         | 
| 199 | 
            -
                  order_columns = order_by.split(',').collect { |s| s.split.first }
         | 
| 200 | 
            -
                  order_columns.delete_if(&:blank?)
         | 
| 200 | 
            +
                  order_columns = [order_by].flatten.map{|o| o.split(',').collect { |s| s.split.first } }.flatten.reject(&:blank?)
         | 
| 201 201 | 
             
                  order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s,i| "#{s} AS alias_#{i}" }
         | 
| 202 202 |  | 
| 203 203 | 
             
                  # return a DISTINCT clause that's distinct on the columns we want but includes
         | 
| @@ -316,7 +316,7 @@ module ::ArJdbc | |
| 316 316 | 
             
                end
         | 
| 317 317 |  | 
| 318 318 | 
             
                def quote_column_name(name) #:nodoc:
         | 
| 319 | 
            -
                  %Q{"#{name.to_s.upcase.gsub( | 
| 319 | 
            +
                  %Q{"#{name.to_s.upcase.gsub(/\"/, '""')}"}
         | 
| 320 320 | 
             
                end
         | 
| 321 321 |  | 
| 322 322 | 
             
                def quoted_true
         | 
| @@ -4,6 +4,7 @@ module ActiveRecord | |
| 4 4 | 
             
                  def derby_connection(config)
         | 
| 5 5 | 
             
                    config[:url] ||= "jdbc:derby:#{config[:database]};create=true"
         | 
| 6 6 | 
             
                    config[:driver] ||= "org.apache.derby.jdbc.EmbeddedDriver"
         | 
| 7 | 
            +
                    config[:adapter_spec] = ::ArJdbc::Derby
         | 
| 7 8 | 
             
                    conn = embedded_driver(config)
         | 
| 8 9 | 
             
                    md = conn.jdbc_connection.meta_data
         | 
| 9 10 | 
             
                    if md.database_major_version < 10 || (md.database_major_version == 10 && md.database_minor_version < 5)
         | 
| @@ -23,9 +23,9 @@ module ::ArJdbc | |
| 23 23 | 
             
                  'Firebird'
         | 
| 24 24 | 
             
                end
         | 
| 25 25 |  | 
| 26 | 
            -
                def arel2_visitors
         | 
| 26 | 
            +
                def self.arel2_visitors(config)
         | 
| 27 27 | 
             
                  require 'arel/visitors/firebird'
         | 
| 28 | 
            -
                  { | 
| 28 | 
            +
                  {}.tap {|v| %w(firebird firebirdsql).each {|a| v[a] = ::Arel::Visitors::Firebird } }
         | 
| 29 29 | 
             
                end
         | 
| 30 30 |  | 
| 31 31 | 
             
                def modify_types(tp)
         | 
| @@ -35,8 +35,8 @@ module ::ArJdbc | |
| 35 35 | 
             
                  tp
         | 
| 36 36 | 
             
                end
         | 
| 37 37 |  | 
| 38 | 
            -
                def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) # :nodoc:
         | 
| 39 | 
            -
                  execute(sql, name)
         | 
| 38 | 
            +
                def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) # :nodoc:
         | 
| 39 | 
            +
                  execute(sql, name, binds)
         | 
| 40 40 | 
             
                  id_value
         | 
| 41 41 | 
             
                end
         | 
| 42 42 |  | 
    
        data/lib/arjdbc/h2/adapter.rb
    CHANGED
    
    | @@ -12,8 +12,9 @@ module ArJdbc | |
| 12 12 | 
             
                  'H2'
         | 
| 13 13 | 
             
                end
         | 
| 14 14 |  | 
| 15 | 
            -
                def arel2_visitors
         | 
| 16 | 
            -
                   | 
| 15 | 
            +
                def self.arel2_visitors(config)
         | 
| 16 | 
            +
                  v = HSQLDB.arel2_visitors(config)
         | 
| 17 | 
            +
                  v.merge({}.tap {|v| %w(h2 jdbch2).each {|a| v[a] = ::Arel::Visitors::HSQLDB } })
         | 
| 17 18 | 
             
                end
         | 
| 18 19 |  | 
| 19 20 | 
             
                def h2_adapter
         | 
| @@ -27,6 +27,9 @@ module ::ArJdbc | |
| 27 27 |  | 
| 28 28 | 
             
                  # Post process default value from JDBC into a Rails-friendly format (columns{-internal})
         | 
| 29 29 | 
             
                  def default_value(value)
         | 
| 30 | 
            +
                    # H2 auto-generated key default value
         | 
| 31 | 
            +
                    return nil if value =~ /^\(NEXT VALUE FOR/i
         | 
| 32 | 
            +
             | 
| 30 33 | 
             
                    # jdbc returns column default strings with actual single quotes around the value.
         | 
| 31 34 | 
             
                    return $1 if value =~ /^'(.*)'$/
         | 
| 32 35 |  | 
| @@ -38,9 +41,9 @@ module ::ArJdbc | |
| 38 41 | 
             
                  'Hsqldb'
         | 
| 39 42 | 
             
                end
         | 
| 40 43 |  | 
| 41 | 
            -
                def arel2_visitors
         | 
| 44 | 
            +
                def self.arel2_visitors(config)
         | 
| 42 45 | 
             
                  require 'arel/visitors/hsqldb'
         | 
| 43 | 
            -
                  { | 
| 46 | 
            +
                  {}.tap {|v| %w(hsqldb jdbchsqldb).each {|a| v[a] = ::Arel::Visitors::HSQLDB } }
         | 
| 44 47 | 
             
                end
         | 
| 45 48 |  | 
| 46 49 | 
             
                def modify_types(tp)
         | 
| @@ -130,9 +130,9 @@ module ::ArJdbc | |
| 130 130 | 
             
                end
         | 
| 131 131 |  | 
| 132 132 | 
             
              private
         | 
| 133 | 
            -
                def select(sql,  | 
| 133 | 
            +
                def select(sql, *rest)
         | 
| 134 134 | 
             
                  # Informix does not like "= NULL", "!= NULL", or "<> NULL".
         | 
| 135 | 
            -
                  execute(sql.gsub(/(!=|<>)\s*null/i, "IS NOT NULL").gsub(/=\s*null/i, "IS NULL"),  | 
| 135 | 
            +
                  execute(sql.gsub(/(!=|<>)\s*null/i, "IS NOT NULL").gsub(/=\s*null/i, "IS NULL"), *rest)
         | 
| 136 136 | 
             
                end
         | 
| 137 137 | 
             
              end # module Informix
         | 
| 138 138 | 
             
            end # module ::ArJdbc
         | 
| @@ -4,6 +4,7 @@ class ActiveRecord::Base | |
| 4 4 | 
             
                  config[:port] ||= 9088
         | 
| 5 5 | 
             
                  config[:url] ||= "jdbc:informix-sqli://#{config[:host]}:#{config[:port]}/#{config[:database]}:INFORMIXSERVER=#{config[:servername]}"
         | 
| 6 6 | 
             
                  config[:driver] = 'com.informix.jdbc.IfxDriver'
         | 
| 7 | 
            +
                  config[:adapter_spec] = ::ArJdbc::Informix
         | 
| 7 8 | 
             
                  jdbc_connection(config)
         | 
| 8 9 | 
             
                end
         | 
| 9 10 | 
             
              end
         | 
    
        data/lib/arjdbc/jdbc/adapter.rb
    CHANGED
    
    | @@ -25,13 +25,16 @@ module ActiveRecord | |
| 25 25 |  | 
| 26 26 | 
             
                  def initialize(connection, logger, config)
         | 
| 27 27 | 
             
                    @config = config
         | 
| 28 | 
            -
                    spec = adapter_spec config
         | 
| 28 | 
            +
                    spec = config[:adapter_spec] || adapter_spec(config)
         | 
| 29 | 
            +
                    config[:adapter_spec] ||= spec
         | 
| 29 30 | 
             
                    unless connection
         | 
| 30 31 | 
             
                      connection_class = jdbc_connection_class spec
         | 
| 31 32 | 
             
                      connection = connection_class.new config
         | 
| 32 33 | 
             
                    end
         | 
| 33 34 | 
             
                    super(connection, logger)
         | 
| 34 | 
            -
                     | 
| 35 | 
            +
                    if spec && (config[:adapter_class].nil? || config[:adapter_class] == JdbcAdapter)
         | 
| 36 | 
            +
                      extend spec
         | 
| 37 | 
            +
                    end
         | 
| 35 38 | 
             
                    configure_arel2_visitors(config)
         | 
| 36 39 | 
             
                    connection.adapter = self
         | 
| 37 40 | 
             
                    JndiConnectionPoolCallbacks.prepare(self, connection)
         | 
| @@ -89,15 +92,27 @@ module ActiveRecord | |
| 89 92 | 
             
                    'JDBC'
         | 
| 90 93 | 
             
                  end
         | 
| 91 94 |  | 
| 92 | 
            -
                  def  | 
| 93 | 
            -
                     | 
| 95 | 
            +
                  def self.visitor_for(pool)
         | 
| 96 | 
            +
                    config = pool.spec.config
         | 
| 97 | 
            +
                    adapter = config[:adapter]
         | 
| 98 | 
            +
                    adapter_spec = config[:adapter_spec] || self
         | 
| 99 | 
            +
                    if adapter =~ /^(jdbc|jndi)$/
         | 
| 100 | 
            +
                      adapter_spec.arel2_visitors(config).values.first.new(pool)
         | 
| 101 | 
            +
                    else
         | 
| 102 | 
            +
                      adapter_spec.arel2_visitors(config)[adapter].new(pool)
         | 
| 103 | 
            +
                    end
         | 
| 104 | 
            +
                  end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                  def self.arel2_visitors(config)
         | 
| 107 | 
            +
                    { 'jdbc' => ::Arel::Visitors::ToSql }
         | 
| 94 108 | 
             
                  end
         | 
| 95 109 |  | 
| 96 110 | 
             
                  def configure_arel2_visitors(config)
         | 
| 97 111 | 
             
                    if defined?(::Arel::Visitors::VISITORS)
         | 
| 98 112 | 
             
                      visitors = ::Arel::Visitors::VISITORS
         | 
| 99 113 | 
             
                      visitor = nil
         | 
| 100 | 
            -
                       | 
| 114 | 
            +
                      adapter_spec = config[:adapter_spec] || self
         | 
| 115 | 
            +
                      adapter_spec.arel2_visitors(config).each do |k,v|
         | 
| 101 116 | 
             
                        visitor = v
         | 
| 102 117 | 
             
                        visitors[k] = v
         | 
| 103 118 | 
             
                      end
         | 
| @@ -176,7 +191,17 @@ module ActiveRecord | |
| 176 191 | 
             
                    @connection.disconnect!
         | 
| 177 192 | 
             
                  end
         | 
| 178 193 |  | 
| 179 | 
            -
                  def  | 
| 194 | 
            +
                  def substitute_binds(manager, binds = [])
         | 
| 195 | 
            +
                    sql = extract_sql(manager)
         | 
| 196 | 
            +
                    if binds.empty?
         | 
| 197 | 
            +
                      sql
         | 
| 198 | 
            +
                    else
         | 
| 199 | 
            +
                      sql.gsub('?') { quote(*binds.shift.reverse) }
         | 
| 200 | 
            +
                    end
         | 
| 201 | 
            +
                  end
         | 
| 202 | 
            +
             | 
| 203 | 
            +
                  def execute(sql, name = nil, binds = [])
         | 
| 204 | 
            +
                    sql = substitute_binds(sql, binds)
         | 
| 180 205 | 
             
                    if name == :skip_logging
         | 
| 181 206 | 
             
                      _execute(sql)
         | 
| 182 207 | 
             
                    else
         | 
| @@ -191,25 +216,31 @@ module ActiveRecord | |
| 191 216 | 
             
                    @connection.execute(sql)
         | 
| 192 217 | 
             
                  end
         | 
| 193 218 |  | 
| 194 | 
            -
                  def jdbc_insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
         | 
| 195 | 
            -
                    insert_sql(sql, name, pk, id_value, sequence_name)
         | 
| 219 | 
            +
                  def jdbc_insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
         | 
| 220 | 
            +
                    insert_sql(sql, name, pk, id_value, sequence_name, binds)
         | 
| 196 221 | 
             
                  end
         | 
| 197 222 |  | 
| 198 | 
            -
                  def jdbc_update(sql, name = nil) #:nodoc:
         | 
| 199 | 
            -
                    execute(sql, name)
         | 
| 223 | 
            +
                  def jdbc_update(sql, name = nil, binds = []) #:nodoc:
         | 
| 224 | 
            +
                    execute(sql, name, binds)
         | 
| 200 225 | 
             
                  end
         | 
| 201 | 
            -
                  def jdbc_select_all(sql, name = nil)
         | 
| 202 | 
            -
                    select(sql, name)
         | 
| 226 | 
            +
                  def jdbc_select_all(sql, name = nil, binds = [])
         | 
| 227 | 
            +
                    select(sql, name, binds)
         | 
| 203 228 | 
             
                  end
         | 
| 204 229 |  | 
| 205 | 
            -
                   | 
| 206 | 
            -
             | 
| 207 | 
            -
             | 
| 208 | 
            -
             | 
| 230 | 
            +
                  if ActiveRecord::VERSION::MAJOR < 3
         | 
| 231 | 
            +
                    # Allow query caching to work even when we override alias_method_chain'd methods
         | 
| 232 | 
            +
                    alias_chained_method :select_all, :query_cache, :jdbc_select_all
         | 
| 233 | 
            +
                    alias_chained_method :update, :query_dirty, :jdbc_update
         | 
| 234 | 
            +
                    alias_chained_method :insert, :query_dirty, :jdbc_insert
         | 
| 235 | 
            +
             | 
| 236 | 
            +
                    # Do we need this? Not in AR 3.
         | 
| 237 | 
            +
                    def select_one(sql, name = nil)
         | 
| 238 | 
            +
                      select(sql, name).first
         | 
| 239 | 
            +
                    end
         | 
| 240 | 
            +
                  end
         | 
| 209 241 |  | 
| 210 | 
            -
                   | 
| 211 | 
            -
             | 
| 212 | 
            -
                    select(sql, name).first
         | 
| 242 | 
            +
                  def last_inserted_id(result)
         | 
| 243 | 
            +
                    result
         | 
| 213 244 | 
             
                  end
         | 
| 214 245 |  | 
| 215 246 | 
             
                  def select_rows(sql, name = nil)
         | 
| @@ -218,11 +249,41 @@ module ActiveRecord | |
| 218 249 | 
             
                    rows
         | 
| 219 250 | 
             
                  end
         | 
| 220 251 |  | 
| 221 | 
            -
                  def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
         | 
| 222 | 
            -
                    id = execute(sql, name = nil)
         | 
| 252 | 
            +
                  def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
         | 
| 253 | 
            +
                    id = execute(sql, name = nil, binds)
         | 
| 223 254 | 
             
                    id_value || id
         | 
| 224 255 | 
             
                  end
         | 
| 225 256 |  | 
| 257 | 
            +
                  ### Rails 3.1 prepared statement support
         | 
| 258 | 
            +
             | 
| 259 | 
            +
                  # Executes +sql+ statement in the context of this connection using
         | 
| 260 | 
            +
                  # +binds+ as the bind substitutes.  +name+ is logged along with
         | 
| 261 | 
            +
                  # the executed +sql+ statement.
         | 
| 262 | 
            +
                  def exec_query(sql, name = 'SQL', binds = [])
         | 
| 263 | 
            +
                    execute(sql, name, binds)
         | 
| 264 | 
            +
                  end
         | 
| 265 | 
            +
             | 
| 266 | 
            +
                  # Executes insert +sql+ statement in the context of this connection using
         | 
| 267 | 
            +
                  # +binds+ as the bind substitutes. +name+ is the logged along with
         | 
| 268 | 
            +
                  # the executed +sql+ statement.
         | 
| 269 | 
            +
                  def exec_insert(sql, name, binds)
         | 
| 270 | 
            +
                    exec_query(sql, name, binds)
         | 
| 271 | 
            +
                  end
         | 
| 272 | 
            +
             | 
| 273 | 
            +
                  # Executes delete +sql+ statement in the context of this connection using
         | 
| 274 | 
            +
                  # +binds+ as the bind substitutes. +name+ is the logged along with
         | 
| 275 | 
            +
                  # the executed +sql+ statement.
         | 
| 276 | 
            +
                  def exec_delete(sql, name, binds)
         | 
| 277 | 
            +
                    exec_query(sql, name, binds)
         | 
| 278 | 
            +
                  end
         | 
| 279 | 
            +
             | 
| 280 | 
            +
                  # Executes update +sql+ statement in the context of this connection using
         | 
| 281 | 
            +
                  # +binds+ as the bind substitutes. +name+ is the logged along with
         | 
| 282 | 
            +
                  # the executed +sql+ statement.
         | 
| 283 | 
            +
                  def exec_update(sql, name, binds)
         | 
| 284 | 
            +
                    exec_query(sql, name, binds)
         | 
| 285 | 
            +
                  end
         | 
| 286 | 
            +
             | 
| 226 287 | 
             
                  def jdbc_columns(table_name, name = nil)
         | 
| 227 288 | 
             
                    @connection.columns(table_name.to_s)
         | 
| 228 289 | 
             
                  end
         | 
| @@ -277,7 +338,16 @@ module ActiveRecord | |
| 277 338 | 
             
                    puts e.backtrace if $DEBUG || ENV['DEBUG']
         | 
| 278 339 | 
             
                    super
         | 
| 279 340 | 
             
                  end
         | 
| 280 | 
            -
             | 
| 341 | 
            +
             | 
| 342 | 
            +
                  def extract_sql(obj)
         | 
| 343 | 
            +
                    if obj.respond_to? :to_sql
         | 
| 344 | 
            +
                      obj.send :to_sql
         | 
| 345 | 
            +
                    else
         | 
| 346 | 
            +
                      obj
         | 
| 347 | 
            +
                    end
         | 
| 348 | 
            +
                  end
         | 
| 349 | 
            +
             | 
| 350 | 
            +
                  protected :translate_exception, :extract_sql
         | 
| 281 351 | 
             
                end
         | 
| 282 352 | 
             
              end
         | 
| 283 353 | 
             
            end
         |