Git Product home page Git Product logo

tiny_tds's Introduction

TinyTDS - Simple and fast FreeTDS bindings for Ruby using DB-Library.

  • CircleCI - CircleCi
  • Gem Version - Gem Version
  • Gitter chat - Community

About TinyTDS

The TinyTDS gem is meant to serve the extremely common use-case of connecting, querying and iterating over results to Microsoft SQL Server from Ruby using the FreeTDS's DB-Library API.

TinyTDS offers automatic casting to Ruby primitives along with proper encoding support. It converts all SQL Server datatypes to native Ruby primitives while supporting :utc or :local time zones for time-like types. To date it is the only Ruby client library that allows client encoding options, defaulting to UTF-8, while connecting to SQL Server. It also properly encodes all string and binary data.

The API is simple and consists of these classes:

  • TinyTds::Client - Your connection to the database.
  • TinyTds::Result - Returned from issuing an #execute on the connection. It includes Enumerable.
  • TinyTds::Error - A wrapper for all FreeTDS exceptions.

Install

Installing with rubygems should just work. TinyTDS is currently tested on Ruby version 2.7.0 and upward.

$ gem install tiny_tds

If you use Windows, we pre-compile TinyTDS with static versions of FreeTDS and supporting libraries. If you're using RubyInstaller, the binary gem will require that devkit is installed and in your path to operate properly.

On all other platforms, we will find these dependencies. It is recommended that you install the latest FreeTDS via your method of choice. For example, here is how to install FreeTDS on Ubuntu. You might also need the build-essential and possibly the libc6-dev packages.

$ apt-get install wget
$ apt-get install build-essential
$ apt-get install libc6-dev

$ wget http://www.freetds.org/files/stable/freetds-1.4.10.tar.gz
$ tar -xzf freetds-1.4.10.tar.gz
$ cd freetds-1.4.10
$ ./configure --prefix=/usr/local --with-tdsver=7.4
$ make
$ make install

Please read the MiniPortile and/or Windows sections at the end of this file for advanced configuration options past the following:

--with-freetds-dir=DIR
  Use the freetds library placed under DIR.

Getting Started

Optionally, Microsoft has done a great job writing an article on how to get started with SQL Server and Ruby using TinyTDS, however, the articles are using outdated versions.

FreeTDS Compatibility & Configuration

TinyTDS is developed against FreeTDs 1.1+. We also test with SQL Server 2017, 2019, 2022 and Azure. Older version of SQL Server or FreeTDS could work, but are not supported.

Important

Windows users of our pre-compiled native gems need not worry about installing FreeTDS and its dependencies.

  • Do I need to install FreeTDS? Yes! Somehow, someway, you are going to need FreeTDS for TinyTDS to compile against.

  • OK, I am installing FreeTDS, how do I configure it? Contrary to what most people think, you do not need to specially configure FreeTDS in any way for client libraries like TinyTDS to use it. About the only requirement is that you compile it with libiconv for proper encoding support. FreeTDS must also be compiled with OpenSSL (or the like) to use it with Azure. See the "Using TinyTDS with Azure" section below for more info.

  • Do I need to configure --with-tdsver equal to anything? Most likely! Technically you should not have to. This is only a default for clients/configs that do not specify what TDS version they want to use. We are currently having issues with passing down a TDS version with the login bit. Till we get that fixed, if you are not using a freetds.conf or a TDSVER environment variable, then make sure to use 7.4.

  • I want to configure FreeTDS using --enable-msdblib and/or --enable-sybase-compat so it works for my database. Cool? It's a waste of time and totally moot! Client libraries like TinyTDS define their own C structure names where they diverge from Sybase to SQL Server. Technically we use the MSDBLIB structures which does not mean we only work with that database vs Sybase. These configs are just a low level default for C libraries that do not define what they want. So I repeat, you do not NEED to use any of these, nor will they hurt anything since we control what C structure names we use internally!

Data Types

Our goal is to support every SQL Server data type and covert it to a logical Ruby object. When dates or times are returned, they are instantiated to either :utc or :local time depending on the query options. Only [datetimeoffset] types are excluded. All strings are associated the to the connection's encoding and all binary data types are associated to Ruby's ASCII-8BIT/BINARY encoding.

Below is a list of the data types we support when using the 7.4 TDS protocol version. Using a lower protocol version will result in these types being returned as strings.

  • [date]
  • [datetime2]
  • [datetimeoffset]
  • [time]

TinyTds::Client Usage

Connect to a database.

client = TinyTds::Client.new username: 'sa', password: 'secret', host: 'mydb.host.net'

