tiny_tds 2.1.0.pre3-x64-mingw32 → 2.1.0.pre4-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 93e0eb01b0d797e9f3e1266a0be08158e4b761c1
4
- data.tar.gz: 6671c344c84c8bbdb1911b042652227292b198fd
3
+ metadata.gz: 4b10c77855d6b29f08fbc6c35c29e1df82bb15cb
4
+ data.tar.gz: 5746f1dfb44f3904195d4a4d77bb2c524065a467
5
5
  SHA512:
6
- metadata.gz: 32165a0fd2f22b0652894313b513e41c0e087528fa8e077338ea55d850e004452160fe4685cf73639c95480efe4f2e7d7c6065f67a7ae939f97194594c6ad21e
7
- data.tar.gz: 7a145ce24108ee06536767427416ffedb7ff6c5ff1ff540bd07ab422c430c4dabbdc630571232da950555e4b1d28c0eda848dea4c5621e75b689e350ebca28a6
6
+ metadata.gz: 32fda2eae82590c2b9b94cbc3c4b414e9ddccd801c0a89e5ff4cd536de524f2376d7fdcdad3cc3f025ad90e2056a53da066b3bb9834d6018a80754cc58dac0df
7
+ data.tar.gz: 03cd68692e427ae91032061216408d53a96ef7fd3cb1f820177997409157dd2b75fa384240da5d8c09dc5c1a2bf110525e0c4bed2f12cce4761c286927e082e8
@@ -4,6 +4,8 @@
4
4
  * Support the FREETDS_DIR environment variable. Fixes #371.
5
5
  * Rename binstubs to tsql-ttds and defncopy-ttds
6
6
  * Support separate timeout values per connection Fixes #348.
7
+ * Allow client proc to capture INFO messages. Fixes #352.
8
+ * Use official HTTP mirrors instead of FTP. Fixes #384.
7
9
 
8
10
 
9
11
  ## 2.0.0
data/README.md CHANGED
@@ -44,7 +44,7 @@ $ apt-get wget
44
44
  $ apt-get install build-essential
45
45
  $ apt-get install libc6-dev
46
46
 
47
- $ wget ftp://ftp.freetds.org/pub/freetds/stable/freetds-1.00.21.tar.gz
47
+ $ wget http://www.freetds.org/files/stable/freetds-1.00.21.tar.gz
48
48
  $ tar -xzf freetds-1.00.21.tar.gz
49
49
  $ cd freetds-1.00.21
50
50
  $ ./configure --prefix=/usr/local --with-tdsver=7.3
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.1.0.pre3
1
+ 2.1.0.pre4
@@ -3,10 +3,11 @@
3
3
 
4
4
  VALUE cTinyTdsClient;
5
5
  extern VALUE mTinyTds, cTinyTdsError;
6
- static ID sym_username, sym_password, sym_dataserver, sym_database, sym_appname, sym_tds_version, sym_login_timeout, sym_timeout, sym_encoding, sym_azure, sym_contained, sym_use_utf16;
6
+ static ID sym_username, sym_password, sym_dataserver, sym_database, sym_appname, sym_tds_version, sym_login_timeout, sym_timeout, sym_encoding, sym_azure, sym_contained, sym_use_utf16, sym_message_handler;
7
7
  static ID intern_source_eql, intern_severity_eql, intern_db_error_number_eql, intern_os_error_number_eql;
8
- static ID intern_new, intern_dup, intern_transpose_iconv_encoding, intern_local_offset, intern_gsub;
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
+ VALUE message_handler;
10
11
 
11
12
 
12
13
  // Lib Macros
@@ -24,7 +25,7 @@ VALUE opt_escape_regex, opt_escape_dblquote;
24
25
 
25
26
  // Lib Backend (Helpers)
26
27
 
