tiny_tds 0.4.2 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|