Add SQL 2014 support to activerecord-sqlserver-ada

2019-08-12 04:36发布

问题:

We've be using the activerecord-sqlserver-adapter gem with sqlserver 2008 and everything works great. We just tried to deploy our Rails 3 app against a new sqlserver 2014 db and I get an error that says:

Currently, only 2005, 2008, 2010, 2011, and 2012 are supported. We got back Microsoft SQL Server 2014 - 12.0.2000.8 (X64)

A quick look at github shows that a small update was recently made to the sqlserver_adapter.rd to resolve this issue. I tried to update the gem and it turned into a bit of dependency hell and eventually looked as though I'd have to upgrade to rails 4 (which I don't particularly want to do right now) in order to get this fix.

So I thought I make my first attempt at a monkey patch and created an .rd in my initializers folder that incorporates the the changes to add sqlserver 2014 support:

module ConnectionAdapters  

    class SqlServerAdapter < AbstractAdapter
      SUPPORTED_VERSIONS = [2005,2008,2010,2011,2012,2014]


      # === SQLServer Specific (DB Reflection) ======================== #

       def sqlserver_2014?
        @database_year == 2014
      end



    end
   end

My intention was to simply override the several lines of code in sqlserver_adapter.rd with change in the fix on github. However when I try to deploy, I now get an UnitializedConstant Error referring to AbstractAdapter.

How can make this patch work? Or this there a better way to accomplish this task?

回答1:

I found a much better solution than a monkey patch. Turns out the guys over at activerecord-sqlserver-adapter updated the various releases so I just had to specify the version 3.2 branch with the SQLServer 2014 support fix. The following line in my gem file resolved the entire issue and we are now connecting to SqlServer '14

gem 'activerecord-sqlserver-adapter', :git => "git://github.com/rails-sqlserver/activerecord-sqlserver-adapter.git", :branch => "3-2-stable" 


回答2:

I did the following with v 4.1.8:

module ActiveRecord
  module ConnectionAdapters
    class SQLServerAdapter < AbstractAdapter
      SUPPORTED_VERSIONS << 2014
      # === SQLServer Specific (DB Reflection) ======================== #

      def sqlserver_2014?
        @database_year = 2014
      end
    end
  end
end


回答3:

I have also addressed this problem with the Ruby 1.8.6 setup that I inherited.

The solution is not really as high-tech as proposed here.

The adapter interface is located at C:\ruby\lib\ruby\gems\1.8\gems\activerecord-sqlserver-adapter-2.3.4\lib\active_record\connection_adapters and is called sqlserver_adapter.rb.

I modified the following code to appear as such:

    class SQLServerAdapter < AbstractAdapter

  ADAPTER_NAME                = 'SQLServer'.freeze
  VERSION                     = '2.3.4'.freeze
  DATABASE_VERSION_REGEXP     = /Microsoft SQL Server\s+(\d{4})/
  SUPPORTED_VERSIONS          = [2000,2005,2008,2012,2016].freeze
  LIMITABLE_TYPES             = ['string','integer','float','char','nchar','varchar','nvarchar'].freeze
  LOST_CONNECTION_EXCEPTIONS  = {
    :odbc => ['ODBC::Error'],
    :ado  => []
  }
  LOST_CONNECTION_MESSAGES    = {
    :odbc => [/link failure/, /server failed/, /connection was already closed/, /invalid handle/i],
    :ado  => []
  }

The only thing I did to modify the adapter code was change [2000,2005,2008] to [2000,2005,2008,2012,2016].

I then used the ODBC Datasource Administrator (32-bit) to configure to use the "SQL Server Native Client 11.0" for the Sql Server 2016 instance.

This last step is the really important one in the ODBC adapter setup.

The "SQL Server" adapter may default to a 64-bit connection which gives the following error when trying to connect to the database:

#<ODBC::Error: S1090 (0) [Microsoft][ODBC Driver Manager] Invalid string or buffer length>.

I am retrofitting an obsolete 2008R2 server set of legacy Ruby programs running on Apache to a new Windows Server 2016 setup, and don't have the luxury of debugging the legacy Ruby code to make it work with a newer version of Ruby and Ruby on Rails.

This low-tech solution fully meets our operational needs, budget and time constraints.