27
- VALUE rb_tinytds_raise_error(DBPROCESS *dbproc, int cancel, const char *error, const char *source, int severity, int dberr, int oserr) {
28
+ VALUE rb_tinytds_raise_error(DBPROCESS *dbproc, int is_message, int cancel, const char *error, const char *source, int severity, int dberr, int oserr) {
28
29
  VALUE e;
29
30
  GET_CLIENT_USERDATA(dbproc);
30
31
  if (cancel && !dbdead(dbproc) && userdata && !userdata->closed) {
@@ -41,6 +42,15 @@ VALUE rb_tinytds_raise_error(DBPROCESS *dbproc, int cancel, const char *error, c
41
42
  rb_funcall(e, intern_db_error_number_eql, 1, INT2FIX(dberr));
42
43
  if (oserr)
43
44
  rb_funcall(e, intern_os_error_number_eql, 1, INT2FIX(oserr));
45
+
46
+ if (severity <= 10 && is_message) {
47
+ if (message_handler && message_handler != Qnil && rb_respond_to(message_handler, intern_call) != 0) {
48
+ rb_funcall(message_handler, intern_call, 1, e);
49
+ }
50
+
51
+ return Qnil;
52
+ }
53
+
44
54
  rb_exc_raise(e);
45
55
  return Qnil;
46
56
  }
@@ -109,6 +119,7 @@ int tinytds_err_handler(DBPROCESS *dbproc, int severity, int dberr, int oserr, c
109
119
  generic message can be sent.
110
120
  */
111
121
  if (!userdata->nonblocking_error.is_set) {
122
+ userdata->nonblocking_error.is_message = 0;
112
123
  userdata->nonblocking_error.cancel = cancel;
113
124
  strncpy(userdata->nonblocking_error.error, dberrstr, ERROR_MSG_SIZE);
114
125
  strncpy(userdata->nonblocking_error.source, source, ERROR_MSG_SIZE);
@@ -119,7 +130,7 @@ int tinytds_err_handler(DBPROCESS *dbproc, int severity, int dberr, int oserr, c
119
130
  }
120
131
 
121
132
  } else {
122
- rb_tinytds_raise_error(dbproc, cancel, dberrstr, source, severity, dberr, oserr);
133
+ rb_tinytds_raise_error(dbproc, 0, cancel, dberrstr, source, severity, dberr, oserr);
123
134
  }
124
135
 
125
136
  return return_value;
@@ -128,25 +139,28 @@ int tinytds_err_handler(DBPROCESS *dbproc, int severity, int dberr, int oserr, c
128
139
  int tinytds_msg_handler(DBPROCESS *dbproc, DBINT msgno, int msgstate, int severity, char *msgtext, char *srvname, char *procname, int line) {
129
140
  static const char *source = "message";
130
141
  GET_CLIENT_USERDATA(dbproc);
131
- if (severity > 10) {
132
- // See tinytds_err_handler() for info about why we do this
133
- if (userdata && userdata->nonblocking) {
134
- if (!userdata->nonblocking_error.is_set) {
135
- userdata->nonblocking_error.cancel = 1;
136
- strncpy(userdata->nonblocking_error.error, msgtext, ERROR_MSG_SIZE);
137
- strncpy(userdata->nonblocking_error.source, source, ERROR_MSG_SIZE);
138
- userdata->nonblocking_error.severity = severity;
139
- userdata->nonblocking_error.dberr = msgno;
140
- userdata->nonblocking_error.oserr = msgstate;
141
- userdata->nonblocking_error.is_set = 1;
142
- }
143
- if (!dbdead(dbproc) && !userdata->closed) {
144
- dbcancel(dbproc);
145
- userdata->dbcancel_sent = 1;
146
- }
147
- } else {
148
- rb_tinytds_raise_error(dbproc, 1, msgtext, source, severity, msgno, msgstate);
142
+
143
+ int is_message_an_error = severity > 10 ? 1 : 0;
144
+
145
+ // See tinytds_err_handler() for info about why we do this
146
+ if (userdata && userdata->nonblocking) {
147
+ if (!userdata->nonblocking_error.is_set) {
148
+ userdata->nonblocking_error.is_message = !is_message_an_error;
149
+ userdata->nonblocking_error.cancel = is_message_an_error;
150
+ strncpy(userdata->nonblocking_error.error, msgtext, ERROR_MSG_SIZE);
151
+ strncpy(userdata->nonblocking_error.source, source, ERROR_MSG_SIZE);
152
+ userdata->nonblocking_error.severity = severity;
153
+ userdata->nonblocking_error.dberr = msgno;
154
+ userdata->nonblocking_error.oserr = msgstate;
155
+ userdata->nonblocking_error.is_set = 1;
149
156
  }
157
+
158
+ if (is_message_an_error && !dbdead(dbproc) && !userdata->closed) {
159
+ dbcancel(dbproc);
160
+ userdata->dbcancel_sent = 1;
161
+ }
162
+ } else {
163
+ rb_tinytds_raise_error(dbproc, !is_message_an_error, is_message_an_error, msgtext, source, severity, msgno, msgstate);
150
164
  }
151
165
  return 0;
152
166
  }
@@ -308,6 +322,7 @@ static VALUE rb_tinytds_connect(VALUE self, VALUE opts) {
308
322
  azure = rb_hash_aref(opts, sym_azure);
309
323
  contained = rb_hash_aref(opts, sym_contained);
310
324
  use_utf16 = rb_hash_aref(opts, sym_use_utf16);
325
+ message_handler = rb_hash_aref(opts, sym_message_handler);
311
326
  /* Dealing with options. */
312
327
  if (dbinit() == FAIL) {
313
328
  rb_raise(cTinyTdsError, "failed dbinit() function");
@@ -350,6 +365,7 @@ static VALUE rb_tinytds_connect(VALUE self, VALUE opts) {
350
365
  rb_warn("TinyTds: :use_utf16 option not supported in this version of FreeTDS.\n");
351
366
  }
352
367
  #endif
368
+
353
369
  cwrap->client = dbopen(cwrap->login, StringValueCStr(dataserver));
354
370
  if (cwrap->client) {
355
371
  VALUE transposed_encoding, timeout_string;
@@ -414,6 +430,7 @@ void init_tinytds_client() {
414
430
  sym_azure = ID2SYM(rb_intern("azure"));
415
431
  sym_contained = ID2SYM(rb_intern("contained"));
416
432
  sym_use_utf16 = ID2SYM(rb_intern("use_utf16"));
433
+ sym_message_handler = ID2SYM(rb_intern("message_handler"));
417
434
  /* Intern TinyTds::Error Accessors */
418
435
  intern_source_eql = rb_intern("source=");
419
436
  intern_severity_eql = rb_intern("severity=");
@@ -425,6 +442,7 @@ void init_tinytds_client() {
425
442
  intern_transpose_iconv_encoding = rb_intern("transpose_iconv_encoding");
426
443
  intern_local_offset = rb_intern("local_offset");
427
444
  intern_gsub = rb_intern("gsub");
445
+ intern_call = rb_intern("call");
428
446
  /* Escape Regexp Global */
429
447
  opt_escape_regex = rb_funcall(rb_cRegexp, intern_new, 1, rb_str_new2("\\\'"));
430
448
  opt_escape_dblquote = rb_str_new2("''");
@@ -8,6 +8,7 @@ void init_tinytds_client();
8
8
 
9
9
  typedef struct {
10
10
  short int is_set;
11
+ int is_message;
11
12
  int cancel;
12
13
  char error[ERROR_MSG_SIZE];
13
14
  char source[ERROR_MSG_SIZE];
@@ -38,7 +39,7 @@ typedef struct {
38
39
  rb_encoding *encoding;
39
40
  } tinytds_client_wrapper;
40
41
 
41
- VALUE rb_tinytds_raise_error(DBPROCESS *dbproc, int cancel, const char *error, const char *source, int severity, int dberr, int oserr);
42
+ VALUE rb_tinytds_raise_error(DBPROCESS *dbproc, int is_message, int cancel, const char *error, const char *source, int severity, int dberr, int oserr);
42
43
 
43
44
  // Lib Macros
44
45
 
@@ -7,9 +7,9 @@ OPENSSL_SOURCE_URI = "https://www.openssl.org/source/openssl-#{OPENSSL_VERSION}.
7
7
 
8
8
  FREETDS_VERSION = ENV['TINYTDS_FREETDS_VERSION'] || "1.00.27"
9
9
  FREETDS_VERSION_INFO = Hash.new { |h,k|
10
- h[k] = {files: "ftp://ftp.freetds.org/pub/freetds/stable/freetds-#{k}.tar.bz2"}
10
+ h[k] = {files: "http://www.freetds.org/files/stable/freetds-#{k}.tar.bz2"}
11
11
  }
12
- FREETDS_VERSION_INFO['1.00'] = {files: 'ftp://ftp.freetds.org/pub/freetds/stable/freetds-1.00.tar.bz2'}
13
- FREETDS_VERSION_INFO['0.99'] = {files: 'ftp://ftp.freetds.org/pub/freetds/current/freetds-dev.0.99.678.tar.gz'}
14
- FREETDS_VERSION_INFO['0.95'] = {files: 'ftp://ftp.freetds.org/pub/freetds/stable/freetds-0.95.92.tar.gz'}
12
+ FREETDS_VERSION_INFO['1.00'] = {files: 'http://www.freetds.org/files/stable/freetds-1.00.tar.bz2'}
13
+ FREETDS_VERSION_INFO['0.99'] = {files: 'http://www.freetds.org/files/current/freetds-dev.0.99.678.tar.gz'}
14
+ FREETDS_VERSION_INFO['0.95'] = {files: 'http://www.freetds.org/files/stable/freetds-0.95.92.tar.gz'}
15
15
  FREETDS_SOURCE_URI = FREETDS_VERSION_INFO[FREETDS_VERSION][:files]
@@ -98,6 +98,7 @@ static void nogvl_cleanup(DBPROCESS *client) {
98
98
  if (userdata->nonblocking_error.is_set) {
99
99
  userdata->nonblocking_error.is_set = 0;
100
100
  rb_tinytds_raise_error(client,
101
+ userdata->nonblocking_error.is_message,
101
102
  userdata->nonblocking_error.cancel,
102
103
  userdata->nonblocking_error.error,
103
104
  userdata->nonblocking_error.source,
@@ -10,6 +10,7 @@ module TinyTds
10
10
  }
11
11
 
12
12
  attr_reader :query_options
13
+ attr_reader :message_handler
13
14
 
14
15
  class << self
15
16
 
@@ -37,6 +38,12 @@ module TinyTds
37
38
  if opts[:dataserver].to_s.empty? && opts[:host].to_s.empty?
38
39
  raise ArgumentError, 'missing :host option if no :dataserver given'
39
40
  end
41
+
42
+ @message_handler = opts[:message_handler]
43
+ if @message_handler && !@message_handler.respond_to?(:call)
44
+ raise ArgumentError, ':message_handler must implement `call` (eg, a Proc or a Method)'
45
+ end
46
+
40
47
  opts[:username] = parse_username(opts)
41
48
  @query_options = self.class.default_query_options.dup
42
49
  opts[:password] = opts[:password].to_s if opts[:password] && opts[:password].to_s.strip != ''
@@ -7,7 +7,7 @@ if [ -z "$FREETDS_VERSION" ]; then
7
7
  FREETDS_VERSION=$(ruby -r "./ext/tiny_tds/extconsts.rb" -e "puts FREETDS_VERSION")
8
8
  fi
9
9
 
10
- wget ftp://ftp.freetds.org/pub/freetds/stable/freetds-$FREETDS_VERSION.tar.gz
10
+ wget http://www.freetds.org/files/stable/freetds-$FREETDS_VERSION.tar.gz
11
11
  tar -xzf freetds-$FREETDS_VERSION.tar.gz
12
12
  cd freetds-$FREETDS_VERSION
13
13
  ./configure --prefix=/opt/local \
@@ -59,7 +59,7 @@ class ClientTest < TinyTds::TestCase
59
59
  end
60
60
 
61
61
  it 'must be able to use :host/:port connection' do
62
- host = ENV['TINYTDS_UNIT_HOST_TEST'] || ENV['TINYTDS_UNIT_HOST']
62
+ host = ENV['TINYTDS_UNIT_HOST_TEST'] || ENV['TINYTDS_UNIT_HOST'] || 'localhost'
63
63
  port = ENV['TINYTDS_UNIT_PORT_TEST'] || ENV['TINYTDS_UNIT_PORT'] || 1433
64
64
  begin
65
65
  client = new_connection dataserver: nil, host: host, port: port
@@ -614,6 +614,46 @@ class ResultTest < TinyTds::TestCase
614
614
 
615
615
  if sqlserver?
616
616
 
617
+ describe 'using :message_handler option' do
618
+ let(:messages) { Array.new }
619
+
620
+ before do
621
+ close_client
622
+ @client = new_connection message_handler: Proc.new { |m| messages << m }
623
+ end
624
+
625
+ after do
626
+ messages.clear
627
+ end
628
+
629
+ it 'has a message handler that responds to call' do
630
+ assert @client.message_handler.respond_to?(:call)
631
+ end
632
+
633
+ it 'calls the provided message handler when severity is 10 or less' do
634
+ (1..10).to_a.each do |severity|
635
+ messages.clear
636
+ msg = "Test #{severity} severity"
637
+ state = rand(1..255)
638
+ @client.execute("RAISERROR(N'#{msg}', #{severity}, #{state})").do
639
+ m = messages.first
640
+ assert_equal 1, messages.length, 'there should be one message after one raiserror'
641
+ assert_equal msg, m.message, 'message text'
642
+ assert_equal severity, m.severity, 'message severity' unless severity == 10 && m.severity.to_i == 0
643
+ assert_equal state, m.os_error_number, 'message state'
644
+ end
645
+ end
646
+
647
+ it 'calls the provided message handler for `print` messages' do
648
+ messages.clear
649
+ msg = 'hello'
650
+ @client.execute("PRINT '#{msg}'").do
651
+ m = messages.first
652
+ assert_equal 1, messages.length, 'there should be one message after one print statement'
653
+ assert_equal msg, m.message, 'message text'
654
+ end
655
+ end
656
+
617
657
  it 'must not raise an error when severity is 10 or less' do
618
658
  (1..10).to_a.each do |severity|
619
659
  @client.execute("RAISERROR(N'Test #{severity} severity', #{severity}, 1)").do
@@ -75,8 +75,8 @@ module TinyTds
75
75
  username = (sqlserver_azure? ? ENV['TINYTDS_UNIT_AZURE_USER'] : ENV['TINYTDS_UNIT_USER']) || 'tinytds'
76
76
  password = (sqlserver_azure? ? ENV['TINYTDS_UNIT_AZURE_PASS'] : ENV['TINYTDS_UNIT_PASS']) || ''
77
77
  { :dataserver => sqlserver_azure? ? nil : ENV['TINYTDS_UNIT_DATASERVER'],
78
- :host => ENV['TINYTDS_UNIT_HOST'],
79
- :port => ENV['TINYTDS_UNIT_PORT'],
78
+ :host => ENV['TINYTDS_UNIT_HOST'] || 'localhost',
79
+ :port => ENV['TINYTDS_UNIT_PORT'] || '1433',
80
80
  :tds_version => ENV['TINYTDS_UNIT_VERSION'],
81
81
  :username => username,
82
82
  :password => password,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tiny_tds
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0.pre3
4
+ version: 2.1.0.pre4
5
5
  platform: x64-mingw32
6
6
  authors:
7
7
  - Ken Collins
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2017-09-06 00:00:00.000000000 Z
13
+ date: 2017-09-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: mini_portile2