Creating a new client takes a hash of options. For valid iconv encoding options, see the output of iconv -l. Only a few have been tested and highly recommended to leave blank for the UTF-8 default.

  • :username - The database server user.
  • :password - The user password.
  • :dataserver - Can be the name for your data server as defined in freetds.conf. Raw hostname or hostname:port will work here too. FreeTDS says that named instance like 'localhost\SQLEXPRESS' work too, but I highly suggest that you use the :host and :port options below. Google how to find your host port if you are using named instances or go here.
  • :host - Used if :dataserver blank. Can be an host name or IP.
  • :port - Defaults to 1433. Only used if :host is used.
  • :database - The default database to use.
  • :appname - Short string seen in SQL Servers process/activity window.
  • :tds_version - TDS version. Defaults to "7.3".
  • :login_timeout - Seconds to wait for login. Default to 60 seconds.
  • :timeout - Seconds to wait for a response to a SQL command. Default 5 seconds. Timeouts caused by network failure will raise a timeout error 1 second after the configured timeout limit is hit (see #481 for details).
  • :encoding - Any valid iconv value like CP1251 or ISO-8859-1. Default UTF-8.
  • :azure - Pass true to signal that you are connecting to azure.
  • :contained - Pass true to signal that you are connecting with a contained database user.
  • :use_utf16 - Instead of using UCS-2 for database wide character encoding use UTF-16. Newer Windows versions use this encoding instead of UCS-2. Default true.
  • :message_handler - Pass in a call-able object such as a Proc or a method to receive info messages from the database. It should have a single parameter, which will be a TinyTds::Error object representing the message. For example:
opts = ... # host, username, password, etc
opts[:message_handler] = Proc.new { |m| puts m.message }
client = TinyTds::Client.new opts
# => Changed database context to 'master'.
# => Changed language setting to us_english.
client.execute("print 'hello world!'").do
# => hello world!

Use the #active? method to determine if a connection is good. The implementation of this method may change but it should always guarantee that a connection is good. Current it checks for either a closed or dead connection.

client.dead?    # => false
client.closed?  # => false
client.active?  # => true
client.execute("SQL TO A DEAD SERVER")
client.dead?    # => true
client.closed?  # => false
client.active?  # => false
client.close
client.closed?  # => true
client.active?  # => false

Escape strings.

client.escape("How's It Going'") # => "How''s It Going''"

Send a SQL string to the database and return a TinyTds::Result object.

result = client.execute("SELECT * FROM [datatypes]")

TinyTds::Result Usage

A result object is returned by the client's execute command. It is important that you either return the data from the query, most likely with the #each method, or that you cancel the results before asking the client to execute another SQL batch. Failing to do so will yield an error.

Calling #each on the result will lazily load each row from the database.

result.each do |row|
  # By default each row is a hash.
  # The keys are the fields, as you'd expect.
  # The values are pre-built Ruby primitives mapped from their corresponding types.
end

A result object has a #fields accessor. It can be called before the result rows are iterated over. Even if no rows are returned, #fields will still return the column names you expected. Any SQL that does not return columned data will always return an empty array for #fields. It is important to remember that if you access the #fields before iterating over the results, the columns will always follow the default query option's :symbolize_keys setting at the client's level and will ignore the query options passed to each.

result = client.execute("USE [tinytdstest]")
result.fields # => []
result.do

result = client.execute("SELECT [id] FROM [datatypes]")
result.fields # => ["id"]
result.cancel
result = client.execute("SELECT [id] FROM [datatypes]")
result.each(:symbolize_keys => true)
result.fields # => [:id]

You can cancel a result object's data from being loading by the server.

result = client.execute("SELECT * FROM [super_big_table]")
result.cancel

You can use results cancelation in conjunction with results lazy loading, no problem.

result = client.execute("SELECT * FROM [super_big_table]")
result.each_with_index do |row, i|
  break if row > 10
end
result.cancel

If the SQL executed by the client returns affected rows, you can easily find out how many.

result.each
result.affected_rows # => 24

This pattern is so common for UPDATE and DELETE statements that the #do method cancels any need for loading the result data and returns the #affected_rows.

result = client.execute("DELETE FROM [datatypes]")
result.do # => 72

Likewise for INSERT statements, the #insert method cancels any need for loading the result data and executes a SCOPE_IDENTITY() for the primary key.

result = client.execute("INSERT INTO [datatypes] ([xml]) VALUES ('<html><br/></html>')")
result.insert # => 420

The result object can handle multiple result sets form batched SQL or stored procedures. It is critical to remember that when calling each with a block for the first time will return each "row" of each result set. Calling each a second time with a block will yield each "set".

sql = ["SELECT TOP (1) [id] FROM [datatypes]",
       "SELECT TOP (2) [bigint] FROM [datatypes] WHERE [bigint] IS NOT NULL"].join(' ')

set1, set2 = client.execute(sql).each
set1 # => [{"id"=>11}]
set2 # => [{"bigint"=>-9223372036854775807}, {"bigint"=>9223372036854775806}]

result = client.execute(sql)

result.each do |rowset|
  # First time data loading, yields each row from each set.
  # 1st: {"id"=>11}
  # 2nd: {"bigint"=>-9223372036854775807}
  # 3rd: {"bigint"=>9223372036854775806}
end

result.each do |rowset|
  # Second time over (if columns cached), yields each set.
  # 1st: [{"id"=>11}]
  # 2nd: [{"bigint"=>-9223372036854775807}, {"bigint"=>9223372036854775806}]
end

Use the #sqlsent? and #canceled? query methods on the client to determine if an active SQL batch still needs to be processed and or if data results were canceled from the last result object. These values reset to true and false respectively for the client at the start of each #execute and new result object. Or if all rows are processed normally, #sqlsent? will return false. To demonstrate, lets assume we have 100 rows in the result object.

client.sqlsent?   # = false
client.canceled?  # = false

result = client.execute("SELECT * FROM [super_big_table]")

client.sqlsent?   # = true
client.canceled?  # = false

result.each do |row|
  # Assume we break after 20 rows with 80 still pending.
  break if row["id"] > 20
end

client.sqlsent?   # = true
client.canceled?  # = false

result.cancel

client.sqlsent?   # = false
client.canceled?  # = true

It is possible to get the return code after executing a stored procedure from either the result or client object.

client.return_code  # => nil

result = client.execute("EXEC tinytds_TestReturnCodes")
result.do
result.return_code  # => 420
client.return_code  # => 420

Query Options

Every TinyTds::Result object can pass query options to the #each method. The defaults are defined and configurable by setting options in the TinyTds::Client.default_query_options hash. The default values are:

  • :as => :hash - Object for each row yielded. Can be set to :array.
  • :symbolize_keys => false - Row hash keys. Defaults to shared/frozen string keys.
  • :cache_rows => true - Successive calls to #each returns the cached rows.
  • :timezone => :local - Local to the Ruby client or :utc for UTC.
  • :empty_sets => true - Include empty results set in queries that return multiple result sets.

Each result gets a copy of the default options you specify at the client level and can be overridden by passing an options hash to the #each method. For example

result.each(:as => :array, :cache_rows => false) do |row|
  # Each row is now an array of values ordered by #fields.
  # Rows are yielded and forgotten about, freeing memory.
end

Besides the standard query options, the result object can take one additional option. Using :first => true will only load the first row of data and cancel all remaining results.

result = client.execute("SELECT * FROM [super_big_table]")
result.each(:first => true) # => [{'id' => 24}]

Row Caching

By default row caching is turned on because the SQL Server adapter for ActiveRecord would not work without it. I hope to find some time to create some performance patches for ActiveRecord that would allow it to take advantages of lazily created yielded rows from result objects. Currently only TinyTDS and the Mysql2 gem allow such a performance gain.

Encoding Error Handling

TinyTDS takes an opinionated stance on how we handle encoding errors. First, we treat errors differently on reads vs. writes. Our opinion is that if you are reading bad data due to your client's encoding option, you would rather just find ? marks in your strings vs being blocked with exceptions. This is how things wold work via ODBC or SMS. On the other hand, writes will raise an exception. In this case we raise the SYBEICONVO/2402 error message which has a description of Error converting characters into server's character set. Some character(s) could not be converted.. Even though the severity of this message is only a 4 and TinyTDS will automatically strip/ignore unknown characters, we feel you should know that you are inserting bad encodings. In this way, a transaction can be rolled back, etc. Remember, any database write that has bad characters due to the client encoding will still be written to the database, but it is up to you rollback said write if needed. Most ORMs like ActiveRecord handle this scenario just fine.

Timeout Error Handling

TinyTDS will raise a TinyTDS::Error when a timeout is reached based on the options supplied to the client. Depending on the reason for the timeout, the connection could be dead or alive. When db processing is the cause for the timeout, the connection should still be usable after the error is raised. When network failure is the cause of the timeout, the connection will be dead. If you attempt to execute another command batch on a dead connection you will see a DBPROCESS is dead or not enabled error. Therefore, it is recommended to check for a dead? connection before trying to execute another command batch.

Binstubs

The TinyTDS gem uses binstub wrappers which mirror compiled FreeTDS Utilities binaries. These native executables are usually installed at the system level when installing FreeTDS. However, when using MiniPortile to install TinyTDS as we do with Windows binaries, these binstubs will find and prefer local gem exe directory executables. These are the following binstubs we wrap.

  • tsql - Used to test connections and debug compile time settings.
  • defncopy - Used to dump schema structures.

Using TinyTDS With Rails & The ActiveRecord SQL Server adapter.

TinyTDS is the default connection mode for the SQL Server adapter in versions 3.1 or higher. The SQL Server adapter can be found using the links below.

Using TinyTDS with Azure

TinyTDS is fully tested with the Azure platform. You must set the azure: true connection option when connecting. This is needed to specify the default database name in the login packet since Azure has no notion of USE [database]. FreeTDS must be compiled with OpenSSL too.

IMPORTANT: Do not use [email protected] for the username connection option! You must use the shorter username@server instead!

Also, please read the Azure SQL Database General Guidelines and Limitations MSDN article to understand the differences. Specifically, the connection constraints section!

Connection Settings

A DBLIB connection does not have the same default SET options for a standard SMS SQL Server connection. Hence, we recommend the following options post establishing your connection.

SQL Server

SET ANSI_DEFAULTS ON

SET QUOTED_IDENTIFIER ON
SET CURSOR_CLOSE_ON_COMMIT OFF
SET IMPLICIT_TRANSACTIONS OFF
SET TEXTSIZE 2147483647
SET CONCAT_NULL_YIELDS_NULL ON

Azure

SET ANSI_NULLS ON
SET ANSI_NULL_DFLT_ON ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON

SET QUOTED_IDENTIFIER ON
SET CURSOR_CLOSE_ON_COMMIT OFF
SET IMPLICIT_TRANSACTIONS OFF
SET TEXTSIZE 2147483647
SET CONCAT_NULL_YIELDS_NULL ON

Thread Safety

TinyTDS must be used with a connection pool for thread safety. If you use ActiveRecord or the Sequel gem this is done for you. However, if you are using TinyTDS on your own, we recommend using the ConnectionPool gem when using threads:

Please read our thread_test.rb file for details on how we test its usage.

Emoji Support 😍

This is possible. Since FreeTDS v1.0, utf-16 is enabled by default and supported by tiny_tds. You can toggle it by using use_utf16 when establishing the connection.

Compiling Gems for Windows

For the convenience of Windows users, TinyTDS ships pre-compiled gems for supported versions of Ruby on Windows. In order to generate these gems, rake-compiler-dock is used. This project provides several Docker images with rvm, cross-compilers and a number of different target versions of Ruby.

Run the following rake task to compile the gems for Windows. This will check the availability of Docker (and boot2docker on Windows or OS-X) and will give some advice for download and installation. When docker is running, it will download the docker image (once-only) and start the build:

$ rake gem:native

The compiled gems will exist in ./pkg directory.

Development & Testing

First, clone the repo using the command line or your Git GUI of choice.

$ git clone [email protected]:rails-sqlserver/tiny_tds.git

After that, the quickest way to get setup for development is to use Docker. Assuming you have downloaded docker for your platform, you can use docker-compose to run the necessary containers for testing.

$ docker-compose up -d

This will download the official SQL Server for Linux Docker image from Microsoft. This will also download a toxiproxy Docker image which we can use to simulate network failures for tests. Basically, it does the following:

$ docker network create main-network
$ docker pull mcr.microsoft.com/mssql/server:2017-latest
$ docker run -p 1433:1433 -d --name sqlserver --network main-network mcr.microsoft.com/mssql/server:2017-latest
$ docker pull shopify/toxiproxy
$ docker run -p 8474:8474 -p 1234:1234 -d --name toxiproxy --network main-network shopify/toxiproxy

Make sure to run these SQL scripts as SA to get the test database and user installed. If needed, install sqlcmd as described by Microsoft for your platform.

/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P super01S3cUr3 -i ./test/sql/db-create.sql
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P super01S3cUr3 -i ./test/sql/db-login.sql

From here you can build and run tests against an installed version of FreeTDS.

$ bundle install
$ bundle exec rake

Examples us using enviornment variables to customize the test task.

$ rake TINYTDS_UNIT_DATASERVER=mydbserver
$ rake TINYTDS_UNIT_DATASERVER=mydbserver TINYTDS_SCHEMA=sqlserver_2017
$ rake TINYTDS_UNIT_HOST=mydb.host.net TINYTDS_SCHEMA=sqlserver_azure

Docker Builds

If you use a multi stage Docker build to assemble your gems in one phase and then copy your app and gems into another, lighter, container without build tools you will need to make sure you tell the OS how to find dependencies for TinyTDS.

After you have built and installed FreeTDS it will normally place library files in /usr/local/lib. When TinyTDS builds native extensions, it already knows to look here but if you copy your app to a new container that link will be broken.

Set the LD_LIBRARY_PATH environment variable export LD_LIBRARY_PATH=/usr/local/lib:${LD_LIBRARY_PATH} and run ldconfig. If you run ldd tiny_tds.so you should not see any broken links. Make sure you also copied in the library dependencies from your build container with a command like COPY --from=builder /usr/local/lib /usr/local/lib.

Help & Support

About Me

My name is Ken Collins and I currently maintain the SQL Server adapter for ActiveRecord and wrote this library as my first cut into learning Ruby C extensions. Hopefully it will help promote the power of Ruby and the Rails framework to those that have not yet discovered it. My blog is metaskills.net and I can be found on twitter as @metaskills. Enjoy!

Special Thanks

License

TinyTDS is Copyright (c) 2010-2015 Ken Collins, [email protected] and Will Bond (Veracross LLC) [email protected]. It is distributed under the MIT license. Windows binaries contain pre-compiled versions of FreeTDS http://www.freetds.org/ which is licensed under the GNU LGPL license at http://www.gnu.org/licenses/lgpl-2.0.html

tiny_tds's People

Contributors

aharpervc avatar ajlam avatar andyundso avatar bf4 avatar bvogelzang avatar coderjoe avatar denispeplin avatar ebryn avatar ecentell-cpf avatar kronn avatar krzcho avatar l8nite avatar largo avatar larskanis avatar lepfhty avatar locks avatar luislavena avatar metaskills avatar mlh758 avatar mroach avatar orgads avatar padmick avatar r-uehara0219 avatar rushed avatar sgrif avatar sukeerthiadiga avatar vjt avatar wbond avatar wok avatar wpolicarpo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tiny_tds's Issues

Installing FreeTDS

Hi Ken,

could you be a little more verbose in the README regarding which options to use for configuring FreeTDS ?

I assume the minimum option is:
./configure --with-tdsver=7.1

and you may even disable odbc, when you are only using TinyTDS on your system
./configure --with-tdsver=7.1 --disable-odbc

Empty result sets missing when query returns multiple result sets

When the SQL query returns multiple result sets, only the sets which contain rows are returned. Sets without any rows are omitted.

sql = "SELECT 10 as first; SELECT 20 as second where 1 = 0; select 30 as third"

result = client.execute( sql )

puts result.each.pretty_inspect
# produces: [[{"first"=>10}], [{"third"=>30}]]

puts result.fields.pretty_inspect
# produces: [[["first"], ["second"]], ["third"]]

In the above I would expect result.each to also include the empty result set for the second select.

Additionally the fields returned don't seem to be correct. I expected result.fields to return an array which contains three arrays, one for each result set.

When I only have one result set, everything works as expected:

sql = "SELECT 10 as first where 1 = 0"

result = client.execute( sql )

puts result.each.pretty_inspect
# produces: []

puts result.fields.pretty_inspect
# ["first"]

Connection Issue to Netcool (Sybase) Database

Hello, I'm at a loss here and hoping you can point me in the right direction. I have a Netcool (Sybase) database that uses port 4100 over tcp and tds version 5.0. I have the connection configured as "PrimaryOS" in /etc/freetds.conf which simply specifies the hostname, port, and tds version as 5.0. Connecting via tsql on the command line is successful and queries work as expected. However, I can't get TinyTds to connect. I have tried supplying the dataserver as 'PrimaryOS' along with the username and password but I get "Adaptive Server is unavailable or does not exist". When I go the :host, :port, and :tds_version route instead, I get "Adaptive Server connection failed" which is different, but still not what I want.

I verified that there are not other freetds.conf files on the filesystem but without any debug info as to why it's not connecting, and the fact that tsql connects fine, I'm at a loss. I'm on Fedora 13 using the distro package supplying version .82. I verified that the development package was installed as well and the TinyTds gem installed with no warnings at all.

Any Ideas? Anything else I could provide that would help? Is there any way to get more debug information out of connection issues?

Thanks in advance,
-Bill

TinyTds throws an exception when encountering odd characters

When I try to use TinyTds to retrieve a row containing some odd characters, it throws a TinyTds::Error exception:

ActiveRecord::StatementInvalid: TinyTds::Error: Some character(s) could not be converted into client's character set. Unconverted bytes were changed to question marks ('?'): SELECT notes FROM [dbo].[customers] WHERE ([dbo].[customers].[id] = 3893620)

The same query works using ODBC, albeit with the odd characters replaced with question marks.

It may be that TinyTds is doing the right thing here, but the net effect renders these data inaccessible. Also, the description doesn't agree with the behavior. I might suggest that TinyTds have a preference which determines whether it throws an exception or munges the invalid characters into question marks and sets a warning flag.

I'm of course happy to provide the invalid data, but I'm not sure how to extract it properly. The database is on SQL Server 2000, the collation character set is SQL_Latin1, and there are no encoding values set in my freetds or tinytds configuration files. The sql type of the column is text.

COALESCE weirdness related to issue #51

Rails 3.1.0
TinyTDS 0.5.0rc1
activerecord-sqlserver-adapter 3.1.0
FreeTDS 0.91

This is very odd. Perhaps it is a setting that I missed related to dslib's treatment of NULLs.

So when I run this in the rails console:

ActiveRecord::Base.connection.select_value("declare @test varchar(10) select COALESCE(@test + ' was not null', 'was null')")

which runs this

EXEC sp_executesql N'declare @test varchar(10) select COALESCE(@test + '' was not null'', ''was null'')'

the result is

" was not null"

When I run the same in tsql

1>  EXEC sp_executesql N'declare @test varchar(10) select COALESCE(@test + '' was not null'', ''was null'')'
2> go

was null
(1 row affected)

P.S. This is what was blowing up the trigger that was causing the issue I reported in #51

TinyTds silently crash when password text larger than 30 characters

When I use TinyTds::Client.new(:username=>'...', :password=>'....longer than 32 characters, actually 54 characters', :host=>"...') then it crash silently. When I reduced character to less or equal 30 characters then it works. Could you please fix it?

My environment: Ruby 1.9.2 on Windows.

SCOPE_IDENTITY returns a BigDecimal

When I execute SQL code through ActiveRecord containing select SCOPE_IDENTITY or select @@IDENTITY the returned type is BigDecimal. Shouldn't it be BigInt or some other integer type and not a decimal type?

I'm using:

ActiveRecord 2.3.5
FreeTDS 0.91
TinyTDS 0.5.0 rc1
activerecord-sqlserver-adapter 2.3.11

Yes I know, I probably shouldn't use activerecord-sqlserver-adapter 2.3.11 together with ActiveRecord 2.3.5.

Result#fields empty if no results are returned, and not callable before #each

Most other database drivers allow calling fields before each, and return the columns that would be used even if no rows are present, which is very helpful information. Sequel relies on such behavior for proper functioning.

Also, because fields is not callable before each, I have to do something like:

        result.each(each_opts.merge!(:as=>:array)) do |r|
          @columns = cols = result.fields.map{|c| output_identifier(c)} unless cols
          h = {}
          cols.zip(r).each{|k, v| h[k] = v}
          h.delete(row_number_column) if @opts[:offset]
          yield h
        end

This means I'm checking the value of cols for every row returned. If fields was callable before each, the check could be moved outside the loop, speeding things up.

In result.c, I see that this is intended behavior. However, it causes problems, such as making it impossible to determine the columns in an empty table without parsing the INFORMATION_SCHEMA.

Could you consider making fields callable before each, and to return columns even if there are no rows returned?

Also, for best performance with Sequel in the default case, there would need to be a way to pass in a list of fields to use for the keys. Sequel uses symbolized keys, but allows you to provide a String method to call on all outputted columns to transform them (the identifier_output_method). The default for Microsoft SQL Server is :downcase, so that you can deal with lowercase identifiers in ruby and still have upcased identifiers in the database. That's the reason we currently grab the columns as an array and use Array#zip. I have an optimization to just use symbolize_keys => :true if no identifier_output_method is used, but it doesn't take effect by default. I realize that such a request is specific to Sequel, so I can understand if you don't want to do that. I'm just informing you now as if may affect your API design should you desire to support it.

Client doesn't understand UTF-BOM

I'm not sure if this belongs here... but I spent some time debugging this,

When the SQL you're executing begins with a UTF BOM, the client reads the string as empty.

sql = File.read('path/to/utf_file_with_bom.sql')
TinyTds::Client.new( connection_info).execute(sql).count
TinyTds::Error: Incorrect syntax near ''.
from (irb):34:in each' from (irb):34:incount'

I'm not sure how to get you an example file, but I could email on request.

Connection timeout option is ignored.

Hello
I am developing an app against a somehow slow machine, and I am getting some timeout connection errors.
Now I am running a specially slow setup procedure and the queries are quite slow, but don't take more than 7 or 8 seconds in the server.
I have modify may database.yml connection to set a timeout of 30 seconds, but the connection still fails in the 5 seconds that are set by default.
I am using the library with the active record adapter for sql server 2.3.11.
Maybe the culprit can be the other gem. I don't know.
Well, thanks for you work.
I really appreciate it.

Best regards,
Juanma Cervera.

Install issues on Debian...

I got tiny_tds to install just fine on OS X where I do my development, but the server I'm running is sporting Debian 5. FreeTDS has been compiled manually in /usr/local (which is exactly what I've done in OS X), however when I try to install tiny_tds I get the following error on Deb:

$ sudo gem install tiny_tds
Building native extensions.  This could take a while...
ERROR:  Error installing tiny_tds:
    ERROR: Failed to build gem native extension.

/usr/local/bin/ruby extconf.rb
looking for library directory /usr/local/lib ... yes
checking for main() in -liconv... no
looking for library directory /usr/local/lib/freetds ... no
looking for library directory /usr/lib ... yes
checking for main() in -liconv... no
-----
Can not find FreeTDS's db-lib or include directory.
-----
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
    --with-opt-dir
    --without-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
    --without-make-prog
    --srcdir=.
    --curdir
    --ruby=/usr/local/bin/ruby
    --with-iconv-dir
    --without-iconv-dir
    --with-iconv-include
    --without-iconv-include=${iconv-dir}/include
    --with-iconv-lib
    --without-iconv-lib=${iconv-dir}/lib
    --with-freetds-dir
    --without-freetds-dir
    --with-freetds-include
    --without-freetds-include=${freetds-dir}/include
    --with-freetds-lib
    --without-freetds-lib=${freetds-dir}/lib
    --with-iconvlib
    --without-iconvlib
    --with-iconvlib
    --without-iconvlib
looking for library directory /usr/lib/freetds ... no
looking for library directory /usr/X11R6/lib ... no
looking for library directory /usr/X11R6/lib/freetds ... no

I'm baffled as to why it can't find it when it explicitly says looking for library directory /usr/local/lib ... yes. Is this somehow related to the iconv errors in the other issue? checking for main() in -liconv... no

TinyTds::Error: Cannot open user default database. Login failed.

I'm trying to use TinyTds to connect to an sql server using Ruby on Rails. This is how my database.yml file look like:

development:
adapter: sqlserver
mode: dblib
dataserver: 192.168.1.13
database: ***
username: ***
password: ***
timeout: 5000

I know that the username, password and database is correct but I cannot get it to work. The error message I get is:

TinyTds::Error: Cannot open user default database. Login failed.

I'm using TinyTds 0.4.5 and Ruby on Rails 3.1rc5 on Mac OS X.

TinyTDS syntax error (where infact there is no error in its generated SQL syntax)

I am using TinyTDS to connect to a remote SQL Server (2005), everything works fine except when I do an UPDATE.
Actually the UPDATE works fine too, but it raises an exception regardless. I can see the updated field when I view the record, but right after the update is finished I get the following exception :

ActiveRecord::StatementInvalid (TinyTds::Error: Incorrect syntax near the keyword 'and'.: UPDATE [surveys] SET [Other CD Type] = N'' WHERE [surveys].[id] = 24):

TOP OF THE TRACE

activerecord (3.0.9) lib/active_record/connection_adapters/abstract_adapter.rb:207:in log' activerecord-sqlserver-adapter (3.0.15) lib/active_record/connection_adapters/sqlserver/database_statements.rb:228:indo_execute'
activerecord-sqlserver-adapter (3.0.15) lib/active_record/connection_adapters/sqlserver/database_statements.rb:19:in execute' activerecord-sqlserver-adapter (3.0.15) lib/active_record/connection_adapters/sqlserver/database_statements.rb:211:inupdate_sql'
activerecord (3.0.9) lib/active_record/connection_adapters/abstract/database_statements.rb:49:in update' activerecord (3.0.9) lib/active_record/connection_adapters/abstract/query_cache.rb:16:inupdate'
arel (2.0.10) lib/arel/crud.rb:20:in update' activerecord (3.0.9) lib/active_record/persistence.rb:259:inupdate'

I can easily verify that there is no syntax error, and in fact it does update the required field in the desired record; however this exception is thrown anyway. I tried disabling activerecord logging but no help. The exception is telling me about a keyword that doesn't even exist in the generated SQL statement.

Thanks very much in advance,

Specs

Platform: Mac OS X Snow Leopard
Ruby 1.8.7
Rails 3.0
freetds 0.8.2
SQL Server 2005 is remote on Windows 2003 Server

Thin processes dying...

The the moment I can't give you a lot of info on what's causing this but I've been keeping an eye on the server using TinyTDS and some the of the thin processes running rails seem to dying.

Checking the logs, here is what was being spit out at the time of death:

FreeTDS: db-lib: exiting because client error handler returned 0 for msgno 20017

Unfortunately, there's just one log in Rails as opposed to a log per instance of thin so I can't tell you precisely what set that off. What I can tell you is that I do nothing but run SELECT statements in the entire app. All my writing is done to PostgreSQL databases. If you need more info than that I'm going to have to try and figure out a way to log it better.

I should also add that this was using ODBC before and didn't have this problem.

Querying failed if target table has datetime column on Windows

client = TinyTds::Client.new(:username => 'sa', :password => 'secret', :host => 'database')
result = client.execute("SELECT * FROM [table_without_datetime]")
result.each do |row| # works fine
  p row
end

# but this crashes with "ArgumentError - argument out of range"
result = client.execute("SELECT * FROM [table_with_datetime]")
result.each do |row| # crash!
  p row
end

stack trace
C:/path/to/script_file.rb:9:in local' C:/path/to/script_file.rb:9:ineach'

environment
RubyInstaller 1.8.7-p352
ruby 1.8.7 (2011-06-30 patchlevel 352) [i386-mingw32]
tiny_tds (0.4.5 x86-mingw32)
WindowsXP SP3

Adaptive Server is unavailable or does not exist

Hi guys,

I port installed FreeTDS. I'm trying to connect to run some pretty basic queries but I'm getting a problem about the Adaptive Server.

Here is what I'm seeing.

Carper-MP:~ Dan$ irb
ruby-1.8.7-p334 :001 > require 'tiny_tds'
true
ruby-1.8.7-p334 :002 > client = TinyTds::Client.new(:username => '...', :password => '...', :dataserver => 'full_resolving_domain_name')
TinyTds::Error: Unable to connect: Adaptive Server is unavailable or does not exist
    from /Users/Dan/.rvm/gems/ruby-1.8.7-p334@empty/gems/tiny_tds-0.4.5/lib/tiny_tds/client.rb:60:in `connect'
    from /Users/Dan/.rvm/gems/ruby-1.8.7-p334@empty/gems/tiny_tds-0.4.5/lib/tiny_tds/client.rb:60:in `initialize'
    from (irb):2:in `new'
    from (irb):2
ruby-1.8.7-p334 :003 >

I have also tried specifying every tds_version, doesn't really change anything.

All help and even points in the right direction are much appreciated :)

Thanks,
Dan

tiny_tds query times out, while tsql succeeds.

I have a SQL query which accumulates results in a temporary table, then selects from that table (~8k rows)

I'm able to execute the query via the tsql command line, but when I issue it via tiny_tds in ruby, I get this message:

TinyTds::Error: Adaptive Server connection timed out

I get this message 5 seconds after issuing it.

I am able to issue simpler queries via tiny_tds.

TinyTDS will not compile on Windows

I installed the latest DevKit to C:\DevKit-451 and FreeTDS put its libraries in C:\DevKit-451\usr\local\bin.
The extconf.rb tries to find the libs and header using the PATH variable and fails as it does not recurse through the directories.

I suggest the following change to extconf.rb : https://gist.github.com/835267

Encoding on Ubuntu

Hello.

I have been writing an app on MacOSX and when I read and write from SQL Server I'm getting the text ad displayed in SSMS. When I deploy the app on Ubuntu whith exactly the same locale and code the nvarchar texts are displayed as garbled on screen. When I however write to the db the text is encoded in some strange manner in the db but is correctly encoded when reading from the db.

I'm using UTF-8 and would like to have the data within SSMS in readable format.

Example is writing this string to the db:

ÞþþÆÆÆæææ

this is what is written into the db:

ÞþþÆÆÆæææ

On the mac the values are written in the correct format. I have tried to specify the encoding in database.yml but it has no effect.

Login failed when using host/port. Works when using dataserver.

I am attempting to use TinyTds in a rails project and it appears that I must use the dataserver option and use the freetds.conf. For some reason, providing the host and port directly reports authentication failed.

From rails console:

client = TinyTds::Client.new(:username=> 'myuser', :password=>'19b19449f29bdd6c39b380f17a0fa110', :host=>'1.2.3.4', :port=>1440)

TinyTds::Error: Login failed for user 'myuser'.

With dataserver:

client = TinyTds::Client.new(:username=> 'myuser', :password=>'19b19449f29bdd6c39b380f17a0fa110', :dataserver=>'development')

=> #TinyTds::Client:0xa57970c

Here's what my freetds.conf looks like:

[development]
host = 1.2.3.4
port = 1440
tds version = 8.0
client charset = UTF-8

OS is Ubuntu 10.10 32-bit. I am running the version of freetds that is available in the official ubuntu repos. If there is any more information you could use let me know.

rake compile fails on Ubuntu x64

Looks like I can now get libiconv to compile but get stuck further along. This is a clean x64 installation (albeit, a minimal install with only the packages I use for development).

$ rake compile
...
cd tmp/x86_64-linux/tiny_tds/1.9.2
make
gcc -shared -o tiny_tds.so client.o tiny_tds_ext.o result.o -L. -L/home/phil/.rvm/rubies/ruby-1.9.2-p290/lib -Wl,-R/home/phil/.rvm/rubies/ruby-1.9.2-p290/lib -L/home/phil/workspace/tiny_tds/ports/x86_64-linux/freetds/0.91/lib -L.  -rdynamic -Wl,-export-dynamic -L/home/phil/workspace/tiny_tds/ports/x86_64-linux/freetds/0.91/lib   -Wl,-R -Wl,/home/phil/.rvm/rubies/ruby-1.9.2-p290/lib -L/home/phil/.rvm/rubies/ruby-1.9.2-p290/lib -lruby -lsybdb -liconv  -lpthread -lrt -ldl -lcrypt -lm   -lc
/usr/bin/ld: /home/phil/workspace/tiny_tds/ports/x86_64-linux/freetds/0.91/lib/libsybdb.a(dblib.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
/home/phil/workspace/tiny_tds/ports/x86_64-linux/freetds/0.91/lib/libsybdb.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [tiny_tds.so] Error 1
rake aborted!

I can submit the full stack trace if required.

I will continue to dig but thought I'd just kick this off in case anyone had any ideas.

Similar to Issue #35: TinyTds::Error: Incorrect syntax near the keyword 'and'

Rails 3.1.0
TinyTDS 0.5.0rc1
activerecord-sqlserver-adapter 3.1.0
FreeTDS 0.91

I get the following when trying to save

 c.save
  EXECUTE (74.4ms)  BEGIN TRANSACTION
   (94.7ms)  EXEC sp_executesql N'UPDATE [Contacts] SET [IsRetired] = 0 WHERE [Contacts].[ContactId] = 1; SELECT @@ROWCOUNT AS AffectedRows'
TinyTds::Error: Incorrect syntax near the keyword 'and'.: EXEC sp_executesql N'UPDATE [Contacts] SET [IsRetired] = 0 WHERE [Contacts].[ContactId] = 847; SELECT @@ROWCOUNT AS AffectedRows'
ActiveRecord::StatementInvalid: TinyTds::Error: Incorrect syntax near the keyword 'and'.: EXEC sp_executesql N'UPDATE [Contacts] SET [IsRetired] = 0 WHERE [Contacts].[ContactId] = 1; SELECT @@ROWCOUNT AS AffectedRows'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-sqlserver-adapter-3.1.0.0/lib/active_record/connection_adapters/sqlserver/database_statements.rb:317:in `each'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-sqlserver-adapter-3.1.0.0/lib/active_record/connection_adapters/sqlserver/database_statements.rb:317:in `handle_to_names_and_values_dblib'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-sqlserver-adapter-3.1.0.0/lib/active_record/connection_adapters/sqlserver/database_statements.rb:306:in `handle_to_names_and_values'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-sqlserver-adapter-3.1.0.0/lib/active_record/connection_adapters/sqlserver/database_statements.rb:277:in `block in raw_select'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0/lib/active_record/connection_adapters/abstract_adapter.rb:244:in `block in log'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.1.0/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0/lib/active_record/connection_adapters/abstract_adapter.rb:239:in `log'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-sqlserver-adapter-3.1.0.0/lib/active_record/connection_adapters/sqlserver/database_statements.rb:274:in `raw_select'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-sqlserver-adapter-3.1.0.0/lib/active_record/connection_adapters/sqlserver/database_statements.rb:257:in `do_exec_query'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-sqlserver-adapter-3.1.0.0/lib/active_record/connection_adapters/sqlserver/database_statements.rb:22:in `exec_query'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:77:in `exec_update'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-sqlserver-adapter-3.1.0.0/lib/active_record/connection_adapters/sqlserver/database_statements.rb:37:in `exec_update'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:96:in `update'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0/lib/active_record/connection_adapters/abstract/query_cache.rb:14:in `update'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0/lib/active_record/persistence.rb:305:in `update'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0/lib/active_record/locking/optimistic.rb:84:in `update'
... 12 levels...
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0/lib/active_record/validations.rb:50:in `save'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0/lib/active_record/attribute_methods/dirty.rb:22:in `save'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0/lib/active_record/transactions.rb:241:in `block (2 levels) in save'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0/lib/active_record/transactions.rb:295:in `block in with_transaction_returning_status'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0/lib/active_record/transactions.rb:208:in `transaction'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0/lib/active_record/transactions.rb:293:in `with_transaction_returning_status'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0/lib/active_record/transactions.rb:241:in `block in save'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0/lib/active_record/transactions.rb:252:in `rollback_active_record_state!'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0/lib/active_record/transactions.rb:240:in `save'
        from (irb):3
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.1.0/lib/rails/commands/console.rb:45:in `start'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.1.0/lib/rails/commands/console.rb:8:in `start'
        from /Users/parker/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.1.0/lib/rails/commands.rb:40:in `<top (required)>'
        from script/rails:6:in `require'
        from script/rails:6:in `<main>

Running the statement in SMS works fine.

Failures In sp_executesql N'...' Kill The Connection

So I may have touched on this issue over the weekend. I noticed that failures in sp_executesql for the 3.1 adapter would not allow the connection to be reused under FreeTDS 0.82. I wrote this test https://github.com/rails-sqlserver/tiny_tds/blob/master/test/result_test.rb#L600 this weekend and it fails only under 0.82. Under 0.91 it works just fine.

should 'error gracefully with incorrect syntax in sp_executesql' do
  if @client.freetds_091_or_higer?
    action = lambda { @client.execute("EXEC sp_executesql N'this will not work'").each }
    assert_raise_tinytds_error(action) do |e|
      assert_match %r|incorrect syntax|i, e.message
      assert_equal 15, e.severity
      assert_equal 156, e.db_error_number
    end
    assert_followup_query
  else
    skip 'FreeTDS 0.91 and higher can only pass this test.'
  end
end

I have also noticed that if I use 0.82 tsql command line utility, that it can cope, but tsql is a mixed bag of code that might not be under the same constraints of the DBLIB interface we are under.

1> EXEC sp_executesql N'this will not work'
2> GO
Msg 156, Level 15, State 1, Server SQLSERVER08, Line 1
Incorrect syntax near the keyword 'not'.
(return status = 156)
1> SELECT 1 AS [one]
2> GO
one
1

So, I'd like to play around with this a bit more to see if we can make TinyTDS cope a bit better. A few thoughts.

  1. We do a lot of work to make sure a bad command batch calls both dbsqlok() and dbcancel() C functions. We do this in the exception handler because it is highly possible that no handle will be returned.

  2. Can anyone confirm that this issue is related to any other, especially in regards to stored procedure failures? As of 8/18/11, FreeTDS 0.91 has been released. So this may just be what is needed, and I am cool with that.

Need to specify iconv location to compile.

On a 64-bit version of OS X (Snow Leopard), I am unable to compile the gem as-is. The error I get is:

ld: in /usr/local/lib/libiconv.2.dylib, missing required architecture x86_64 in file

I was able to resolve the problem by using another version of iconv (that is not installed in the standard location), but this required adding the following line to ext/tiny_tds/extconf.rb

dir_config('iconv')

Could this be included as a permanent fix for other people who have iconv in a non-standard location? I'm new to attempting to contribute, so I'm not sure if this was the right way submit this. Let me know if there is something else I need to do.

Julia

Problem using tiny_tds and Bundler

Hi,

TinyTDS works wonderfully when I've installed the gem via the console on my production Ubuntu server ('gem install tiny_tds'), because I can add additional options for discovering FreeTDS (--with-freetds-include, --with-freetds-lib, etc.). I'll access irb and connect to my database just fine.

When I deploy to production w/ Capistrano and Bundler, however, I get a "Adaptive Server connection failed" error when I try to access the database. Deploying the app doesn't produce any errors, it's only when I go to "rails console" that the connection errors appear.

I've added "/usr/local/freetds" to my $PATH variable. Doesn't seem to make a difference.

Any ideas? Thank you!

Problem With $ rake native gem

Seems to be missing the arch when calling the native pkg command?

$ rake --trace native gem
(in /home/hortoncd/tiny_tds)
rake-compiler must be configured first to enable cross-compilation
** Invoke native (first_time)
** Invoke native:i486-linux (first_time)
** Invoke native:tiny_tds:i486-linux (first_time)
** Invoke lib/tiny_tds/tiny_tds.so (first_time, not_needed)
** Invoke copy:tiny_tds:i486-linux:1.8.7 (first_time)
** Invoke lib/tiny_tds (first_time, not_needed)
** Invoke tmp/i486-linux/tiny_tds/1.8.7/tiny_tds.so (first_time, not_needed)
** Invoke tmp/i486-linux/tiny_tds/1.8.7/Makefile (first_time, not_needed)
** Invoke tmp/i486-linux/tiny_tds/1.8.7 (first_time, not_needed)
** Invoke ext/tiny_tds/extconf.rb (first_time, not_needed)
** Invoke ext/tiny_tds/client.c (first_time, not_needed)
** Invoke ext/tiny_tds/tiny_tds_ext.c (first_time, not_needed)
** Invoke ext/tiny_tds/result.c (first_time, not_needed)
** Execute copy:tiny_tds:i486-linux:1.8.7
install -c tmp/i486-linux/tiny_tds/1.8.7/tiny_tds.so lib/tiny_tds/tiny_tds.so
** Execute native:tiny_tds:i486-linux
** Execute native:i486-linux
** Execute native
** Invoke gem (first_time)
** Invoke pkg/tiny_tds-0.5.0.rc1.gem (first_time)
** Invoke pkg (first_time)
** Execute pkg
mkdir -p pkg
** Invoke pkg/tiny_tds-0.5.0.rc1 (first_time)
** Invoke .gitignore (first_time, not_needed)
** Invoke CHANGELOG (first_time, not_needed)
** Invoke Gemfile (first_time, not_needed)
** Invoke MIT-LICENSE (first_time, not_needed)
** Invoke NOTES (first_time, not_needed)
** Invoke README.rdoc (first_time, not_needed)
** Invoke Rakefile (first_time, not_needed)
** Invoke ext/tiny_tds/client.c (not_needed)
** Invoke ext/tiny_tds/client.h (first_time, not_needed)
** Invoke ext/tiny_tds/extconf.rb (not_needed)
** Invoke ext/tiny_tds/result.c (not_needed)
** Invoke ext/tiny_tds/result.h (first_time, not_needed)
** Invoke ext/tiny_tds/tiny_tds_ext.c (not_needed)
** Invoke ext/tiny_tds/tiny_tds_ext.h (first_time, not_needed)
** Invoke lib/tiny_tds.rb (first_time, not_needed)
** Invoke lib/tiny_tds/client.rb (first_time, not_needed)
** Invoke lib/tiny_tds/error.rb (first_time, not_needed)
** Invoke lib/tiny_tds/result.rb (first_time, not_needed)
** Invoke lib/tiny_tds/version.rb (first_time, not_needed)
** Invoke tasks/ports.rake (first_time, not_needed)
** Invoke test/benchmark/query.rb (first_time, not_needed)
** Invoke test/benchmark/query_odbc.rb (first_time, not_needed)
** Invoke test/benchmark/query_tinytds.rb (first_time, not_needed)
** Invoke test/client_test.rb (first_time, not_needed)
** Invoke test/result_test.rb (first_time, not_needed)
** Invoke test/schema/1px.gif (first_time, not_needed)
** Invoke test/schema/sqlserver_2000.sql (first_time, not_needed)
** Invoke test/schema/sqlserver_2005.sql (first_time, not_needed)
** Invoke test/schema/sqlserver_2008.sql (first_time, not_needed)
** Invoke test/schema/sqlserver_azure.sql (first_time, not_needed)
** Invoke test/schema_test.rb (first_time, not_needed)
** Invoke test/test_helper.rb (first_time, not_needed)
** Invoke lib/tiny_tds/tiny_tds.so (not_needed)
** Execute pkg/tiny_tds-0.5.0.rc1
mkdir -p pkg
mkdir -p pkg/tiny_tds-0.5.0.rc1
rm -f pkg/tiny_tds-0.5.0.rc1/.gitignore
ln .gitignore pkg/tiny_tds-0.5.0.rc1/.gitignore
rm -f pkg/tiny_tds-0.5.0.rc1/CHANGELOG
ln CHANGELOG pkg/tiny_tds-0.5.0.rc1/CHANGELOG
rm -f pkg/tiny_tds-0.5.0.rc1/Gemfile
ln Gemfile pkg/tiny_tds-0.5.0.rc1/Gemfile
rm -f pkg/tiny_tds-0.5.0.rc1/MIT-LICENSE
ln MIT-LICENSE pkg/tiny_tds-0.5.0.rc1/MIT-LICENSE
rm -f pkg/tiny_tds-0.5.0.rc1/NOTES
ln NOTES pkg/tiny_tds-0.5.0.rc1/NOTES
rm -f pkg/tiny_tds-0.5.0.rc1/README.rdoc
ln README.rdoc pkg/tiny_tds-0.5.0.rc1/README.rdoc
rm -f pkg/tiny_tds-0.5.0.rc1/Rakefile
ln Rakefile pkg/tiny_tds-0.5.0.rc1/Rakefile
mkdir -p pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds
rm -f pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/client.c
ln ext/tiny_tds/client.c pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/client.c
rm -f pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/client.h
ln ext/tiny_tds/client.h pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/client.h
rm -f pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/extconf.rb
ln ext/tiny_tds/extconf.rb pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/extconf.rb
rm -f pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/result.c
ln ext/tiny_tds/result.c pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/result.c
rm -f pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/result.h
ln ext/tiny_tds/result.h pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/result.h
rm -f pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/tiny_tds_ext.c
ln ext/tiny_tds/tiny_tds_ext.c pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/tiny_tds_ext.c
rm -f pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/tiny_tds_ext.h
ln ext/tiny_tds/tiny_tds_ext.h pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/tiny_tds_ext.h
mkdir -p pkg/tiny_tds-0.5.0.rc1/lib
rm -f pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds.rb
ln lib/tiny_tds.rb pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds.rb
mkdir -p pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds
rm -f pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/client.rb
ln lib/tiny_tds/client.rb pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/client.rb
rm -f pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/error.rb
ln lib/tiny_tds/error.rb pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/error.rb
rm -f pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/result.rb
ln lib/tiny_tds/result.rb pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/result.rb
rm -f pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/version.rb
ln lib/tiny_tds/version.rb pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/version.rb
mkdir -p pkg/tiny_tds-0.5.0.rc1/tasks
rm -f pkg/tiny_tds-0.5.0.rc1/tasks/ports.rake
ln tasks/ports.rake pkg/tiny_tds-0.5.0.rc1/tasks/ports.rake
mkdir -p pkg/tiny_tds-0.5.0.rc1/test/benchmark
rm -f pkg/tiny_tds-0.5.0.rc1/test/benchmark/query.rb
ln test/benchmark/query.rb pkg/tiny_tds-0.5.0.rc1/test/benchmark/query.rb
rm -f pkg/tiny_tds-0.5.0.rc1/test/benchmark/query_odbc.rb
ln test/benchmark/query_odbc.rb pkg/tiny_tds-0.5.0.rc1/test/benchmark/query_odbc.rb
rm -f pkg/tiny_tds-0.5.0.rc1/test/benchmark/query_tinytds.rb
ln test/benchmark/query_tinytds.rb pkg/tiny_tds-0.5.0.rc1/test/benchmark/query_tinytds.rb
rm -f pkg/tiny_tds-0.5.0.rc1/test/client_test.rb
ln test/client_test.rb pkg/tiny_tds-0.5.0.rc1/test/client_test.rb
rm -f pkg/tiny_tds-0.5.0.rc1/test/result_test.rb
ln test/result_test.rb pkg/tiny_tds-0.5.0.rc1/test/result_test.rb
mkdir -p pkg/tiny_tds-0.5.0.rc1/test/schema
rm -f pkg/tiny_tds-0.5.0.rc1/test/schema/1px.gif
ln test/schema/1px.gif pkg/tiny_tds-0.5.0.rc1/test/schema/1px.gif
rm -f pkg/tiny_tds-0.5.0.rc1/test/schema/sqlserver_2000.sql
ln test/schema/sqlserver_2000.sql pkg/tiny_tds-0.5.0.rc1/test/schema/sqlserver_2000.sql
rm -f pkg/tiny_tds-0.5.0.rc1/test/schema/sqlserver_2005.sql
ln test/schema/sqlserver_2005.sql pkg/tiny_tds-0.5.0.rc1/test/schema/sqlserver_2005.sql
rm -f pkg/tiny_tds-0.5.0.rc1/test/schema/sqlserver_2008.sql
ln test/schema/sqlserver_2008.sql pkg/tiny_tds-0.5.0.rc1/test/schema/sqlserver_2008.sql
rm -f pkg/tiny_tds-0.5.0.rc1/test/schema/sqlserver_azure.sql
ln test/schema/sqlserver_azure.sql pkg/tiny_tds-0.5.0.rc1/test/schema/sqlserver_azure.sql
rm -f pkg/tiny_tds-0.5.0.rc1/test/schema_test.rb
ln test/schema_test.rb pkg/tiny_tds-0.5.0.rc1/test/schema_test.rb
rm -f pkg/tiny_tds-0.5.0.rc1/test/test_helper.rb
ln test/test_helper.rb pkg/tiny_tds-0.5.0.rc1/test/test_helper.rb
mkdir -p pkg
rm -f pkg/tiny_tds-0.5.0.rc1/.gitignore
ln .gitignore pkg/tiny_tds-0.5.0.rc1/.gitignore
rm -f pkg/tiny_tds-0.5.0.rc1/CHANGELOG
ln CHANGELOG pkg/tiny_tds-0.5.0.rc1/CHANGELOG
rm -f pkg/tiny_tds-0.5.0.rc1/Gemfile
ln Gemfile pkg/tiny_tds-0.5.0.rc1/Gemfile
rm -f pkg/tiny_tds-0.5.0.rc1/MIT-LICENSE
ln MIT-LICENSE pkg/tiny_tds-0.5.0.rc1/MIT-LICENSE
rm -f pkg/tiny_tds-0.5.0.rc1/NOTES
ln NOTES pkg/tiny_tds-0.5.0.rc1/NOTES
rm -f pkg/tiny_tds-0.5.0.rc1/README.rdoc
ln README.rdoc pkg/tiny_tds-0.5.0.rc1/README.rdoc
rm -f pkg/tiny_tds-0.5.0.rc1/Rakefile
ln Rakefile pkg/tiny_tds-0.5.0.rc1/Rakefile
rm -f pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/client.c
ln ext/tiny_tds/client.c pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/client.c
rm -f pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/client.h
ln ext/tiny_tds/client.h pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/client.h
rm -f pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/extconf.rb
ln ext/tiny_tds/extconf.rb pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/extconf.rb
rm -f pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/result.c
ln ext/tiny_tds/result.c pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/result.c
rm -f pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/result.h
ln ext/tiny_tds/result.h pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/result.h
rm -f pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/tiny_tds_ext.c
ln ext/tiny_tds/tiny_tds_ext.c pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/tiny_tds_ext.c
rm -f pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/tiny_tds_ext.h
ln ext/tiny_tds/tiny_tds_ext.h pkg/tiny_tds-0.5.0.rc1/ext/tiny_tds/tiny_tds_ext.h
rm -f pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds.rb
ln lib/tiny_tds.rb pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds.rb
rm -f pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/client.rb
ln lib/tiny_tds/client.rb pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/client.rb
rm -f pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/error.rb
ln lib/tiny_tds/error.rb pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/error.rb
rm -f pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/result.rb
ln lib/tiny_tds/result.rb pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/result.rb
rm -f pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/version.rb
ln lib/tiny_tds/version.rb pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/version.rb
rm -f pkg/tiny_tds-0.5.0.rc1/tasks/ports.rake
ln tasks/ports.rake pkg/tiny_tds-0.5.0.rc1/tasks/ports.rake
rm -f pkg/tiny_tds-0.5.0.rc1/test/benchmark/query.rb
ln test/benchmark/query.rb pkg/tiny_tds-0.5.0.rc1/test/benchmark/query.rb
rm -f pkg/tiny_tds-0.5.0.rc1/test/benchmark/query_odbc.rb
ln test/benchmark/query_odbc.rb pkg/tiny_tds-0.5.0.rc1/test/benchmark/query_odbc.rb
rm -f pkg/tiny_tds-0.5.0.rc1/test/benchmark/query_tinytds.rb
ln test/benchmark/query_tinytds.rb pkg/tiny_tds-0.5.0.rc1/test/benchmark/query_tinytds.rb
rm -f pkg/tiny_tds-0.5.0.rc1/test/client_test.rb
ln test/client_test.rb pkg/tiny_tds-0.5.0.rc1/test/client_test.rb
rm -f pkg/tiny_tds-0.5.0.rc1/test/result_test.rb
ln test/result_test.rb pkg/tiny_tds-0.5.0.rc1/test/result_test.rb
rm -f pkg/tiny_tds-0.5.0.rc1/test/schema/1px.gif
ln test/schema/1px.gif pkg/tiny_tds-0.5.0.rc1/test/schema/1px.gif
rm -f pkg/tiny_tds-0.5.0.rc1/test/schema/sqlserver_2000.sql
ln test/schema/sqlserver_2000.sql pkg/tiny_tds-0.5.0.rc1/test/schema/sqlserver_2000.sql
rm -f pkg/tiny_tds-0.5.0.rc1/test/schema/sqlserver_2005.sql
ln test/schema/sqlserver_2005.sql pkg/tiny_tds-0.5.0.rc1/test/schema/sqlserver_2005.sql
rm -f pkg/tiny_tds-0.5.0.rc1/test/schema/sqlserver_2008.sql
ln test/schema/sqlserver_2008.sql pkg/tiny_tds-0.5.0.rc1/test/schema/sqlserver_2008.sql
rm -f pkg/tiny_tds-0.5.0.rc1/test/schema/sqlserver_azure.sql
ln test/schema/sqlserver_azure.sql pkg/tiny_tds-0.5.0.rc1/test/schema/sqlserver_azure.sql
rm -f pkg/tiny_tds-0.5.0.rc1/test/schema_test.rb
ln test/schema_test.rb pkg/tiny_tds-0.5.0.rc1/test/schema_test.rb
rm -f pkg/tiny_tds-0.5.0.rc1/test/test_helper.rb
ln test/test_helper.rb pkg/tiny_tds-0.5.0.rc1/test/test_helper.rb
rm -f pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/tiny_tds.so
ln lib/tiny_tds/tiny_tds.so pkg/tiny_tds-0.5.0.rc1/lib/tiny_tds/tiny_tds.so
** Invoke .gitignore (not_needed)
** Invoke CHANGELOG (not_needed)
** Invoke Gemfile (not_needed)
** Invoke MIT-LICENSE (not_needed)
** Invoke NOTES (not_needed)
** Invoke README.rdoc (not_needed)
** Invoke Rakefile (not_needed)
** Invoke ext/tiny_tds/client.c (not_needed)
** Invoke ext/tiny_tds/client.h (not_needed)
** Invoke ext/tiny_tds/extconf.rb (not_needed)
** Invoke ext/tiny_tds/result.c (not_needed)
** Invoke ext/tiny_tds/result.h (not_needed)
** Invoke ext/tiny_tds/tiny_tds_ext.c (not_needed)
** Invoke ext/tiny_tds/tiny_tds_ext.h (not_needed)
** Invoke lib/tiny_tds.rb (not_needed)
** Invoke lib/tiny_tds/client.rb (not_needed)
** Invoke lib/tiny_tds/error.rb (not_needed)
** Invoke lib/tiny_tds/result.rb (not_needed)
** Invoke lib/tiny_tds/version.rb (not_needed)
** Invoke tasks/ports.rake (not_needed)
** Invoke test/benchmark/query.rb (not_needed)
** Invoke test/benchmark/query_odbc.rb (not_needed)
** Invoke test/benchmark/query_tinytds.rb (not_needed)
** Invoke test/client_test.rb (not_needed)
** Invoke test/result_test.rb (not_needed)
** Invoke test/schema/1px.gif (not_needed)
** Invoke test/schema/sqlserver_2000.sql (not_needed)
** Invoke test/schema/sqlserver_2005.sql (not_needed)
** Invoke test/schema/sqlserver_2008.sql (not_needed)
** Invoke test/schema/sqlserver_azure.sql (not_needed)
** Invoke test/schema_test.rb (not_needed)
** Invoke test/test_helper.rb (not_needed)
** Execute pkg/tiny_tds-0.5.0.rc1.gem
WARNING:  no rubyforge_project specified
  Successfully built RubyGem
  Name: tiny_tds
  Version: 0.5.0.rc1
  File: tiny_tds-0.5.0.rc1.gem
mv tiny_tds-0.5.0.rc1.gem pkg/tiny_tds-0.5.0.rc1.gem
** Invoke pkg/tiny_tds-0.5.0.rc1-x86-linux.gem (first_time)
** Invoke pkg (not_needed)
rake aborted!
Don't know how to build task 'pkg/tiny_tds-0.5.0.rc1-x86-linux'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:1728:in `[]'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:605:in `invoke_prerequisites'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:604:in `each'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:604:in `invoke_prerequisites'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:596:in `invoke_with_call_chain'
/usr/lib/ruby/1.8/monitor.rb:242:in `synchronize'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:590:in `invoke_with_call_chain'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:607:in `invoke_prerequisites'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:604:in `each'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:604:in `invoke_prerequisites'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:596:in `invoke_with_call_chain'
/usr/lib/ruby/1.8/monitor.rb:242:in `synchronize'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:590:in `invoke_with_call_chain'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:583:in `invoke'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2051:in `invoke_task'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in `top_level'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in `each'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in `top_level'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2023:in `top_level'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2001:in `run'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:1998:in `run'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/bin/rake:31
/usr/bin/rake:19:in `load'
/usr/bin/rake:19

Frequent vague timeout errors (TinyTds::Error)

I'm frequently seeing the following error, after which all queries seem to produce the same result, requiring a restart of my rails server. Any insight as to what might cause this, as well as how recover?

TinyTds::Error: Attempt to initiate a new SQL Server operation with results pending.: SELECT: Attempt to initiate a new SQL Server operation with results pending.: SELECT...

insert command encoding error

i am using your tinytds lib to communicate with sqlserver 2000,
my ruby is 1.9 and insert string command is utf-8 encoding.
the tinytds client is utf-8 encoding too, and the OS environment is
"
tsql -C
Version: freetds v0.82
freetds.conf directory: /etc/freetds
MS db-lib source compatibility: no
Sybase binary compatibility: yes
Thread safety: yes
iconv library: yes
TDS version: 4.2
iODBC: no
unixodbc: yes
"

but when I execute a insert command contains Chinese chars in some values , i will get the syntax error,
and not always get this error,

below is my code

insert="INSERT INTO [GL_accvouch]( iperiod,  csign,  isignseq,ino_id,  inid,  dbill_date,  idoc,cbill,cdigest,ccode,cexch_name,md,mc,md_f,mc_f,  nfrat,cdept_id,cperson_id,citem_id,citem_class,ccode_equal,iyear,iYPeriod) values ('7','po','1','169','1','2011-07-19','0','测试职员','TTTTExpenseSys:刘建,普通费用[BXFY2011053012960]','55011201','人民币',73.0,0,73.0,0,1,'1006','','CN-20110030','00','218102','2011','201107')"
client = TinyTds::Client.new(:host=>'1.1.1.1',:database=>'db',:username=>'sa',:password=>'',:encoding=>'utf-8')
      client.execute(insert).insert

and i will get this error message

Unclosed quotation mark before the character string ')'.

it seems that the encoding problem ,cause when i delete the chinese characters, i will not get this error any more

so anyone have some idea to solve this problem?
thanks!

:symbolize_keys => true fails with non ascii chars

Created new test:

should 'have properly encoded column names with symbol keys' do
  col_name = "öäüß"
  @client.execute("DROP TABLE [test_encoding]").do rescue nil
  @client.execute("CREATE TABLE [dbo].[test_encoding] ( [#{col_name}] [nvarchar](10) NOT NULL )").do
  @client.execute("INSERT INTO [test_encoding] ([#{col_name}]) VALUES (N'#{col_name}')").do
  result = @client.execute("SELECT [#{col_name}] FROM [test_encoding]")
  row = result.each(:as => :hash, :symbolize_keys => true).first
  assert_equal col_name, result.fields.first
  assert_equal col_name, row.keys.first
  assert_utf8_encoding result.fields.first
  assert_utf8_encoding row.keys.first
end unless sqlserver_azure?
  1. Error:
    test_0028_have_properly_encoded_column_names_with_symbol_keys(Basic query and result):
    EncodingError: invalid encoding symbol
    test/result_test.rb:308:in each' test/result_test.rb:308:inblock (2 levels) in class:ResultTest'

Look like Xcode 4 break tiny_tds 0.4.0

Installing tiny_tds (0.4.0) with native extensions /Library/Ruby/Site/1.8/rubygems/installer.rb:529:in `build_extensions': ERROR: Failed to build gem native extension. (Gem::Installer::ExtensionBuildError)

        /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby extconf.rb 
looking for library directory /usr/local/narwhal/lib ... yes
checking for main() in -liconv... yes
checking for main() in -lsybdb... yes
looking for include directory /usr/local/narwhal/include ... no
looking for include directory /usr/local/narwhal/include/freetds ... no
looking for include directory /usr/local/freetds/include ... yes
checking for sybfront.h... yes
checking for sybdb.h... yes
creating Makefile

make
gcc -I. -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -DHAVE_SYBFRONT_H -DHAVE_SYBDB_H -I/usr/local/freetds/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE   -I/usr/local/freetds/include -fno-common -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE  -fno-common  -pipe -fno-common   -c client.c
gcc -I. -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -DHAVE_SYBFRONT_H -DHAVE_SYBDB_H -I/usr/local/freetds/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE   -I/usr/local/freetds/include -fno-common -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE  -fno-common  -pipe -fno-common   -c result.c
result.c: In function ‘rb_tinytds_result_fetch_row’:
result.c:194: error: ‘DBDATEREC’ has no member named ‘dateyear’
result.c:195: error: ‘DBDATEREC’ has no member named ‘datemonth’
result.c:196: error: ‘DBDATEREC’ has no member named ‘datedmonth’
result.c:197: error: ‘DBDATEREC’ has no member named ‘datehour’
result.c:198: error: ‘DBDATEREC’ has no member named ‘dateminute’
result.c:199: error: ‘DBDATEREC’ has no member named ‘datesecond’
result.c:200: error: ‘DBDATEREC’ has no member named ‘datemsecond’
result.c: In function ‘rb_tinytds_result_fetch_row’:
result.c:194: error: ‘DBDATEREC’ has no member named ‘dateyear’
result.c:195: error: ‘DBDATEREC’ has no member named ‘datemonth’
result.c:196: error: ‘DBDATEREC’ has no member named ‘datedmonth’
result.c:197: error: ‘DBDATEREC’ has no member named ‘datehour’
result.c:198: error: ‘DBDATEREC’ has no member named ‘dateminute’
result.c:199: error: ‘DBDATEREC’ has no member named ‘datesecond’
result.c:200: error: ‘DBDATEREC’ has no member named ‘datemsecond’
lipo: can't open input file: /var/tmp//ccCY35HC.out (No such file or directory)
make: *** [result.o] Error 1


Gem files will remain installed in /Library/Ruby/Gems/1.8/gems/tiny_tds-0.4.0 for inspection.
Results logged to /Library/Ruby/Gems/1.8/gems/tiny_tds-0.4.0/ext/tiny_tds/gem_make.out
    from /Library/Ruby/Site/1.8/rubygems/installer.rb:482:in `each'
    from /Library/Ruby/Site/1.8/rubygems/installer.rb:482:in `build_extensions'
    from /Library/Ruby/Site/1.8/rubygems/installer.rb:156:in `install'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.0.10/lib/bundler/source.rb:96:in `install'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.0.10/lib/bundler/installer.rb:55:in `run'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.0.10/lib/bundler/spec_set.rb:12:in `each'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.0.10/lib/bundler/spec_set.rb:12:in `each'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.0.10/lib/bundler/installer.rb:44:in `run'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.0.10/lib/bundler/installer.rb:8:in `install'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.0.10/lib/bundler/cli.rb:275:in `update'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.0.10/lib/bundler/vendor/thor/task.rb:22:in `send'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.0.10/lib/bundler/vendor/thor/task.rb:22:in `run'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.0.10/lib/bundler/vendor/thor/invocation.rb:118:in `invoke_task'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.0.10/lib/bundler/vendor/thor.rb:246:in `dispatch'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.0.10/lib/bundler/vendor/thor/base.rb:389:in `start'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.0.10/bin/bundle:13
    from /Library/Ruby/Gems/1.8/bin/bundle:19:in `load'
    from /Library/Ruby/Gems/1.8/bin/bundle:19

Misleading error message

When using :host with non existent host name:

client = TinyTds::Client.new(:username => 'sa', :password => '********', :host => 'AQL2005', :database => 'ZwickTest', :encoding => 'CP850')
TinyTds::Error: Server name not found in configuration files
C:/Ruby192/lib/ruby/gems/1.9.1/gems/tiny_tds-0.4.5.rc1-x86-mingw32/lib/tiny_tds/client.rb:60:in connect' C:/Ruby192/lib/ruby/gems/1.9.1/gems/tiny_tds-0.4.5.rc1-x86-mingw32/lib/tiny_tds/client.rb:60:ininitialize'

better message would be:
TinyTds::Error: Server 'AQL2005' not found on network

Mysql2 conflicting with TinyTDS

Right now, I have a rails app that connects to two different sqlserver servers and one mysql server. Previously, it worked fine with freetds/odbc setup. After swapping it to tinytds 0.4.5 and setting up the configs, tinytds seems to take over and activerecord thinks the default models should be accessed via tinytds.

The user table is a default table that should be using the production env defined in the database.yaml, which uses mysql2.

ruby-1.9.2-p180 :002 > User.first
ActiveRecord::StatementInvalid: TinyTds::Error: Incorrect syntax near '1'.: SELECT [users].* FROM [users] LIMIT 1
from /Users/michael/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.0.7/lib/active_record/connection_adapters/abstract_adapter.rb:207:in rescue in log' from /Users/michael/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.0.7/lib/active_record/connection_adapters/abstract_adapter.rb:199:inlog'
from /Users/michael/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-sqlserver-adapter-3.0.15/lib/active_record/connection_adapters/sqlserver/database_statements.rb:250:in raw_select' from /Users/michael/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-sqlserver-adapter-3.0.15/lib/active_record/connection_adapters/sqlserver/database_statements.rb:194:inselect'
from /Users/michael/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.0.7/lib/active_record/connection_adapters/abstract/database_statements.rb:7:in select_all' from /Users/michael/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.0.7/lib/active_record/connection_adapters/abstract/query_cache.rb:56:inselect_all'
from /Users/michael/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.0.7/lib/active_record/base.rb:468:in find_by_sql' from /Users/michael/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.0.7/lib/active_record/relation.rb:64:into_a'
from /Users/michael/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.0.7/lib/active_record/relation/finder_methods.rb:341:in find_first' from /Users/michael/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.0.7/lib/active_record/relation/finder_methods.rb:122:infirst'
from /Users/michael/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.0.7/lib/active_record/base.rb:439:in first' from (irb):2 from /Users/michael/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.7/lib/rails/commands/console.rb:44:instart'
from /Users/michael/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.7/lib/rails/commands/console.rb:8:in start' from /Users/michael/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.7/lib/rails/commands.rb:23:in<top (required)>'
from script/rails:6:in `require'

Data storage and reading problems

I use varchar (max) to save a text (UTF-8), the length is 14,000 bytes or so, when read with tiny_tds only read 4096 bytes.
Try to use text or nvarchar (max) or ntext these types, can not read the full content.
Want to know what the problem is caused, how to solve?

Here is test code:
client = TinyTds:: Client.new (: username => 'gim',: password => '123qwe !@#',: host => '192 .168.2.74 ',: database =>' bbs')
r = client.execute ("select * from replies where id = 1078")
r.first ["content"]. size

ruby1.8: util.c:101: tds_set_state: Assertion `tds->state < (sizeof(state_names)/sizeof(state_names[0]))' failed.

I'm preforming a somewhat complicated SQLServer query, selecting several thousand rows, then iterating over the results to create ActiveRecords in a MySQL database.

It's failing partway through, through at different points.

The last two attempts, I've gotten through 260 and 213 rows, before seeing this (which crashes irb):

ruby1.8: util.c:101: tds_set_state: Assertion `tds->state < (sizeof(state_names)/sizeof(state_names[0]))' failed.

Any advice or insight?

tiny_tds (0.4.2)
ruby 1.8.7 (2011-02-18 patchlevel 334) [i486-linux]
Linux 2.6.38-1-686 on Debian

Problem with PK ID field returned with ActiveRecord - Sqlserver - TinyTDS

I'm running into some issues with the incorrect PK being returned
to active record upon a model object being created. I've debugged
things quite a bit, and the SQL is getting into TinyTDS, the wrong ID
gets returned? For some reason the ID always gets returned as 19...
Its maddening :) Any help or thoughts on what is going on, would be
much appreciated! Thanks!
OK, so here are some of the details:
Debugged ActiveRecord::Persistence.create
and saw that the value of new_id was being returned as 19.
------------- SNIPPET -------------
new_id = if attributes_values.empty?
self.class.unscoped.insert
connection.empty_insert_statement_value
else
self.class.unscoped.insert attributes_values
end

