Skip to content

Commit

Permalink
Update our TDS version constants to reflect changed 8.0/9.0 to 7.1/7.…
Browse files Browse the repository at this point in the history
…2 DBLIB versions in FreeTDS while making it backward compatible, again like FreeTDS. Even tho you can not configure FreeTDS with TDS version 7.2 or technically even use it, I added tests to prove that we correctly handle both varchar(max) and nvarchar(max) with large amounts of data.
  • Loading branch information
metaskills committed Sep 4, 2011
1 parent 1878194 commit 9241f0f
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 19 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG
@@ -1,6 +1,11 @@

* 0.5.0 *

* Update our TDS version constants to reflect changed 8.0/9.0 to 7.1/7.2 DBLIB versions in FreeTDS
while making it backward compatible, again like FreeTDS. Even tho you can not configure FreeTDS with
TDS version 7.2 or technically even use it, I added tests to prove that we correctly handle both
varchar(max) and nvarchar(max) with large amounts of data.

* FreeTDS 0.91 has been released. Update our port scripts.

* Add test for 0.91 and higher to handle incorrect syntax in sp_executesql.
Expand Down Expand Up @@ -39,7 +44,8 @@

* 0.4.2 *

* Iconv is a dep only when compiling locally. However, left in the ability to configure it for native gem installation but you must use --enable-iconv before using --with-iconv-dir=/some/dir
* Iconv is a dep only when compiling locally. However, left in the ability to configure it for native gem installation
but you must use --enable-iconv before using --with-iconv-dir=/some/dir

* Really fix what 0.4.1 was supposed to do, force SYBDBLIB compile.

