mysql2 0.3.12b4 → 0.3.12b5
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.md +32 -0
- data/README.md +15 -9
- data/ext/mysql2/client.c +146 -74
- data/ext/mysql2/extconf.rb +1 -0
- data/ext/mysql2/mysql2_ext.h +3 -3
- data/ext/mysql2/mysql_enc_name_to_ruby.h +168 -0
- data/ext/mysql2/mysql_enc_to_ruby.h +246 -0
- data/ext/mysql2/result.c +64 -59
- data/lib/mysql2.rb +2 -2
- data/lib/mysql2/client.rb +9 -210
- data/lib/mysql2/version.rb +1 -1
- data/spec/mysql2/client_spec.rb +123 -14
- data/spec/mysql2/error_spec.rb +1 -1
- data/spec/mysql2/result_spec.rb +2 -2
- data/support/mysql_enc_to_ruby.rb +82 -0
- data/support/ruby_enc_to_mysql.rb +61 -0
- metadata +19 -116
- data/.gitignore +0 -14
- data/.rbenv-version +0 -1
- data/.rspec +0 -3
- data/.rvmrc +0 -1
- data/.travis.yml +0 -7
- data/Gemfile +0 -3
- data/Gemfile.lock +0 -61
- data/Rakefile +0 -5
- data/benchmark/active_record.rb +0 -51
- data/benchmark/active_record_threaded.rb +0 -42
- data/benchmark/allocations.rb +0 -33
- data/benchmark/escape.rb +0 -36
- data/benchmark/query_with_mysql_casting.rb +0 -80
- data/benchmark/query_without_mysql_casting.rb +0 -56
- data/benchmark/sequel.rb +0 -37
- data/benchmark/setup_db.rb +0 -119
- data/benchmark/threaded.rb +0 -44
- data/mysql2.gemspec +0 -29
- data/tasks/benchmarks.rake +0 -20
- data/tasks/compile.rake +0 -71
- data/tasks/rspec.rake +0 -26
- data/tasks/vendor_mysql.rake +0 -40
data/ext/mysql2/extconf.rb
CHANGED
data/ext/mysql2/mysql2_ext.h
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
#ifndef MYSQL2_EXT
|
2
2
|
#define MYSQL2_EXT
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
/* tell rbx not to use it's caching compat layer
|
5
|
+
by doing this we're making a promise to RBX that
|
6
|
+
we'll never modify the pointers we get back from RSTRING_PTR */
|
7
7
|
#define RSTRING_NOT_MODIFIED
|
8
8
|
#include <ruby.h>
|
9
9
|
#include <fcntl.h>
|
@@ -0,0 +1,168 @@
|
|
1
|
+
/* C code produced by gperf version 3.0.3 */
|
2
|
+
/* Command-line: gperf */
|
3
|
+
/* Computed positions: -k'1,3,$' */
|
4
|
+
|
5
|
+
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
|
6
|
+
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
|
7
|
+
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
|
8
|
+
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
|
9
|
+
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
|
10
|
+
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
|
11
|
+
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
|
12
|
+
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
|
13
|
+
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
|
14
|
+
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
|
15
|
+
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
|
16
|
+
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
|
17
|
+
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
|
18
|
+
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
|
19
|
+
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
|
20
|
+
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
|
21
|
+
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
|
22
|
+
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
|
23
|
+
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
|
24
|
+
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
|
25
|
+
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
|
26
|
+
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
|
27
|
+
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
|
28
|
+
/* The character set is not based on ISO-646. */
|
29
|
+
error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
|
30
|
+
#endif
|
31
|
+
|
32
|
+
struct mysql2_mysql_enc_name_to_rb_map { const char *name; const char *rb_name; };
|
33
|
+
/* maximum key range = 66, duplicates = 0 */
|
34
|
+
|
35
|
+
#ifdef __GNUC__
|
36
|
+
__inline
|
37
|
+
#else
|
38
|
+
#ifdef __cplusplus
|
39
|
+
inline
|
40
|
+
#endif
|
41
|
+
#endif
|
42
|
+
static unsigned int
|
43
|
+
mysql2_mysql_enc_name_to_rb_hash (str, len)
|
44
|
+
register const char *str;
|
45
|
+
register unsigned int len;
|
46
|
+
{
|
47
|
+
static const unsigned char asso_values[] =
|
48
|
+
{
|
49
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
50
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
51
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
52
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
53
|
+
69, 69, 69, 69, 69, 69, 69, 69, 40, 5,
|
54
|
+
0, 69, 0, 40, 25, 20, 10, 55, 69, 69,
|
55
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
56
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
57
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
58
|
+
69, 69, 69, 69, 69, 69, 69, 35, 5, 0,
|
59
|
+
10, 0, 20, 0, 5, 5, 69, 0, 10, 15,
|
60
|
+
0, 0, 69, 69, 25, 5, 5, 0, 69, 30,
|
61
|
+
69, 0, 69, 69, 69, 69, 69, 69, 69, 69,
|
62
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
63
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
64
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
65
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
66
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
67
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
68
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
69
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
70
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
71
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
72
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
73
|
+
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
|
74
|
+
69, 69, 69, 69, 69, 69
|
75
|
+
};
|
76
|
+
return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];
|
77
|
+
}
|
78
|
+
|
79
|
+
#ifdef __GNUC__
|
80
|
+
__inline
|
81
|
+
#ifdef __GNUC_STDC_INLINE__
|
82
|
+
__attribute__ ((__gnu_inline__))
|
83
|
+
#endif
|
84
|
+
#endif
|
85
|
+
const struct mysql2_mysql_enc_name_to_rb_map *
|
86
|
+
mysql2_mysql_enc_name_to_rb (str, len)
|
87
|
+
register const char *str;
|
88
|
+
register unsigned int len;
|
89
|
+
{
|
90
|
+
enum
|
91
|
+
{
|
92
|
+
TOTAL_KEYWORDS = 39,
|
93
|
+
MIN_WORD_LENGTH = 3,
|
94
|
+
MAX_WORD_LENGTH = 8,
|
95
|
+
MIN_HASH_VALUE = 3,
|
96
|
+
MAX_HASH_VALUE = 68
|
97
|
+
};
|
98
|
+
|
99
|
+
static const struct mysql2_mysql_enc_name_to_rb_map wordlist[] =
|
100
|
+
{
|
101
|
+
{""}, {""}, {""},
|
102
|
+
{"gbk", "GBK"},
|
103
|
+
{""},
|
104
|
+
{"greek", "ISO-8859-7"},
|
105
|
+
{"gb2312", "GB2312"},
|
106
|
+
{"keybcs2", NULL},
|
107
|
+
{""},
|
108
|
+
{"ucs2", "UTF-16BE"},
|
109
|
+
{"koi8u", "KOI8-R"},
|
110
|
+
{"binary", "ASCII-8BIT"},
|
111
|
+
{"eucjpms", "eucJP-ms"},
|
112
|
+
{""},
|
113
|
+
{"ujis", "eucJP-ms"},
|
114
|
+
{"cp852", "CP852"},
|
115
|
+
{"cp1251", "Windows-1251"},
|
116
|
+
{"geostd8", NULL},
|
117
|
+
{""},
|
118
|
+
{"sjis", "Shift_JIS"},
|
119
|
+
{"macce", "macCentEuro"},
|
120
|
+
{"latin2", "ISO-8859-2"},
|
121
|
+
{""},
|
122
|
+
{"macroman", "macRoman"},
|
123
|
+
{"dec8", NULL},
|
124
|
+
{"utf32", "UTF-32"},
|
125
|
+
{"latin1", "ISO-8859-1"},
|
126
|
+
{"utf8mb4", "UTF-8"},
|
127
|
+
{"hp8", NULL},
|
128
|
+
{"swe7", NULL},
|
129
|
+
{"euckr", "EUC-KR"},
|
130
|
+
{"cp1257", "Windows-1257"},
|
131
|
+
{""}, {""},
|
132
|
+
{"utf8", "UTF-8"},
|
133
|
+
{"koi8r", "KOI8-R"},
|
134
|
+
{"cp1256", "Windows-1256"},
|
135
|
+
{""}, {""}, {""},
|
136
|
+
{"cp866", "IBM866"},
|
137
|
+
{"latin7", "ISO-8859-13"},
|
138
|
+
{""}, {""}, {""},
|
139
|
+
{"ascii", "US-ASCII"},
|
140
|
+
{"hebrew", "ISO-8859-8"},
|
141
|
+
{""}, {""},
|
142
|
+
{"big5", "Big5"},
|
143
|
+
{"utf16", "UTF-16"},
|
144
|
+
{"cp1250", "Windows-1250"},
|
145
|
+
{""}, {""}, {""},
|
146
|
+
{"cp850", "CP850"},
|
147
|
+
{"tis620", "TIS-620"},
|
148
|
+
{""}, {""}, {""},
|
149
|
+
{"cp932", "Windows-31J"},
|
150
|
+
{"latin5", "ISO-8859-9"},
|
151
|
+
{""}, {""}, {""}, {""}, {""}, {""},
|
152
|
+
{"armscii8", NULL}
|
153
|
+
};
|
154
|
+
|
155
|
+
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
|
156
|
+
{
|
157
|
+
register int key = mysql2_mysql_enc_name_to_rb_hash (str, len);
|
158
|
+
|
159
|
+
if (key <= MAX_HASH_VALUE && key >= 0)
|
160
|
+
{
|
161
|
+
register const char *s = wordlist[key].name;
|
162
|
+
|
163
|
+
if (*str == *s && !strcmp (str + 1, s + 1))
|
164
|
+
return &wordlist[key];
|
165
|
+
}
|
166
|
+
}
|
167
|
+
return 0;
|
168
|
+
}
|
@@ -0,0 +1,246 @@
|
|
1
|
+
const char *mysql2_mysql_enc_to_rb[] = {
|
2
|
+
"Big5",
|
3
|
+
"ISO-8859-2",
|
4
|
+
NULL,
|
5
|
+
"CP850",
|
6
|
+
"ISO-8859-1",
|
7
|
+
NULL,
|
8
|
+
"KOI8-R",
|
9
|
+
"ISO-8859-1",
|
10
|
+
"ISO-8859-2",
|
11
|
+
NULL,
|
12
|
+
"US-ASCII",
|
13
|
+
"eucJP-ms",
|
14
|
+
"Shift_JIS",
|
15
|
+
"Windows-1251",
|
16
|
+
"ISO-8859-1",
|
17
|
+
"ISO-8859-8",
|
18
|
+
NULL,
|
19
|
+
"TIS-620",
|
20
|
+
"EUC-KR",
|
21
|
+
"ISO-8859-13",
|
22
|
+
"ISO-8859-2",
|
23
|
+
"KOI8-R",
|
24
|
+
"Windows-1251",
|
25
|
+
"GB2312",
|
26
|
+
"ISO-8859-7",
|
27
|
+
"Windows-1250",
|
28
|
+
"ISO-8859-2",
|
29
|
+
"GBK",
|
30
|
+
"Windows-1257",
|
31
|
+
"ISO-8859-9",
|
32
|
+
"ISO-8859-1",
|
33
|
+
NULL,
|
34
|
+
"UTF-8",
|
35
|
+
"Windows-1250",
|
36
|
+
"UTF-16BE",
|
37
|
+
"IBM866",
|
38
|
+
NULL,
|
39
|
+
"macCentEuro",
|
40
|
+
"macRoman",
|
41
|
+
"CP852",
|
42
|
+
"ISO-8859-13",
|
43
|
+
"ISO-8859-13",
|
44
|
+
"macCentEuro",
|
45
|
+
"Windows-1250",
|
46
|
+
"UTF-8",
|
47
|
+
"UTF-8",
|
48
|
+
"ISO-8859-1",
|
49
|
+
"ISO-8859-1",
|
50
|
+
"ISO-8859-1",
|
51
|
+
"Windows-1251",
|
52
|
+
"Windows-1251",
|
53
|
+
"Windows-1251",
|
54
|
+
"macRoman",
|
55
|
+
"UTF-16",
|
56
|
+
"UTF-16",
|
57
|
+
NULL,
|
58
|
+
"Windows-1256",
|
59
|
+
"Windows-1257",
|
60
|
+
"Windows-1257",
|
61
|
+
"UTF-32",
|
62
|
+
"UTF-32",
|
63
|
+
NULL,
|
64
|
+
"ASCII-8BIT",
|
65
|
+
NULL,
|
66
|
+
"US-ASCII",
|
67
|
+
"Windows-1250",
|
68
|
+
"Windows-1256",
|
69
|
+
"IBM866",
|
70
|
+
NULL,
|
71
|
+
"ISO-8859-7",
|
72
|
+
"ISO-8859-8",
|
73
|
+
NULL,
|
74
|
+
NULL,
|
75
|
+
"KOI8-R",
|
76
|
+
"KOI8-R",
|
77
|
+
NULL,
|
78
|
+
"ISO-8859-2",
|
79
|
+
"ISO-8859-9",
|
80
|
+
"ISO-8859-13",
|
81
|
+
"CP850",
|
82
|
+
"CP852",
|
83
|
+
NULL,
|
84
|
+
"UTF-8",
|
85
|
+
"Big5",
|
86
|
+
"EUC-KR",
|
87
|
+
"GB2312",
|
88
|
+
"GBK",
|
89
|
+
"Shift_JIS",
|
90
|
+
"TIS-620",
|
91
|
+
"UTF-16BE",
|
92
|
+
"eucJP-ms",
|
93
|
+
NULL,
|
94
|
+
NULL,
|
95
|
+
"ISO-8859-1",
|
96
|
+
"Windows-31J",
|
97
|
+
"Windows-31J",
|
98
|
+
"eucJP-ms",
|
99
|
+
"eucJP-ms",
|
100
|
+
"Windows-1250",
|
101
|
+
NULL,
|
102
|
+
"UTF-16",
|
103
|
+
"UTF-16",
|
104
|
+
"UTF-16",
|
105
|
+
"UTF-16",
|
106
|
+
"UTF-16",
|
107
|
+
"UTF-16",
|
108
|
+
"UTF-16",
|
109
|
+
"UTF-16",
|
110
|
+
"UTF-16",
|
111
|
+
"UTF-16",
|
112
|
+
"UTF-16",
|
113
|
+
"UTF-16",
|
114
|
+
"UTF-16",
|
115
|
+
"UTF-16",
|
116
|
+
"UTF-16",
|
117
|
+
"UTF-16",
|
118
|
+
"UTF-16",
|
119
|
+
"UTF-16",
|
120
|
+
"UTF-16",
|
121
|
+
"UTF-16",
|
122
|
+
NULL,
|
123
|
+
NULL,
|
124
|
+
NULL,
|
125
|
+
NULL,
|
126
|
+
NULL,
|
127
|
+
NULL,
|
128
|
+
NULL,
|
129
|
+
"UTF-16BE",
|
130
|
+
"UTF-16BE",
|
131
|
+
"UTF-16BE",
|
132
|
+
"UTF-16BE",
|
133
|
+
"UTF-16BE",
|
134
|
+
"UTF-16BE",
|
135
|
+
"UTF-16BE",
|
136
|
+
"UTF-16BE",
|
137
|
+
"UTF-16BE",
|
138
|
+
"UTF-16BE",
|
139
|
+
"UTF-16BE",
|
140
|
+
"UTF-16BE",
|
141
|
+
"UTF-16BE",
|
142
|
+
"UTF-16BE",
|
143
|
+
"UTF-16BE",
|
144
|
+
"UTF-16BE",
|
145
|
+
"UTF-16BE",
|
146
|
+
"UTF-16BE",
|
147
|
+
"UTF-16BE",
|
148
|
+
"UTF-16BE",
|
149
|
+
NULL,
|
150
|
+
NULL,
|
151
|
+
NULL,
|
152
|
+
NULL,
|
153
|
+
NULL,
|
154
|
+
NULL,
|
155
|
+
NULL,
|
156
|
+
NULL,
|
157
|
+
NULL,
|
158
|
+
NULL,
|
159
|
+
NULL,
|
160
|
+
NULL,
|
161
|
+
"UTF-32",
|
162
|
+
"UTF-32",
|
163
|
+
"UTF-32",
|
164
|
+
"UTF-32",
|
165
|
+
"UTF-32",
|
166
|
+
"UTF-32",
|
167
|
+
"UTF-32",
|
168
|
+
"UTF-32",
|
169
|
+
"UTF-32",
|
170
|
+
"UTF-32",
|
171
|
+
"UTF-32",
|
172
|
+
"UTF-32",
|
173
|
+
"UTF-32",
|
174
|
+
"UTF-32",
|
175
|
+
"UTF-32",
|
176
|
+
"UTF-32",
|
177
|
+
"UTF-32",
|
178
|
+
"UTF-32",
|
179
|
+
"UTF-32",
|
180
|
+
"UTF-32",
|
181
|
+
NULL,
|
182
|
+
NULL,
|
183
|
+
NULL,
|
184
|
+
NULL,
|
185
|
+
NULL,
|
186
|
+
NULL,
|
187
|
+
NULL,
|
188
|
+
NULL,
|
189
|
+
NULL,
|
190
|
+
NULL,
|
191
|
+
NULL,
|
192
|
+
NULL,
|
193
|
+
"UTF-8",
|
194
|
+
"UTF-8",
|
195
|
+
"UTF-8",
|
196
|
+
"UTF-8",
|
197
|
+
"UTF-8",
|
198
|
+
"UTF-8",
|
199
|
+
"UTF-8",
|
200
|
+
"UTF-8",
|
201
|
+
"UTF-8",
|
202
|
+
"UTF-8",
|
203
|
+
"UTF-8",
|
204
|
+
"UTF-8",
|
205
|
+
"UTF-8",
|
206
|
+
"UTF-8",
|
207
|
+
"UTF-8",
|
208
|
+
"UTF-8",
|
209
|
+
"UTF-8",
|
210
|
+
"UTF-8",
|
211
|
+
"UTF-8",
|
212
|
+
"UTF-8",
|
213
|
+
NULL,
|
214
|
+
NULL,
|
215
|
+
NULL,
|
216
|
+
NULL,
|
217
|
+
NULL,
|
218
|
+
NULL,
|
219
|
+
NULL,
|
220
|
+
NULL,
|
221
|
+
NULL,
|
222
|
+
NULL,
|
223
|
+
NULL,
|
224
|
+
NULL,
|
225
|
+
"UTF-8",
|
226
|
+
"UTF-8",
|
227
|
+
"UTF-8",
|
228
|
+
"UTF-8",
|
229
|
+
"UTF-8",
|
230
|
+
"UTF-8",
|
231
|
+
"UTF-8",
|
232
|
+
"UTF-8",
|
233
|
+
"UTF-8",
|
234
|
+
"UTF-8",
|
235
|
+
"UTF-8",
|
236
|
+
"UTF-8",
|
237
|
+
"UTF-8",
|
238
|
+
"UTF-8",
|
239
|
+
"UTF-8",
|
240
|
+
"UTF-8",
|
241
|
+
"UTF-8",
|
242
|
+
"UTF-8",
|
243
|
+
"UTF-8",
|
244
|
+
"UTF-8"
|
245
|
+
};
|
246
|
+
|
data/ext/mysql2/result.c
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
#include <mysql2_ext.h>
|
2
2
|
#include <stdint.h>
|
3
3
|
|
4
|
+
#include "mysql_enc_to_ruby.h"
|
5
|
+
|
4
6
|
#ifdef HAVE_RUBY_ENCODING_H
|
5
7
|
static rb_encoding *binaryEncoding;
|
6
8
|
#endif
|
@@ -27,7 +29,7 @@ static rb_encoding *binaryEncoding;
|
|
27
29
|
* (0*31557600) + (1*2592000) + (1*86400) + (0*3600) + (0*60) + 0
|
28
30
|
*/
|
29
31
|
#define MYSQL2_MIN_TIME 2678400ULL
|
30
|
-
#elif SIZEOF_INT < SIZEOF_LONG
|
32
|
+
#elif SIZEOF_INT < SIZEOF_LONG /* 64bit Ruby 1.8 */
|
31
33
|
/* 0139-1-1 00:00:00 UTC
|
32
34
|
*
|
33
35
|
* (139*31557600) + (1*2592000) + (1*86400) + (0*3600) + (0*60) + 0
|
@@ -51,11 +53,9 @@ static VALUE cMysql2Result;
|
|
51
53
|
static VALUE cBigDecimal, cDate, cDateTime;
|
52
54
|
static VALUE opt_decimal_zero, opt_float_zero, opt_time_year, opt_time_month, opt_utc_offset;
|
53
55
|
extern VALUE mMysql2, cMysql2Client, cMysql2Error;
|
54
|
-
static
|
55
|
-
static ID intern_new, intern_utc, intern_local, intern_encoding_from_charset_code,
|
56
|
-
intern_localtime, intern_local_offset, intern_civil, intern_new_offset;
|
56
|
+
static ID intern_new, intern_utc, intern_local, intern_localtime, intern_local_offset, intern_civil, intern_new_offset;
|
57
57
|
static VALUE sym_symbolize_keys, sym_as, sym_array, sym_database_timezone, sym_application_timezone,
|
58
|
-
sym_local, sym_utc, sym_cast_booleans, sym_cache_rows, sym_cast, sym_stream;
|
58
|
+
sym_local, sym_utc, sym_cast_booleans, sym_cache_rows, sym_cast, sym_stream, sym_name;
|
59
59
|
static ID intern_merge;
|
60
60
|
|
61
61
|
static void rb_mysql_result_mark(void * wrapper) {
|
@@ -140,20 +140,24 @@ static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, short int
|
|
140
140
|
|
141
141
|
#ifdef HAVE_RUBY_ENCODING_H
|
142
142
|
static VALUE mysql2_set_field_string_encoding(VALUE val, MYSQL_FIELD field, rb_encoding *default_internal_enc, rb_encoding *conn_enc) {
|
143
|
-
|
143
|
+
/* if binary flag is set, respect it's wishes */
|
144
144
|
if (field.flags & BINARY_FLAG && field.charsetnr == 63) {
|
145
145
|
rb_enc_associate(val, binaryEncoding);
|
146
146
|
} else {
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
147
|
+
/* lookup the encoding configured on this field */
|
148
|
+
const char *enc_name;
|
149
|
+
int enc_index;
|
150
|
+
|
151
|
+
enc_name = mysql2_mysql_enc_to_rb[field.charsetnr-1];
|
152
|
+
if (enc_name != NULL) {
|
153
|
+
/* use the field encoding we were able to match */
|
154
|
+
enc_index = rb_enc_find_index(enc_name);
|
155
|
+
rb_enc_set_index(val, enc_index);
|
153
156
|
} else {
|
154
|
-
|
157
|
+
/* otherwise fall-back to the connection's encoding */
|
155
158
|
rb_enc_associate(val, conn_enc);
|
156
159
|
}
|
160
|
+
|
157
161
|
if (default_internal_enc) {
|
158
162
|
val = rb_str_export_to_enc(val, default_internal_enc);
|
159
163
|
}
|
@@ -215,26 +219,26 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
|
|
215
219
|
}
|
216
220
|
} else {
|
217
221
|
switch(type) {
|
218
|
-
case MYSQL_TYPE_NULL:
|
222
|
+
case MYSQL_TYPE_NULL: /* NULL-type field */
|
219
223
|
val = Qnil;
|
220
224
|
break;
|
221
|
-
case MYSQL_TYPE_BIT:
|
225
|
+
case MYSQL_TYPE_BIT: /* BIT field (MySQL 5.0.3 and up) */
|
222
226
|
val = rb_str_new(row[i], fieldLengths[i]);
|
223
227
|
break;
|
224
|
-
case MYSQL_TYPE_TINY:
|
228
|
+
case MYSQL_TYPE_TINY: /* TINYINT field */
|
225
229
|
if (castBool && fields[i].length == 1) {
|
226
230
|
val = *row[i] != '0' ? Qtrue : Qfalse;
|
227
231
|
break;
|
228
232
|
}
|
229
|
-
case MYSQL_TYPE_SHORT:
|
230
|
-
case MYSQL_TYPE_LONG:
|
231
|
-
case MYSQL_TYPE_INT24:
|
232
|
-
case MYSQL_TYPE_LONGLONG:
|
233
|
-
case MYSQL_TYPE_YEAR:
|
233
|
+
case MYSQL_TYPE_SHORT: /* SMALLINT field */
|
234
|
+
case MYSQL_TYPE_LONG: /* INTEGER field */
|
235
|
+
case MYSQL_TYPE_INT24: /* MEDIUMINT field */
|
236
|
+
case MYSQL_TYPE_LONGLONG: /* BIGINT field */
|
237
|
+
case MYSQL_TYPE_YEAR: /* YEAR field */
|
234
238
|
val = rb_cstr2inum(row[i], 10);
|
235
239
|
break;
|
236
|
-
case MYSQL_TYPE_DECIMAL:
|
237
|
-
case MYSQL_TYPE_NEWDECIMAL:
|
240
|
+
case MYSQL_TYPE_DECIMAL: /* DECIMAL or NUMERIC field */
|
241
|
+
case MYSQL_TYPE_NEWDECIMAL: /* Precision math DECIMAL or NUMERIC field (MySQL 5.0.3 and up) */
|
238
242
|
if (fields[i].decimals == 0) {
|
239
243
|
val = rb_cstr2inum(row[i], 10);
|
240
244
|
} else if (strtod(row[i], NULL) == 0.000000){
|
@@ -243,8 +247,8 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
|
|
243
247
|
val = rb_funcall(cBigDecimal, intern_new, 1, rb_str_new(row[i], fieldLengths[i]));
|
244
248
|
}
|
245
249
|
break;
|
246
|
-
case MYSQL_TYPE_FLOAT:
|
247
|
-
case MYSQL_TYPE_DOUBLE: {
|
250
|
+
case MYSQL_TYPE_FLOAT: /* FLOAT field */
|
251
|
+
case MYSQL_TYPE_DOUBLE: { /* DOUBLE or REAL field */
|
248
252
|
double column_to_double;
|
249
253
|
column_to_double = strtod(row[i], NULL);
|
250
254
|
if (column_to_double == 0.000000){
|
@@ -254,25 +258,27 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
|
|
254
258
|
}
|
255
259
|
break;
|
256
260
|
}
|
257
|
-
case MYSQL_TYPE_TIME: {
|
258
|
-
int
|
259
|
-
|
260
|
-
|
261
|
+
case MYSQL_TYPE_TIME: { /* TIME field */
|
262
|
+
int tokens;
|
263
|
+
unsigned int hour=0, min=0, sec=0;
|
264
|
+
tokens = sscanf(row[i], "%2u:%2u:%2u", &hour, &min, &sec);
|
265
|
+
val = rb_funcall(rb_cTime, db_timezone, 6, opt_time_year, opt_time_month, opt_time_month, UINT2NUM(hour), UINT2NUM(min), UINT2NUM(sec));
|
261
266
|
if (!NIL_P(app_timezone)) {
|
262
267
|
if (app_timezone == intern_local) {
|
263
268
|
val = rb_funcall(val, intern_localtime, 0);
|
264
|
-
} else {
|
269
|
+
} else { /* utc */
|
265
270
|
val = rb_funcall(val, intern_utc, 0);
|
266
271
|
}
|
267
272
|
}
|
268
273
|
break;
|
269
274
|
}
|
270
|
-
case MYSQL_TYPE_TIMESTAMP:
|
271
|
-
case MYSQL_TYPE_DATETIME: {
|
272
|
-
|
275
|
+
case MYSQL_TYPE_TIMESTAMP: /* TIMESTAMP field */
|
276
|
+
case MYSQL_TYPE_DATETIME: { /* DATETIME field */
|
277
|
+
int tokens;
|
278
|
+
unsigned int year=0, month=0, day=0, hour=0, min=0, sec=0, msec=0;
|
273
279
|
uint64_t seconds;
|
274
280
|
|
275
|
-
tokens = sscanf(row[i], "%
|
281
|
+
tokens = sscanf(row[i], "%4u-%2u-%2u %2u:%2u:%2u.%6u", &year, &month, &day, &hour, &min, &sec, &msec);
|
276
282
|
seconds = (year*31557600ULL) + (month*2592000ULL) + (day*86400ULL) + (hour*3600ULL) + (min*60ULL) + sec;
|
277
283
|
|
278
284
|
if (seconds == 0) {
|
@@ -282,26 +288,26 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
|
|
282
288
|
rb_raise(cMysql2Error, "Invalid date: %s", row[i]);
|
283
289
|
val = Qnil;
|
284
290
|
} else {
|
285
|
-
if (seconds < MYSQL2_MIN_TIME || seconds > MYSQL2_MAX_TIME) {
|
291
|
+
if (seconds < MYSQL2_MIN_TIME || seconds > MYSQL2_MAX_TIME) { /* use DateTime for larger date range, does not support microseconds */
|
286
292
|
VALUE offset = INT2NUM(0);
|
287
293
|
if (db_timezone == intern_local) {
|
288
294
|
offset = rb_funcall(cMysql2Client, intern_local_offset, 0);
|
289
295
|
}
|
290
|
-
val = rb_funcall(cDateTime, intern_civil, 7,
|
296
|
+
val = rb_funcall(cDateTime, intern_civil, 7, UINT2NUM(year), UINT2NUM(month), UINT2NUM(day), UINT2NUM(hour), UINT2NUM(min), UINT2NUM(sec), offset);
|
291
297
|
if (!NIL_P(app_timezone)) {
|
292
298
|
if (app_timezone == intern_local) {
|
293
299
|
offset = rb_funcall(cMysql2Client, intern_local_offset, 0);
|
294
300
|
val = rb_funcall(val, intern_new_offset, 1, offset);
|
295
|
-
} else {
|
301
|
+
} else { /* utc */
|
296
302
|
val = rb_funcall(val, intern_new_offset, 1, opt_utc_offset);
|
297
303
|
}
|
298
304
|
}
|
299
|
-
} else {
|
300
|
-
val = rb_funcall(rb_cTime, db_timezone,
|
305
|
+
} else { /* use Time, supports microseconds */
|
306
|
+
val = rb_funcall(rb_cTime, db_timezone, 7, UINT2NUM(year), UINT2NUM(month), UINT2NUM(day), UINT2NUM(hour), UINT2NUM(min), UINT2NUM(sec), UINT2NUM(msec));
|
301
307
|
if (!NIL_P(app_timezone)) {
|
302
308
|
if (app_timezone == intern_local) {
|
303
309
|
val = rb_funcall(val, intern_localtime, 0);
|
304
|
-
} else {
|
310
|
+
} else { /* utc */
|
305
311
|
val = rb_funcall(val, intern_utc, 0);
|
306
312
|
}
|
307
313
|
}
|
@@ -310,10 +316,11 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
|
|
310
316
|
}
|
311
317
|
break;
|
312
318
|
}
|
313
|
-
case MYSQL_TYPE_DATE:
|
314
|
-
case MYSQL_TYPE_NEWDATE: {
|
315
|
-
int
|
316
|
-
|
319
|
+
case MYSQL_TYPE_DATE: /* DATE field */
|
320
|
+
case MYSQL_TYPE_NEWDATE: { /* Newer const used > 5.0 */
|
321
|
+
int tokens;
|
322
|
+
unsigned int year=0, month=0, day=0;
|
323
|
+
tokens = sscanf(row[i], "%4u-%2u-%2u", &year, &month, &day);
|
317
324
|
if (year+month+day == 0) {
|
318
325
|
val = Qnil;
|
319
326
|
} else {
|
@@ -321,7 +328,7 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
|
|
321
328
|
rb_raise(cMysql2Error, "Invalid date: %s", row[i]);
|
322
329
|
val = Qnil;
|
323
330
|
} else {
|
324
|
-
val = rb_funcall(cDate, intern_new, 3,
|
331
|
+
val = rb_funcall(cDate, intern_new, 3, UINT2NUM(year), UINT2NUM(month), UINT2NUM(day));
|
325
332
|
}
|
326
333
|
}
|
327
334
|
break;
|
@@ -332,10 +339,10 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
|
|
332
339
|
case MYSQL_TYPE_BLOB:
|
333
340
|
case MYSQL_TYPE_VAR_STRING:
|
334
341
|
case MYSQL_TYPE_VARCHAR:
|
335
|
-
case MYSQL_TYPE_STRING:
|
336
|
-
case MYSQL_TYPE_SET:
|
337
|
-
case MYSQL_TYPE_ENUM:
|
338
|
-
case MYSQL_TYPE_GEOMETRY:
|
342
|
+
case MYSQL_TYPE_STRING: /* CHAR or BINARY field */
|
343
|
+
case MYSQL_TYPE_SET: /* SET field */
|
344
|
+
case MYSQL_TYPE_ENUM: /* ENUM field */
|
345
|
+
case MYSQL_TYPE_GEOMETRY: /* Spatial fielda */
|
339
346
|
default:
|
340
347
|
val = rb_str_new(row[i], fieldLengths[i]);
|
341
348
|
#ifdef HAVE_RUBY_ENCODING_H
|
@@ -455,8 +462,8 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
|
455
462
|
|
456
463
|
if (wrapper->lastRowProcessed == 0) {
|
457
464
|
if(streaming) {
|
458
|
-
|
459
|
-
|
465
|
+
/* We can't get number of rows if we're streaming, */
|
466
|
+
/* until we've finished fetching all rows */
|
460
467
|
wrapper->numberOfRows = 0;
|
461
468
|
wrapper->rows = rb_ary_new();
|
462
469
|
} else {
|
@@ -493,8 +500,8 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
|
493
500
|
}
|
494
501
|
} else {
|
495
502
|
if (cacheRows && wrapper->lastRowProcessed == wrapper->numberOfRows) {
|
496
|
-
|
497
|
-
|
503
|
+
/* we've already read the entire dataset from the C result into our */
|
504
|
+
/* internal array. Lets hand that over to the user since it's ready to go */
|
498
505
|
for (i = 0; i < wrapper->numberOfRows; i++) {
|
499
506
|
rb_yield(rb_ary_entry(wrapper->rows, i));
|
500
507
|
}
|
@@ -516,7 +523,7 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
|
516
523
|
}
|
517
524
|
|
518
525
|
if (row == Qnil) {
|
519
|
-
|
526
|
+
/* we don't need the mysql C dataset around anymore, peace it */
|
520
527
|
rb_mysql_result_free_result(wrapper);
|
521
528
|
return Qnil;
|
522
529
|
}
|
@@ -526,7 +533,7 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
|
526
533
|
}
|
527
534
|
}
|
528
535
|
if (wrapper->lastRowProcessed == wrapper->numberOfRows) {
|
529
|
-
|
536
|
+
/* we don't need the mysql C dataset around anymore, peace it */
|
530
537
|
rb_mysql_result_free_result(wrapper);
|
531
538
|
}
|
532
539
|
}
|
@@ -579,9 +586,6 @@ void init_mysql2_result() {
|
|
579
586
|
rb_define_method(cMysql2Result, "count", rb_mysql_result_count, 0);
|
580
587
|
rb_define_alias(cMysql2Result, "size", "count");
|
581
588
|
|
582
|
-
intern_encoding_from_charset = rb_intern("encoding_from_charset");
|
583
|
-
intern_encoding_from_charset_code = rb_intern("encoding_from_charset_code");
|
584
|
-
|
585
589
|
intern_new = rb_intern("new");
|
586
590
|
intern_utc = rb_intern("utc");
|
587
591
|
intern_local = rb_intern("local");
|
@@ -602,9 +606,10 @@ void init_mysql2_result() {
|
|
602
606
|
sym_cache_rows = ID2SYM(rb_intern("cache_rows"));
|
603
607
|
sym_cast = ID2SYM(rb_intern("cast"));
|
604
608
|
sym_stream = ID2SYM(rb_intern("stream"));
|
609
|
+
sym_name = ID2SYM(rb_intern("name"));
|
605
610
|
|
606
611
|
opt_decimal_zero = rb_str_new2("0.0");
|
607
|
-
rb_global_variable(&opt_decimal_zero);
|
612
|
+
rb_global_variable(&opt_decimal_zero); /*never GC */
|
608
613
|
opt_float_zero = rb_float_new((double)0);
|
609
614
|
rb_global_variable(&opt_float_zero);
|
610
615
|
opt_time_year = INT2NUM(2000);
|