self.id ||= new_id

Here is all I'm doing:
user = User.new :email => '[email protected]'
user.authentications.build( :provider => 'provider_name', :uid =>
self.employee_id )
user.first_name = 'Eric'
user.save!
The problem is that the new user gets assigned the value of 19 as the
PK ID (column name is ID), then the authentications child gets the
wrong FK assigned during its creation.
tSQL Config:
titanium:gems ejlevin1$ tsql -C
Compile-time settings (established with the "configure" script)
Version: freetds v0.82
freetds.conf directory: /opt/local/etc/freetds
MS db-lib source compatibility: no
Sybase binary compatibility: no
Thread safety: yes
iconv library: yes
TDS version: 5.0
iODBC: no
unixodbc: yes
freetds.conf Config section:
[myQA]
host = HOSTNAME
port = 1433
tds version = 8.0

Calling Result#cancel after calling #cancel or #each causes problems

If I call Result#cancel after calling #cancel or #each, I get a long pause and then a TinyTds::Error exception with the message "DBPROCESS is dead or not enabled". After that, the Client that created the Result is not usable and attempting to call Client#execute results in the same error message.

The documentation states that you should call cancel if you don't call each, but doesn't specify the result of calling cancel more than once or calling cancel after each.

I think one of the following options would be best:

  1. Make cancel a no-op if cancel or each has already been called.
  2. Offer a cancelable? method that returns false if each or cancel has been called and true otherwise.
  3. Add another method that calls cancel if cancel or each has not been called.
  4. Have Client#execute automatically cancel an active Result (if any).