Expand Down
2 changes: 2 additions & 0 deletions ext/tiny_tds/client.c
Expand Up @@ -54,6 +54,8 @@ int tinytds_err_handler(DBPROCESS *dbproc, int severity, int dberr, int oserr, c
int return_value = INT_CONTINUE;
int cancel = 0;
switch(dberr) {
case 100: /* SYBEVERDOWN */
return INT_CANCEL;
case SYBESMSG:
return return_value;
case SYBEICONVI:
Expand Down
32 changes: 19 additions & 13 deletions lib/tiny_tds/client.rb
Expand Up @@ -7,8 +7,10 @@ class Client
'100' => 2,
'42' => 3,
'70' => 4,
'71' => 5,
'80' => 5,
'90' => 6 # TODO: untested
'72' => 6,
'90' => 6
}.freeze

TDS_VERSIONS_GETTERS = {
Expand All @@ -21,8 +23,8 @@ class Client
6 => {:name => 'DBTDS_4_9_5', :description => '4.9.5 (NCR) SQL Server'},
7 => {:name => 'DBTDS_5_0', :description => '5.0 SQL Server'},
8 => {:name => 'DBTDS_7_0', :description => 'Microsoft SQL Server 7.0'},
9 => {:name => 'DBTDS_8_0', :description => 'Microsoft SQL Server 2000'},
10 => {:name => 'DBTDS_9_0', :description => 'Microsoft SQL Server 2005'}
9 => {:name => 'DBTDS_7_1', :description => 'Microsoft SQL Server 2000'},
10 => {:name => 'DBTDS_7_2', :description => 'Microsoft SQL Server 2005'}
}.freeze

@@default_query_options = {
Expand All @@ -35,15 +37,19 @@ class Client

attr_reader :query_options

def self.default_query_options
@@default_query_options
end

# Most, if not all, iconv encoding names can be found by ruby. Just in case, you can
# overide this method to return a string name that Encoding.find would work with. Default
# is to return the passed encoding.
def self.transpose_iconv_encoding(encoding)
encoding
class << self

def default_query_options
@@default_query_options
end

# Most, if not all, iconv encoding names can be found by ruby. Just in case, you can
# overide this method to return a string name that Encoding.find would work with. Default
# is to return the passed encoding.
def transpose_iconv_encoding(encoding)
encoding
end

end


Expand All @@ -52,7 +58,7 @@ def initialize(opts={})
raise ArgumentError, 'missing :host option if no :dataserver given' if opts[:dataserver].to_s.empty? && opts[:host].to_s.empty?
@query_options = @@default_query_options.dup
opts[:appname] ||= 'TinyTds'
opts[:tds_version] = TDS_VERSIONS_SETTERS[opts[:tds_version].to_s] || TDS_VERSIONS_SETTERS['80']
opts[:tds_lversion] = TDS_VERSIONS_SETTERS[opts[:tds_version].to_s] || TDS_VERSIONS_SETTERS['71']
opts[:login_timeout] ||= 60
opts[:timeout] ||= 5
opts[:encoding] = (opts[:encoding].nil? || opts[:encoding].downcase == 'utf8') ? 'UTF-8' : opts[:encoding].upcase
Expand Down
6 changes: 3 additions & 3 deletions tasks/ports.rake
Expand Up @@ -5,11 +5,11 @@ namespace :ports do

# If your using 0.82, you may have to make a conf file to get it to work. For example:
# $ export FREETDSCONF='/opt/local/etc/freetds/freetds.conf'

ICONV_VERSION = "1.13.1"
FREETDS_VERSION = ENV['TINYTDS_FREETDS_082'] ? "0.82" : "0.91"
FREETDS_VERSION_INFO = {
"0.82" => {:files => "http://ibiblio.org/pub/Linux/ALPHA/freetds/old/0.82/freetds-patched.tgz"},
"0.82" => {:files => "http://ibiblio.org/pub/Linux/ALPHA/freetds/old/0.82/freetds-0.82.tar.gz"},
# "0.82" => {:files => "http://ibiblio.org/pub/Linux/ALPHA/freetds/old/0.82/freetds-patched.tgz"},
"0.91" => {:files => "http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/freetds-0.91.tar.gz"} }

ORIGINAL_HOST = RbConfig::CONFIG["arch"]
Expand Down Expand Up @@ -42,7 +42,7 @@ namespace :ports do
# recipe.configure_options << "--disable-debug"
recipe.configure_options << '--sysconfdir="C:/Sites"' if recipe.host != ORIGINAL_HOST
recipe.configure_options << "--disable-odbc"
recipe.configure_options << "--with-tdsver=7.1"
recipe.configure_options << ENV['TINYTDS_FREETDS_082'] ? "--with-tdsver=8.0" : "--with-tdsver=7.1"
recipe.cook
touch checkpoint
end
Expand Down
2 changes: 1 addition & 1 deletion test/client_test.rb
Expand Up @@ -25,7 +25,7 @@ class ClientTest < TinyTds::TestCase

should 'have a getters for the tds version information (brittle since conf takes precedence)' do
assert_equal 9, @client.tds_version
assert_equal 'DBTDS_8_0 - Microsoft SQL Server 2000', @client.tds_version_info
assert_equal 'DBTDS_7_1 - Microsoft SQL Server 2000', @client.tds_version_info
end

should 'use UTF-8 client charset/encoding by default' do
Expand Down
33 changes: 32 additions & 1 deletion test/result_test.rb
Expand Up @@ -110,7 +110,7 @@ class ResultTest < TinyTds::TestCase
assert_equal text, row['varchar_50']
end
end

should 'insert and find unicode data' do
rollback_transaction(@client) do
text = '✓'
Expand Down Expand Up @@ -546,6 +546,28 @@ class ResultTest < TinyTds::TestCase

end

context 'with data type' do

context 'char max' do

setup do
@big_text = 'x' * 2_000_000
@old_textsize = @client.execute("SELECT @@TEXTSIZE AS [textsize]").each.first['textsize'].inspect
@client.execute("SET TEXTSIZE #{(@big_text.length*2)+1}").do
end

should 'insert and select large varchar_max' do
insert_and_select_datatype :varchar_max
end

should 'insert and select large nvarchar_max' do
insert_and_select_datatype :nvarchar_max
end

end unless sqlserver_2000?

end

context 'when shit happens' do

should 'cope with nil or empty buffer' do
Expand Down Expand Up @@ -624,5 +646,14 @@ def assert_followup_query
assert_equal 1, result.each.first['one']
end

def insert_and_select_datatype(datatype)
rollback_transaction(@client) do
@client.execute("DELETE FROM [datatypes] WHERE [#{datatype}] IS NOT NULL").do
id = @client.execute("INSERT INTO [datatypes] ([#{datatype}]) VALUES (N'#{@big_text}')").insert
found_text = find_value id, datatype
flunk "Large #{datatype} data with a length of #{@big_text.length} did not match found text with length of #{found_text.length}" unless @big_text == found_text
end
end

end

0 comments on commit 9241f0f

Please sign in to comment.