odbc_adapter 5.0.0 → 5.0.1
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.
- checksums.yaml +4 -4
 - data/README.md +26 -4
 - data/bin/console +5 -0
 - data/lib/active_record/connection_adapters/odbc_adapter.rb +16 -11
 - data/lib/odbc_adapter.rb +0 -15
 - data/lib/odbc_adapter/adapters/mysql_odbc_adapter.rb +31 -50
 - data/lib/odbc_adapter/adapters/null_odbc_adapter.rb +31 -0
 - data/lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb +42 -35
 - data/lib/odbc_adapter/database_limits.rb +2 -2
 - data/lib/odbc_adapter/database_metadata.rb +44 -0
 - data/lib/odbc_adapter/database_statements.rb +2 -4
 - data/lib/odbc_adapter/error.rb +4 -0
 - data/lib/odbc_adapter/quoting.rb +3 -4
 - data/lib/odbc_adapter/registry.rb +50 -0
 - data/lib/odbc_adapter/schema_statements.rb +22 -3
 - data/lib/odbc_adapter/version.rb +1 -1
 - data/odbc_adapter.gemspec +1 -0
 - metadata +20 -3
 - data/lib/odbc_adapter/dbms.rb +0 -50
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: f5157fd72c8b51e81109ffbc557706d5164e52ea
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 07045f2ee0d6f4a8c61f0566e9a2ed4af6a88565
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 5ac83f350948348b7f0e36bc68881b2b401f47ebd449f615abee9f5650d1c1bda3fb6fb5de7519e3af5d5d4efbc5b2d61b67bacd96795eb96b3fcdbe77b0e1cb
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 7263035cff902e1776abc8000b961d55779d1c6e9084cbaea24561d3ea2aef85bc9331bfbceee3885d85ad2dfa8909150edc8dee275652566cd25a51f645c129
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -2,10 +2,16 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            [](https://travis-ci.com/localytics/odbc_adapter)
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
            An ActiveRecord ODBC adapter.
         
     | 
| 
      
 5 
     | 
    
         
            +
            An ActiveRecord ODBC adapter. Master branch is working off of edge Rails. Previous work has been done to make it compatible with Rails 3.2 and 4.2; for those versions use the 3.2.x or 4.2.x gem releases.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            This adapter will work for basic queries for most DBMSs out of the box, without support for migrations. Full support is built-in for MySQL 5 and PostgreSQL 9 databases. You can register your own adapter to get more support for your DBMS using the `ODBCAdapter.register` function.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            A lot of this work is based on [OpenLink's ActiveRecord adapter](http://odbc-rails.rubyforge.org/) which works for earlier versions of Rails.
         
     | 
| 
       6 
10 
     | 
    
         | 
| 
       7 
11 
     | 
    
         
             
            ## Installation
         
     | 
| 
       8 
12 
     | 
    
         | 
| 
      
 13 
     | 
    
         
            +
            Ensure you have the ODBC driver installed on your machine. You will also need the driver for whichever database to which you want ODBC to connect.
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
       9 
15 
     | 
    
         
             
            Add this line to your application's Gemfile:
         
     | 
| 
       10 
16 
     | 
    
         | 
| 
       11 
17 
     | 
    
         
             
            ```ruby
         
     | 
| 
         @@ -22,11 +28,27 @@ Or install it yourself as: 
     | 
|
| 
       22 
28 
     | 
    
         | 
| 
       23 
29 
     | 
    
         
             
            ## Usage
         
     | 
| 
       24 
30 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
      
 31 
     | 
    
         
            +
            Configure your `database.yml` by either using the `dsn` option to point to a DSN that corresponds to a valid entry in your `~/.odbc.ini` file:
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            ```
         
     | 
| 
      
 34 
     | 
    
         
            +
            development:
         
     | 
| 
      
 35 
     | 
    
         
            +
              adapter:  odbc
         
     | 
| 
      
 36 
     | 
    
         
            +
              dsn: MyDatabaseDSN
         
     | 
| 
      
 37 
     | 
    
         
            +
            ```
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            or by using the `conn_str` option and specifying the entire connection string:
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            ```
         
     | 
| 
      
 42 
     | 
    
         
            +
            development:
         
     | 
| 
      
 43 
     | 
    
         
            +
              adapter: odbc
         
     | 
| 
      
 44 
     | 
    
         
            +
              conn_str: "DRIVER={PostgreSQL ANSI};SERVER=localhost;PORT=5432;DATABASE=my_database;UID=postgres;"
         
     | 
| 
      
 45 
     | 
    
         
            +
            ```
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            ActiveRecord models that use this connection will now be connecting to the configured database using the ODBC driver.
         
     | 
| 
       26 
48 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
      
 49 
     | 
    
         
            +
            ## Testing
         
     | 
| 
       28 
50 
     | 
    
         | 
| 
       29 
     | 
    
         
            -
            To  
     | 
| 
      
 51 
     | 
    
         
            +
            To run the tests, you'll need the ODBC driver as well as the connection adapter for each database against which you're trying to test. Then run `DSN=MyDatabaseDSN bundle exec rake test` and the test suite will be run by connecting to your database.
         
     | 
| 
       30 
52 
     | 
    
         | 
| 
       31 
53 
     | 
    
         
             
            ## Contributing
         
     | 
| 
       32 
54 
     | 
    
         | 
    
        data/bin/console
    CHANGED
    
    | 
         @@ -3,5 +3,10 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            require 'bundler/setup'
         
     | 
| 
       4 
4 
     | 
    
         
             
            require 'odbc_adapter'
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
      
 6 
     | 
    
         
            +
            options = { adapter: 'odbc' }
         
     | 
| 
      
 7 
     | 
    
         
            +
            options[:dsn]      = ENV['DSN']      if ENV['DSN']
         
     | 
| 
      
 8 
     | 
    
         
            +
            options[:conn_str] = ENV['CONN_STR'] if ENV['CONN_STR']
         
     | 
| 
      
 9 
     | 
    
         
            +
            ActiveRecord::Base.establish_connection(options) if options.any?
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
       6 
11 
     | 
    
         
             
            require 'irb'
         
     | 
| 
       7 
12 
     | 
    
         
             
            IRB.start
         
     | 
| 
         @@ -2,22 +2,23 @@ require 'active_record' 
     | 
|
| 
       2 
2 
     | 
    
         
             
            require 'arel/visitors/bind_visitor'
         
     | 
| 
       3 
3 
     | 
    
         
             
            require 'odbc'
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
            require 'odbc_adapter'
         
     | 
| 
       6 
5 
     | 
    
         
             
            require 'odbc_adapter/database_limits'
         
     | 
| 
       7 
6 
     | 
    
         
             
            require 'odbc_adapter/database_statements'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'odbc_adapter/error'
         
     | 
| 
       8 
8 
     | 
    
         
             
            require 'odbc_adapter/quoting'
         
     | 
| 
       9 
9 
     | 
    
         
             
            require 'odbc_adapter/schema_statements'
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
            require 'odbc_adapter/column'
         
     | 
| 
       12 
12 
     | 
    
         
             
            require 'odbc_adapter/column_metadata'
         
     | 
| 
       13 
     | 
    
         
            -
            require 'odbc_adapter/ 
     | 
| 
      
 13 
     | 
    
         
            +
            require 'odbc_adapter/database_metadata'
         
     | 
| 
      
 14 
     | 
    
         
            +
            require 'odbc_adapter/registry'
         
     | 
| 
       14 
15 
     | 
    
         
             
            require 'odbc_adapter/type_caster'
         
     | 
| 
       15 
16 
     | 
    
         
             
            require 'odbc_adapter/version'
         
     | 
| 
       16 
17 
     | 
    
         | 
| 
       17 
18 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       18 
19 
     | 
    
         
             
              class Base
         
     | 
| 
       19 
20 
     | 
    
         
             
                class << self
         
     | 
| 
       20 
     | 
    
         
            -
                  def odbc_connection(config) 
     | 
| 
      
 21 
     | 
    
         
            +
                  def odbc_connection(config)
         
     | 
| 
       21 
22 
     | 
    
         
             
                    config = config.symbolize_keys
         
     | 
| 
       22 
23 
     | 
    
         | 
| 
       23 
24 
     | 
    
         
             
                    connection, options =
         
     | 
| 
         @@ -29,8 +30,8 @@ module ActiveRecord 
     | 
|
| 
       29 
30 
     | 
    
         
             
                        raise ArgumentError, "No data source name (:dsn) or connection string (:conn_str) specified."
         
     | 
| 
       30 
31 
     | 
    
         
             
                      end
         
     | 
| 
       31 
32 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
                     
     | 
| 
       33 
     | 
    
         
            -
                     
     | 
| 
      
 33 
     | 
    
         
            +
                    database_metadata = ::ODBCAdapter::DatabaseMetadata.new(connection)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    database_metadata.adapter_class.new(connection, logger, database_metadata)
         
     | 
| 
       34 
35 
     | 
    
         
             
                  end
         
     | 
| 
       35 
36 
     | 
    
         | 
| 
       36 
37 
     | 
    
         
             
                  private
         
     | 
| 
         @@ -75,14 +76,16 @@ module ActiveRecord 
     | 
|
| 
       75 
76 
     | 
    
         | 
| 
       76 
77 
     | 
    
         
             
                  ADAPTER_NAME = 'ODBC'.freeze
         
     | 
| 
       77 
78 
     | 
    
         
             
                  BOOLEAN_TYPE = 'BOOLEAN'.freeze
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
       78 
80 
     | 
    
         
             
                  ERR_DUPLICATE_KEY_VALUE = 23505
         
     | 
| 
      
 81 
     | 
    
         
            +
                  ERR_QUERY_TIMED_OUT = /Query has timed out/
         
     | 
| 
       79 
82 
     | 
    
         | 
| 
       80 
     | 
    
         
            -
                  attr_reader : 
     | 
| 
      
 83 
     | 
    
         
            +
                  attr_reader :database_metadata
         
     | 
| 
       81 
84 
     | 
    
         | 
| 
       82 
     | 
    
         
            -
                  def initialize(connection, logger,  
     | 
| 
      
 85 
     | 
    
         
            +
                  def initialize(connection, logger, database_metadata)
         
     | 
| 
       83 
86 
     | 
    
         
             
                    super(connection, logger)
         
     | 
| 
       84 
     | 
    
         
            -
                    @connection 
     | 
| 
       85 
     | 
    
         
            -
                    @ 
     | 
| 
      
 87 
     | 
    
         
            +
                    @connection        = connection
         
     | 
| 
      
 88 
     | 
    
         
            +
                    @database_metadata = database_metadata
         
     | 
| 
       86 
89 
     | 
    
         
             
                  end
         
     | 
| 
       87 
90 
     | 
    
         | 
| 
       88 
91 
     | 
    
         
             
                  # Returns the human-readable name of the adapter. Use mixed case - one
         
     | 
| 
         @@ -165,9 +168,11 @@ module ActiveRecord 
     | 
|
| 
       165 
168 
     | 
    
         
             
                  end
         
     | 
| 
       166 
169 
     | 
    
         | 
| 
       167 
170 
     | 
    
         
             
                  def translate_exception(exception, message)
         
     | 
| 
       168 
     | 
    
         
            -
                    case 
     | 
| 
       169 
     | 
    
         
            -
                    when ERR_DUPLICATE_KEY_VALUE
         
     | 
| 
      
 171 
     | 
    
         
            +
                    case
         
     | 
| 
      
 172 
     | 
    
         
            +
                    when exception.message[/^\d+/].to_i == ERR_DUPLICATE_KEY_VALUE
         
     | 
| 
       170 
173 
     | 
    
         
             
                      ActiveRecord::RecordNotUnique.new(message, exception)
         
     | 
| 
      
 174 
     | 
    
         
            +
                    when exception.message =~ ERR_QUERY_TIMED_OUT
         
     | 
| 
      
 175 
     | 
    
         
            +
                      ::ODBCAdapter::QueryTimeoutError.new(message, exception)
         
     | 
| 
       171 
176 
     | 
    
         
             
                    else
         
     | 
| 
       172 
177 
     | 
    
         
             
                      super
         
     | 
| 
       173 
178 
     | 
    
         
             
                    end
         
     | 
    
        data/lib/odbc_adapter.rb
    CHANGED
    
    | 
         @@ -1,17 +1,2 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Requiring with this pattern to mirror ActiveRecord
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'active_record/connection_adapters/odbc_adapter'
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
            module ODBCAdapter
         
     | 
| 
       5 
     | 
    
         
            -
              class << self
         
     | 
| 
       6 
     | 
    
         
            -
                def dbms_registry
         
     | 
| 
       7 
     | 
    
         
            -
                  @dbms_registry ||= {
         
     | 
| 
       8 
     | 
    
         
            -
                    /my.*sql/i => :MySQL,
         
     | 
| 
       9 
     | 
    
         
            -
                    /postgres/i => :PostgreSQL
         
     | 
| 
       10 
     | 
    
         
            -
                  }
         
     | 
| 
       11 
     | 
    
         
            -
                end
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
                def register(pattern, superclass, &block)
         
     | 
| 
       14 
     | 
    
         
            -
                  dbms_registry[pattern] = Class.new(superclass, &block)
         
     | 
| 
       15 
     | 
    
         
            -
                end
         
     | 
| 
       16 
     | 
    
         
            -
              end
         
     | 
| 
       17 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module ODBCAdapter
         
     | 
| 
       2 
2 
     | 
    
         
             
              module Adapters
         
     | 
| 
       3 
3 
     | 
    
         
             
                # Overrides specific to MySQL. Mostly taken from
         
     | 
| 
       4 
     | 
    
         
            -
                # ActiveRecord::ConnectionAdapters:: 
     | 
| 
      
 4 
     | 
    
         
            +
                # ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter
         
     | 
| 
       5 
5 
     | 
    
         
             
                class MySQLODBCAdapter < ActiveRecord::ConnectionAdapters::ODBCAdapter
         
     | 
| 
       6 
6 
     | 
    
         
             
                  PRIMARY_KEY = 'INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY'.freeze
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
         @@ -27,27 +27,6 @@ module ODBCAdapter 
     | 
|
| 
       27 
27 
     | 
    
         
             
                    execute("TRUNCATE TABLE #{quote_table_name(table_name)}", name)
         
     | 
| 
       28 
28 
     | 
    
         
             
                  end
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                  def limited_update_conditions(where_sql, _quoted_table_name, _quoted_primary_key)
         
     | 
| 
       31 
     | 
    
         
            -
                    where_sql
         
     | 
| 
       32 
     | 
    
         
            -
                  end
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                  # Taken from ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter
         
     | 
| 
       35 
     | 
    
         
            -
                  def join_to_update(update, select) #:nodoc:
         
     | 
| 
       36 
     | 
    
         
            -
                    if select.limit || select.offset || select.orders.any?
         
     | 
| 
       37 
     | 
    
         
            -
                      subsubselect = select.clone
         
     | 
| 
       38 
     | 
    
         
            -
                      subsubselect.projections = [update.key]
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                      subselect = Arel::SelectManager.new(select.engine)
         
     | 
| 
       41 
     | 
    
         
            -
                      subselect.project Arel.sql(update.key.name)
         
     | 
| 
       42 
     | 
    
         
            -
                      subselect.from subsubselect.as('__active_record_temp')
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                      update.where update.key.in(subselect)
         
     | 
| 
       45 
     | 
    
         
            -
                    else
         
     | 
| 
       46 
     | 
    
         
            -
                      update.table select.source
         
     | 
| 
       47 
     | 
    
         
            -
                      update.wheres = select.constraints
         
     | 
| 
       48 
     | 
    
         
            -
                    end
         
     | 
| 
       49 
     | 
    
         
            -
                  end
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
30 
     | 
    
         
             
                  # Quotes a string, escaping any ' (single quote) and \ (backslash)
         
     | 
| 
       52 
31 
     | 
    
         
             
                  # characters.
         
     | 
| 
       53 
32 
     | 
    
         
             
                  def quote_string(string)
         
     | 
| 
         @@ -70,7 +49,7 @@ module ODBCAdapter 
     | 
|
| 
       70 
49 
     | 
    
         
             
                    0
         
     | 
| 
       71 
50 
     | 
    
         
             
                  end
         
     | 
| 
       72 
51 
     | 
    
         | 
| 
       73 
     | 
    
         
            -
                  def disable_referential_integrity(&block) 
     | 
| 
      
 52 
     | 
    
         
            +
                  def disable_referential_integrity(&block)
         
     | 
| 
       74 
53 
     | 
    
         
             
                    old = select_value("SELECT @@FOREIGN_KEY_CHECKS")
         
     | 
| 
       75 
54 
     | 
    
         | 
| 
       76 
55 
     | 
    
         
             
                    begin
         
     | 
| 
         @@ -81,13 +60,14 @@ module ODBCAdapter 
     | 
|
| 
       81 
60 
     | 
    
         
             
                    end
         
     | 
| 
       82 
61 
     | 
    
         
             
                  end
         
     | 
| 
       83 
62 
     | 
    
         | 
| 
       84 
     | 
    
         
            -
                  # Create a new MySQL database with optional <tt>:charset</tt> and 
     | 
| 
       85 
     | 
    
         
            -
                  # Charset defaults to utf8.
         
     | 
| 
      
 63 
     | 
    
         
            +
                  # Create a new MySQL database with optional <tt>:charset</tt> and
         
     | 
| 
      
 64 
     | 
    
         
            +
                  # <tt>:collation</tt>. Charset defaults to utf8.
         
     | 
| 
       86 
65 
     | 
    
         
             
                  #
         
     | 
| 
       87 
66 
     | 
    
         
             
                  # Example:
         
     | 
| 
       88 
     | 
    
         
            -
                  #   create_database 'charset_test', : 
     | 
| 
       89 
     | 
    
         
            -
                  # 
     | 
| 
       90 
     | 
    
         
            -
                  #   create_database ' 
     | 
| 
      
 67 
     | 
    
         
            +
                  #   create_database 'charset_test', charset: 'latin1',
         
     | 
| 
      
 68 
     | 
    
         
            +
                  #                                   collation: 'latin1_bin'
         
     | 
| 
      
 69 
     | 
    
         
            +
                  #   create_database 'rails_development'
         
     | 
| 
      
 70 
     | 
    
         
            +
                  #   create_database 'rails_development', charset: :big5
         
     | 
| 
       91 
71 
     | 
    
         
             
                  def create_database(name, options = {})
         
     | 
| 
       92 
72 
     | 
    
         
             
                    if options[:collation]
         
     | 
| 
       93 
73 
     | 
    
         
             
                      execute("CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{options[:charset] || 'utf8'}` COLLATE `#{options[:collation]}`")
         
     | 
| 
         @@ -99,8 +79,8 @@ module ODBCAdapter 
     | 
|
| 
       99 
79 
     | 
    
         
             
                  # Drops a MySQL database.
         
     | 
| 
       100 
80 
     | 
    
         
             
                  #
         
     | 
| 
       101 
81 
     | 
    
         
             
                  # Example:
         
     | 
| 
       102 
     | 
    
         
            -
                  #   drop_database(' 
     | 
| 
       103 
     | 
    
         
            -
                  def drop_database(name) 
     | 
| 
      
 82 
     | 
    
         
            +
                  #   drop_database('rails_development')
         
     | 
| 
      
 83 
     | 
    
         
            +
                  def drop_database(name)
         
     | 
| 
       104 
84 
     | 
    
         
             
                    execute("DROP DATABASE IF EXISTS `#{name}`")
         
     | 
| 
       105 
85 
     | 
    
         
             
                  end
         
     | 
| 
       106 
86 
     | 
    
         | 
| 
         @@ -114,9 +94,8 @@ module ODBCAdapter 
     | 
|
| 
       114 
94 
     | 
    
         
             
                  end
         
     | 
| 
       115 
95 
     | 
    
         | 
| 
       116 
96 
     | 
    
         
             
                  def change_column(table_name, column_name, type, options = {})
         
     | 
| 
       117 
     | 
    
         
            -
                    # column_name.to_s used in case column_name is a symbol
         
     | 
| 
       118 
97 
     | 
    
         
             
                    unless options_include_default?(options)
         
     | 
| 
       119 
     | 
    
         
            -
                      options[:default] =  
     | 
| 
      
 98 
     | 
    
         
            +
                      options[:default] = column_for(table_name, column_name).default
         
     | 
| 
       120 
99 
     | 
    
         
             
                    end
         
     | 
| 
       121 
100 
     | 
    
         | 
| 
       122 
101 
     | 
    
         
             
                    change_column_sql = "ALTER TABLE #{table_name} CHANGE #{column_name} #{column_name} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
         
     | 
| 
         @@ -124,26 +103,36 @@ module ODBCAdapter 
     | 
|
| 
       124 
103 
     | 
    
         
             
                    execute(change_column_sql)
         
     | 
| 
       125 
104 
     | 
    
         
             
                  end
         
     | 
| 
       126 
105 
     | 
    
         | 
| 
       127 
     | 
    
         
            -
                  def change_column_default(table_name, column_name,  
     | 
| 
       128 
     | 
    
         
            -
                     
     | 
| 
       129 
     | 
    
         
            -
                     
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
      
 106 
     | 
    
         
            +
                  def change_column_default(table_name, column_name, default_or_changes)
         
     | 
| 
      
 107 
     | 
    
         
            +
                    default = extract_new_default_value(default_or_changes)
         
     | 
| 
      
 108 
     | 
    
         
            +
                    column = column_for(table_name, column_name)
         
     | 
| 
      
 109 
     | 
    
         
            +
                    change_column(table_name, column_name, column.sql_type, default: default)
         
     | 
| 
      
 110 
     | 
    
         
            +
                  end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                  def change_column_null(table_name, column_name, null, default = nil)
         
     | 
| 
      
 113 
     | 
    
         
            +
                    column = column_for(table_name, column_name)
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                    unless null || default.nil?
         
     | 
| 
      
 116 
     | 
    
         
            +
                      execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
         
     | 
| 
      
 117 
     | 
    
         
            +
                    end
         
     | 
| 
      
 118 
     | 
    
         
            +
                    change_column(table_name, column_name, column.sql_type, null: null)
         
     | 
| 
       131 
119 
     | 
    
         
             
                  end
         
     | 
| 
       132 
120 
     | 
    
         | 
| 
       133 
121 
     | 
    
         
             
                  def rename_column(table_name, column_name, new_column_name)
         
     | 
| 
       134 
     | 
    
         
            -
                     
     | 
| 
       135 
     | 
    
         
            -
                    current_type =  
     | 
| 
       136 
     | 
    
         
            -
                    current_type << "(#{ 
     | 
| 
      
 122 
     | 
    
         
            +
                    column = column_for(table_name, column_name)
         
     | 
| 
      
 123 
     | 
    
         
            +
                    current_type = column.native_type
         
     | 
| 
      
 124 
     | 
    
         
            +
                    current_type << "(#{column.limit})" if column.limit
         
     | 
| 
       137 
125 
     | 
    
         
             
                    execute("ALTER TABLE #{table_name} CHANGE #{column_name} #{new_column_name} #{current_type}")
         
     | 
| 
       138 
126 
     | 
    
         
             
                  end
         
     | 
| 
       139 
127 
     | 
    
         | 
| 
      
 128 
     | 
    
         
            +
                  # Skip primary key indexes
         
     | 
| 
       140 
129 
     | 
    
         
             
                  def indexes(table_name, name = nil)
         
     | 
| 
       141 
     | 
    
         
            -
                     
     | 
| 
       142 
     | 
    
         
            -
                    super(table_name, name).delete_if { |i| i.unique && i.name =~ /^PRIMARY$/ }
         
     | 
| 
      
 130 
     | 
    
         
            +
                    super(table_name, name).reject { |i| i.unique && i.name =~ /^PRIMARY$/ }
         
     | 
| 
       143 
131 
     | 
    
         
             
                  end
         
     | 
| 
       144 
132 
     | 
    
         | 
| 
      
 133 
     | 
    
         
            +
                  # MySQL 5.x doesn't allow DEFAULT NULL for first timestamp column in a
         
     | 
| 
      
 134 
     | 
    
         
            +
                  # table
         
     | 
| 
       145 
135 
     | 
    
         
             
                  def options_include_default?(options)
         
     | 
| 
       146 
     | 
    
         
            -
                    # MySQL 5.x doesn't allow DEFAULT NULL for first timestamp column in a table
         
     | 
| 
       147 
136 
     | 
    
         
             
                    if options.include?(:default) && options[:default].nil?
         
     | 
| 
       148 
137 
     | 
    
         
             
                      if options.include?(:column) && options[:column].native_type =~ /timestamp/i
         
     | 
| 
       149 
138 
     | 
    
         
             
                        options.delete(:default)
         
     | 
| 
         @@ -152,14 +141,6 @@ module ODBCAdapter 
     | 
|
| 
       152 
141 
     | 
    
         
             
                    super(options)
         
     | 
| 
       153 
142 
     | 
    
         
             
                  end
         
     | 
| 
       154 
143 
     | 
    
         | 
| 
       155 
     | 
    
         
            -
                  def structure_dump
         
     | 
| 
       156 
     | 
    
         
            -
                    select_all("SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'").map do |table|
         
     | 
| 
       157 
     | 
    
         
            -
                      table.delete('Table_type')
         
     | 
| 
       158 
     | 
    
         
            -
                      sql = "SHOW CREATE TABLE #{quote_table_name(table.to_a.first.last)}"
         
     | 
| 
       159 
     | 
    
         
            -
                      exec_query(sql).first['Create Table'] + ";\n\n"
         
     | 
| 
       160 
     | 
    
         
            -
                    end.join
         
     | 
| 
       161 
     | 
    
         
            -
                  end
         
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
144 
     | 
    
         
             
                  protected
         
     | 
| 
       164 
145 
     | 
    
         | 
| 
       165 
146 
     | 
    
         
             
                  def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module ODBCAdapter
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Adapters
         
     | 
| 
      
 3 
     | 
    
         
            +
                # A default adapter used for databases that are no explicitly listed in the
         
     | 
| 
      
 4 
     | 
    
         
            +
                # registry. This allows for minimal support for DBMSs for which we don't
         
     | 
| 
      
 5 
     | 
    
         
            +
                # have an explicit adapter.
         
     | 
| 
      
 6 
     | 
    
         
            +
                class NullODBCAdapter < ActiveRecord::ConnectionAdapters::ODBCAdapter
         
     | 
| 
      
 7 
     | 
    
         
            +
                  class BindSubstitution < Arel::Visitors::ToSql
         
     | 
| 
      
 8 
     | 
    
         
            +
                    include Arel::Visitors::BindVisitor
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  # Using a BindVisitor so that the SQL string gets substituted before it is
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # sent to the DBMS (to attempt to get as much coverage as possible for
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # DBMSs we don't support).
         
     | 
| 
      
 14 
     | 
    
         
            +
                  def arel_visitor
         
     | 
| 
      
 15 
     | 
    
         
            +
                    BindSubstitution.new(self)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  # Explicitly turning off prepared_statements in the null adapter because
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # there isn't really a standard on which substitution character to use.
         
     | 
| 
      
 20 
     | 
    
         
            +
                  def prepared_statements
         
     | 
| 
      
 21 
     | 
    
         
            +
                    false
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  # Turning off support for migrations because there is no information to
         
     | 
| 
      
 25 
     | 
    
         
            +
                  # go off of for what syntax the DBMS will expect.
         
     | 
| 
      
 26 
     | 
    
         
            +
                  def supports_migrations?
         
     | 
| 
      
 27 
     | 
    
         
            +
                    false
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -6,6 +6,8 @@ module ODBCAdapter 
     | 
|
| 
       6 
6 
     | 
    
         
             
                  BOOLEAN_TYPE = 'bool'.freeze
         
     | 
| 
       7 
7 
     | 
    
         
             
                  PRIMARY_KEY  = 'SERIAL PRIMARY KEY'.freeze
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
      
 9 
     | 
    
         
            +
                  alias :create :insert
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
       9 
11 
     | 
    
         
             
                  # Override to handle booleans appropriately
         
     | 
| 
       10 
12 
     | 
    
         
             
                  def native_database_types
         
     | 
| 
       11 
13 
     | 
    
         
             
                    @native_database_types ||= super.merge(boolean: { name: 'bool' })
         
     | 
| 
         @@ -25,34 +27,14 @@ module ODBCAdapter 
     | 
|
| 
       25 
27 
     | 
    
         
             
                    exec_query("TRUNCATE TABLE #{quote_table_name(table_name)}", name)
         
     | 
| 
       26 
28 
     | 
    
         
             
                  end
         
     | 
| 
       27 
29 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
                  # Returns the sequence name for a table's primary key or some other 
     | 
| 
       29 
     | 
    
         
            -
                   
     | 
| 
      
 30 
     | 
    
         
            +
                  # Returns the sequence name for a table's primary key or some other
         
     | 
| 
      
 31 
     | 
    
         
            +
                  # specified key.
         
     | 
| 
      
 32 
     | 
    
         
            +
                  def default_sequence_name(table_name, pk = nil)
         
     | 
| 
       30 
33 
     | 
    
         
             
                    serial_sequence(table_name, pk || 'id').split('.').last
         
     | 
| 
       31 
34 
     | 
    
         
             
                  rescue ActiveRecord::StatementInvalid
         
     | 
| 
       32 
35 
     | 
    
         
             
                    "#{table_name}_#{pk || 'id'}_seq"
         
     | 
| 
       33 
36 
     | 
    
         
             
                  end
         
     | 
| 
       34 
37 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
                  # Returns the current ID of a table's sequence.
         
     | 
| 
       36 
     | 
    
         
            -
                  def last_insert_id(sequence_name)
         
     | 
| 
       37 
     | 
    
         
            -
                    r = exec_query("SELECT currval('#{sequence_name}')", 'SQL')
         
     | 
| 
       38 
     | 
    
         
            -
                    Integer(r.rows.first.first)
         
     | 
| 
       39 
     | 
    
         
            -
                  end
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
                  # Executes an INSERT query and returns the new record's ID
         
     | 
| 
       42 
     | 
    
         
            -
                  def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
         
     | 
| 
       43 
     | 
    
         
            -
                    unless pk
         
     | 
| 
       44 
     | 
    
         
            -
                      table_ref = extract_table_ref_from_insert_sql(sql)
         
     | 
| 
       45 
     | 
    
         
            -
                      pk = primary_key(table_ref) if table_ref
         
     | 
| 
       46 
     | 
    
         
            -
                    end
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
                    if pk
         
     | 
| 
       49 
     | 
    
         
            -
                      select_value("#{sql} RETURNING #{quote_column_name(pk)}")
         
     | 
| 
       50 
     | 
    
         
            -
                    else
         
     | 
| 
       51 
     | 
    
         
            -
                      super
         
     | 
| 
       52 
     | 
    
         
            -
                    end
         
     | 
| 
       53 
     | 
    
         
            -
                  end
         
     | 
| 
       54 
     | 
    
         
            -
                  alias :create :insert
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
38 
     | 
    
         
             
                  def sql_for_insert(sql, pk, id_value, sequence_name, binds)
         
     | 
| 
       57 
39 
     | 
    
         
             
                    unless pk
         
     | 
| 
       58 
40 
     | 
    
         
             
                      table_ref = extract_table_ref_from_insert_sql(sql)
         
     | 
| 
         @@ -81,20 +63,21 @@ module ODBCAdapter 
     | 
|
| 
       81 
63 
     | 
    
         
             
                    string.gsub(/\\/, '\&\&').gsub(/'/, "''")
         
     | 
| 
       82 
64 
     | 
    
         
             
                  end
         
     | 
| 
       83 
65 
     | 
    
         | 
| 
       84 
     | 
    
         
            -
                  def disable_referential_integrity 
     | 
| 
      
 66 
     | 
    
         
            +
                  def disable_referential_integrity
         
     | 
| 
       85 
67 
     | 
    
         
             
                    execute(tables.map { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER ALL" }.join(';'))
         
     | 
| 
       86 
68 
     | 
    
         
             
                    yield
         
     | 
| 
       87 
69 
     | 
    
         
             
                  ensure
         
     | 
| 
       88 
70 
     | 
    
         
             
                    execute(tables.map { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER ALL" }.join(';'))
         
     | 
| 
       89 
71 
     | 
    
         
             
                  end
         
     | 
| 
       90 
72 
     | 
    
         | 
| 
       91 
     | 
    
         
            -
                  # Create a new PostgreSQL database. Options include <tt>:owner</tt>, 
     | 
| 
       92 
     | 
    
         
            -
                  # <tt>: 
     | 
| 
       93 
     | 
    
         
            -
                  #  
     | 
| 
      
 73 
     | 
    
         
            +
                  # Create a new PostgreSQL database. Options include <tt>:owner</tt>,
         
     | 
| 
      
 74 
     | 
    
         
            +
                  # <tt>:template</tt>, <tt>:encoding</tt>, <tt>:tablespace</tt>, and
         
     | 
| 
      
 75 
     | 
    
         
            +
                  # <tt>:connection_limit</tt> (note that MySQL uses <tt>:charset</tt>
         
     | 
| 
      
 76 
     | 
    
         
            +
                  # while PostgreSQL uses <tt>:encoding</tt>).
         
     | 
| 
       94 
77 
     | 
    
         
             
                  #
         
     | 
| 
       95 
78 
     | 
    
         
             
                  # Example:
         
     | 
| 
       96 
79 
     | 
    
         
             
                  #   create_database config[:database], config
         
     | 
| 
       97 
     | 
    
         
            -
                  #   create_database 'foo_development', : 
     | 
| 
      
 80 
     | 
    
         
            +
                  #   create_database 'foo_development', encoding: 'unicode'
         
     | 
| 
       98 
81 
     | 
    
         
             
                  def create_database(name, options = {})
         
     | 
| 
       99 
82 
     | 
    
         
             
                    options = options.reverse_merge(encoding: 'utf8')
         
     | 
| 
       100 
83 
     | 
    
         | 
| 
         @@ -121,8 +104,8 @@ module ODBCAdapter 
     | 
|
| 
       121 
104 
     | 
    
         
             
                  # Drops a PostgreSQL database.
         
     | 
| 
       122 
105 
     | 
    
         
             
                  #
         
     | 
| 
       123 
106 
     | 
    
         
             
                  # Example:
         
     | 
| 
       124 
     | 
    
         
            -
                  #   drop_database ' 
     | 
| 
       125 
     | 
    
         
            -
                  def drop_database(name) 
     | 
| 
      
 107 
     | 
    
         
            +
                  #   drop_database 'rails_development'
         
     | 
| 
      
 108 
     | 
    
         
            +
                  def drop_database(name)
         
     | 
| 
       126 
109 
     | 
    
         
             
                    execute "DROP DATABASE IF EXISTS #{quote_table_name(name)}"
         
     | 
| 
       127 
110 
     | 
    
         
             
                  end
         
     | 
| 
       128 
111 
     | 
    
         | 
| 
         @@ -152,17 +135,19 @@ module ODBCAdapter 
     | 
|
| 
       152 
135 
     | 
    
         
             
                    execute("ALTER INDEX #{quote_column_name(old_name)} RENAME TO #{quote_table_name(new_name)}")
         
     | 
| 
       153 
136 
     | 
    
         
             
                  end
         
     | 
| 
       154 
137 
     | 
    
         | 
| 
       155 
     | 
    
         
            -
                  # Returns a SELECT DISTINCT clause for a given set of columns and a given 
     | 
| 
      
 138 
     | 
    
         
            +
                  # Returns a SELECT DISTINCT clause for a given set of columns and a given
         
     | 
| 
      
 139 
     | 
    
         
            +
                  # ORDER BY clause.
         
     | 
| 
       156 
140 
     | 
    
         
             
                  #
         
     | 
| 
       157 
     | 
    
         
            -
                  # PostgreSQL requires the ORDER BY columns in the select list for 
     | 
| 
       158 
     | 
    
         
            -
                  # requires that the ORDER BY include the distinct 
     | 
| 
      
 141 
     | 
    
         
            +
                  # PostgreSQL requires the ORDER BY columns in the select list for
         
     | 
| 
      
 142 
     | 
    
         
            +
                  # distinct queries, and requires that the ORDER BY include the distinct
         
     | 
| 
      
 143 
     | 
    
         
            +
                  # column.
         
     | 
| 
       159 
144 
     | 
    
         
             
                  #
         
     | 
| 
       160 
145 
     | 
    
         
             
                  #   distinct("posts.id", "posts.created_at desc")
         
     | 
| 
       161 
146 
     | 
    
         
             
                  def distinct(columns, orders)
         
     | 
| 
       162 
147 
     | 
    
         
             
                    return "DISTINCT #{columns}" if orders.empty?
         
     | 
| 
       163 
148 
     | 
    
         | 
| 
       164 
     | 
    
         
            -
                    # Construct a clean list of column names from the ORDER BY clause, 
     | 
| 
       165 
     | 
    
         
            -
                    # any ASC/DESC modifiers
         
     | 
| 
      
 149 
     | 
    
         
            +
                    # Construct a clean list of column names from the ORDER BY clause,
         
     | 
| 
      
 150 
     | 
    
         
            +
                    # removing any ASC/DESC modifiers
         
     | 
| 
       166 
151 
     | 
    
         
             
                    order_columns = orders.map { |s| s.gsub(/\s+(ASC|DESC)\s*(NULLS\s+(FIRST|LAST)\s*)?/i, '') }
         
     | 
| 
       167 
152 
     | 
    
         
             
                    order_columns.reject! { |c| c.blank? }
         
     | 
| 
       168 
153 
     | 
    
         
             
                    order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s,i| "#{s} AS alias_#{i}" }
         
     | 
| 
         @@ -170,6 +155,28 @@ module ODBCAdapter 
     | 
|
| 
       170 
155 
     | 
    
         
             
                    "DISTINCT #{columns}, #{order_columns * ', '}"
         
     | 
| 
       171 
156 
     | 
    
         
             
                  end
         
     | 
| 
       172 
157 
     | 
    
         | 
| 
      
 158 
     | 
    
         
            +
                  protected
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                  # Executes an INSERT query and returns the new record's ID
         
     | 
| 
      
 161 
     | 
    
         
            +
                  def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
         
     | 
| 
      
 162 
     | 
    
         
            +
                    unless pk
         
     | 
| 
      
 163 
     | 
    
         
            +
                      table_ref = extract_table_ref_from_insert_sql(sql)
         
     | 
| 
      
 164 
     | 
    
         
            +
                      pk = primary_key(table_ref) if table_ref
         
     | 
| 
      
 165 
     | 
    
         
            +
                    end
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
                    if pk
         
     | 
| 
      
 168 
     | 
    
         
            +
                      select_value("#{sql} RETURNING #{quote_column_name(pk)}")
         
     | 
| 
      
 169 
     | 
    
         
            +
                    else
         
     | 
| 
      
 170 
     | 
    
         
            +
                      super
         
     | 
| 
      
 171 
     | 
    
         
            +
                    end
         
     | 
| 
      
 172 
     | 
    
         
            +
                  end
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
                  # Returns the current ID of a table's sequence.
         
     | 
| 
      
 175 
     | 
    
         
            +
                  def last_insert_id(sequence_name)
         
     | 
| 
      
 176 
     | 
    
         
            +
                    r = exec_query("SELECT currval('#{sequence_name}')", 'SQL')
         
     | 
| 
      
 177 
     | 
    
         
            +
                    Integer(r.rows.first.first)
         
     | 
| 
      
 178 
     | 
    
         
            +
                  end
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
       173 
180 
     | 
    
         
             
                  private
         
     | 
| 
       174 
181 
     | 
    
         | 
| 
       175 
182 
     | 
    
         
             
                  def serial_sequence(table, column)
         
     | 
| 
         @@ -2,8 +2,8 @@ module ODBCAdapter 
     | 
|
| 
       2 
2 
     | 
    
         
             
              module DatabaseLimits
         
     | 
| 
       3 
3 
     | 
    
         
             
                # Returns the maximum length of a table name.
         
     | 
| 
       4 
4 
     | 
    
         
             
                def table_alias_length
         
     | 
| 
       5 
     | 
    
         
            -
                  max_identifier_length =  
     | 
| 
       6 
     | 
    
         
            -
                  max_table_name_length =  
     | 
| 
      
 5 
     | 
    
         
            +
                  max_identifier_length = database_metadata.max_identifier_len
         
     | 
| 
      
 6 
     | 
    
         
            +
                  max_table_name_length = database_metadata.max_table_name_len
         
     | 
| 
       7 
7 
     | 
    
         
             
                  [max_identifier_length, max_table_name_length].max
         
     | 
| 
       8 
8 
     | 
    
         
             
                end
         
     | 
| 
       9 
9 
     | 
    
         
             
              end
         
     | 
| 
         @@ -0,0 +1,44 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module ODBCAdapter
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Caches SQLGetInfo output
         
     | 
| 
      
 3 
     | 
    
         
            +
              class DatabaseMetadata
         
     | 
| 
      
 4 
     | 
    
         
            +
                FIELDS = %i[
         
     | 
| 
      
 5 
     | 
    
         
            +
                  SQL_DBMS_NAME
         
     | 
| 
      
 6 
     | 
    
         
            +
                  SQL_DBMS_VER
         
     | 
| 
      
 7 
     | 
    
         
            +
                  SQL_IDENTIFIER_CASE
         
     | 
| 
      
 8 
     | 
    
         
            +
                  SQL_QUOTED_IDENTIFIER_CASE
         
     | 
| 
      
 9 
     | 
    
         
            +
                  SQL_IDENTIFIER_QUOTE_CHAR
         
     | 
| 
      
 10 
     | 
    
         
            +
                  SQL_MAX_IDENTIFIER_LEN
         
     | 
| 
      
 11 
     | 
    
         
            +
                  SQL_MAX_TABLE_NAME_LEN
         
     | 
| 
      
 12 
     | 
    
         
            +
                  SQL_USER_NAME
         
     | 
| 
      
 13 
     | 
    
         
            +
                  SQL_DATABASE_NAME
         
     | 
| 
      
 14 
     | 
    
         
            +
                ]
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                attr_reader :values
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                def initialize(connection)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @values = Hash[FIELDS.map { |field| [field, connection.get_info(ODBC.const_get(field))] }]
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                def adapter_class
         
     | 
| 
      
 23 
     | 
    
         
            +
                  ODBCAdapter.adapter_for(dbms_name)
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                def upcase_identifiers?
         
     | 
| 
      
 27 
     | 
    
         
            +
                  @upcase_identifiers ||= (identifier_case == ODBC::SQL_IC_UPPER)
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                # A little bit of metaprogramming magic here to create accessors for each of
         
     | 
| 
      
 31 
     | 
    
         
            +
                # the fields reported on by the DBMS.
         
     | 
| 
      
 32 
     | 
    
         
            +
                FIELDS.each do |field|
         
     | 
| 
      
 33 
     | 
    
         
            +
                  define_method(field.to_s.downcase.gsub('sql_', '')) do
         
     | 
| 
      
 34 
     | 
    
         
            +
                    value_for(field)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                private
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def value_for(field)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  values[field]
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -87,8 +87,7 @@ module ODBCAdapter 
     | 
|
| 
       87 
87 
     | 
    
         | 
| 
       88 
88 
     | 
    
         
             
                # Assume received identifier is in DBMS's data dictionary case.
         
     | 
| 
       89 
89 
     | 
    
         
             
                def format_case(identifier)
         
     | 
| 
       90 
     | 
    
         
            -
                   
     | 
| 
       91 
     | 
    
         
            -
                  when ODBC::SQL_IC_UPPER
         
     | 
| 
      
 90 
     | 
    
         
            +
                  if database_metadata.upcase_identifiers?
         
     | 
| 
       92 
91 
     | 
    
         
             
                    identifier =~ /[a-z]/ ? identifier : identifier.downcase
         
     | 
| 
       93 
92 
     | 
    
         
             
                  else
         
     | 
| 
       94 
93 
     | 
    
         
             
                    identifier
         
     | 
| 
         @@ -114,8 +113,7 @@ module ODBCAdapter 
     | 
|
| 
       114 
113 
     | 
    
         
             
                # Converts an identifier to the case conventions used by the DBMS.
         
     | 
| 
       115 
114 
     | 
    
         
             
                # Assume received identifier is in ActiveRecord case.
         
     | 
| 
       116 
115 
     | 
    
         
             
                def native_case(identifier)
         
     | 
| 
       117 
     | 
    
         
            -
                   
     | 
| 
       118 
     | 
    
         
            -
                  when ODBC::SQL_IC_UPPER
         
     | 
| 
      
 116 
     | 
    
         
            +
                  if database_metadata.upcase_identifiers?
         
     | 
| 
       119 
117 
     | 
    
         
             
                    identifier =~ /[A-Z]/ ? identifier : identifier.upcase
         
     | 
| 
       120 
118 
     | 
    
         
             
                  else
         
     | 
| 
       121 
119 
     | 
    
         
             
                    identifier
         
     | 
    
        data/lib/odbc_adapter/quoting.rb
    CHANGED
    
    | 
         @@ -8,7 +8,7 @@ module ODBCAdapter 
     | 
|
| 
       8 
8 
     | 
    
         
             
                # Returns a quoted form of the column name.
         
     | 
| 
       9 
9 
     | 
    
         
             
                def quote_column_name(name)
         
     | 
| 
       10 
10 
     | 
    
         
             
                  name = name.to_s
         
     | 
| 
       11 
     | 
    
         
            -
                  quote_char =  
     | 
| 
      
 11 
     | 
    
         
            +
                  quote_char = database_metadata.identifier_quote_char.to_s.strip
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
                  return name if quote_char.length.zero?
         
     | 
| 
       14 
14 
     | 
    
         
             
                  quote_char = quote_char[0]
         
     | 
| 
         @@ -16,9 +16,8 @@ module ODBCAdapter 
     | 
|
| 
       16 
16 
     | 
    
         
             
                  # Avoid quoting any already quoted name
         
     | 
| 
       17 
17 
     | 
    
         
             
                  return name if name[0] == quote_char && name[-1] == quote_char
         
     | 
| 
       18 
18 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
                  # If  
     | 
| 
       20 
     | 
    
         
            -
                   
     | 
| 
       21 
     | 
    
         
            -
                  if dbms.field_for(ODBC::SQL_IDENTIFIER_CASE) == ODBC::SQL_IC_UPPER
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # If upcase identifiers, only quote mixed case names.
         
     | 
| 
      
 20 
     | 
    
         
            +
                  if database_metadata.upcase_identifiers?
         
     | 
| 
       22 
21 
     | 
    
         
             
                    return name unless (name =~ /([A-Z]+[a-z])|([a-z]+[A-Z])/)
         
     | 
| 
       23 
22 
     | 
    
         
             
                  end
         
     | 
| 
       24 
23 
     | 
    
         | 
| 
         @@ -0,0 +1,50 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module ODBCAdapter
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Registry
         
     | 
| 
      
 3 
     | 
    
         
            +
                attr_reader :dbs
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @dbs = {
         
     | 
| 
      
 7 
     | 
    
         
            +
                    /my.*sql/i  => :MySQL,
         
     | 
| 
      
 8 
     | 
    
         
            +
                    /postgres/i => :PostgreSQL
         
     | 
| 
      
 9 
     | 
    
         
            +
                  }
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def adapter_for(reported_name)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  reported_name = reported_name.downcase.gsub(/\s/, '')
         
     | 
| 
      
 14 
     | 
    
         
            +
                  found =
         
     | 
| 
      
 15 
     | 
    
         
            +
                    dbs.detect do |pattern, adapter|
         
     | 
| 
      
 16 
     | 
    
         
            +
                      adapter if reported_name =~ pattern
         
     | 
| 
      
 17 
     | 
    
         
            +
                    end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  normalize_adapter(found && found.last || :Null)
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                def register(pattern, superclass = Object, &block)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  dbs[pattern] = Class.new(superclass, &block)
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                private
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def normalize_adapter(adapter)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  return adapter unless adapter.is_a?(Symbol)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  require "odbc_adapter/adapters/#{adapter.downcase}_odbc_adapter"
         
     | 
| 
      
 31 
     | 
    
         
            +
                  Adapters.const_get(:"#{adapter}ODBCAdapter")
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              class << self
         
     | 
| 
      
 36 
     | 
    
         
            +
                def adapter_for(reported_name)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  registry.adapter_for(reported_name)
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def register(pattern, superclass = Object, &block)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  registry.register(pattern, superclass, &block)
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                private
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                def registry
         
     | 
| 
      
 47 
     | 
    
         
            +
                  @registry ||= Registry.new
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -51,7 +51,7 @@ module ODBCAdapter 
     | 
|
| 
       51 
51 
     | 
    
         
             
                    next_row = result[row_idx + 1]
         
     | 
| 
       52 
52 
     | 
    
         | 
| 
       53 
53 
     | 
    
         
             
                    if (row_idx == result.length - 1) || (next_row[6] == 0 || next_row[7] == 1)
         
     | 
| 
       54 
     | 
    
         
            -
                      indices << IndexDefinition.new(table_name, format_case(index_name), unique, index_cols)
         
     | 
| 
      
 54 
     | 
    
         
            +
                      indices << ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, format_case(index_name), unique, index_cols)
         
     | 
| 
       55 
55 
     | 
    
         
             
                    end
         
     | 
| 
       56 
56 
     | 
    
         
             
                  end
         
     | 
| 
       57 
57 
     | 
    
         
             
                end
         
     | 
| 
         @@ -95,15 +95,34 @@ module ODBCAdapter 
     | 
|
| 
       95 
95 
     | 
    
         
             
                  result[0] && result[0][3]
         
     | 
| 
       96 
96 
     | 
    
         
             
                end
         
     | 
| 
       97 
97 
     | 
    
         | 
| 
      
 98 
     | 
    
         
            +
                def foreign_keys(table_name)
         
     | 
| 
      
 99 
     | 
    
         
            +
                  stmt   = @connection.foreign_keys(native_case(table_name.to_s))
         
     | 
| 
      
 100 
     | 
    
         
            +
                  result = stmt.fetch_all || []
         
     | 
| 
      
 101 
     | 
    
         
            +
                  stmt.drop unless stmt.nil?
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                  result.map do |key|
         
     | 
| 
      
 104 
     | 
    
         
            +
                    fk_from_table      = key[2]  # PKTABLE_NAME
         
     | 
| 
      
 105 
     | 
    
         
            +
                    fk_to_table        = key[6]  # FKTABLE_NAME
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                    ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(fk_from_table, fk_to_table,
         
     | 
| 
      
 108 
     | 
    
         
            +
                      name:        key[11], # FK_NAME
         
     | 
| 
      
 109 
     | 
    
         
            +
                      column:      key[3],  # PKCOLUMN_NAME
         
     | 
| 
      
 110 
     | 
    
         
            +
                      primary_key: key[7],  # FKCOLUMN_NAME
         
     | 
| 
      
 111 
     | 
    
         
            +
                      on_delete:   key[10], # DELETE_RULE
         
     | 
| 
      
 112 
     | 
    
         
            +
                      on_update:   key[9]   # UPDATE_RULE
         
     | 
| 
      
 113 
     | 
    
         
            +
                    )
         
     | 
| 
      
 114 
     | 
    
         
            +
                  end
         
     | 
| 
      
 115 
     | 
    
         
            +
                end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
       98 
117 
     | 
    
         
             
                # Ensure it's shorter than the maximum identifier length for the current
         
     | 
| 
       99 
118 
     | 
    
         
             
                # dbms
         
     | 
| 
       100 
119 
     | 
    
         
             
                def index_name(table_name, options)
         
     | 
| 
       101 
     | 
    
         
            -
                  maximum =  
     | 
| 
      
 120 
     | 
    
         
            +
                  maximum = database_metadata.max_identifier_len || 255
         
     | 
| 
       102 
121 
     | 
    
         
             
                  super(table_name, options)[0...maximum]
         
     | 
| 
       103 
122 
     | 
    
         
             
                end
         
     | 
| 
       104 
123 
     | 
    
         | 
| 
       105 
124 
     | 
    
         
             
                def current_database
         
     | 
| 
       106 
     | 
    
         
            -
                   
     | 
| 
      
 125 
     | 
    
         
            +
                  database_metadata.database_name.strip
         
     | 
| 
       107 
126 
     | 
    
         
             
                end
         
     | 
| 
       108 
127 
     | 
    
         
             
              end
         
     | 
| 
       109 
128 
     | 
    
         
             
            end
         
     | 
    
        data/lib/odbc_adapter/version.rb
    CHANGED
    
    
    
        data/odbc_adapter.gemspec
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: odbc_adapter
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 5.0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 5.0.1
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Localytics
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: exe
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2017- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2017-02-09 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: ruby-odbc
         
     | 
| 
         @@ -66,6 +66,20 @@ dependencies: 
     | 
|
| 
       66 
66 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       67 
67 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       68 
68 
     | 
    
         
             
                    version: '5.0'
         
     | 
| 
      
 69 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 70 
     | 
    
         
            +
              name: simplecov
         
     | 
| 
      
 71 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 72 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 73 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 74 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 75 
     | 
    
         
            +
                    version: '0.12'
         
     | 
| 
      
 76 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 77 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 78 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 79 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 80 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 81 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 82 
     | 
    
         
            +
                    version: '0.12'
         
     | 
| 
       69 
83 
     | 
    
         
             
            description: 
         
     | 
| 
       70 
84 
     | 
    
         
             
            email:
         
     | 
| 
       71 
85 
     | 
    
         
             
            - oss@localytics.com
         
     | 
| 
         @@ -85,13 +99,16 @@ files: 
     | 
|
| 
       85 
99 
     | 
    
         
             
            - lib/active_record/connection_adapters/odbc_adapter.rb
         
     | 
| 
       86 
100 
     | 
    
         
             
            - lib/odbc_adapter.rb
         
     | 
| 
       87 
101 
     | 
    
         
             
            - lib/odbc_adapter/adapters/mysql_odbc_adapter.rb
         
     | 
| 
      
 102 
     | 
    
         
            +
            - lib/odbc_adapter/adapters/null_odbc_adapter.rb
         
     | 
| 
       88 
103 
     | 
    
         
             
            - lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb
         
     | 
| 
       89 
104 
     | 
    
         
             
            - lib/odbc_adapter/column.rb
         
     | 
| 
       90 
105 
     | 
    
         
             
            - lib/odbc_adapter/column_metadata.rb
         
     | 
| 
       91 
106 
     | 
    
         
             
            - lib/odbc_adapter/database_limits.rb
         
     | 
| 
      
 107 
     | 
    
         
            +
            - lib/odbc_adapter/database_metadata.rb
         
     | 
| 
       92 
108 
     | 
    
         
             
            - lib/odbc_adapter/database_statements.rb
         
     | 
| 
       93 
     | 
    
         
            -
            - lib/odbc_adapter/ 
     | 
| 
      
 109 
     | 
    
         
            +
            - lib/odbc_adapter/error.rb
         
     | 
| 
       94 
110 
     | 
    
         
             
            - lib/odbc_adapter/quoting.rb
         
     | 
| 
      
 111 
     | 
    
         
            +
            - lib/odbc_adapter/registry.rb
         
     | 
| 
       95 
112 
     | 
    
         
             
            - lib/odbc_adapter/schema_statements.rb
         
     | 
| 
       96 
113 
     | 
    
         
             
            - lib/odbc_adapter/type_caster.rb
         
     | 
| 
       97 
114 
     | 
    
         
             
            - lib/odbc_adapter/version.rb
         
     | 
    
        data/lib/odbc_adapter/dbms.rb
    DELETED
    
    | 
         @@ -1,50 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            module ODBCAdapter
         
     | 
| 
       2 
     | 
    
         
            -
              # Caches SQLGetInfo output
         
     | 
| 
       3 
     | 
    
         
            -
              class DBMS
         
     | 
| 
       4 
     | 
    
         
            -
                FIELDS = [
         
     | 
| 
       5 
     | 
    
         
            -
                  ODBC::SQL_DBMS_NAME,
         
     | 
| 
       6 
     | 
    
         
            -
                  ODBC::SQL_DBMS_VER,
         
     | 
| 
       7 
     | 
    
         
            -
                  ODBC::SQL_IDENTIFIER_CASE,
         
     | 
| 
       8 
     | 
    
         
            -
                  ODBC::SQL_QUOTED_IDENTIFIER_CASE,
         
     | 
| 
       9 
     | 
    
         
            -
                  ODBC::SQL_IDENTIFIER_QUOTE_CHAR,
         
     | 
| 
       10 
     | 
    
         
            -
                  ODBC::SQL_MAX_IDENTIFIER_LEN,
         
     | 
| 
       11 
     | 
    
         
            -
                  ODBC::SQL_MAX_TABLE_NAME_LEN,
         
     | 
| 
       12 
     | 
    
         
            -
                  ODBC::SQL_USER_NAME,
         
     | 
| 
       13 
     | 
    
         
            -
                  ODBC::SQL_DATABASE_NAME
         
     | 
| 
       14 
     | 
    
         
            -
                ]
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
                attr_reader :fields
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
                def initialize(connection)
         
     | 
| 
       19 
     | 
    
         
            -
                  @fields = Hash[FIELDS.map { |field| [field, connection.get_info(field)] }]
         
     | 
| 
       20 
     | 
    
         
            -
                end
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                def adapter_class
         
     | 
| 
       23 
     | 
    
         
            -
                  return adapter unless adapter.is_a?(Symbol)
         
     | 
| 
       24 
     | 
    
         
            -
                  require "odbc_adapter/adapters/#{adapter.downcase}_odbc_adapter"
         
     | 
| 
       25 
     | 
    
         
            -
                  Adapters.const_get(:"#{adapter}ODBCAdapter")
         
     | 
| 
       26 
     | 
    
         
            -
                end
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
                def field_for(field)
         
     | 
| 
       29 
     | 
    
         
            -
                  fields[field]
         
     | 
| 
       30 
     | 
    
         
            -
                end
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
                private
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                # Maps a DBMS name to a symbol
         
     | 
| 
       35 
     | 
    
         
            -
                # Different ODBC drivers might return different names for the same DBMS
         
     | 
| 
       36 
     | 
    
         
            -
                def adapter
         
     | 
| 
       37 
     | 
    
         
            -
                  @adapter ||=
         
     | 
| 
       38 
     | 
    
         
            -
                    begin
         
     | 
| 
       39 
     | 
    
         
            -
                      reported = field_for(ODBC::SQL_DBMS_NAME).downcase.gsub(/\s/, '')
         
     | 
| 
       40 
     | 
    
         
            -
                      found =
         
     | 
| 
       41 
     | 
    
         
            -
                        ODBCAdapter.dbms_registry.detect do |pattern, adapter|
         
     | 
| 
       42 
     | 
    
         
            -
                          adapter if reported =~ pattern
         
     | 
| 
       43 
     | 
    
         
            -
                        end
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
                      raise ArgumentError, "ODBCAdapter: Unsupported database (#{reported})" if found.nil?
         
     | 
| 
       46 
     | 
    
         
            -
                      found.last
         
     | 
| 
       47 
     | 
    
         
            -
                    end
         
     | 
| 
       48 
     | 
    
         
            -
                end
         
     | 
| 
       49 
     | 
    
         
            -
              end
         
     | 
| 
       50 
     | 
    
         
            -
            end
         
     |