The reason I need this is that I'm working on a tiny_tds adapter for Sequel, and the interface looks like:

  def execute(sql, opts={})
    synchronize(opts[:server]) do |c|
      begin
        r = log_yield(sql){c.execute(sql)}
        yield(r) if block_given?
      rescue TinyTds::Error => e
        raise_error(e)
      ensure
        #r.cancel
      end
    end
  end

With this interface, I can't know whether the block has called cancel or each or neither (especially if the block raises an exception). And if you don't call cancel or each, you get a "Attempt to initiate a new Adaptive Server operation with results pending" error raised on the next attempt to use the Client.

gem install on jruby-1.6.3 don't work

if I try to run gem install tiny_tds with jruby-1.6.3, it show the following stacktrace.

~/foo (master) $ gem install tiny_tds
Building native extensions.  This could take a while...
ERROR:  Error installing tiny_tds:
    ERROR: Failed to build gem native extension.

        /Users/plentz/.rvm/rubies/jruby-1.6.3/bin/jruby extconf.rb
WARNING: JRuby does not support native extensions or the `mkmf' library very well.
Check http://kenai.com/projects/jruby/pages/Home for alternatives.
looking for library directory /Users/plentz/.rvm/gems/jruby-1.6.3/lib ... no
looking for library directory /Users/plentz/.rvm/gems/jruby-1.6.3/lib/freetds ... no
looking for library directory /Users/plentz/.rvm/gems/jruby-1.6.3@global/lib ... no
looking for library directory /Users/plentz/.rvm/gems/jruby-1.6.3@global/lib/freetds ... no
looking for library directory /Users/plentz/.rvm/rubies/jruby-1.6.3/lib ... yes
checking for main() in -lsybdb... no
looking for library directory /Users/plentz/.rvm/rubies/jruby-1.6.3/lib/freetds ... no
looking for library directory /Users/plentz/.rvm/lib ... yes
checking for main() in -lsybdb... no
looking for library directory /Users/plentz/.rvm/lib/freetds ... no
looking for library directory /opt/local/lib ... yes
checking for main() in -lsybdb... no
looking for library directory /opt/local/lib/freetds ... no
looking for library directory /usr/local/mysql/lib ... yes
checking for main() in -lsybdb... no
looking for library directory /usr/local/mysql/lib/freetds ... no
looking for library directory /opt/local/lib/postgresql84/lib ... no
looking for library directory /opt/local/lib/postgresql84/lib/freetds ... no
looking for library directory /usr/lib ... yes
checking for main() in -lsybdb... no
looking for library directory /usr/lib/freetds ... no
looking for library directory /usr/local/lib ... yes
checking for main() in -lsybdb... no
looking for library directory /usr/local/lib/freetds ... no
looking for library directory /usr/X11/lib ... yes
checking for main() in -lsybdb... no
looking for library directory /usr/X11/lib/freetds ... no
-----
Can not find FreeTDS's db-lib or include directory.
-----
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
    --with-opt-dir
    --without-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
    --without-make-prog
    --srcdir=.
    --curdir
    --ruby=/Users/plentz/.rvm/rubies/jruby-1.6.3/bin/jruby
    --enable-iconv
    --disable-iconv
    --enable-iconv
    --disable-iconv
    --with-freetds-dir
    --without-freetds-dir
    --with-freetds-include
    --without-freetds-include=${freetds-dir}/include
    --with-freetds-lib
    --without-freetds-lib=${freetds-dir}/lib
    --enable-lookup
    --disable-lookup
    --with-sybdblib
    --without-sybdblib
    --with-sybdblib
    --without-sybdblib
    --with-sybdblib
    --without-sybdblib
    --with-sybdblib
    --without-sybdblib
    --with-sybdblib
    --without-sybdblib
    --with-sybdblib
    --without-sybdblib
    --with-sybdblib
    --without-sybdblib


Gem files will remain installed in /Users/plentz/.rvm/gems/jruby-1.6.3/gems/tiny_tds-0.4.5 for inspection.
Results logged to /Users/plentz/.rvm/gems/jruby-1.6.3/gems/tiny_tds-0.4.5/ext/tiny_tds/gem_make.out

datetime casting to DateTime when it should be Time

Some values in a datetime column are being cast to a DateTime when they could be cast to a Time.

ie '2018-12-31 00:00:00.0' is a DateTime while '2019-01-01 00:00:00.0' is a Time.

I think this is because on https://github.com/rails-sqlserver/tiny_tds/blob/master/ext/tiny_tds/result.c#L204 the sum of the day, year and month is being compared to 2058. I think that this should just be the year. i.e.

if (year < 1902 || year > 2058) {

On 64bit machines I think that time can handle a much wider range of dates - so I am not sure if that should be considered when checking if an instance of Time can be used for the value.

FIX for `require`: libsybdb.so.5: cannot open shared object file: No such file or directory -

If you get the following error after gem install tiny_tds have successfully build the native extension:

/superpathhere/ruby/1.9.1/gems/activesupport-3.0.7/lib/active_support/dependencies.rb:239:in `require': libsybdb.so.5: cannot open shared object file: No such file or directory - /superpaththere/ruby/1.9.1/gems/tiny_tds-0.4.5/lib/tiny_tds/tiny_tds.so (LoadError)

