Skip to content

Commit

Permalink
Tested ruby 1.9, ruby-odbc 0.9996, and DBI 0.4.1. Also added correct …
Browse files Browse the repository at this point in the history
…support for UTF-8 character encoding going in and out of the DB. See before gist http://gist.github.com/111709 and after gist http://gist.github.com/111719
  • Loading branch information
metaskills committed May 14, 2009
1 parent d6be139 commit d9fe27e
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 6 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@

MASTER

*
* Tested ruby 1.9, ruby-odbc 0.9996, and DBI 0.4.1. Also added correct support for UTF-8 character
encoding going in and out of the DB. See before gist http://gist.github.com/111709 and after gist
http://gist.github.com/111719


* 2.2.16 * (April 21st, 2009)
Expand Down
7 changes: 4 additions & 3 deletions README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ The SQL Server adapter for rails is back for ActiveRecord 2.2 and up! We are cur

== What's New

* Fully tested under 1.9!!! Correctly encodes/decodes UTF-8 types in ruby 1.9 too.
* Now supports both rails 2.2 & 2.3!!!
* An ActiveRecord::Base.execute_procedure method that can be used by classes.
* Enabled support for DDL transactions.
Expand Down Expand Up @@ -119,11 +120,11 @@ It is our goal to match the adapter version with each version of rails. However

== Installation

First, you will need Ruby DBI and Ruby ODBC. To my knowledge the ADO DBD for DBI is no longer supported. The installation below is not a comprehensive walk thru on how to get all the required moving parts like FreeTDS installed and/or configured. It will also assume gem installations of both the dependent libraries and the adapter itself.
First, you will need Ruby DBI and Ruby ODBC. If you are using the adapter under 1.9, then you need at least ruby-odbc version 0.9996. To my knowledge the ADO DBD for DBI is no longer supported. The installation below is not a comprehensive walk thru on how to get all the required moving parts like FreeTDS installed and/or configured. It will also assume gem installations of both the dependent libraries and the adapter itself.

It should be noted that this version of the adapter was developed using both the ancient 0.0.23 version of DBI up to the current stable release of 0.4.0. Because later versions of DBI will be changing many things, IT IS HIGHLY RECOMMENDED that you max your install to version 0.4.0 which the examples below show. For the time being we are not supporting DBI versions higher than 0.4.0. The good news is that if you were using a very old DBI with ADO, technically this adapter will still work for you, but be warned your path is getting old and may not be supported for long.
It should be noted that this version of the adapter was developed using both the ancient 0.0.23 version of DBI up to the current stable release of 0.4.1. Note that DBI 0.4.1 is the minimal for ruby 1.9 compatibility. Because later versions of DBI will be changing many things, IT IS HIGHLY RECOMMENDED that you max your install to version 0.4.0 which the examples below show. For the time being we are not supporting DBI versions higher than 0.4.0. The good news is that if you were using a very old DBI with ADO, technically this adapter will still work for you, but be warned your path is getting old and may not be supported for long.

$ gem install dbi --version 0.4.0
$ gem install dbi --version 0.4.1
$ gem install dbd-odbc --version 0.2.4
$ gem install rails-sqlserver-2000-2005-adapter -s http://gems.github.com

Expand Down
20 changes: 20 additions & 0 deletions lib/active_record/connection_adapters/sqlserver_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ def initialize(name, default, sql_type = nil, null = true, sqlserver_options = {

class << self

def string_to_utf8_encoding(value)
value.force_encoding('UTF-8') rescue value
end

def string_to_binary(value)
"0x#{value.unpack("H*")[0]}"
end
Expand All @@ -59,6 +63,22 @@ def binary_to_string(value)

end

def type_cast(value)
if value && type == :string && is_utf8?
self.class.string_to_utf8_encoding(value)
else
super
end
end

def type_cast_code(var_name)
if type == :string && is_utf8?
"#{self.class.name}.string_to_utf8_encoding(#{var_name})"
else
super
end
end

def is_identity?
@sqlserver_options[:is_identity]
end
Expand Down
2 changes: 2 additions & 0 deletions test/cases/sqlserver_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ def sqlserver_2000? ; ActiveRecord::Base.connection.sqlserver_2000? ; end
def sqlserver_2005? ; ActiveRecord::Base.connection.sqlserver_2005? ; end
def active_record_2_point_2? ; ActiveRecord::VERSION::MAJOR == 2 && ActiveRecord::VERSION::MINOR == 2 ; end
def active_record_2_point_3? ; ActiveRecord::VERSION::MAJOR == 2 && ActiveRecord::VERSION::MINOR == 3 ; end
def ruby_19? ; RUBY_VERSION >= '1.9' ; end
end
def assert_sql(*patterns_to_match)
$queries_executed = []
Expand All @@ -113,6 +114,7 @@ def sqlserver_2000? ; self.class.sqlserver_2000? ; end
def sqlserver_2005? ; self.class.sqlserver_2005? ; end
def active_record_2_point_2? ; self.class.active_record_2_point_2? ; end
def active_record_2_point_3? ; self.class.active_record_2_point_3? ; end
def ruby_19? ; self.class.ruby_19? ; end
end
end

Expand Down
9 changes: 7 additions & 2 deletions test/cases/unicode_test_sqlserver.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# encoding: utf-8
require 'cases/sqlserver_helper'

class UnicodeTestSqlserver < ActiveRecord::TestCase
Expand Down Expand Up @@ -30,13 +29,19 @@ class UnicodeTestSqlserver < ActiveRecord::TestCase
context 'Testing unicode data' do

setup do
@unicode_data = "一二34五六"
@unicode_data = "\344\270\200\344\272\21434\344\272\224\345\205\255"
@encoded_unicode_data = "\344\270\200\344\272\21434\344\272\224\345\205\255".force_encoding('UTF-8') if ruby_19?
end

should 'insert into nvarchar field' do
assert data = SqlServerUnicode.create!(:nvarchar => @unicode_data)
assert_equal @unicode_data, data.reload.nvarchar
end

should 're-encode data on DB reads' do
assert data = SqlServerUnicode.create!(:nvarchar => @unicode_data)
assert_equal @encoded_unicode_data, data.reload.nvarchar
end if ruby_19?

end

Expand Down

0 comments on commit d9fe27e

Please sign in to comment.