tiny_tds 3.2.1-x64-mingw-ucrt → 3.3.0-x64-mingw-ucrt
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.
- checksums.yaml +4 -4
- data/.devcontainer/Dockerfile +21 -0
- data/.devcontainer/boot.sh +6 -0
- data/.devcontainer/compose.yaml +40 -0
- data/.devcontainer/devcontainer.json +30 -0
- data/.github/workflows/ci.yml +17 -5
- data/CHANGELOG.md +7 -0
- data/README.md +17 -33
- data/Rakefile +5 -0
- data/VERSION +1 -1
- data/astyle.conf +8 -0
- data/ext/tiny_tds/client.c +163 -64
- data/ext/tiny_tds/extconsts.rb +2 -2
- data/ext/tiny_tds/result.c +171 -42
- data/ext/tiny_tds/result.h +2 -2
- data/ext/tiny_tds/tiny_tds_ext.c +2 -1
- data/lib/tiny_tds/3.1/tiny_tds.so +0 -0
- data/lib/tiny_tds/3.2/tiny_tds.so +0 -0
- data/lib/tiny_tds/3.3/tiny_tds.so +0 -0
- data/lib/tiny_tds/3.4/tiny_tds.so +0 -0
- data/lib/tiny_tds/bin.rb +2 -2
- data/lib/tiny_tds/gem.rb +6 -6
- data/lib/tiny_tds.rb +1 -2
- data/ports/x64-mingw-ucrt/bin/defncopy.exe +0 -0
- data/ports/x64-mingw-ucrt/bin/libsybdb-5.dll +0 -0
- data/ports/x64-mingw-ucrt/bin/tsql.exe +0 -0
- data/test/bin/restore-from-native-gem.ps1 +7 -1
- data/test/gem_test.rb +23 -28
- data/test/thread_test.rb +1 -1
- data/tiny_tds.gemspec +2 -2
- metadata +7 -10
- data/docker-compose.yml +0 -34
- data/setup_cimgruby_dev.sh +0 -25
- data/start_dev.sh +0 -21
- data/test/bin/install-mssql.ps1 +0 -42
- data/test/bin/install-mssqltools.sh +0 -9
- data/test/bin/install-openssl.sh +0 -18
- data/test/bin/setup_tinytds_db.sh +0 -7
- data/test/bin/setup_volume_permissions.sh +0 -10
data/ext/tiny_tds/client.c
CHANGED
@@ -8,12 +8,54 @@ static ID intern_source_eql, intern_severity_eql, intern_db_error_number_eql, in
|
|
8
8
|
static ID intern_new, intern_dup, intern_transpose_iconv_encoding, intern_local_offset, intern_gsub, intern_call;
|
9
9
|
VALUE opt_escape_regex, opt_escape_dblquote;
|
10
10
|
|
11
|
+
static void rb_tinytds_client_mark(void *ptr)
|
12
|
+
{
|
13
|
+
tinytds_client_wrapper *cwrap = (tinytds_client_wrapper *)ptr;
|
14
|
+
|
15
|
+
if (cwrap) {
|
16
|
+
rb_gc_mark(cwrap->charset);
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
static void rb_tinytds_client_free(void *ptr)
|
21
|
+
{
|
22
|
+
tinytds_client_wrapper *cwrap = (tinytds_client_wrapper *)ptr;
|
23
|
+
|
24
|
+
if (cwrap->login) {
|
25
|
+
dbloginfree(cwrap->login);
|
26
|
+
}
|
27
|
+
|
28
|
+
if (cwrap->client && !cwrap->closed) {
|
29
|
+
dbclose(cwrap->client);
|
30
|
+
cwrap->client = NULL;
|
31
|
+
cwrap->closed = 1;
|
32
|
+
cwrap->userdata->closed = 1;
|
33
|
+
}
|
34
|
+
|
35
|
+
xfree(cwrap->userdata);
|
36
|
+
xfree(ptr);
|
37
|
+
}
|
38
|
+
|
39
|
+
static size_t tinytds_client_wrapper_size(const void* data)
|
40
|
+
{
|
41
|
+
return sizeof(tinytds_client_wrapper);
|
42
|
+
}
|
43
|
+
|
44
|
+
static const rb_data_type_t tinytds_client_wrapper_type = {
|
45
|
+
.wrap_struct_name = "tinytds_client_wrapper",
|
46
|
+
.function = {
|
47
|
+
.dmark = rb_tinytds_client_mark,
|
48
|
+
.dfree = rb_tinytds_client_free,
|
49
|
+
.dsize = tinytds_client_wrapper_size,
|
50
|
+
},
|
51
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
52
|
+
};
|
11
53
|
|
12
54
|
// Lib Macros
|
13
55
|
|
14
56
|
#define GET_CLIENT_WRAPPER(self) \
|
15
57
|
tinytds_client_wrapper *cwrap; \
|
16
|
-
|
58
|
+
TypedData_Get_Struct(self, tinytds_client_wrapper, &tinytds_client_wrapper_type, cwrap)
|
17
59
|
|
18
60
|
#define REQUIRE_OPEN_CLIENT(cwrap) \
|
19
61
|
if (cwrap->closed || cwrap->userdata->closed) { \
|
@@ -24,26 +66,36 @@ VALUE opt_escape_regex, opt_escape_dblquote;
|
|
24
66
|
|
25
67
|
// Lib Backend (Helpers)
|
26
68
|
|
27
|
-
VALUE rb_tinytds_raise_error(DBPROCESS *dbproc, tinytds_errordata error)
|
69
|
+
VALUE rb_tinytds_raise_error(DBPROCESS *dbproc, tinytds_errordata error)
|
70
|
+
{
|
28
71
|
VALUE e;
|
29
72
|
GET_CLIENT_USERDATA(dbproc);
|
73
|
+
|
30
74
|
if (error.cancel && !dbdead(dbproc) && userdata && !userdata->closed) {
|
31
75
|
userdata->dbsqlok_sent = 1;
|
32
76
|
dbsqlok(dbproc);
|
33
77
|
userdata->dbcancel_sent = 1;
|
34
78
|
dbcancel(dbproc);
|
35
79
|
}
|
80
|
+
|
36
81
|
e = rb_exc_new2(cTinyTdsError, error.error);
|
37
82
|
rb_funcall(e, intern_source_eql, 1, rb_str_new2(error.source));
|
38
|
-
|
83
|
+
|
84
|
+
if (error.severity) {
|
39
85
|
rb_funcall(e, intern_severity_eql, 1, INT2FIX(error.severity));
|
40
|
-
|
86
|
+
}
|
87
|
+
|
88
|
+
if (error.dberr) {
|
41
89
|
rb_funcall(e, intern_db_error_number_eql, 1, INT2FIX(error.dberr));
|
42
|
-
|
90
|
+
}
|
91
|
+
|
92
|
+
if (error.oserr) {
|
43
93
|
rb_funcall(e, intern_os_error_number_eql, 1, INT2FIX(error.oserr));
|
94
|
+
}
|
44
95
|
|
45
96
|
if (error.severity <= 10 && error.is_message) {
|
46
97
|
VALUE message_handler = userdata && userdata->message_handler ? userdata->message_handler : Qnil;
|
98
|
+
|
47
99
|
if (message_handler && message_handler != Qnil && rb_respond_to(message_handler, intern_call) != 0) {
|
48
100
|
rb_funcall(message_handler, intern_call, 1, e);
|
49
101
|
}
|
@@ -57,7 +109,8 @@ VALUE rb_tinytds_raise_error(DBPROCESS *dbproc, tinytds_errordata error) {
|
|
57
109
|
|
58
110
|
|
59
111
|
// Lib Backend (Memory Management & Handlers)
|
60
|
-
static void push_userdata_error(tinytds_client_userdata *userdata, tinytds_errordata error)
|
112
|
+
static void push_userdata_error(tinytds_client_userdata *userdata, tinytds_errordata error)
|
113
|
+
{
|
61
114
|
// reallocate memory for the array as needed
|
62
115
|
if (userdata->nonblocking_errors_size == userdata->nonblocking_errors_length) {
|
63
116
|
userdata->nonblocking_errors_size *= 2;
|
@@ -68,7 +121,8 @@ static void push_userdata_error(tinytds_client_userdata *userdata, tinytds_error
|
|
68
121
|
userdata->nonblocking_errors_length++;
|
69
122
|
}
|
70
123
|
|
71
|
-
int tinytds_err_handler(DBPROCESS *dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr)
|
124
|
+
int tinytds_err_handler(DBPROCESS *dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr)
|
125
|
+
{
|
72
126
|
static const char *source = "error";
|
73
127
|
/* Everything should cancel by default */
|
74
128
|
int return_value = INT_CANCEL;
|
@@ -91,6 +145,7 @@ int tinytds_err_handler(DBPROCESS *dbproc, int severity, int dberr, int oserr, c
|
|
91
145
|
return return_value;
|
92
146
|
|
93
147
|
case SYBETIME:
|
148
|
+
|
94
149
|
/*
|
95
150
|
SYBETIME is the only error that can send INT_TIMEOUT or INT_CONTINUE,
|
96
151
|
but we don't ever want to automatically retry. Instead have the app
|
@@ -99,19 +154,23 @@ int tinytds_err_handler(DBPROCESS *dbproc, int severity, int dberr, int oserr, c
|
|
99
154
|
if (userdata && userdata->timing_out) {
|
100
155
|
return INT_CANCEL;
|
101
156
|
}
|
157
|
+
|
102
158
|
// userdata will not be set if hitting timeout during login so check for it first
|
103
159
|
if (userdata) {
|
104
160
|
userdata->timing_out = 1;
|
105
161
|
}
|
162
|
+
|
106
163
|
return_value = INT_TIMEOUT;
|
107
164
|
cancel = 1;
|
108
165
|
break;
|
109
166
|
|
110
167
|
case SYBEWRIT:
|
168
|
+
|
111
169
|
/* Write errors may happen after we abort a statement */
|
112
170
|
if (userdata && (userdata->dbsqlok_sent || userdata->dbcancel_sent)) {
|
113
171
|
return return_value;
|
114
172
|
}
|
173
|
+
|
115
174
|
cancel = 1;
|
116
175
|
break;
|
117
176
|
}
|
@@ -137,6 +196,7 @@ int tinytds_err_handler(DBPROCESS *dbproc, int severity, int dberr, int oserr, c
|
|
137
196
|
dbcancel(dbproc);
|
138
197
|
userdata->dbcancel_sent = 1;
|
139
198
|
}
|
199
|
+
|
140
200
|
push_userdata_error(userdata, error_data);
|
141
201
|
} else {
|
142
202
|
rb_tinytds_raise_error(dbproc, error_data);
|
@@ -145,7 +205,8 @@ int tinytds_err_handler(DBPROCESS *dbproc, int severity, int dberr, int oserr, c
|
|
145
205
|
return return_value;
|
146
206
|
}
|
147
207
|
|
148
|
-
int tinytds_msg_handler(DBPROCESS *dbproc, DBINT msgno, int msgstate, int severity, char *msgtext, char *srvname, char *procname, int line)
|
208
|
+
int tinytds_msg_handler(DBPROCESS *dbproc, DBINT msgno, int msgstate, int severity, char *msgtext, char *srvname, char *procname, int line)
|
209
|
+
{
|
149
210
|
static const char *source = "message";
|
150
211
|
GET_CLIENT_USERDATA(dbproc);
|
151
212
|
|
@@ -177,6 +238,7 @@ int tinytds_msg_handler(DBPROCESS *dbproc, DBINT msgno, int msgstate, int severi
|
|
177
238
|
} else {
|
178
239
|
rb_tinytds_raise_error(dbproc, error_data);
|
179
240
|
}
|
241
|
+
|
180
242
|
return 0;
|
181
243
|
}
|
182
244
|
|
@@ -187,7 +249,8 @@ Right now, we only care about cases where a read from the server is
|
|
187
249
|
taking longer than the specified timeout and dbcancel is not working.
|
188
250
|
In these cases we decide that we actually want to handle the interrupt
|
189
251
|
*/
|
190
|
-
static int check_interrupt(void *ptr)
|
252
|
+
static int check_interrupt(void *ptr)
|
253
|
+
{
|
191
254
|
GET_CLIENT_USERDATA((DBPROCESS *)ptr);
|
192
255
|
return userdata->timing_out;
|
193
256
|
}
|
@@ -199,15 +262,19 @@ Right now, this is only used in cases where a read from the server is
|
|
199
262
|
taking longer than the specified timeout and dbcancel is not working.
|
200
263
|
Return INT_CANCEL to abort the current command batch.
|
201
264
|
*/
|
202
|
-
static int handle_interrupt(void *ptr)
|
265
|
+
static int handle_interrupt(void *ptr)
|
266
|
+
{
|
203
267
|
GET_CLIENT_USERDATA((DBPROCESS *)ptr);
|
268
|
+
|
204
269
|
if (userdata->timing_out) {
|
205
270
|
return INT_CANCEL;
|
206
271
|
}
|
272
|
+
|
207
273
|
return INT_CONTINUE;
|
208
274
|
}
|
209
275
|
|
210
|
-
static void rb_tinytds_client_reset_userdata(tinytds_client_userdata *userdata)
|
276
|
+
static void rb_tinytds_client_reset_userdata(tinytds_client_userdata *userdata)
|
277
|
+
{
|
211
278
|
userdata->timing_out = 0;
|
212
279
|
userdata->dbsql_sent = 0;
|
213
280
|
userdata->dbsqlok_sent = 0;
|
@@ -219,31 +286,11 @@ static void rb_tinytds_client_reset_userdata(tinytds_client_userdata *userdata)
|
|
219
286
|
userdata->nonblocking_errors_size = 0;
|
220
287
|
}
|
221
288
|
|
222
|
-
static
|
223
|
-
|
224
|
-
if (cwrap) {
|
225
|
-
rb_gc_mark(cwrap->charset);
|
226
|
-
}
|
227
|
-
}
|
228
|
-
|
229
|
-
static void rb_tinytds_client_free(void *ptr) {
|
230
|
-
tinytds_client_wrapper *cwrap = (tinytds_client_wrapper *)ptr;
|
231
|
-
if (cwrap->login)
|
232
|
-
dbloginfree(cwrap->login);
|
233
|
-
if (cwrap->client && !cwrap->closed) {
|
234
|
-
dbclose(cwrap->client);
|
235
|
-
cwrap->client = NULL;
|
236
|
-
cwrap->closed = 1;
|
237
|
-
cwrap->userdata->closed = 1;
|
238
|
-
}
|
239
|
-
xfree(cwrap->userdata);
|
240
|
-
xfree(ptr);
|
241
|
-
}
|
242
|
-
|
243
|
-
static VALUE allocate(VALUE klass) {
|
289
|
+
static VALUE allocate(VALUE klass)
|
290
|
+
{
|
244
291
|
VALUE obj;
|
245
292
|
tinytds_client_wrapper *cwrap;
|
246
|
-
obj =
|
293
|
+
obj = TypedData_Make_Struct(klass, tinytds_client_wrapper, &tinytds_client_wrapper_type, cwrap);
|
247
294
|
cwrap->closed = 1;
|
248
295
|
cwrap->charset = Qnil;
|
249
296
|
cwrap->userdata = malloc(sizeof(tinytds_client_userdata));
|
@@ -255,52 +302,63 @@ static VALUE allocate(VALUE klass) {
|
|
255
302
|
|
256
303
|
// TinyTds::Client (public)
|
257
304
|
|
258
|
-
static VALUE rb_tinytds_tds_version(VALUE self)
|
305
|
+
static VALUE rb_tinytds_tds_version(VALUE self)
|
306
|
+
{
|
259
307
|
GET_CLIENT_WRAPPER(self);
|
260
308
|
return INT2FIX(dbtds(cwrap->client));
|
261
309
|
}
|
262
310
|
|
263
|
-
static VALUE rb_tinytds_close(VALUE self)
|
311
|
+
static VALUE rb_tinytds_close(VALUE self)
|
312
|
+
{
|
264
313
|
GET_CLIENT_WRAPPER(self);
|
314
|
+
|
265
315
|
if (cwrap->client && !cwrap->closed) {
|
266
316
|
dbclose(cwrap->client);
|
267
317
|
cwrap->client = NULL;
|
268
318
|
cwrap->closed = 1;
|
269
319
|
cwrap->userdata->closed = 1;
|
270
320
|
}
|
321
|
+
|
271
322
|
return Qtrue;
|
272
323
|
}
|
273
324
|
|
274
|
-
static VALUE rb_tinytds_dead(VALUE self)
|
325
|
+
static VALUE rb_tinytds_dead(VALUE self)
|
326
|
+
{
|
275
327
|
GET_CLIENT_WRAPPER(self);
|
276
328
|
return dbdead(cwrap->client) ? Qtrue : Qfalse;
|
277
329
|
}
|
278
330
|
|
279
|
-
static VALUE rb_tinytds_closed(VALUE self)
|
331
|
+
static VALUE rb_tinytds_closed(VALUE self)
|
332
|
+
{
|
280
333
|
GET_CLIENT_WRAPPER(self);
|
281
334
|
return (cwrap->closed || cwrap->userdata->closed) ? Qtrue : Qfalse;
|
282
335
|
}
|
283
336
|
|
284
|
-
static VALUE rb_tinytds_canceled(VALUE self)
|
337
|
+
static VALUE rb_tinytds_canceled(VALUE self)
|
338
|
+
{
|
285
339
|
GET_CLIENT_WRAPPER(self);
|
286
340
|
return cwrap->userdata->dbcancel_sent ? Qtrue : Qfalse;
|
287
341
|
}
|
288
342
|
|
289
|
-
static VALUE rb_tinytds_sqlsent(VALUE self)
|
343
|
+
static VALUE rb_tinytds_sqlsent(VALUE self)
|
344
|
+
{
|
290
345
|
GET_CLIENT_WRAPPER(self);
|
291
346
|
return cwrap->userdata->dbsql_sent ? Qtrue : Qfalse;
|
292
347
|
}
|
293
348
|
|
294
|
-
static VALUE rb_tinytds_execute(VALUE self, VALUE sql)
|
349
|
+
static VALUE rb_tinytds_execute(VALUE self, VALUE sql)
|
350
|
+
{
|
295
351
|
VALUE result;
|
296
352
|
|
297
353
|
GET_CLIENT_WRAPPER(self);
|
298
354
|
rb_tinytds_client_reset_userdata(cwrap->userdata);
|
299
355
|
REQUIRE_OPEN_CLIENT(cwrap);
|
300
356
|
dbcmd(cwrap->client, StringValueCStr(sql));
|
357
|
+
|
301
358
|
if (dbsqlsend(cwrap->client) == FAIL) {
|
302
359
|
rb_raise(cTinyTdsError, "failed dbsqlsend() function");
|
303
360
|
}
|
361
|
+
|
304
362
|
cwrap->userdata->dbsql_sent = 1;
|
305
363
|
result = rb_tinytds_new_result_obj(cwrap);
|
306
364
|
rb_iv_set(result, "@query_options", rb_funcall(rb_iv_get(self, "@query_options"), intern_dup, 0));
|
@@ -312,17 +370,20 @@ static VALUE rb_tinytds_execute(VALUE self, VALUE sql) {
|
|
312
370
|
}
|
313
371
|
}
|
314
372
|
|
315
|
-
static VALUE rb_tinytds_charset(VALUE self)
|
373
|
+
static VALUE rb_tinytds_charset(VALUE self)
|
374
|
+
{
|
316
375
|
GET_CLIENT_WRAPPER(self);
|
317
376
|
return cwrap->charset;
|
318
377
|
}
|
319
378
|
|
320
|
-
static VALUE rb_tinytds_encoding(VALUE self)
|
379
|
+
static VALUE rb_tinytds_encoding(VALUE self)
|
380
|
+
{
|
321
381
|
GET_CLIENT_WRAPPER(self);
|
322
382
|
return rb_enc_from_encoding(cwrap->encoding);
|
323
383
|
}
|
324
384
|
|
325
|
-
static VALUE rb_tinytds_escape(VALUE self, VALUE string)
|
385
|
+
static VALUE rb_tinytds_escape(VALUE self, VALUE string)
|
386
|
+
{
|
326
387
|
VALUE new_string;
|
327
388
|
GET_CLIENT_WRAPPER(self);
|
328
389
|
|
@@ -333,8 +394,10 @@ static VALUE rb_tinytds_escape(VALUE self, VALUE string) {
|
|
333
394
|
}
|
334
395
|
|
335
396
|
/* Duplicated in result.c */
|
336
|
-
static VALUE rb_tinytds_return_code(VALUE self)
|
397
|
+
static VALUE rb_tinytds_return_code(VALUE self)
|
398
|
+
{
|
337
399
|
GET_CLIENT_WRAPPER(self);
|
400
|
+
|
338
401
|
if (cwrap->client && dbhasretstat(cwrap->client)) {
|
339
402
|
return LONG2NUM((long)dbretstatus(cwrap->client));
|
340
403
|
} else {
|
@@ -342,7 +405,8 @@ static VALUE rb_tinytds_return_code(VALUE self) {
|
|
342
405
|
}
|
343
406
|
}
|
344
407
|
|
345
|
-
static VALUE rb_tinytds_identity_sql(VALUE self)
|
408
|
+
static VALUE rb_tinytds_identity_sql(VALUE self)
|
409
|
+
{
|
346
410
|
GET_CLIENT_WRAPPER(self);
|
347
411
|
return rb_str_new2(cwrap->identity_insert_sql);
|
348
412
|
}
|
@@ -351,7 +415,8 @@ static VALUE rb_tinytds_identity_sql(VALUE self) {
|
|
351
415
|
|
352
416
|
// TinyTds::Client (protected)
|
353
417
|
|
354
|
-
static VALUE rb_tinytds_connect(VALUE self, VALUE opts)
|
418
|
+
static VALUE rb_tinytds_connect(VALUE self, VALUE opts)
|
419
|
+
{
|
355
420
|
/* Parsing options hash to local vars. */
|
356
421
|
VALUE user, pass, dataserver, database, app, version, ltimeout, timeout, charset, azure, contained, use_utf16;
|
357
422
|
GET_CLIENT_WRAPPER(self);
|
@@ -369,44 +434,69 @@ static VALUE rb_tinytds_connect(VALUE self, VALUE opts) {
|
|
369
434
|
contained = rb_hash_aref(opts, sym_contained);
|
370
435
|
use_utf16 = rb_hash_aref(opts, sym_use_utf16);
|
371
436
|
cwrap->userdata->message_handler = rb_hash_aref(opts, sym_message_handler);
|
437
|
+
|
372
438
|
/* Dealing with options. */
|
373
439
|
if (dbinit() == FAIL) {
|
374
440
|
rb_raise(cTinyTdsError, "failed dbinit() function");
|
375
441
|
return self;
|
376
442
|
}
|
443
|
+
|
377
444
|
dberrhandle(tinytds_err_handler);
|
378
445
|
dbmsghandle(tinytds_msg_handler);
|
379
446
|
cwrap->login = dblogin();
|
380
|
-
|
447
|
+
|
448
|
+
if (!NIL_P(version)) {
|
381
449
|
dbsetlversion(cwrap->login, NUM2INT(version));
|
382
|
-
|
450
|
+
}
|
451
|
+
|
452
|
+
if (!NIL_P(user)) {
|
383
453
|
dbsetluser(cwrap->login, StringValueCStr(user));
|
384
|
-
|
454
|
+
}
|
455
|
+
|
456
|
+
if (!NIL_P(pass)) {
|
385
457
|
dbsetlpwd(cwrap->login, StringValueCStr(pass));
|
386
|
-
|
458
|
+
}
|
459
|
+
|
460
|
+
if (!NIL_P(app)) {
|
387
461
|
dbsetlapp(cwrap->login, StringValueCStr(app));
|
388
|
-
|
462
|
+
}
|
463
|
+
|
464
|
+
if (!NIL_P(ltimeout)) {
|
389
465
|
dbsetlogintime(NUM2INT(ltimeout));
|
390
|
-
|
466
|
+
}
|
467
|
+
|
468
|
+
if (!NIL_P(charset)) {
|
391
469
|
DBSETLCHARSET(cwrap->login, StringValueCStr(charset));
|
470
|
+
}
|
471
|
+
|
392
472
|
if (!NIL_P(database)) {
|
393
473
|
if (azure == Qtrue || contained == Qtrue) {
|
394
474
|
#ifdef DBSETLDBNAME
|
395
|
-
|
475
|
+
DBSETLDBNAME(cwrap->login, StringValueCStr(database));
|
396
476
|
#else
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
477
|
+
|
478
|
+
if (azure == Qtrue) {
|
479
|
+
rb_warn("TinyTds: :azure option is not supported in this version of FreeTDS.\n");
|
480
|
+
}
|
481
|
+
|
482
|
+
if (contained == Qtrue) {
|
483
|
+
rb_warn("TinyTds: :contained option is not supported in this version of FreeTDS.\n");
|
484
|
+
}
|
485
|
+
|
403
486
|
#endif
|
404
487
|
}
|
405
488
|
}
|
406
|
-
|
407
|
-
if (use_utf16 ==
|
489
|
+
|
490
|
+
if (use_utf16 == Qtrue) {
|
491
|
+
DBSETLUTF16(cwrap->login, 1);
|
492
|
+
}
|
493
|
+
|
494
|
+
if (use_utf16 == Qfalse) {
|
495
|
+
DBSETLUTF16(cwrap->login, 0);
|
496
|
+
}
|
408
497
|
|
409
498
|
cwrap->client = dbopen(cwrap->login, StringValueCStr(dataserver));
|
499
|
+
|
410
500
|
if (cwrap->client) {
|
411
501
|
if (dbtds(cwrap->client) < 11) {
|
412
502
|
rb_raise(cTinyTdsError, "connecting with a TDS version older than 7.3!");
|
@@ -416,31 +506,40 @@ static VALUE rb_tinytds_connect(VALUE self, VALUE opts) {
|
|
416
506
|
|
417
507
|
cwrap->closed = 0;
|
418
508
|
cwrap->charset = charset;
|
419
|
-
|
509
|
+
|
510
|
+
if (!NIL_P(version)) {
|
420
511
|
dbsetversion(NUM2INT(version));
|
512
|
+
}
|
513
|
+
|
421
514
|
if (!NIL_P(timeout)) {
|
422
515
|
timeout_string = rb_sprintf("%"PRIsVALUE"", timeout);
|
516
|
+
|
423
517
|
if (dbsetopt(cwrap->client, DBSETTIME, StringValueCStr(timeout_string), 0) == FAIL) {
|
424
518
|
dbsettime(NUM2INT(timeout));
|
425
519
|
}
|
426
520
|
}
|
521
|
+
|
427
522
|
dbsetuserdata(cwrap->client, (BYTE*)cwrap->userdata);
|
428
523
|
dbsetinterrupt(cwrap->client, check_interrupt, handle_interrupt);
|
429
524
|
cwrap->userdata->closed = 0;
|
525
|
+
|
430
526
|
if (!NIL_P(database) && (azure != Qtrue)) {
|
431
527
|
dbuse(cwrap->client, StringValueCStr(database));
|
432
528
|
}
|
529
|
+
|
433
530
|
transposed_encoding = rb_funcall(cTinyTdsClient, intern_transpose_iconv_encoding, 1, charset);
|
434
531
|
cwrap->encoding = rb_enc_find(StringValueCStr(transposed_encoding));
|
435
532
|
cwrap->identity_insert_sql = "SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident";
|
436
533
|
}
|
534
|
+
|
437
535
|
return self;
|
438
536
|
}
|
439
537
|
|
440
538
|
|
441
539
|
// Lib Init
|
442
540
|
|
443
|
-
void init_tinytds_client()
|
541
|
+
void init_tinytds_client()
|
542
|
+
{
|
444
543
|
cTinyTdsClient = rb_define_class_under(mTinyTds, "Client", rb_cObject);
|
445
544
|
rb_define_alloc_func(cTinyTdsClient, allocate);
|
446
545
|
/* Define TinyTds::Client Public Methods */
|
data/ext/tiny_tds/extconsts.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
ICONV_VERSION = ENV["TINYTDS_ICONV_VERSION"] || "1.18"
|
2
2
|
ICONV_SOURCE_URI = "http://ftp.gnu.org/pub/gnu/libiconv/libiconv-#{ICONV_VERSION}.tar.gz"
|
3
3
|
|
4
|
-
OPENSSL_VERSION = ENV["TINYTDS_OPENSSL_VERSION"] || "3.
|
4
|
+
OPENSSL_VERSION = ENV["TINYTDS_OPENSSL_VERSION"] || "3.5.2"
|
5
5
|
OPENSSL_SOURCE_URI = "https://www.openssl.org/source/openssl-#{OPENSSL_VERSION}.tar.gz"
|
6
6
|
|
7
|
-
FREETDS_VERSION = ENV["TINYTDS_FREETDS_VERSION"] || "1.4
|
7
|
+
FREETDS_VERSION = ENV["TINYTDS_FREETDS_VERSION"] || "1.5.4"
|
8
8
|
FREETDS_SOURCE_URI = "http://www.freetds.org/files/stable/freetds-#{FREETDS_VERSION}.tar.bz2"
|