run this command ldconfig /usr/local/lib<---- for ubuntu 11.04
I have used user specific RVM

I used way too long time on this and I hope this will make it easier for someone else in the future

Unable to cancel after failed execute('exec sp_helptext xXxXx')

In the active-record-adapter, there is the following code:

     select_values("EXEC sp_helptext #{quote_table_name(table_name)}").join

After chasing down a lot of code, it looks like there is a problem in tiny_tds..

Here is an example:

begin
#r = c.execute('select x as foo')
r = c.execute('exec sp_helptext xXxXx')
r.each { |e| pp ["e", e] }
rescue
r.cancel
end

Executing the code above will fail with r being nil. Executing the code above it will succeed canceling r.

The problem is that once the sp_helptext has failed, nothing else on that connection can succeed.

Any help appreciated.

Missing ruby/version.h when installing on CentOS.

My co-workers said they could not get the gem to compile on our dumb old dev servers, centos. Here is the error we see.

gcc -I. -I. -I/usr/lib/ruby/1.8/i386-linux -I. -DHAVE_SQLFRONT_H 
-DHAVE_SYBDB_H -DHAVE_SYBERROR_H  -D_FILE_OFFSET_BITS=64 -fPIC -O2 
-g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector 
--param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic 
-fasynchronous-unwind-tables -fno-strict-aliasing  -fPIC  -c tiny_tds_ext.c

