Skip to content

Commit

Permalink
Reenable Rubocop, add encoding config parameter (#29)
Browse files Browse the repository at this point in the history
Reenable Rubocop, add utf8 encoding config parameter
  • Loading branch information
bwarminski authored Jan 17, 2019
1 parent da38fcb commit 7e27df4
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 17 deletions.
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
AllCops:
DisplayCopNames: true
DisplayStyleGuide: true
TargetRubyVersion: 2.1
Exclude:
- 'vendor/**/*'

Expand Down
3 changes: 1 addition & 2 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ Rake::TestTask.new(:test) do |t|
end

RuboCop::RakeTask.new(:rubocop)
# Temporarily removing as a prereq to get tests back up and working
# Rake::Task[:test].prerequisites << :rubocop
Rake::Task[:test].prerequisites << :rubocop

task default: :test
3 changes: 2 additions & 1 deletion docker/test.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/bash

echo "Testing mysql" && CONN_STR='DRIVER=MySQL;SERVER=localhost;DATABASE=odbc_test;USER=root;PASSWORD=;' bundle exec rake && \
echo "Testing postgres" && CONN_STR='DRIVER={PostgreSQL ANSI};SERVER=localhost;PORT=5432;DATABASE=odbc_test;UID=postgres;' bundle exec rake
echo "Testing postgres" && CONN_STR='DRIVER={PostgreSQL ANSI};SERVER=localhost;PORT=5432;DATABASE=odbc_test;UID=postgres;' bundle exec rake && \
echo "Testing postgres utf8" && CONN_STR='DRIVER={PostgreSQL UNICODE};SERVER=localhost;PORT=5432;DATABASE=odbc_test;UID=postgres;ENCODING=utf8' bundle exec rake
27 changes: 18 additions & 9 deletions lib/active_record/connection_adapters/odbc_adapter.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'active_record'
require 'arel/visitors/bind_visitor'
require 'odbc'
require 'odbc_utf8'

require 'odbc_adapter/database_limits'
require 'odbc_adapter/database_statements'
Expand Down Expand Up @@ -30,7 +31,7 @@ def odbc_connection(config)
raise ArgumentError, 'No data source name (:dsn) or connection string (:conn_str) specified.'
end

database_metadata = ::ODBCAdapter::DatabaseMetadata.new(connection)
database_metadata = ::ODBCAdapter::DatabaseMetadata.new(connection, config[:encoding_bug])
database_metadata.adapter_class.new(connection, logger, config, database_metadata)
end

Expand All @@ -40,21 +41,27 @@ def odbc_connection(config)
def odbc_dsn_connection(config)
username = config[:username] ? config[:username].to_s : nil
password = config[:password] ? config[:password].to_s : nil
connection = ODBC.connect(config[:dsn], username, password)
[connection, config.merge(username: username, password: password)]
odbc_module = config[:encoding] == 'utf8' ? ODBC_UTF8 : ODBC
connection = odbc_module.connect(config[:dsn], username, password)

# encoding_bug indicates that the driver is using non ASCII and has the issue referenced here https://github.com/larskanis/ruby-odbc/issues/2
[connection, config.merge(username: username, password: password, encoding_bug: config[:encoding] == 'utf8')]
end

# Connect using ODBC connection string
# Supports DSN-based or DSN-less connections
# e.g. "DSN=virt5;UID=rails;PWD=rails"
# "DRIVER={OpenLink Virtuoso};HOST=carlmbp;UID=rails;PWD=rails"
def odbc_conn_str_connection(config)
driver = ODBC::Driver.new
attrs = config[:conn_str].split(';').map { |option| option.split('=', 2) }.to_h
odbc_module = attrs['ENCODING'] == 'utf8' ? ODBC_UTF8 : ODBC
driver = odbc_module::Driver.new
driver.name = 'odbc'
driver.attrs = config[:conn_str].split(';').map { |option| option.split('=', 2) }.to_h
driver.attrs = attrs

connection = ODBC::Database.new.drvconnect(driver)
[connection, config.merge(driver: driver)]
connection = odbc_module::Database.new.drvconnect(driver)
# encoding_bug indicates that the driver is using non ASCII and has the issue referenced here https://github.com/larskanis/ruby-odbc/issues/2
[connection, config.merge(driver: driver, encoding: attrs['ENCODING'], encoding_bug: attrs['ENCODING'] == 'utf8')]
end
end
end
Expand Down Expand Up @@ -107,11 +114,12 @@ def active?
# new connection with the database.
def reconnect!
disconnect!
odbc_module = @config[:encoding] == 'utf8' ? ODBC_UTF8 : ODBC
@connection =
if @config.key?(:dsn)
ODBC.connect(@config[:dsn], @config[:username], @config[:password])
odbc_module.connect(@config[:dsn], @config[:username], @config[:password])
else
ODBC::Database.new.drvconnect(@config[:driver])
odbc_module::Database.new.drvconnect(@config[:driver])
end
configure_time_options(@connection)
super
Expand All @@ -134,6 +142,7 @@ def new_column(name, default, sql_type_metadata, null, table_name, default_funct
protected

# Build the type map for ActiveRecord
# Here, ODBC and ODBC_UTF8 constants are interchangeable
def initialize_type_map(map)
map.register_type 'boolean', Type::Boolean.new
map.register_type ODBC::SQL_CHAR, Type::String.new
Expand Down
11 changes: 9 additions & 2 deletions lib/odbc_adapter/database_metadata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,15 @@ class DatabaseMetadata

attr_reader :values

def initialize(connection)
@values = Hash[FIELDS.map { |field| [field, connection.get_info(ODBC.const_get(field))] }]
# has_encoding_bug refers to https://github.com/larskanis/ruby-odbc/issues/2 where ruby-odbc in UTF8 mode
# returns incorrectly encoded responses to getInfo
def initialize(connection, has_encoding_bug = false)
@values = Hash[FIELDS.map do |field|
info = connection.get_info(ODBC.const_get(field))
info = info.encode(Encoding.default_external, 'UTF-16LE') if info.is_a?(String) && has_encoding_bug

[field, info]
end]
end

def adapter_class
Expand Down
2 changes: 1 addition & 1 deletion lib/odbc_adapter/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module ODBCAdapter
VERSION = '5.0.3'.freeze
VERSION = '5.0.4'.freeze
end
2 changes: 1 addition & 1 deletion odbc_adapter.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'bundler', '~> 1.14'
spec.add_development_dependency 'minitest', '~> 5.10'
spec.add_development_dependency 'rake', '~> 12.0'
spec.add_development_dependency 'rubocop', '~> 0.48'
spec.add_development_dependency 'rubocop', '0.48.1'
spec.add_development_dependency 'simplecov', '~> 0.14'
end
2 changes: 1 addition & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class User < ActiveRecord::Base
{ first_name: 'Jason', last_name: 'Dsouza', letters: 11 },
{ first_name: 'Ash', last_name: 'Hepburn', letters: 10 },
{ first_name: 'Sharif', last_name: 'Younes', letters: 12 },
{ first_name: 'Ryan', last_name: 'Brown', letters: 9 }
{ first_name: 'Ryan', last_name: 'Brüwn', letters: 9 }
]
)
end
Expand Down

0 comments on commit 7e27df4

Please sign in to comment.