tiny_tds 0.4.2 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +9 -0
- data/README.rdoc +22 -7
- data/ext/tiny_tds/client.c +27 -3
- data/lib/tiny_tds.rb +1 -1
- data/lib/tiny_tds/client.rb +3 -0
- metadata +4 -4
data/CHANGELOG
CHANGED
@@ -1,4 +1,13 @@
|
|
1
1
|
|
2
|
+
* 0.4.3 *
|
3
|
+
|
4
|
+
* New Client#active? method to check for good connection. Always use this abstract method.
|
5
|
+
|
6
|
+
* Better SYBEWRIT "Write to SQL Server failed." error handling. New Client#dead? check.
|
7
|
+
|
8
|
+
* Azure tested using latest FreeTDS with submitted patch. https://gist.github.com/889190
|
9
|
+
|
10
|
+
|
2
11
|
* 0.4.2 *
|
3
12
|
|
4
13
|
* Iconv is a dep only when compiling locally. However, left in the ability to configure it for native gem installation but you must use --enable-iconv before using --with-iconv-dir=/some/dir
|
data/README.rdoc
CHANGED
@@ -30,7 +30,7 @@ Although we search for FreeTDS's libraries and headers, you may have to specify
|
|
30
30
|
|
31
31
|
== FreeTDS Compatibility
|
32
32
|
|
33
|
-
TinyTDS is developed for FreeTDS 0.82 & 0.83.dev. It is tested with SQL Server 2000, 2005, and
|
33
|
+
TinyTDS is developed for FreeTDS 0.82 & 0.83.dev. It is tested with SQL Server 2000, 2005, 2008 and Azure using TDS Version 8.0. We utilize FreeTDS's db-lib client library. We compile against sybdb.h, undefine MSDBLIB and define SYBDBLIB which means that internally we conform to sybase API to db-lib. TinyTDS will work for both Sybase & Miscrosoft SQL Server. You do NOT need to compile FreeTDS with the "--enable-msdblib" option for our client to work properly. However, please make sure to compile FreeTDS with libiconv support for encodings to work at their best. Run "tsql -C" in your console and check for "iconv library: yes".
|
34
34
|
|
35
35
|
|
36
36
|
|
@@ -64,11 +64,20 @@ Creating a new client takes a hash of options. For valid iconv encoding options,
|
|
64
64
|
* :login_timeout - Seconds to wait for login. Default to 60 seconds.
|
65
65
|
* :timeout - Seconds to wait for a response to a SQL command. Default 5 seconds.
|
66
66
|
* :encoding - Any valid iconv value like CP1251 or ISO-8859-1. Default UTF-8.
|
67
|
+
* :azure - Pass true to signal that you are connecting to azure.
|
67
68
|
|
68
|
-
|
69
|
-
|
69
|
+
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.
|
70
|
+
|
71
|
+
client.dead? # => false
|
72
|
+
client.closed? # => false
|
73
|
+
client.active? # => true
|
74
|
+
client.execute("SQL TO A DEAD SERVER")
|
75
|
+
client.dead? # => true
|
76
|
+
client.closed? # => false
|
77
|
+
client.active? # => false
|
70
78
|
client.close
|
71
|
-
client.closed?
|
79
|
+
client.closed? # => true
|
80
|
+
client.active? # => false
|
72
81
|
|
73
82
|
Escape strings.
|
74
83
|
|
@@ -95,7 +104,7 @@ Calling #each on the result will lazily load each row from the database.
|
|
95
104
|
|
96
105
|
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.
|
97
106
|
|
98
|
-
result = client.execute("USE [
|
107
|
+
result = client.execute("USE [tinytdstest]")
|
99
108
|
result.fields # => []
|
100
109
|
result.do
|
101
110
|
|
@@ -219,9 +228,15 @@ http://github.com/rails-sqlserver/activerecord-sqlserver-adapter/wiki/Using-Tiny
|
|
219
228
|
|
220
229
|
|
221
230
|
|
231
|
+
== Using TinyTDS with Azure
|
232
|
+
|
233
|
+
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 in the login packet since Azure has no notion of "USE [database]". You must use the latest FreeTDS 0.83.dev and it must be compiled with OpenSSL.
|
234
|
+
|
235
|
+
|
236
|
+
|
222
237
|
== Development & Testing
|
223
238
|
|
224
|
-
We use bundler for development. Simply run "bundle install" then "rake" to build the gem and run the unit tests. The tests assume you have created a database named "
|
239
|
+
We use bundler for development. Simply run "bundle install" then "rake" to build the gem and run the unit tests. The tests assume you have created a database named "tinytdstest" accessible by a database owner named "tinytds". Before running the test rake task, you may need to define a pair of environment variables that help the client connect to your specific FreeTDS database server name and which schema (2000, 2005, 2008 or azure) to use. For example:
|
225
240
|
|
226
241
|
$ rake TINYTDS_UNIT_DATASERVER=mydbserver TINYTDS_SCHEMA=sqlserver_2008
|
227
242
|
|
@@ -244,7 +259,7 @@ Current to do list.
|
|
244
259
|
|
245
260
|
== About Me
|
246
261
|
|
247
|
-
My name is Ken Collins and
|
262
|
+
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 http://metaskills.net and I can be found on twitter as @metaskills. Enjoy!
|
248
263
|
|
249
264
|
|
250
265
|
|
data/ext/tiny_tds/client.c
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
VALUE cTinyTdsClient;
|
6
6
|
extern VALUE mTinyTds, cTinyTdsError;
|
7
|
-
static ID sym_username, sym_password, sym_dataserver, sym_database, sym_appname, sym_tds_version, sym_login_timeout, sym_timeout, sym_encoding;
|
7
|
+
static ID sym_username, sym_password, sym_dataserver, sym_database, sym_appname, sym_tds_version, sym_login_timeout, sym_timeout, sym_encoding, sym_azure;
|
8
8
|
static ID intern_source_eql, intern_severity_eql, intern_db_error_number_eql, intern_os_error_number_eql;
|
9
9
|
static ID intern_new, intern_dup, intern_transpose_iconv_encoding, intern_local_offset, intern_gsub;
|
10
10
|
VALUE opt_escape_regex, opt_escape_dblquote;
|
@@ -66,6 +66,8 @@ int tinytds_err_handler(DBPROCESS *dbproc, int severity, int dberr, int oserr, c
|
|
66
66
|
case SYBESEOF: {
|
67
67
|
if (userdata && userdata->timing_out)
|
68
68
|
return_value = INT_TIMEOUT;
|
69
|
+
return INT_CANCEL;
|
70
|
+
break;
|
69
71
|
}
|
70
72
|
case SYBETIME: {
|
71
73
|
if (userdata) {
|
@@ -78,6 +80,12 @@ int tinytds_err_handler(DBPROCESS *dbproc, int severity, int dberr, int oserr, c
|
|
78
80
|
cancel = 1;
|
79
81
|
break;
|
80
82
|
}
|
83
|
+
case SYBEWRIT: {
|
84
|
+
if (userdata && (userdata->dbsqlok_sent || userdata->dbcancel_sent))
|
85
|
+
return INT_CANCEL;
|
86
|
+
cancel = 1;
|
87
|
+
break;
|
88
|
+
}
|
81
89
|
case SYBEREAD:
|
82
90
|
cancel = 1;
|
83
91
|
break;
|
@@ -150,6 +158,11 @@ static VALUE rb_tinytds_close(VALUE self) {
|
|
150
158
|
return Qtrue;
|
151
159
|
}
|
152
160
|
|
161
|
+
static VALUE rb_tinytds_dead(VALUE self) {
|
162
|
+
GET_CLIENT_WRAPPER(self);
|
163
|
+
return dbdead(cwrap->client) ? Qtrue : Qfalse;
|
164
|
+
}
|
165
|
+
|
153
166
|
static VALUE rb_tinytds_closed(VALUE self) {
|
154
167
|
GET_CLIENT_WRAPPER(self);
|
155
168
|
return (cwrap->closed || cwrap->userdata->closed) ? Qtrue : Qfalse;
|
@@ -224,7 +237,7 @@ static VALUE rb_tinytds_return_code(VALUE self) {
|
|
224
237
|
|
225
238
|
static VALUE rb_tinytds_connect(VALUE self, VALUE opts) {
|
226
239
|
/* Parsing options hash to local vars. */
|
227
|
-
VALUE user, pass, dataserver, database, app, version, ltimeout, timeout, charset;
|
240
|
+
VALUE user, pass, dataserver, database, app, version, ltimeout, timeout, charset, azure;
|
228
241
|
user = rb_hash_aref(opts, sym_username);
|
229
242
|
pass = rb_hash_aref(opts, sym_password);
|
230
243
|
dataserver = rb_hash_aref(opts, sym_dataserver);
|
@@ -234,6 +247,7 @@ static VALUE rb_tinytds_connect(VALUE self, VALUE opts) {
|
|
234
247
|
ltimeout = rb_hash_aref(opts, sym_login_timeout);
|
235
248
|
timeout = rb_hash_aref(opts, sym_timeout);
|
236
249
|
charset = rb_hash_aref(opts, sym_encoding);
|
250
|
+
azure = rb_hash_aref(opts, sym_azure);
|
237
251
|
/* Dealing with options. */
|
238
252
|
if (dbinit() == FAIL) {
|
239
253
|
rb_raise(cTinyTdsError, "failed dbinit() function");
|
@@ -257,14 +271,22 @@ static VALUE rb_tinytds_connect(VALUE self, VALUE opts) {
|
|
257
271
|
dbsettime(NUM2INT(timeout));
|
258
272
|
if (!NIL_P(charset))
|
259
273
|
DBSETLCHARSET(cwrap->login, StringValuePtr(charset));
|
274
|
+
if (!NIL_P(database) && (azure == Qtrue)) {
|
275
|
+
#ifdef DBSETLDBNAME
|
276
|
+
DBSETLDBNAME(cwrap->login, StringValuePtr(database));
|
277
|
+
#else
|
278
|
+
rb_warn("TinyTds: Azure connections not supported in this version of FreeTDS.\n");
|
279
|
+
#endif
|
280
|
+
}
|
260
281
|
cwrap->client = dbopen(cwrap->login, StringValuePtr(dataserver));
|
261
282
|
if (cwrap->client) {
|
262
283
|
cwrap->closed = 0;
|
263
284
|
cwrap->charset = charset;
|
264
285
|
dbsetuserdata(cwrap->client, (BYTE*)cwrap->userdata);
|
265
286
|
cwrap->userdata->closed = 0;
|
266
|
-
if (!NIL_P(database))
|
287
|
+
if (!NIL_P(database) && (azure != Qtrue)) {
|
267
288
|
dbuse(cwrap->client, StringValuePtr(database));
|
289
|
+
}
|
268
290
|
#ifdef HAVE_RUBY_ENCODING_H
|
269
291
|
VALUE transposed_encoding = rb_funcall(cTinyTdsClient, intern_transpose_iconv_encoding, 1, charset);
|
270
292
|
cwrap->encoding = rb_enc_find(StringValuePtr(transposed_encoding));
|
@@ -284,6 +306,7 @@ void init_tinytds_client() {
|
|
284
306
|
rb_define_method(cTinyTdsClient, "close", rb_tinytds_close, 0);
|
285
307
|
rb_define_method(cTinyTdsClient, "closed?", rb_tinytds_closed, 0);
|
286
308
|
rb_define_method(cTinyTdsClient, "canceled?", rb_tinytds_canceled, 0);
|
309
|
+
rb_define_method(cTinyTdsClient, "dead?", rb_tinytds_dead, 0);
|
287
310
|
rb_define_method(cTinyTdsClient, "sqlsent?", rb_tinytds_sqlsent, 0);
|
288
311
|
rb_define_method(cTinyTdsClient, "execute", rb_tinytds_execute, 1);
|
289
312
|
rb_define_method(cTinyTdsClient, "charset", rb_tinytds_charset, 0);
|
@@ -302,6 +325,7 @@ void init_tinytds_client() {
|
|
302
325
|
sym_login_timeout = ID2SYM(rb_intern("login_timeout"));
|
303
326
|
sym_timeout = ID2SYM(rb_intern("timeout"));
|
304
327
|
sym_encoding = ID2SYM(rb_intern("encoding"));
|
328
|
+
sym_azure = ID2SYM(rb_intern("azure"));
|
305
329
|
/* Intern TinyTds::Error Accessors */
|
306
330
|
intern_source_eql = rb_intern("source=");
|
307
331
|
intern_severity_eql = rb_intern("severity=");
|
data/lib/tiny_tds.rb
CHANGED
data/lib/tiny_tds/client.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tiny_tds
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 9
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
version: 0.4.
|
9
|
+
- 3
|
10
|
+
version: 0.4.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ken Collins
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-
|
19
|
+
date: 2011-04-01 00:00:00 -04:00
|
20
20
|
default_executable:
|
21
21
|
dependencies: []
|
22
22
|
|