In file included from tiny_tds_ext.c:2:
./tiny_tds_ext.h:6:26: error: ruby/version.h: No such file or directory
make: *** [tiny_tds_ext.o] Error 1

Erik, I remember we put that check in for the 1.8.6 fix, commit here b4c4e51

I just did a local search for that file out of curiousity. It's odd that I do not have one in my 1.8.6 space.

∴ find ~/.rvm -name "version.h" | grep "ruby/version.h"
/Users/kencollins/.rvm/repos/ruby-1.9.2-head/include/ruby/version.h
/Users/kencollins/.rvm/rubies/ruby-1.9.2-p0/include/ruby-1.9.1/ruby/version.h
/Users/kencollins/.rvm/src/ruby-1.9.2-p0/include/ruby/version.h

∴ sudo find /opt -name "version.h" | grep "ruby/version.h"
/opt/local/include/ruby-1.9.1/ruby/version.h

Poor Connections Need To Be Graceful

I am creating this issue for @marnen. We have concluded that this tests fails for him

marnen@79a587a

Potentially more tests fail giving that his network connection times out in a different case of the test suite. So basically the course of action for me is to confirm that we gracefully handle poor network connections and that the connection raises the error and allows the client to still be used.

Output Parameters for Stored Procedures

Microsoft SQL has the concept of output parameters for stored procedures. It's one of four methods for returning data from a stored procedures (http://msdn.microsoft.com/en-us/library/aa174792%28v=sql.80%29.aspx). TinyTds currently has no native support for output parameters, so this limitation must be worked around as follows:

