mysql2 0.4.10 → 0.5.2
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/README.md +28 -10
- data/examples/eventmachine.rb +0 -2
- data/examples/threaded.rb +2 -4
- data/ext/mysql2/client.c +100 -51
- data/ext/mysql2/client.h +1 -39
- data/ext/mysql2/extconf.rb +23 -20
- data/ext/mysql2/mysql2_ext.c +2 -1
- data/ext/mysql2/mysql2_ext.h +8 -4
- data/ext/mysql2/mysql_enc_to_ruby.h +10 -0
- data/ext/mysql2/result.c +17 -76
- data/ext/mysql2/result.h +2 -3
- data/ext/mysql2/statement.c +78 -71
- data/ext/mysql2/statement.h +0 -2
- data/ext/mysql2/wait_for_single_fd.h +2 -1
- data/lib/mysql2.rb +14 -15
- data/lib/mysql2/client.rb +33 -27
- data/lib/mysql2/em.rb +2 -4
- data/lib/mysql2/error.rb +49 -20
- data/lib/mysql2/result.rb +2 -0
- data/lib/mysql2/statement.rb +3 -9
- data/lib/mysql2/version.rb +1 -1
- data/spec/em/em_spec.rb +5 -6
- data/spec/mysql2/client_spec.rb +206 -173
- data/spec/mysql2/error_spec.rb +0 -4
- data/spec/mysql2/result_spec.rb +94 -154
- data/spec/mysql2/statement_spec.rb +105 -169
- data/spec/spec_helper.rb +6 -2
- data/support/mysql_enc_to_ruby.rb +2 -2
- data/support/ruby_enc_to_mysql.rb +5 -5
- metadata +6 -5
data/ext/mysql2/client.h
CHANGED
@@ -1,41 +1,6 @@
|
|
1
1
|
#ifndef MYSQL2_CLIENT_H
|
2
2
|
#define MYSQL2_CLIENT_H
|
3
3
|
|
4
|
-
#ifndef HAVE_RB_THREAD_CALL_WITHOUT_GVL
|
5
|
-
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
6
|
-
|
7
|
-
/* emulate rb_thread_call_without_gvl with rb_thread_blocking_region */
|
8
|
-
#define rb_thread_call_without_gvl(func, data1, ubf, data2) \
|
9
|
-
rb_thread_blocking_region((rb_blocking_function_t *)func, data1, ubf, data2)
|
10
|
-
|
11
|
-
#else /* ! HAVE_RB_THREAD_BLOCKING_REGION */
|
12
|
-
/*
|
13
|
-
* partial emulation of the 2.0 rb_thread_call_without_gvl under 1.8,
|
14
|
-
* this is enough for dealing with blocking I/O functions in the
|
15
|
-
* presence of threads.
|
16
|
-
*/
|
17
|
-
|
18
|
-
#include <rubysig.h>
|
19
|
-
#define RUBY_UBF_IO ((rb_unblock_function_t *)-1)
|
20
|
-
typedef void rb_unblock_function_t(void *);
|
21
|
-
static void *
|
22
|
-
rb_thread_call_without_gvl(
|
23
|
-
void *(*func)(void *), void *data1,
|
24
|
-
RB_MYSQL_UNUSED rb_unblock_function_t *ubf,
|
25
|
-
RB_MYSQL_UNUSED void *data2)
|
26
|
-
{
|
27
|
-
void *rv;
|
28
|
-
|
29
|
-
TRAP_BEG;
|
30
|
-
rv = func(data1);
|
31
|
-
TRAP_END;
|
32
|
-
|
33
|
-
return rv;
|
34
|
-
}
|
35
|
-
|
36
|
-
#endif /* ! HAVE_RB_THREAD_BLOCKING_REGION */
|
37
|
-
#endif /* ! HAVE_RB_THREAD_CALL_WITHOUT_GVL */
|
38
|
-
|
39
4
|
typedef struct {
|
40
5
|
VALUE encoding;
|
41
6
|
VALUE active_thread; /* rb_thread_current() or Qnil */
|
@@ -51,6 +16,7 @@ typedef struct {
|
|
51
16
|
} mysql_client_wrapper;
|
52
17
|
|
53
18
|
void rb_mysql_client_set_active_thread(VALUE self);
|
19
|
+
void rb_mysql_set_server_query_flags(MYSQL *client, VALUE result);
|
54
20
|
|
55
21
|
#define GET_CLIENT(self) \
|
56
22
|
mysql_client_wrapper *wrapper; \
|
@@ -60,7 +26,3 @@ void init_mysql2_client(void);
|
|
60
26
|
void decr_mysql2_client(mysql_client_wrapper *wrapper);
|
61
27
|
|
62
28
|
#endif
|
63
|
-
|
64
|
-
#ifndef HAVE_RB_HASH_DUP
|
65
|
-
VALUE rb_hash_dup(VALUE other);
|
66
|
-
#endif
|
data/ext/mysql2/extconf.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: UTF-8
|
2
1
|
require 'mkmf'
|
3
2
|
require 'English'
|
4
3
|
|
@@ -13,7 +12,7 @@ def asplode(lib)
|
|
13
12
|
end
|
14
13
|
|
15
14
|
def add_ssl_defines(header)
|
16
|
-
all_modes_found = %w
|
15
|
+
all_modes_found = %w[SSL_MODE_DISABLED SSL_MODE_PREFERRED SSL_MODE_REQUIRED SSL_MODE_VERIFY_CA SSL_MODE_VERIFY_IDENTITY].inject(true) do |m, ssl_mode|
|
17
16
|
m && have_const(ssl_mode, header)
|
18
17
|
end
|
19
18
|
$CFLAGS << ' -DFULL_SSL_MODE_SUPPORT' if all_modes_found
|
@@ -26,19 +25,12 @@ end
|
|
26
25
|
have_func('rb_absint_size')
|
27
26
|
have_func('rb_absint_singlebit_p')
|
28
27
|
|
29
|
-
#
|
30
|
-
have_header('ruby/thread.h') && have_func('rb_thread_call_without_gvl', 'ruby/thread.h')
|
31
|
-
|
32
|
-
# 1.9-only
|
33
|
-
have_func('rb_thread_blocking_region')
|
28
|
+
# Missing in RBX (https://github.com/rubinius/rubinius/issues/3771)
|
34
29
|
have_func('rb_wait_for_single_fd')
|
35
|
-
have_func('rb_hash_dup')
|
36
|
-
have_func('rb_intern3')
|
37
|
-
have_func('rb_big_cmp')
|
38
30
|
|
39
31
|
# borrowed from mysqlplus
|
40
32
|
# http://github.com/oldmoe/mysqlplus/blob/master/ext/extconf.rb
|
41
|
-
dirs = ENV.fetch('PATH').split(File::PATH_SEPARATOR) + %w
|
33
|
+
dirs = ENV.fetch('PATH').split(File::PATH_SEPARATOR) + %w[
|
42
34
|
/opt
|
43
35
|
/opt/local
|
44
36
|
/opt/local/mysql
|
@@ -50,20 +42,19 @@ dirs = ENV.fetch('PATH').split(File::PATH_SEPARATOR) + %w(
|
|
50
42
|
/usr/local/mysql-*
|
51
43
|
/usr/local/lib/mysql5*
|
52
44
|
/usr/local/opt/mysql5*
|
53
|
-
|
45
|
+
].map { |dir| dir << '/bin' }
|
54
46
|
|
55
47
|
# For those without HOMEBREW_ROOT in PATH
|
56
48
|
dirs << "#{ENV['HOMEBREW_ROOT']}/bin" if ENV['HOMEBREW_ROOT']
|
57
49
|
|
58
|
-
GLOB = "{#{dirs.join(',')}}/{mysql_config,mysql_config5,mariadb_config}"
|
50
|
+
GLOB = "{#{dirs.join(',')}}/{mysql_config,mysql_config5,mariadb_config}".freeze
|
59
51
|
|
60
52
|
# If the user has provided a --with-mysql-dir argument, we must respect it or fail.
|
61
53
|
inc, lib = dir_config('mysql')
|
62
54
|
if inc && lib
|
63
|
-
#
|
64
|
-
#
|
55
|
+
# Ruby versions below 2.0 on Unix and below 2.1 on Windows
|
56
|
+
# do not properly search for lib directories, and must be corrected:
|
65
57
|
# https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/39717
|
66
|
-
# do not properly search for lib directories, and must be corrected
|
67
58
|
unless lib && lib[-3, 3] == 'lib'
|
68
59
|
@libdir_basename = 'lib'
|
69
60
|
inc, lib = dir_config('mysql')
|
@@ -72,6 +63,7 @@ if inc && lib
|
|
72
63
|
abort "-----\nCannot find library dir(s) #{lib}\n-----" unless lib && lib.split(File::PATH_SEPARATOR).any? { |dir| File.directory?(dir) }
|
73
64
|
warn "-----\nUsing --with-mysql-dir=#{File.dirname inc}\n-----"
|
74
65
|
rpath_dir = lib
|
66
|
+
have_library('mysqlclient')
|
75
67
|
elsif (mc = (with_config('mysql-config') || Dir[GLOB].first))
|
76
68
|
# If the user has provided a --with-mysql-config argument, we must respect it or fail.
|
77
69
|
# If the user gave --with-mysql-config with no argument means we should try to find it.
|
@@ -92,7 +84,7 @@ elsif (mc = (with_config('mysql-config') || Dir[GLOB].first))
|
|
92
84
|
else
|
93
85
|
_, usr_local_lib = dir_config('mysql', '/usr/local')
|
94
86
|
|
95
|
-
asplode("mysql client") unless find_library('mysqlclient',
|
87
|
+
asplode("mysql client") unless find_library('mysqlclient', nil, usr_local_lib, "#{usr_local_lib}/mysql")
|
96
88
|
|
97
89
|
rpath_dir = usr_local_lib
|
98
90
|
end
|
@@ -105,7 +97,7 @@ else
|
|
105
97
|
asplode 'mysql.h'
|
106
98
|
end
|
107
99
|
|
108
|
-
%w
|
100
|
+
%w[errmsg.h].each do |h|
|
109
101
|
header = [prefix, h].compact.join('/')
|
110
102
|
asplode h unless have_header header
|
111
103
|
end
|
@@ -114,7 +106,18 @@ mysql_h = [prefix, 'mysql.h'].compact.join('/')
|
|
114
106
|
add_ssl_defines(mysql_h)
|
115
107
|
have_struct_member('MYSQL', 'net.vio', mysql_h)
|
116
108
|
have_struct_member('MYSQL', 'net.pvio', mysql_h)
|
109
|
+
|
110
|
+
# These constants are actually enums, so they cannot be detected by #ifdef in C code.
|
117
111
|
have_const('MYSQL_ENABLE_CLEARTEXT_PLUGIN', mysql_h)
|
112
|
+
have_const('SERVER_QUERY_NO_GOOD_INDEX_USED', mysql_h)
|
113
|
+
have_const('SERVER_QUERY_NO_INDEX_USED', mysql_h)
|
114
|
+
have_const('SERVER_QUERY_WAS_SLOW', mysql_h)
|
115
|
+
have_const('MYSQL_OPTION_MULTI_STATEMENTS_ON', mysql_h)
|
116
|
+
have_const('MYSQL_OPTION_MULTI_STATEMENTS_OFF', mysql_h)
|
117
|
+
|
118
|
+
# my_bool is replaced by C99 bool in MySQL 8.0, but we want
|
119
|
+
# to retain compatibility with the typedef in earlier MySQLs.
|
120
|
+
have_type('my_bool', mysql_h)
|
118
121
|
|
119
122
|
# This is our wishlist. We use whichever flags work on the host.
|
120
123
|
# -Wall and -Wextra are included by default.
|
@@ -150,7 +153,7 @@ sanitizers = with_config('sanitize')
|
|
150
153
|
case sanitizers
|
151
154
|
when true
|
152
155
|
# Try them all, turn on whatever we can
|
153
|
-
enabled_sanitizers = %w
|
156
|
+
enabled_sanitizers = %w[address cfi integer memory thread undefined].select do |s|
|
154
157
|
try_link('int main() {return 0;}', "-Werror -fsanitize=#{s}")
|
155
158
|
end
|
156
159
|
abort "-----\nCould not enable any sanitizers!\n-----" if enabled_sanitizers.empty?
|
@@ -178,7 +181,7 @@ unless enabled_sanitizers.empty?
|
|
178
181
|
$CFLAGS << ' -g -fno-omit-frame-pointer'
|
179
182
|
end
|
180
183
|
|
181
|
-
if RUBY_PLATFORM =~ /mswin|mingw/
|
184
|
+
if RUBY_PLATFORM =~ /mswin|mingw/ && !defined?(RubyInstaller)
|
182
185
|
# Build libmysql.a interface link library
|
183
186
|
require 'rake'
|
184
187
|
|
data/ext/mysql2/mysql2_ext.c
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
#include <mysql2_ext.h>
|
2
2
|
|
3
|
-
VALUE mMysql2, cMysql2Error;
|
3
|
+
VALUE mMysql2, cMysql2Error, cMysql2TimeoutError;
|
4
4
|
|
5
5
|
/* Ruby Extension initializer */
|
6
6
|
void Init_mysql2() {
|
7
7
|
mMysql2 = rb_define_module("Mysql2");
|
8
8
|
cMysql2Error = rb_const_get(mMysql2, rb_intern("Error"));
|
9
|
+
cMysql2TimeoutError = rb_const_get(cMysql2Error, rb_intern("TimeoutError"));
|
9
10
|
|
10
11
|
init_mysql2_client();
|
11
12
|
init_mysql2_result();
|
data/ext/mysql2/mysql2_ext.h
CHANGED
@@ -17,12 +17,8 @@ void Init_mysql2(void);
|
|
17
17
|
#include <mysql/errmsg.h>
|
18
18
|
#endif
|
19
19
|
|
20
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
21
20
|
#include <ruby/encoding.h>
|
22
|
-
#endif
|
23
|
-
#ifdef HAVE_RUBY_THREAD_H
|
24
21
|
#include <ruby/thread.h>
|
25
|
-
#endif
|
26
22
|
|
27
23
|
#if defined(__GNUC__) && (__GNUC__ >= 3)
|
28
24
|
#define RB_MYSQL_NORETURN __attribute__ ((noreturn))
|
@@ -32,6 +28,14 @@ void Init_mysql2(void);
|
|
32
28
|
#define RB_MYSQL_UNUSED
|
33
29
|
#endif
|
34
30
|
|
31
|
+
/* MySQL 8.0 replaces my_bool with C99 bool. Earlier versions of MySQL had
|
32
|
+
* a typedef to char. Gem users reported failures on big endian systems when
|
33
|
+
* using C99 bool types with older MySQLs due to mismatched behavior. */
|
34
|
+
#ifndef HAVE_TYPE_MY_BOOL
|
35
|
+
#include <stdbool.h>
|
36
|
+
typedef bool my_bool;
|
37
|
+
#endif
|
38
|
+
|
35
39
|
#include <client.h>
|
36
40
|
#include <statement.h>
|
37
41
|
#include <result.h>
|
@@ -245,5 +245,15 @@ static const char *mysql2_mysql_enc_to_rb[] = {
|
|
245
245
|
"UTF-8",
|
246
246
|
"UTF-8",
|
247
247
|
"UTF-8",
|
248
|
+
"UTF-8",
|
249
|
+
NULL,
|
250
|
+
NULL,
|
251
|
+
NULL,
|
252
|
+
NULL,
|
253
|
+
NULL,
|
254
|
+
NULL,
|
255
|
+
NULL,
|
248
256
|
"UTF-8"
|
249
257
|
};
|
258
|
+
|
259
|
+
#define CHARSETNR_SIZE (sizeof(mysql2_mysql_enc_to_rb)/sizeof(mysql2_mysql_enc_to_rb[0]))
|
data/ext/mysql2/result.c
CHANGED
@@ -2,51 +2,19 @@
|
|
2
2
|
|
3
3
|
#include "mysql_enc_to_ruby.h"
|
4
4
|
|
5
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
6
5
|
static rb_encoding *binaryEncoding;
|
7
|
-
#endif
|
8
6
|
|
9
|
-
#if (SIZEOF_INT < SIZEOF_LONG) || defined(HAVE_RUBY_ENCODING_H)
|
10
7
|
/* on 64bit platforms we can handle dates way outside 2038-01-19T03:14:07
|
11
8
|
*
|
12
9
|
* (9999*31557600) + (12*2592000) + (31*86400) + (11*3600) + (59*60) + 59
|
13
10
|
*/
|
14
11
|
#define MYSQL2_MAX_TIME 315578267999ULL
|
15
|
-
#else
|
16
|
-
/**
|
17
|
-
* On 32bit platforms the maximum date the Time class can handle is 2038-01-19T03:14:07
|
18
|
-
* 2038 years + 1 month + 19 days + 3 hours + 14 minutes + 7 seconds = 64318634047 seconds
|
19
|
-
*
|
20
|
-
* (2038*31557600) + (1*2592000) + (19*86400) + (3*3600) + (14*60) + 7
|
21
|
-
*/
|
22
|
-
#define MYSQL2_MAX_TIME 64318634047ULL
|
23
|
-
#endif
|
24
12
|
|
25
|
-
#if defined(HAVE_RUBY_ENCODING_H)
|
26
13
|
/* 0000-1-1 00:00:00 UTC
|
27
14
|
*
|
28
15
|
* (0*31557600) + (1*2592000) + (1*86400) + (0*3600) + (0*60) + 0
|
29
16
|
*/
|
30
17
|
#define MYSQL2_MIN_TIME 2678400ULL
|
31
|
-
#elif SIZEOF_INT < SIZEOF_LONG /* 64bit Ruby 1.8 */
|
32
|
-
/* 0139-1-1 00:00:00 UTC
|
33
|
-
*
|
34
|
-
* (139*31557600) + (1*2592000) + (1*86400) + (0*3600) + (0*60) + 0
|
35
|
-
*/
|
36
|
-
#define MYSQL2_MIN_TIME 4389184800ULL
|
37
|
-
#elif defined(NEGATIVE_TIME_T)
|
38
|
-
/* 1901-12-13 20:45:52 UTC : The oldest time in 32-bit signed time_t.
|
39
|
-
*
|
40
|
-
* (1901*31557600) + (12*2592000) + (13*86400) + (20*3600) + (45*60) + 52
|
41
|
-
*/
|
42
|
-
#define MYSQL2_MIN_TIME 60023299552ULL
|
43
|
-
#else
|
44
|
-
/* 1970-01-01 00:00:01 UTC : The Unix epoch - the oldest time in portable time_t.
|
45
|
-
*
|
46
|
-
* (1970*31557600) + (1*2592000) + (1*86400) + (0*3600) + (0*60) + 1
|
47
|
-
*/
|
48
|
-
#define MYSQL2_MIN_TIME 62171150401ULL
|
49
|
-
#endif
|
50
18
|
|
51
19
|
#define GET_RESULT(self) \
|
52
20
|
mysql2_result_wrapper *wrapper; \
|
@@ -64,14 +32,14 @@ typedef struct {
|
|
64
32
|
VALUE block_given;
|
65
33
|
} result_each_args;
|
66
34
|
|
67
|
-
VALUE cBigDecimal, cDateTime, cDate;
|
68
|
-
static VALUE cMysql2Result;
|
69
|
-
static VALUE opt_decimal_zero, opt_float_zero, opt_time_year, opt_time_month, opt_utc_offset;
|
70
35
|
extern VALUE mMysql2, cMysql2Client, cMysql2Error;
|
71
|
-
static
|
72
|
-
static VALUE
|
73
|
-
|
74
|
-
|
36
|
+
static VALUE cMysql2Result, cDateTime, cDate;
|
37
|
+
static VALUE opt_decimal_zero, opt_float_zero, opt_time_year, opt_time_month, opt_utc_offset;
|
38
|
+
static ID intern_new, intern_utc, intern_local, intern_localtime, intern_local_offset,
|
39
|
+
intern_civil, intern_new_offset, intern_merge, intern_BigDecimal;
|
40
|
+
static VALUE sym_symbolize_keys, sym_as, sym_array, sym_database_timezone,
|
41
|
+
sym_application_timezone, sym_local, sym_utc, sym_cast_booleans,
|
42
|
+
sym_cache_rows, sym_cast, sym_stream, sym_name;
|
75
43
|
|
76
44
|
/* Mark any VALUEs that are only referenced in C, so the GC won't get them. */
|
77
45
|
static void rb_mysql_result_mark(void * wrapper) {
|
@@ -179,29 +147,19 @@ static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, int symbo
|
|
179
147
|
rb_field = rb_ary_entry(wrapper->fields, idx);
|
180
148
|
if (rb_field == Qnil) {
|
181
149
|
MYSQL_FIELD *field = NULL;
|
182
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
183
150
|
rb_encoding *default_internal_enc = rb_default_internal_encoding();
|
184
151
|
rb_encoding *conn_enc = rb_to_encoding(wrapper->encoding);
|
185
|
-
#endif
|
186
152
|
|
187
153
|
field = mysql_fetch_field_direct(wrapper->result, idx);
|
188
154
|
if (symbolize_keys) {
|
189
|
-
#ifdef HAVE_RB_INTERN3
|
190
155
|
rb_field = rb_intern3(field->name, field->name_length, rb_utf8_encoding());
|
191
156
|
rb_field = ID2SYM(rb_field);
|
192
|
-
#else
|
193
|
-
VALUE colStr;
|
194
|
-
colStr = rb_str_new(field->name, field->name_length);
|
195
|
-
rb_field = ID2SYM(rb_to_id(colStr));
|
196
|
-
#endif
|
197
157
|
} else {
|
198
158
|
rb_field = rb_str_new(field->name, field->name_length);
|
199
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
200
159
|
rb_enc_associate(rb_field, conn_enc);
|
201
160
|
if (default_internal_enc) {
|
202
161
|
rb_field = rb_str_export_to_enc(rb_field, default_internal_enc);
|
203
162
|
}
|
204
|
-
#endif
|
205
163
|
}
|
206
164
|
rb_ary_store(wrapper->fields, idx, rb_field);
|
207
165
|
}
|
@@ -209,7 +167,6 @@ static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, int symbo
|
|
209
167
|
return rb_field;
|
210
168
|
}
|
211
169
|
|
212
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
213
170
|
static VALUE mysql2_set_field_string_encoding(VALUE val, MYSQL_FIELD field, rb_encoding *default_internal_enc, rb_encoding *conn_enc) {
|
214
171
|
/* if binary flag is set, respect its wishes */
|
215
172
|
if (field.flags & BINARY_FLAG && field.charsetnr == 63) {
|
@@ -222,7 +179,8 @@ static VALUE mysql2_set_field_string_encoding(VALUE val, MYSQL_FIELD field, rb_e
|
|
222
179
|
const char *enc_name;
|
223
180
|
int enc_index;
|
224
181
|
|
225
|
-
enc_name = mysql2_mysql_enc_to_rb[field.charsetnr-1];
|
182
|
+
enc_name = (field.charsetnr-1 < CHARSETNR_SIZE) ? mysql2_mysql_enc_to_rb[field.charsetnr-1] : NULL;
|
183
|
+
|
226
184
|
if (enc_name != NULL) {
|
227
185
|
/* use the field encoding we were able to match */
|
228
186
|
enc_index = rb_enc_find_index(enc_name);
|
@@ -238,7 +196,6 @@ static VALUE mysql2_set_field_string_encoding(VALUE val, MYSQL_FIELD field, rb_e
|
|
238
196
|
}
|
239
197
|
return val;
|
240
198
|
}
|
241
|
-
#endif
|
242
199
|
|
243
200
|
/* Interpret microseconds digits left-aligned in fixed-width field.
|
244
201
|
* e.g. 10.123 seconds means 10 seconds and 123000 microseconds,
|
@@ -262,8 +219,8 @@ static void rb_mysql_result_alloc_result_buffers(VALUE self, MYSQL_FIELD *fields
|
|
262
219
|
if (wrapper->result_buffers != NULL) return;
|
263
220
|
|
264
221
|
wrapper->result_buffers = xcalloc(wrapper->numberOfFields, sizeof(MYSQL_BIND));
|
265
|
-
wrapper->is_null = xcalloc(wrapper->numberOfFields, sizeof(
|
266
|
-
wrapper->error = xcalloc(wrapper->numberOfFields, sizeof(
|
222
|
+
wrapper->is_null = xcalloc(wrapper->numberOfFields, sizeof(my_bool));
|
223
|
+
wrapper->error = xcalloc(wrapper->numberOfFields, sizeof(my_bool));
|
267
224
|
wrapper->length = xcalloc(wrapper->numberOfFields, sizeof(unsigned long));
|
268
225
|
|
269
226
|
for (i = 0; i < wrapper->numberOfFields; i++) {
|
@@ -278,12 +235,12 @@ static void rb_mysql_result_alloc_result_buffers(VALUE self, MYSQL_FIELD *fields
|
|
278
235
|
wrapper->result_buffers[i].buffer_length = sizeof(signed char);
|
279
236
|
break;
|
280
237
|
case MYSQL_TYPE_SHORT: // short int
|
238
|
+
case MYSQL_TYPE_YEAR: // short int
|
281
239
|
wrapper->result_buffers[i].buffer = xcalloc(1, sizeof(short int));
|
282
240
|
wrapper->result_buffers[i].buffer_length = sizeof(short int);
|
283
241
|
break;
|
284
242
|
case MYSQL_TYPE_INT24: // int
|
285
243
|
case MYSQL_TYPE_LONG: // int
|
286
|
-
case MYSQL_TYPE_YEAR: // int
|
287
244
|
wrapper->result_buffers[i].buffer = xcalloc(1, sizeof(int));
|
288
245
|
wrapper->result_buffers[i].buffer_length = sizeof(int);
|
289
246
|
break;
|
@@ -335,16 +292,12 @@ static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, co
|
|
335
292
|
VALUE rowVal;
|
336
293
|
unsigned int i = 0;
|
337
294
|
|
338
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
339
295
|
rb_encoding *default_internal_enc;
|
340
296
|
rb_encoding *conn_enc;
|
341
|
-
#endif
|
342
297
|
GET_RESULT(self);
|
343
298
|
|
344
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
345
299
|
default_internal_enc = rb_default_internal_encoding();
|
346
300
|
conn_enc = rb_to_encoding(wrapper->encoding);
|
347
|
-
#endif
|
348
301
|
|
349
302
|
if (wrapper->fields == Qnil) {
|
350
303
|
wrapper->numberOfFields = mysql_num_fields(wrapper->result);
|
@@ -413,6 +366,7 @@ static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, co
|
|
413
366
|
}
|
414
367
|
break;
|
415
368
|
case MYSQL_TYPE_SHORT: // short int
|
369
|
+
case MYSQL_TYPE_YEAR: // short int
|
416
370
|
if (result_buffer->is_unsigned) {
|
417
371
|
val = UINT2NUM(*((unsigned short int*)result_buffer->buffer));
|
418
372
|
} else {
|
@@ -421,7 +375,6 @@ static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, co
|
|
421
375
|
break;
|
422
376
|
case MYSQL_TYPE_INT24: // int
|
423
377
|
case MYSQL_TYPE_LONG: // int
|
424
|
-
case MYSQL_TYPE_YEAR: // int
|
425
378
|
if (result_buffer->is_unsigned) {
|
426
379
|
val = UINT2NUM(*((unsigned int*)result_buffer->buffer));
|
427
380
|
} else {
|
@@ -492,7 +445,7 @@ static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, co
|
|
492
445
|
}
|
493
446
|
case MYSQL_TYPE_DECIMAL: // char[]
|
494
447
|
case MYSQL_TYPE_NEWDECIMAL: // char[]
|
495
|
-
val = rb_funcall(
|
448
|
+
val = rb_funcall(rb_mKernel, intern_BigDecimal, 1, rb_str_new(result_buffer->buffer, *(result_buffer->length)));
|
496
449
|
break;
|
497
450
|
case MYSQL_TYPE_STRING: // char[]
|
498
451
|
case MYSQL_TYPE_VAR_STRING: // char[]
|
@@ -506,9 +459,7 @@ static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, co
|
|
506
459
|
case MYSQL_TYPE_GEOMETRY: // char[]
|
507
460
|
default:
|
508
461
|
val = rb_str_new(result_buffer->buffer, *(result_buffer->length));
|
509
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
510
462
|
val = mysql2_set_field_string_encoding(val, fields[i], default_internal_enc, conn_enc);
|
511
|
-
#endif
|
512
463
|
break;
|
513
464
|
}
|
514
465
|
}
|
@@ -530,16 +481,12 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, MYSQL_FIELD * fields, const r
|
|
530
481
|
unsigned int i = 0;
|
531
482
|
unsigned long * fieldLengths;
|
532
483
|
void * ptr;
|
533
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
534
484
|
rb_encoding *default_internal_enc;
|
535
485
|
rb_encoding *conn_enc;
|
536
|
-
#endif
|
537
486
|
GET_RESULT(self);
|
538
487
|
|
539
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
540
488
|
default_internal_enc = rb_default_internal_encoding();
|
541
489
|
conn_enc = rb_to_encoding(wrapper->encoding);
|
542
|
-
#endif
|
543
490
|
|
544
491
|
ptr = wrapper->result;
|
545
492
|
row = (MYSQL_ROW)rb_thread_call_without_gvl(nogvl_fetch_row, ptr, RUBY_UBF_IO, 0);
|
@@ -569,9 +516,7 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, MYSQL_FIELD * fields, const r
|
|
569
516
|
val = Qnil;
|
570
517
|
} else {
|
571
518
|
val = rb_str_new(row[i], fieldLengths[i]);
|
572
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
573
519
|
val = mysql2_set_field_string_encoding(val, fields[i], default_internal_enc, conn_enc);
|
574
|
-
#endif
|
575
520
|
}
|
576
521
|
} else {
|
577
522
|
switch(type) {
|
@@ -602,9 +547,9 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, MYSQL_FIELD * fields, const r
|
|
602
547
|
if (fields[i].decimals == 0) {
|
603
548
|
val = rb_cstr2inum(row[i], 10);
|
604
549
|
} else if (strtod(row[i], NULL) == 0.000000){
|
605
|
-
val = rb_funcall(
|
550
|
+
val = rb_funcall(rb_mKernel, intern_BigDecimal, 1, opt_decimal_zero);
|
606
551
|
}else{
|
607
|
-
val = rb_funcall(
|
552
|
+
val = rb_funcall(rb_mKernel, intern_BigDecimal, 1, rb_str_new(row[i], fieldLengths[i]));
|
608
553
|
}
|
609
554
|
break;
|
610
555
|
case MYSQL_TYPE_FLOAT: /* FLOAT field */
|
@@ -722,9 +667,7 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, MYSQL_FIELD * fields, const r
|
|
722
667
|
case MYSQL_TYPE_GEOMETRY: /* Spatial fielda */
|
723
668
|
default:
|
724
669
|
val = rb_str_new(row[i], fieldLengths[i]);
|
725
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
726
670
|
val = mysql2_set_field_string_encoding(val, fields[i], default_internal_enc, conn_enc);
|
727
|
-
#endif
|
728
671
|
break;
|
729
672
|
}
|
730
673
|
}
|
@@ -1017,7 +960,6 @@ VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_
|
|
1017
960
|
}
|
1018
961
|
|
1019
962
|
void init_mysql2_result() {
|
1020
|
-
cBigDecimal = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
|
1021
963
|
cDate = rb_const_get(rb_cObject, rb_intern("Date"));
|
1022
964
|
cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime"));
|
1023
965
|
|
@@ -1036,6 +978,7 @@ void init_mysql2_result() {
|
|
1036
978
|
intern_local_offset = rb_intern("local_offset");
|
1037
979
|
intern_civil = rb_intern("civil");
|
1038
980
|
intern_new_offset = rb_intern("new_offset");
|
981
|
+
intern_BigDecimal = rb_intern("BigDecimal");
|
1039
982
|
|
1040
983
|
sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys"));
|
1041
984
|
sym_as = ID2SYM(rb_intern("as"));
|
@@ -1058,7 +1001,5 @@ void init_mysql2_result() {
|
|
1058
1001
|
opt_time_month = INT2NUM(1);
|
1059
1002
|
opt_utc_offset = INT2NUM(0);
|
1060
1003
|
|
1061
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
1062
1004
|
binaryEncoding = rb_enc_find("binary");
|
1063
|
-
#endif
|
1064
1005
|
}
|