DECLARE @out1 nvarchar(255), @out2 nvarchar(255), @result int
EXEC @result = testSproc 'some input', @out1 OUTPUT, @out2 OUTPUT
SELECT @out1 as 'out1', @out2 as 'out2', @result as 'result'

You may also notice that because the call to "EXEC" was not the last statement in this batch, using the #return_code method will return nil, so we need to add the return code (@Result) to the SELECT statement in order to retrieve its value.

Ideally, it would be nice if there was a construct for stored procedures. For a few example interfaces

client = <TinyTds::Client object>
input_params = ['value1'] # Hash or array for named or unnamed parameters
output_params = {:out1 => nil, :out2 => nil} # Hash or array for named or unnamed parameters
client.sproc('testSproc', input_params, output_params).do
puts output_params[:out1] #=> "Some value"

OR...

client = <TinyTds::Client object>
# Unnamed parameters
sproc = client.sproc('testSproc').input('param1', 'param2').output(:out1, :out2)
sproc #=> <TinyTds::Sproc object>
# Or named parameters
sproc = client.sproc('testSproc').input(:param1 => 'value', :param2 => 'value').output(:out1 => nil, :out2 => nil)
sproc.execute
sproc.output[:out1] #=> Retrieves the value of the output parameter :out1.

While you can still use stored procedures with output parameters without a special interface, this would be quite a nice addition to TinyTds, and would make it into a proper MSSQL client in my opinion.

Refer to: http://www.freetds.org/faq.html#ms.output.parameters

EDIT: Whoops, my examples were completely flawed. Now fixed.

Error while installing 0.4.5

Installing tiny_tds (0.4.5)
** [out :: 10.32.49.6] with native extensions
** [out :: x.x.x.x] /opt/appdata00/client2/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/installer.rb:551:in rescue in block in build_extensions': ERROR: Failed to build gem native extension. (Gem::Installer::ExtensionBuildError) ** [out :: x.x.x.x] ** [out :: x.x.x.x] /opt/appdata00/client2/.rvm/rubies/ruby-1.9.2-p290/bin/ruby extconf.rb -- --with-freetds-dir=/opt/sm/pkg/active ** [out :: x.x.x.x] looking for library directory /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/lib ... no ** [out :: x.x.x.x] looking for library directory /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/lib/freetds ... no ** [out :: x.x.x.x] looking for library directory /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@global/lib ... no ** [out :: x.x.x.x] looking for library directory /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@global/lib/freetds ... no ** [out :: x.x.x.x] looking for library directory /opt/appdata00/client2/.rvm/rubies/ruby-1.9.2-p290/lib ... yes ** [out :: x.x.x.x] checking for main() in -lsybdb... yes ** [out :: x.x.x.x] looking for include directory /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/include ... no ** [out :: x.x.x.x] looking for include directory /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/include/freetds ... no ** [out :: x.x.x.x] looking for include directory /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@global/include ... no ** [out :: x.x.x.x] looking for include directory /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@global/include/freetds ... no ** [out :: x.x.x.x] looking for include directory /opt/appdata00/client2/.rvm/rubies/ruby-1.9.2-p290/include ... yes ** [out :: x.x.x.x] checking for sybfront.h... yes ** [out :: x.x.x.x] checking for sybdb.h... yes ** [out :: x.x.x.x] creating Makefile ** [out :: x.x.x.x] ** [out :: x.x.x.x] make ** [out :: x.x.x.x] gcc -I. -I/opt/appdata00/client2/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/x86_64-linux -I/opt/appdata00/client2/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/ruby/backward -I/opt/appdata00/client2/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1 -I. -DHAVE_SYBFRONT_H -DHAVE_SYBDB_H -I/opt/appdata00/client2/.rvm/rubies/ruby-1.9.2-p290/include -I/opt/sm/pkg/active/include -I/opt/appdata00/client2/.rvm/rubies/ruby-1.9.2-p290/include -fPIC -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -fPIC -o result.o -c result.c ** [out :: x.x.x.x] In file included from ./tiny_tds_ext.h:16, ** [out :: x.x.x.x] from result.c:2: ** [out :: x.x.x.x] ./result.h:6: error: redefinition of typedef 'DBBIGINT' ** [out :: x.x.x.x] /opt/sm/pkg/active/include/sybdb.h:237: error: previous declaration of 'DBBIGINT' was here ** [out :: x.x.x.x] make: *** [result.o] Error 1 ** [out :: x.x.x.x] ** [out :: x.x.x.x] ** [out :: x.x.x.x] Gem files will remain installed in /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/gems/tiny_tds-0.4.5 for inspection. ** [out :: x.x.x.x] Results logged to /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/gems/tiny_tds-0.4.5/ext/tiny_tds/gem_make.out ** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/installer.rb:529:inblock in build_extensions'
** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/installer.rb:504:in each' ** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/installer.rb:504:inbuild_extensions'
** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/installer.rb:180:in install' ** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/gems/bundler-1.0.18/lib/bundler/source.rb:101:inblock in install'
** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/gems/bundler-1.0.18/lib/bundler/rubygems_integration.rb:78:in preserve_paths' ** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/gems/bundler-1.0.18/lib/bundler/source.rb:91:ininstall'
** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/gems/bundler-1.0.18/lib/bundler/installer.rb:58:in block (2 levels) in run' ** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/gems/bundler-1.0.18/lib/bundler/rubygems_integration.rb:93:inwith_build_args'
** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/gems/bundler-1.0.18/lib/bundler/installer.rb:57:in block in run' ** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/gems/bundler-1.0.18/lib/bundler/installer.rb:49:inrun'
** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/gems/bundler-1.0.18/lib/bundler/installer.rb:8:in install' ** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/gems/bundler-1.0.18/lib/bundler/cli.rb:220:ininstal
** [out :: x.x.x.x] l'
** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/gems/bundler-1.0.18/lib/bundler/vendor/thor/task.rb:22:in run' ** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/gems/bundler-1.0.18/lib/bundler/vendor/thor/invocation.rb:118:ininvoke_task'
** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/gems/bundler-1.0.18/lib/bundler/vendor/thor.rb:263:in dispatch' ** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/gems/bundler-1.0.18/lib/bundler/vendor/thor/base.rb:386:instart'
** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/gems/bundler-1.0.18/bin/bundle:13:in <top (required)>' ** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/bin/bundle:19:inload'
** [out :: x.x.x.x] from /opt/appdata00/client2/.rvm/gems/ruby-1.9.2-p290@hsi/bin/bundle:19:in <main>' ** [out :: 10.32.49.6] /opt/appdata00/client2/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/installer.rb:551:inrescue in block in build_extensions'
** [out :: 10.32.49.6] :

UUID Fields

If I have a field set to UUID. Here's what I get back in Sequel using TinyTDS:

:id=>"\xB6\xF9\x16\xB0A~\x94K\x9E\xA1u\xC5\xFC\xEC\x9D\x89"

I believe Sequel defaults to a string in the absence of a sensible native datatype.

"Adaptive Server connection timed out" with SQL Server 9.00.4053.00

Hello,

I'm trying to run rake db:migrate from my rails application to a SQL Server 2005 (9.00.4053.00).
Several commands are run on the server, according to SQL Server Profiler:

set textsize 64512 
go
use MyDatabase
go
SET ANSI_DEFAULTS ON
go
SET CURSOR_CLOSE_ON_COMMIT OFF
go
SET IMPLICIT_TRANSACTIONS OFF
go
SELECT @@version
go
USE [MyDatabase]
go
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME <> 'dtproperties' AND TABLE_SCHEMA = schema_name()
go
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME <> 'dtproperties' AND TABLE_SCHEMA = schema_name()
go
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME <> 'dtproperties' AND TABLE_SCHEMA = schema_name()
go

I patched tiny_tds to add some printf traces in rb_tinytds_raise_error.
From what I understand, the connection times out, and tiny_tds tries to sync with the server again with dbsqlok, but stays locked into this call for 15 minutes, before an other timeout occurs.

05/19/11t08:12:10 rb_tinytds_raise_error(0x01e8f580, 1, Adaptive Server connection timed out, error, 6, 20003, 0)
05/19/11t08:12:10 Calling dbsqlok
05/19/11t08:27:10 rb_tinytds_raise_error(0x01e8f580, 1, Read from the server failed, error, 9, 20004, 60)
05/19/11t08:27:10 Calling dbsqlok
05/19/11t08:27:10 Returned from dbsqlok
05/19/11t08:27:10 rb_tinytds_raise_error(0x01e8f580, 0, DBPROCESS is dead or not enabled, error, 1, 20047, 0)
05/19/11t08:27:10 rb_tinytds_raise_error(0x01e8f580, 0, DBPROCESS is dead or not enabled, error, 1, 20047, 0)

I don't really know how your library works, I'm just guessing. Do you have an idea?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.