mysql 2.7 → 2.8.1
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/History.txt +12 -0
- data/Manifest.txt +16 -0
- data/README.txt +23 -0
- data/Rakefile +22 -0
- data/ext/mysql_api/extconf.rb +98 -0
- data/{mysql.c.in → ext/mysql_api/mysql.c} +302 -213
- data/{README.html → extra/README.html} +97 -9
- data/{README_ja.html → extra/README_ja.html} +98 -9
- data/{tommy.css → extra/tommy.css} +0 -0
- data/lib/mysql.rb +16 -0
- data/tasks/gem.rake +24 -0
- data/tasks/native.rake +30 -0
- data/tasks/vendor_mysql.rake +41 -0
- data/{test.rb → test/test_mysql.rb} +189 -60
- metadata +90 -39
- data/extconf.rb +0 -67
- data/mysql.gemspec +0 -34
data/History.txt
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
=== 2.8.1 / 2009-08-21
|
2
|
+
|
3
|
+
* New features:
|
4
|
+
* Early support for Ruby 1.9
|
5
|
+
|
6
|
+
* Enhancements:
|
7
|
+
* Improved gem release process using Hoe as development dependency
|
8
|
+
* Implemented support for cross compilation
|
9
|
+
* Binary version built against MySQL 5.0.83
|
10
|
+
|
11
|
+
* Bug fixes:
|
12
|
+
* Improved detection of mysql and it's configuration (mysql_config)
|
data/Manifest.txt
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
COPYING
|
2
|
+
COPYING.ja
|
3
|
+
History.txt
|
4
|
+
Manifest.txt
|
5
|
+
README.txt
|
6
|
+
Rakefile
|
7
|
+
ext/mysql_api/extconf.rb
|
8
|
+
ext/mysql_api/mysql.c
|
9
|
+
extra/README.html
|
10
|
+
extra/README_ja.html
|
11
|
+
extra/tommy.css
|
12
|
+
lib/mysql.rb
|
13
|
+
tasks/gem.rake
|
14
|
+
tasks/native.rake
|
15
|
+
tasks/vendor_mysql.rake
|
16
|
+
test/test_mysql.rb
|
data/README.txt
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
= MySQL/Ruby Interface
|
2
|
+
|
3
|
+
* http://mysql-win.rubyforge.org
|
4
|
+
* http://rubyforge.org/projects/mysql-win
|
5
|
+
* http://github.com/luislaven/mysql-gem
|
6
|
+
|
7
|
+
== DESCRIPTION
|
8
|
+
|
9
|
+
This is the MySQL API module for Ruby. It provides the same functions for Ruby
|
10
|
+
programs that the MySQL C API provides for C programs.
|
11
|
+
|
12
|
+
This is a conversion of tmtm's original extension into a proper RubyGems.
|
13
|
+
|
14
|
+
=== Warning about incompatible MySQL versions
|
15
|
+
|
16
|
+
Mixing MySQL versions will generate segmentation faults.
|
17
|
+
|
18
|
+
Running the binary version of this gem against a different version of MySQL
|
19
|
+
shared library <tt>libMySQL.dll</tt> will generate segmentation faults and
|
20
|
+
terminate your application.
|
21
|
+
|
22
|
+
Please use the exact same MAJOR.MINOR version of MySQL, see History.txt for
|
23
|
+
specific version of MySQL used to build the binaries.
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2008 Luis Lavena
|
3
|
+
#
|
4
|
+
# This source code is released under the MIT License.
|
5
|
+
# See LICENSE file for details
|
6
|
+
#++
|
7
|
+
|
8
|
+
#
|
9
|
+
# NOTE: Keep this file clean.
|
10
|
+
# Add your customizations inside tasks directory.
|
11
|
+
# Thank You.
|
12
|
+
#
|
13
|
+
|
14
|
+
begin
|
15
|
+
require 'rake'
|
16
|
+
rescue LoadError
|
17
|
+
require 'rubygems'
|
18
|
+
require 'rake'
|
19
|
+
end
|
20
|
+
|
21
|
+
# load rakefile extensions (tasks)
|
22
|
+
Dir['tasks/*.rake'].sort.each { |f| load f }
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# Darwin (OSX) special cases for universal binaries
|
2
|
+
# This is to avoid the lack of UB binaries for MySQL
|
3
|
+
if RUBY_PLATFORM =~ /darwin/
|
4
|
+
ENV["RC_ARCHS"] = `uname -m`.chomp if `uname -sr` =~ /^Darwin/
|
5
|
+
|
6
|
+
# On PowerPC the defaults are fine
|
7
|
+
ENV["RC_ARCHS"] = '' if `uname -m` =~ /^Power Macintosh/
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'mkmf'
|
11
|
+
|
12
|
+
# Improved detection of mysql_config
|
13
|
+
# Code from DataObjects do_mysql adapter
|
14
|
+
|
15
|
+
# All instances of mysql_config on PATH ...
|
16
|
+
def mysql_config_paths
|
17
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).collect do |path|
|
18
|
+
[ "#{path}/mysql_config", "#{path}/mysql_config5" ].
|
19
|
+
detect { |bin| File.exist?(bin) }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# The first mysql_config binary on PATH ...
|
24
|
+
def default_mysql_config_path
|
25
|
+
mysql_config_paths.compact.first
|
26
|
+
end
|
27
|
+
|
28
|
+
# Allow overriding path to mysql_config on command line using:
|
29
|
+
# ruby extconf.rb --with-mysql-config=/path/to/mysql_config
|
30
|
+
if RUBY_PLATFORM =~ /mswin|mingw/
|
31
|
+
inc, lib = dir_config('mysql')
|
32
|
+
exit 1 unless have_library("libmysql")
|
33
|
+
elsif mc = with_config('mysql-config', default_mysql_config_path) then
|
34
|
+
mc = 'mysql_config' if mc == true
|
35
|
+
cflags = `#{mc} --cflags`.chomp
|
36
|
+
exit 1 if $? != 0
|
37
|
+
libs = `#{mc} --libs`.chomp
|
38
|
+
exit 1 if $? != 0
|
39
|
+
$CPPFLAGS += ' ' + cflags
|
40
|
+
$libs = libs + " " + $libs
|
41
|
+
else
|
42
|
+
inc, lib = dir_config('mysql', '/usr/local')
|
43
|
+
libs = ['m', 'z', 'socket', 'nsl', 'mygcc']
|
44
|
+
while not find_library('mysqlclient', 'mysql_query', lib, "#{lib}/mysql") do
|
45
|
+
exit 1 if libs.empty?
|
46
|
+
have_library(libs.shift)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
have_func('mysql_ssl_set')
|
51
|
+
have_func('rb_str_set_len')
|
52
|
+
have_func('rb_thread_start_timer')
|
53
|
+
|
54
|
+
if have_header('mysql.h') then
|
55
|
+
src = "#include <errmsg.h>\n#include <mysqld_error.h>\n"
|
56
|
+
elsif have_header('mysql/mysql.h') then
|
57
|
+
src = "#include <mysql/errmsg.h>\n#include <mysql/mysqld_error.h>\n"
|
58
|
+
else
|
59
|
+
exit 1
|
60
|
+
end
|
61
|
+
|
62
|
+
# make mysql constant
|
63
|
+
File.open("conftest.c", "w") do |f|
|
64
|
+
f.puts src
|
65
|
+
end
|
66
|
+
if defined? cpp_command then
|
67
|
+
cpp = Config.expand(cpp_command(''))
|
68
|
+
else
|
69
|
+
cpp = Config.expand sprintf(CPP, $CPPFLAGS, $CFLAGS, '')
|
70
|
+
end
|
71
|
+
if RUBY_PLATFORM =~ /mswin/ && !/-E/.match(cpp)
|
72
|
+
cpp << " -E"
|
73
|
+
end
|
74
|
+
unless system "#{cpp} > confout" then
|
75
|
+
exit 1
|
76
|
+
end
|
77
|
+
File.unlink "conftest.c"
|
78
|
+
|
79
|
+
error_syms = []
|
80
|
+
IO.foreach('confout') do |l|
|
81
|
+
next unless l =~ /errmsg\.h|mysqld_error\.h/
|
82
|
+
fn = l.split(/\"/)[1]
|
83
|
+
IO.foreach(fn) do |m|
|
84
|
+
if m =~ /^#define\s+([CE]R_[0-9A-Z_]+)/ then
|
85
|
+
error_syms << $1
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
File.unlink 'confout'
|
90
|
+
error_syms.uniq!
|
91
|
+
|
92
|
+
File.open('error_const.h', 'w') do |f|
|
93
|
+
error_syms.each do |s|
|
94
|
+
f.puts " rb_define_mysql_const(#{s});"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
create_makefile("mysql_api")
|
@@ -1,9 +1,21 @@
|
|
1
1
|
/* ruby mysql module
|
2
|
-
* $Id: mysql.c
|
2
|
+
* $Id: mysql.c 244 2009-02-01 08:43:39Z tommy $
|
3
3
|
*/
|
4
4
|
|
5
|
-
#include
|
6
|
-
#
|
5
|
+
#include <ruby.h>
|
6
|
+
#ifndef RSTRING_PTR
|
7
|
+
#define RSTRING_PTR(str) RSTRING(str)->ptr
|
8
|
+
#endif
|
9
|
+
#ifndef RSTRING_LEN
|
10
|
+
#define RSTRING_LEN(str) RSTRING(str)->len
|
11
|
+
#endif
|
12
|
+
#ifndef RARRAY_PTR
|
13
|
+
#define RARRAY_PTR(ary) RARRAY(ary)->ptr
|
14
|
+
#endif
|
15
|
+
#ifndef HAVE_RB_STR_SET_LEN
|
16
|
+
#define rb_str_set_len(str, length) (RSTRING_LEN(str) = (length))
|
17
|
+
#endif
|
18
|
+
|
7
19
|
#ifdef HAVE_MYSQL_H
|
8
20
|
#include <mysql.h>
|
9
21
|
#include <errmsg.h>
|
@@ -14,26 +26,10 @@
|
|
14
26
|
#include <mysql/mysqld_error.h>
|
15
27
|
#endif
|
16
28
|
|
17
|
-
#define MYSQL_RUBY_VERSION
|
29
|
+
#define MYSQL_RUBY_VERSION 20801
|
18
30
|
|
19
31
|
#define GC_STORE_RESULT_LIMIT 20
|
20
32
|
|
21
|
-
#ifndef Qtrue /* ruby 1.2.x ? */
|
22
|
-
#define Qtrue TRUE
|
23
|
-
#define Qfalse FALSE
|
24
|
-
#define rb_exc_raise rb_raise
|
25
|
-
#define rb_exc_new2 exc_new2
|
26
|
-
#define rb_str_new str_new
|
27
|
-
#define rb_str_new2 str_new2
|
28
|
-
#define rb_ary_new2 ary_new2
|
29
|
-
#define rb_ary_store ary_store
|
30
|
-
#define rb_obj_alloc obj_alloc
|
31
|
-
#define rb_hash_new hash_new
|
32
|
-
#define rb_hash_aset hash_aset
|
33
|
-
#define rb_eStandardError eStandardError
|
34
|
-
#define rb_cObject cObject
|
35
|
-
#endif
|
36
|
-
|
37
33
|
#if MYSQL_VERSION_ID < 32224
|
38
34
|
#define mysql_field_count mysql_num_fields
|
39
35
|
#endif
|
@@ -92,7 +88,7 @@ static void free_mysql(struct mysql* my)
|
|
92
88
|
{
|
93
89
|
if (my->connection == Qtrue)
|
94
90
|
mysql_close(&my->handler);
|
95
|
-
|
91
|
+
xfree(my);
|
96
92
|
}
|
97
93
|
|
98
94
|
static void free_mysqlres(struct mysql_res* resp)
|
@@ -101,7 +97,7 @@ static void free_mysqlres(struct mysql_res* resp)
|
|
101
97
|
mysql_free_result(resp->res);
|
102
98
|
store_result_count--;
|
103
99
|
}
|
104
|
-
|
100
|
+
xfree(resp);
|
105
101
|
}
|
106
102
|
|
107
103
|
#if MYSQL_VERSION_ID >= 40101
|
@@ -129,6 +125,7 @@ static void free_mysqlstmt_memory(struct mysql_stmt *s)
|
|
129
125
|
for (i = 0; i < s->result.n; i++) {
|
130
126
|
if (s->result.bind[i].buffer)
|
131
127
|
xfree(s->result.bind[i].buffer);
|
128
|
+
s->result.bind[i].buffer = NULL;
|
132
129
|
}
|
133
130
|
xfree(s->result.bind);
|
134
131
|
s->result.bind = NULL;
|
@@ -144,6 +141,19 @@ static void free_mysqlstmt_memory(struct mysql_stmt *s)
|
|
144
141
|
s->result.n = 0;
|
145
142
|
}
|
146
143
|
|
144
|
+
static void free_execute_memory(struct mysql_stmt *s)
|
145
|
+
{
|
146
|
+
if (s->res && s->result.bind) {
|
147
|
+
int i;
|
148
|
+
for (i = 0; i < s->result.n; i++) {
|
149
|
+
if (s->result.bind[i].buffer)
|
150
|
+
xfree(s->result.bind[i].buffer);
|
151
|
+
s->result.bind[i].buffer = NULL;
|
152
|
+
}
|
153
|
+
}
|
154
|
+
mysql_stmt_free_result(s->stmt);
|
155
|
+
}
|
156
|
+
|
147
157
|
static void free_mysqlstmt(struct mysql_stmt* s)
|
148
158
|
{
|
149
159
|
free_mysqlstmt_memory(s);
|
@@ -151,7 +161,7 @@ static void free_mysqlstmt(struct mysql_stmt* s)
|
|
151
161
|
mysql_stmt_close(s->stmt);
|
152
162
|
if (s->res)
|
153
163
|
mysql_free_result(s->res);
|
154
|
-
|
164
|
+
xfree(s);
|
155
165
|
}
|
156
166
|
#endif
|
157
167
|
|
@@ -170,6 +180,8 @@ static VALUE mysqlres2obj(MYSQL_RES* res)
|
|
170
180
|
VALUE obj;
|
171
181
|
struct mysql_res* resp;
|
172
182
|
obj = Data_Make_Struct(cMysqlRes, struct mysql_res, 0, free_mysqlres, resp);
|
183
|
+
rb_iv_set(obj, "colname", Qnil);
|
184
|
+
rb_iv_set(obj, "tblcolname", Qnil);
|
173
185
|
resp->res = res;
|
174
186
|
resp->freed = Qfalse;
|
175
187
|
rb_obj_call_init(obj, 0, NULL);
|
@@ -182,7 +194,6 @@ static VALUE mysqlres2obj(MYSQL_RES* res)
|
|
182
194
|
static VALUE make_field_obj(MYSQL_FIELD* f)
|
183
195
|
{
|
184
196
|
VALUE obj;
|
185
|
-
VALUE hash;
|
186
197
|
if (f == NULL)
|
187
198
|
return Qnil;
|
188
199
|
obj = rb_obj_alloc(cMysqlField);
|
@@ -240,6 +251,9 @@ static VALUE real_connect(int argc, VALUE* argv, VALUE klass)
|
|
240
251
|
pp = NILorINT(port);
|
241
252
|
s = NILorSTRING(sock);
|
242
253
|
|
254
|
+
#ifdef HAVE_RB_THREAD_START_TIMER
|
255
|
+
rb_thread_stop_timer();
|
256
|
+
#endif
|
243
257
|
obj = Data_Make_Struct(klass, struct mysql, 0, free_mysql, myp);
|
244
258
|
#if MYSQL_VERSION_ID >= 32200
|
245
259
|
mysql_init(&myp->handler);
|
@@ -249,7 +263,15 @@ static VALUE real_connect(int argc, VALUE* argv, VALUE klass)
|
|
249
263
|
#else
|
250
264
|
if (mysql_real_connect(&myp->handler, h, u, p, pp, s) == NULL)
|
251
265
|
#endif
|
252
|
-
|
266
|
+
{
|
267
|
+
#ifdef HAVE_RB_THREAD_START_TIMER
|
268
|
+
rb_thread_start_timer();
|
269
|
+
#endif
|
270
|
+
mysql_raise(&myp->handler);
|
271
|
+
}
|
272
|
+
#ifdef HAVE_RB_THREAD_START_TIMER
|
273
|
+
rb_thread_start_timer();
|
274
|
+
#endif
|
253
275
|
|
254
276
|
myp->handler.reconnect = 0;
|
255
277
|
myp->connection = Qtrue;
|
@@ -264,8 +286,8 @@ static VALUE escape_string(VALUE klass, VALUE str)
|
|
264
286
|
{
|
265
287
|
VALUE ret;
|
266
288
|
Check_Type(str, T_STRING);
|
267
|
-
ret = rb_str_new(0, (
|
268
|
-
|
289
|
+
ret = rb_str_new(0, (RSTRING_LEN(str))*2+1);
|
290
|
+
rb_str_set_len(ret, mysql_escape_string(RSTRING_PTR(ret), RSTRING_PTR(str), RSTRING_LEN(str)));
|
269
291
|
return ret;
|
270
292
|
}
|
271
293
|
|
@@ -313,8 +335,18 @@ static VALUE real_connect2(int argc, VALUE* argv, VALUE obj)
|
|
313
335
|
pp = NILorINT(port);
|
314
336
|
s = NILorSTRING(sock);
|
315
337
|
|
316
|
-
|
317
|
-
|
338
|
+
#ifdef HAVE_RB_THREAD_START_TIMER
|
339
|
+
rb_thread_stop_timer();
|
340
|
+
#endif
|
341
|
+
if (mysql_real_connect(m, h, u, p, d, pp, s, f) == NULL) {
|
342
|
+
#ifdef HAVE_RB_THREAD_START_TIMER
|
343
|
+
rb_thread_start_timer();
|
344
|
+
#endif
|
345
|
+
mysql_raise(m);
|
346
|
+
}
|
347
|
+
#ifdef HAVE_RB_THREAD_START_TIMER
|
348
|
+
rb_thread_start_timer();
|
349
|
+
#endif
|
318
350
|
m->reconnect = 0;
|
319
351
|
GetMysqlStruct(obj)->connection = Qtrue;
|
320
352
|
|
@@ -398,8 +430,8 @@ static VALUE real_escape_string(VALUE obj, VALUE str)
|
|
398
430
|
MYSQL* m = GetHandler(obj);
|
399
431
|
VALUE ret;
|
400
432
|
Check_Type(str, T_STRING);
|
401
|
-
ret = rb_str_new(0, (
|
402
|
-
|
433
|
+
ret = rb_str_new(0, (RSTRING_LEN(str))*2+1);
|
434
|
+
rb_str_set_len(ret, mysql_real_escape_string(m, RSTRING_PTR(ret), RSTRING_PTR(str), RSTRING_LEN(str)));
|
403
435
|
return ret;
|
404
436
|
}
|
405
437
|
#endif
|
@@ -446,8 +478,6 @@ static VALUE my_close(VALUE obj)
|
|
446
478
|
{
|
447
479
|
MYSQL* m = GetHandler(obj);
|
448
480
|
mysql_close(m);
|
449
|
-
if (mysql_errno(m))
|
450
|
-
mysql_raise(m);
|
451
481
|
GetMysqlStruct(obj)->connection = Qfalse;
|
452
482
|
return obj;
|
453
483
|
}
|
@@ -700,14 +730,14 @@ static VALUE res_free(VALUE);
|
|
700
730
|
/* query(sql) */
|
701
731
|
static VALUE query(VALUE obj, VALUE sql)
|
702
732
|
{
|
733
|
+
int loop = 0;
|
703
734
|
MYSQL* m = GetHandler(obj);
|
704
735
|
Check_Type(sql, T_STRING);
|
736
|
+
if (GetMysqlStruct(obj)->connection == Qfalse) {
|
737
|
+
rb_raise(eMysql, "query: not connected");
|
738
|
+
}
|
705
739
|
if (rb_block_given_p()) {
|
706
|
-
|
707
|
-
if (mysql_get_server_version(m) >= 40101 && mysql_set_server_option(m, MYSQL_OPTION_MULTI_STATEMENTS_ON) != 0)
|
708
|
-
mysql_raise(m);
|
709
|
-
#endif
|
710
|
-
if (mysql_real_query(m, RSTRING(sql)->ptr, RSTRING(sql)->len) != 0)
|
740
|
+
if (mysql_real_query(m, RSTRING_PTR(sql), RSTRING_LEN(sql)) != 0)
|
711
741
|
mysql_raise(m);
|
712
742
|
do {
|
713
743
|
MYSQL_RES* res = mysql_store_result(m);
|
@@ -718,15 +748,16 @@ static VALUE query(VALUE obj, VALUE sql)
|
|
718
748
|
VALUE robj = mysqlres2obj(res);
|
719
749
|
rb_ensure(rb_yield, robj, res_free, robj);
|
720
750
|
}
|
721
|
-
}
|
722
751
|
#if MYSQL_VERSION_ID >= 40101
|
723
|
-
|
752
|
+
if ((loop = mysql_next_result(m)) > 0)
|
753
|
+
mysql_raise(m);
|
754
|
+
} while (loop == 0);
|
724
755
|
#else
|
725
|
-
while (0);
|
756
|
+
} while (0);
|
726
757
|
#endif
|
727
758
|
return obj;
|
728
759
|
}
|
729
|
-
if (mysql_real_query(m,
|
760
|
+
if (mysql_real_query(m, RSTRING_PTR(sql), RSTRING_LEN(sql)) != 0)
|
730
761
|
mysql_raise(m);
|
731
762
|
if (GetMysqlStruct(obj)->query_with_result == Qfalse)
|
732
763
|
return obj;
|
@@ -878,11 +909,7 @@ static VALUE query_with_result(VALUE obj)
|
|
878
909
|
static VALUE query_with_result_set(VALUE obj, VALUE flag)
|
879
910
|
{
|
880
911
|
if (TYPE(flag) != T_TRUE && TYPE(flag) != T_FALSE)
|
881
|
-
#if RUBY_VERSION_CODE < 160
|
882
|
-
TypeError("invalid type, required true or false.");
|
883
|
-
#else
|
884
912
|
rb_raise(rb_eTypeError, "invalid type, required true or false.");
|
885
|
-
#endif
|
886
913
|
GetMysqlStruct(obj)->query_with_result = flag;
|
887
914
|
return flag;
|
888
915
|
}
|
@@ -956,11 +983,7 @@ static VALUE fetch_field_direct(VALUE obj, VALUE nr)
|
|
956
983
|
max = mysql_num_fields(res);
|
957
984
|
n = NUM2INT(nr);
|
958
985
|
if (n >= max)
|
959
|
-
#if RUBY_VERSION_CODE < 160
|
960
|
-
Raise(eMysql, "%d: out of range (max: %d)", n, max-1);
|
961
|
-
#else
|
962
986
|
rb_raise(eMysql, "%d: out of range (max: %d)", n, max-1);
|
963
|
-
#endif
|
964
987
|
#if MYSQL_VERSION_ID >= 32226
|
965
988
|
return make_field_obj(mysql_fetch_field_direct(res, n));
|
966
989
|
#else
|
@@ -1020,19 +1043,40 @@ static VALUE fetch_hash2(VALUE obj, VALUE with_table)
|
|
1020
1043
|
MYSQL_FIELD* fields = mysql_fetch_fields(res);
|
1021
1044
|
unsigned int i;
|
1022
1045
|
VALUE hash;
|
1046
|
+
VALUE colname;
|
1023
1047
|
if (row == NULL)
|
1024
1048
|
return Qnil;
|
1025
1049
|
hash = rb_hash_new();
|
1050
|
+
|
1051
|
+
if (with_table == Qnil || with_table == Qfalse) {
|
1052
|
+
colname = rb_iv_get(obj, "colname");
|
1053
|
+
if (colname == Qnil) {
|
1054
|
+
colname = rb_ary_new2(n);
|
1055
|
+
for (i=0; i<n; i++) {
|
1056
|
+
VALUE s = rb_tainted_str_new2(fields[i].name);
|
1057
|
+
rb_obj_freeze(s);
|
1058
|
+
rb_ary_store(colname, i, s);
|
1059
|
+
}
|
1060
|
+
rb_obj_freeze(colname);
|
1061
|
+
rb_iv_set(obj, "colname", colname);
|
1062
|
+
}
|
1063
|
+
} else {
|
1064
|
+
colname = rb_iv_get(obj, "tblcolname");
|
1065
|
+
if (colname == Qnil) {
|
1066
|
+
colname = rb_ary_new2(n);
|
1067
|
+
for (i=0; i<n; i++) {
|
1068
|
+
int len = strlen(fields[i].table)+strlen(fields[i].name)+1;
|
1069
|
+
VALUE s = rb_tainted_str_new(NULL, len);
|
1070
|
+
snprintf(RSTRING_PTR(s), len+1, "%s.%s", fields[i].table, fields[i].name);
|
1071
|
+
rb_obj_freeze(s);
|
1072
|
+
rb_ary_store(colname, i, s);
|
1073
|
+
}
|
1074
|
+
rb_obj_freeze(colname);
|
1075
|
+
rb_iv_set(obj, "tblcolname", colname);
|
1076
|
+
}
|
1077
|
+
}
|
1026
1078
|
for (i=0; i<n; i++) {
|
1027
|
-
|
1028
|
-
if (with_table == Qnil || with_table == Qfalse)
|
1029
|
-
col = rb_tainted_str_new2(fields[i].name);
|
1030
|
-
else {
|
1031
|
-
col = rb_tainted_str_new(fields[i].table, strlen(fields[i].table)+strlen(fields[i].name)+1);
|
1032
|
-
RSTRING(col)->ptr[strlen(fields[i].table)] = '.';
|
1033
|
-
strcpy(RSTRING(col)->ptr+strlen(fields[i].table)+1, fields[i].name);
|
1034
|
-
}
|
1035
|
-
rb_hash_aset(hash, col, row[i]? rb_tainted_str_new(row[i], lengths[i]): Qnil);
|
1079
|
+
rb_hash_aset(hash, rb_ary_entry(colname, i), row[i]? rb_tainted_str_new(row[i], lengths[i]): Qnil);
|
1036
1080
|
}
|
1037
1081
|
return hash;
|
1038
1082
|
}
|
@@ -1154,8 +1198,8 @@ static VALUE field_hash(VALUE obj)
|
|
1154
1198
|
static VALUE field_inspect(VALUE obj)
|
1155
1199
|
{
|
1156
1200
|
VALUE n = rb_iv_get(obj, "name");
|
1157
|
-
VALUE s = rb_str_new(0,
|
1158
|
-
sprintf(
|
1201
|
+
VALUE s = rb_str_new(0, RSTRING_LEN(n) + 16);
|
1202
|
+
sprintf(RSTRING_PTR(s), "#<Mysql::Field:%s>", RSTRING_PTR(n));
|
1159
1203
|
return s;
|
1160
1204
|
}
|
1161
1205
|
|
@@ -1257,7 +1301,6 @@ static VALUE stmt_attr_set(VALUE obj, VALUE opt, VALUE val)
|
|
1257
1301
|
#endif
|
1258
1302
|
|
1259
1303
|
/* bind_result(bind,...) */
|
1260
|
-
static enum enum_field_types buffer_type(MYSQL_FIELD *field);
|
1261
1304
|
static VALUE stmt_bind_result(int argc, VALUE *argv, VALUE obj)
|
1262
1305
|
{
|
1263
1306
|
struct mysql_stmt* s = DATA_PTR(obj);
|
@@ -1270,7 +1313,7 @@ static VALUE stmt_bind_result(int argc, VALUE *argv, VALUE obj)
|
|
1270
1313
|
for (i = 0; i < argc; i++) {
|
1271
1314
|
if (argv[i] == Qnil || argv[i] == rb_cNilClass) {
|
1272
1315
|
field = mysql_fetch_fields(s->res);
|
1273
|
-
|
1316
|
+
s->result.bind[i].buffer_type = field[i].type;
|
1274
1317
|
}
|
1275
1318
|
else if (argv[i] == rb_cString)
|
1276
1319
|
s->result.bind[i].buffer_type = MYSQL_TYPE_STRING;
|
@@ -1281,7 +1324,7 @@ static VALUE stmt_bind_result(int argc, VALUE *argv, VALUE obj)
|
|
1281
1324
|
else if (argv[i] == cMysqlTime)
|
1282
1325
|
s->result.bind[i].buffer_type = MYSQL_TYPE_DATETIME;
|
1283
1326
|
else
|
1284
|
-
rb_raise(rb_eTypeError, "unrecognized class: %s",
|
1327
|
+
rb_raise(rb_eTypeError, "unrecognized class: %s", RSTRING_PTR(rb_inspect(argv[i])));
|
1285
1328
|
if (mysql_stmt_bind_result(s->stmt, s->result.bind))
|
1286
1329
|
mysql_stmt_raise(s->stmt);
|
1287
1330
|
}
|
@@ -1312,76 +1355,84 @@ static VALUE stmt_execute(int argc, VALUE *argv, VALUE obj)
|
|
1312
1355
|
{
|
1313
1356
|
struct mysql_stmt *s = DATA_PTR(obj);
|
1314
1357
|
MYSQL_STMT *stmt = s->stmt;
|
1315
|
-
my_bool true = 1;
|
1316
|
-
my_bool false = 0;
|
1317
1358
|
int i;
|
1318
1359
|
|
1319
1360
|
check_stmt_closed(obj);
|
1361
|
+
free_execute_memory(s);
|
1320
1362
|
if (s->param.n != argc)
|
1321
1363
|
rb_raise(eMysql, "execute: param_count(%d) != number of argument(%d)", s->param.n, argc);
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1364
|
+
if (argc > 0) {
|
1365
|
+
memset(s->param.bind, 0, sizeof(*(s->param.bind))*argc);
|
1366
|
+
for (i = 0; i < argc; i++) {
|
1367
|
+
switch (TYPE(argv[i])) {
|
1368
|
+
case T_NIL:
|
1369
|
+
s->param.bind[i].buffer_type = MYSQL_TYPE_NULL;
|
1370
|
+
break;
|
1371
|
+
case T_FIXNUM:
|
1372
|
+
#if SIZEOF_INT < SIZEOF_LONG
|
1373
|
+
s->param.bind[i].buffer_type = MYSQL_TYPE_LONGLONG;
|
1374
|
+
s->param.bind[i].buffer = &(s->param.buffer[i]);
|
1375
|
+
*(LONG_LONG*)(s->param.bind[i].buffer) = FIX2LONG(argv[i]);
|
1376
|
+
#else
|
1377
|
+
s->param.bind[i].buffer_type = MYSQL_TYPE_LONG;
|
1378
|
+
s->param.bind[i].buffer = &(s->param.buffer[i]);
|
1379
|
+
*(int*)(s->param.bind[i].buffer) = FIX2INT(argv[i]);
|
1380
|
+
#endif
|
1381
|
+
break;
|
1382
|
+
case T_BIGNUM:
|
1383
|
+
s->param.bind[i].buffer_type = MYSQL_TYPE_LONGLONG;
|
1384
|
+
s->param.bind[i].buffer = &(s->param.buffer[i]);
|
1385
|
+
*(LONG_LONG*)(s->param.bind[i].buffer) = rb_big2ll(argv[i]);
|
1386
|
+
break;
|
1387
|
+
case T_FLOAT:
|
1388
|
+
s->param.bind[i].buffer_type = MYSQL_TYPE_DOUBLE;
|
1389
|
+
s->param.bind[i].buffer = &(s->param.buffer[i]);
|
1390
|
+
*(double*)(s->param.bind[i].buffer) = NUM2DBL(argv[i]);
|
1391
|
+
break;
|
1392
|
+
case T_STRING:
|
1393
|
+
s->param.bind[i].buffer_type = MYSQL_TYPE_STRING;
|
1394
|
+
s->param.bind[i].buffer = RSTRING_PTR(argv[i]);
|
1395
|
+
s->param.bind[i].buffer_length = RSTRING_LEN(argv[i]);
|
1396
|
+
s->param.length[i] = RSTRING_LEN(argv[i]);
|
1397
|
+
s->param.bind[i].length = &(s->param.length[i]);
|
1398
|
+
break;
|
1399
|
+
default:
|
1400
|
+
if (CLASS_OF(argv[i]) == rb_cTime) {
|
1401
|
+
MYSQL_TIME t;
|
1402
|
+
VALUE a = rb_funcall(argv[i], rb_intern("to_a"), 0);
|
1403
|
+
s->param.bind[i].buffer_type = MYSQL_TYPE_DATETIME;
|
1404
|
+
s->param.bind[i].buffer = &(s->param.buffer[i]);
|
1405
|
+
memset(&t, 0, sizeof(t)); /* avoid warning */
|
1406
|
+
t.second_part = 0;
|
1407
|
+
t.neg = 0;
|
1408
|
+
t.second = FIX2INT(RARRAY_PTR(a)[0]);
|
1409
|
+
t.minute = FIX2INT(RARRAY_PTR(a)[1]);
|
1410
|
+
t.hour = FIX2INT(RARRAY_PTR(a)[2]);
|
1411
|
+
t.day = FIX2INT(RARRAY_PTR(a)[3]);
|
1412
|
+
t.month = FIX2INT(RARRAY_PTR(a)[4]);
|
1413
|
+
t.year = FIX2INT(RARRAY_PTR(a)[5]);
|
1414
|
+
*(MYSQL_TIME*)&(s->param.buffer[i]) = t;
|
1415
|
+
} else if (CLASS_OF(argv[i]) == cMysqlTime) {
|
1416
|
+
MYSQL_TIME t;
|
1417
|
+
s->param.bind[i].buffer_type = MYSQL_TYPE_DATETIME;
|
1418
|
+
s->param.bind[i].buffer = &(s->param.buffer[i]);
|
1419
|
+
memset(&t, 0, sizeof(t)); /* avoid warning */
|
1420
|
+
t.second_part = 0;
|
1421
|
+
t.neg = 0;
|
1422
|
+
t.second = NUM2INT(rb_iv_get(argv[i], "second"));
|
1423
|
+
t.minute = NUM2INT(rb_iv_get(argv[i], "minute"));
|
1424
|
+
t.hour = NUM2INT(rb_iv_get(argv[i], "hour"));
|
1425
|
+
t.day = NUM2INT(rb_iv_get(argv[i], "day"));
|
1426
|
+
t.month = NUM2INT(rb_iv_get(argv[i], "month"));
|
1427
|
+
t.year = NUM2INT(rb_iv_get(argv[i], "year"));
|
1428
|
+
*(MYSQL_TIME*)&(s->param.buffer[i]) = t;
|
1429
|
+
} else
|
1430
|
+
rb_raise(rb_eTypeError, "unsupported type: %d", TYPE(argv[i]));
|
1431
|
+
}
|
1432
|
+
}
|
1433
|
+
if (mysql_stmt_bind_param(stmt, s->param.bind))
|
1434
|
+
mysql_stmt_raise(stmt);
|
1382
1435
|
}
|
1383
|
-
if (mysql_stmt_bind_param(stmt, s->param.bind))
|
1384
|
-
mysql_stmt_raise(stmt);
|
1385
1436
|
|
1386
1437
|
if (mysql_stmt_execute(stmt))
|
1387
1438
|
mysql_stmt_raise(stmt);
|
@@ -1391,16 +1442,47 @@ static VALUE stmt_execute(int argc, VALUE *argv, VALUE obj)
|
|
1391
1442
|
mysql_stmt_raise(stmt);
|
1392
1443
|
field = mysql_fetch_fields(s->res);
|
1393
1444
|
for (i = 0; i < s->result.n; i++) {
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1445
|
+
switch(s->result.bind[i].buffer_type) {
|
1446
|
+
case MYSQL_TYPE_NULL:
|
1447
|
+
break;
|
1448
|
+
case MYSQL_TYPE_TINY:
|
1449
|
+
case MYSQL_TYPE_SHORT:
|
1450
|
+
case MYSQL_TYPE_YEAR:
|
1451
|
+
case MYSQL_TYPE_INT24:
|
1452
|
+
case MYSQL_TYPE_LONG:
|
1453
|
+
case MYSQL_TYPE_LONGLONG:
|
1454
|
+
case MYSQL_TYPE_FLOAT:
|
1455
|
+
case MYSQL_TYPE_DOUBLE:
|
1456
|
+
s->result.bind[i].buffer = xmalloc(8);
|
1457
|
+
s->result.bind[i].buffer_length = 8;
|
1458
|
+
memset(s->result.bind[i].buffer, 0, 8);
|
1459
|
+
break;
|
1460
|
+
case MYSQL_TYPE_DECIMAL:
|
1461
|
+
case MYSQL_TYPE_STRING:
|
1462
|
+
case MYSQL_TYPE_VAR_STRING:
|
1463
|
+
case MYSQL_TYPE_TINY_BLOB:
|
1464
|
+
case MYSQL_TYPE_BLOB:
|
1465
|
+
case MYSQL_TYPE_MEDIUM_BLOB:
|
1466
|
+
case MYSQL_TYPE_LONG_BLOB:
|
1467
|
+
#if MYSQL_VERSION_ID >= 50003
|
1468
|
+
case MYSQL_TYPE_NEWDECIMAL:
|
1469
|
+
case MYSQL_TYPE_BIT:
|
1470
|
+
#endif
|
1471
|
+
s->result.bind[i].buffer = xmalloc(field[i].max_length);
|
1397
1472
|
memset(s->result.bind[i].buffer, 0, field[i].max_length);
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1473
|
+
s->result.bind[i].buffer_length = field[i].max_length;
|
1474
|
+
break;
|
1475
|
+
case MYSQL_TYPE_TIME:
|
1476
|
+
case MYSQL_TYPE_DATE:
|
1477
|
+
case MYSQL_TYPE_DATETIME:
|
1478
|
+
case MYSQL_TYPE_TIMESTAMP:
|
1479
|
+
s->result.bind[i].buffer = xmalloc(sizeof(MYSQL_TIME));
|
1480
|
+
s->result.bind[i].buffer_length = sizeof(MYSQL_TIME);
|
1402
1481
|
memset(s->result.bind[i].buffer, 0, sizeof(MYSQL_TIME));
|
1403
|
-
|
1482
|
+
break;
|
1483
|
+
default:
|
1484
|
+
rb_raise(rb_eTypeError, "unknown buffer_type: %d", s->result.bind[i].buffer_type);
|
1485
|
+
}
|
1404
1486
|
}
|
1405
1487
|
if (mysql_stmt_bind_result(s->stmt, s->result.bind))
|
1406
1488
|
mysql_stmt_raise(s->stmt);
|
@@ -1420,6 +1502,10 @@ static VALUE stmt_fetch(VALUE obj)
|
|
1420
1502
|
r = mysql_stmt_fetch(s->stmt);
|
1421
1503
|
if (r == MYSQL_NO_DATA)
|
1422
1504
|
return Qnil;
|
1505
|
+
#ifdef MYSQL_DATA_TRUNCATED
|
1506
|
+
if (r == MYSQL_DATA_TRUNCATED)
|
1507
|
+
rb_raise(rb_eRuntimeError, "unexpectedly data truncated");
|
1508
|
+
#endif
|
1423
1509
|
if (r == 1)
|
1424
1510
|
mysql_stmt_raise(s->stmt);
|
1425
1511
|
|
@@ -1431,34 +1517,66 @@ static VALUE stmt_fetch(VALUE obj)
|
|
1431
1517
|
VALUE v;
|
1432
1518
|
MYSQL_TIME *t;
|
1433
1519
|
switch (s->result.bind[i].buffer_type) {
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1520
|
+
case MYSQL_TYPE_TINY:
|
1521
|
+
if (s->result.bind[i].is_unsigned)
|
1522
|
+
v = UINT2NUM(*(unsigned char *)s->result.bind[i].buffer);
|
1523
|
+
else
|
1524
|
+
v = INT2NUM(*(signed char *)s->result.bind[i].buffer);
|
1525
|
+
break;
|
1526
|
+
case MYSQL_TYPE_SHORT:
|
1527
|
+
case MYSQL_TYPE_YEAR:
|
1528
|
+
if (s->result.bind[i].is_unsigned)
|
1529
|
+
v = UINT2NUM(*(unsigned short *)s->result.bind[i].buffer);
|
1530
|
+
else
|
1531
|
+
v = INT2NUM(*(short *)s->result.bind[i].buffer);
|
1532
|
+
break;
|
1533
|
+
case MYSQL_TYPE_INT24:
|
1534
|
+
case MYSQL_TYPE_LONG:
|
1535
|
+
if (s->result.bind[i].is_unsigned)
|
1536
|
+
v = UINT2NUM(*(unsigned int *)s->result.bind[i].buffer);
|
1537
|
+
else
|
1538
|
+
v = INT2NUM(*(int *)s->result.bind[i].buffer);
|
1539
|
+
break;
|
1540
|
+
case MYSQL_TYPE_LONGLONG:
|
1541
|
+
if (s->result.bind[i].is_unsigned)
|
1542
|
+
v = ULL2NUM(*(unsigned long long *)s->result.bind[i].buffer);
|
1543
|
+
else
|
1544
|
+
v = LL2NUM(*(long long *)s->result.bind[i].buffer);
|
1545
|
+
break;
|
1546
|
+
case MYSQL_TYPE_FLOAT:
|
1547
|
+
v = rb_float_new((double)(*(float *)s->result.bind[i].buffer));
|
1548
|
+
break;
|
1549
|
+
case MYSQL_TYPE_DOUBLE:
|
1550
|
+
v = rb_float_new(*(double *)s->result.bind[i].buffer);
|
1551
|
+
break;
|
1552
|
+
case MYSQL_TYPE_TIME:
|
1553
|
+
case MYSQL_TYPE_DATE:
|
1554
|
+
case MYSQL_TYPE_DATETIME:
|
1555
|
+
case MYSQL_TYPE_TIMESTAMP:
|
1556
|
+
t = (MYSQL_TIME *)s->result.bind[i].buffer;
|
1557
|
+
v = rb_obj_alloc(cMysqlTime);
|
1558
|
+
rb_funcall(v, rb_intern("initialize"), 8,
|
1559
|
+
INT2FIX(t->year), INT2FIX(t->month),
|
1560
|
+
INT2FIX(t->day), INT2FIX(t->hour),
|
1561
|
+
INT2FIX(t->minute), INT2FIX(t->second),
|
1562
|
+
(t->neg ? Qtrue : Qfalse),
|
1563
|
+
INT2FIX(t->second_part));
|
1564
|
+
break;
|
1565
|
+
case MYSQL_TYPE_DECIMAL:
|
1566
|
+
case MYSQL_TYPE_STRING:
|
1567
|
+
case MYSQL_TYPE_VAR_STRING:
|
1568
|
+
case MYSQL_TYPE_TINY_BLOB:
|
1569
|
+
case MYSQL_TYPE_BLOB:
|
1570
|
+
case MYSQL_TYPE_MEDIUM_BLOB:
|
1571
|
+
case MYSQL_TYPE_LONG_BLOB:
|
1572
|
+
#if MYSQL_VERSION_ID >= 50003
|
1573
|
+
case MYSQL_TYPE_NEWDECIMAL:
|
1574
|
+
case MYSQL_TYPE_BIT:
|
1575
|
+
#endif
|
1576
|
+
v = rb_tainted_str_new(s->result.bind[i].buffer, s->result.length[i]);
|
1577
|
+
break;
|
1578
|
+
default:
|
1579
|
+
rb_raise(rb_eTypeError, "unknown buffer_type: %d", s->result.bind[i].buffer_type);
|
1462
1580
|
}
|
1463
1581
|
rb_ary_push(ret, v);
|
1464
1582
|
}
|
@@ -1491,10 +1609,6 @@ static VALUE stmt_free_result(VALUE obj)
|
|
1491
1609
|
{
|
1492
1610
|
struct mysql_stmt* s = DATA_PTR(obj);
|
1493
1611
|
check_stmt_closed(obj);
|
1494
|
-
if (s->res) {
|
1495
|
-
mysql_free_result(s->res);
|
1496
|
-
s->res = NULL;
|
1497
|
-
}
|
1498
1612
|
if (mysql_stmt_free_result(s->stmt))
|
1499
1613
|
mysql_stmt_raise(s->stmt);
|
1500
1614
|
return obj;
|
@@ -1531,46 +1645,6 @@ static VALUE stmt_param_count(VALUE obj)
|
|
1531
1645
|
}
|
1532
1646
|
|
1533
1647
|
/* prepare(query) */
|
1534
|
-
static enum enum_field_types buffer_type(MYSQL_FIELD *field)
|
1535
|
-
{
|
1536
|
-
switch (field->type) {
|
1537
|
-
case FIELD_TYPE_TINY:
|
1538
|
-
case FIELD_TYPE_SHORT:
|
1539
|
-
case FIELD_TYPE_INT24:
|
1540
|
-
case FIELD_TYPE_YEAR:
|
1541
|
-
return MYSQL_TYPE_LONG;
|
1542
|
-
case FIELD_TYPE_LONG:
|
1543
|
-
case FIELD_TYPE_LONGLONG:
|
1544
|
-
return MYSQL_TYPE_LONGLONG;
|
1545
|
-
case FIELD_TYPE_FLOAT:
|
1546
|
-
case FIELD_TYPE_DOUBLE:
|
1547
|
-
return MYSQL_TYPE_DOUBLE;
|
1548
|
-
case FIELD_TYPE_TIMESTAMP:
|
1549
|
-
return MYSQL_TYPE_TIMESTAMP;
|
1550
|
-
case FIELD_TYPE_DATE:
|
1551
|
-
return MYSQL_TYPE_DATE;
|
1552
|
-
case FIELD_TYPE_TIME:
|
1553
|
-
return MYSQL_TYPE_TIME;
|
1554
|
-
case FIELD_TYPE_DATETIME:
|
1555
|
-
return MYSQL_TYPE_DATETIME;
|
1556
|
-
case FIELD_TYPE_STRING:
|
1557
|
-
case FIELD_TYPE_VAR_STRING:
|
1558
|
-
case FIELD_TYPE_SET:
|
1559
|
-
case FIELD_TYPE_ENUM:
|
1560
|
-
case FIELD_TYPE_DECIMAL:
|
1561
|
-
#if MYSQL_VERSION_ID >= 50003
|
1562
|
-
case FIELD_TYPE_NEWDECIMAL:
|
1563
|
-
#endif
|
1564
|
-
return MYSQL_TYPE_STRING;
|
1565
|
-
case FIELD_TYPE_BLOB:
|
1566
|
-
return MYSQL_TYPE_BLOB;
|
1567
|
-
case FIELD_TYPE_NULL:
|
1568
|
-
return MYSQL_TYPE_NULL;
|
1569
|
-
default:
|
1570
|
-
rb_raise(rb_eTypeError, "unknown type: %d", field->type);
|
1571
|
-
}
|
1572
|
-
}
|
1573
|
-
|
1574
1648
|
static VALUE stmt_prepare(VALUE obj, VALUE query)
|
1575
1649
|
{
|
1576
1650
|
struct mysql_stmt* s = DATA_PTR(obj);
|
@@ -1581,7 +1655,7 @@ static VALUE stmt_prepare(VALUE obj, VALUE query)
|
|
1581
1655
|
free_mysqlstmt_memory(s);
|
1582
1656
|
check_stmt_closed(obj);
|
1583
1657
|
Check_Type(query, T_STRING);
|
1584
|
-
if (mysql_stmt_prepare(s->stmt,
|
1658
|
+
if (mysql_stmt_prepare(s->stmt, RSTRING_PTR(query), RSTRING_LEN(query)))
|
1585
1659
|
mysql_stmt_raise(s->stmt);
|
1586
1660
|
|
1587
1661
|
n = mysql_stmt_param_count(s->stmt);
|
@@ -1599,9 +1673,14 @@ static VALUE stmt_prepare(VALUE obj, VALUE query)
|
|
1599
1673
|
field = mysql_fetch_fields(s->res);
|
1600
1674
|
memset(s->result.bind, 0, sizeof(s->result.bind[0]) * n);
|
1601
1675
|
for (i = 0; i < n; i++) {
|
1602
|
-
|
1676
|
+
s->result.bind[i].buffer_type = field[i].type;
|
1677
|
+
#if MYSQL_VERSION_ID < 50003
|
1678
|
+
if (field[i].type == MYSQL_TYPE_DECIMAL)
|
1679
|
+
s->result.bind[i].buffer_type = MYSQL_TYPE_STRING;
|
1680
|
+
#endif
|
1603
1681
|
s->result.bind[i].is_null = &(s->result.is_null[i]);
|
1604
1682
|
s->result.bind[i].length = &(s->result.length[i]);
|
1683
|
+
s->result.bind[i].is_unsigned = ((field[i].flags & UNSIGNED_FLAG) != 0);
|
1605
1684
|
}
|
1606
1685
|
} else {
|
1607
1686
|
if (mysql_stmt_errno(s->stmt))
|
@@ -1630,8 +1709,11 @@ static VALUE stmt_result_metadata(VALUE obj)
|
|
1630
1709
|
MYSQL_RES *res;
|
1631
1710
|
check_stmt_closed(obj);
|
1632
1711
|
res = mysql_stmt_result_metadata(s->stmt);
|
1633
|
-
if (res == NULL
|
1712
|
+
if (res == NULL) {
|
1713
|
+
if (mysql_stmt_errno(s->stmt) != 0)
|
1634
1714
|
mysql_stmt_raise(s->stmt);
|
1715
|
+
return Qnil;
|
1716
|
+
}
|
1635
1717
|
return mysqlres2obj(res);
|
1636
1718
|
}
|
1637
1719
|
|
@@ -1670,7 +1752,7 @@ static VALUE stmt_send_long_data(VALUE obj, VALUE col, VALUE data)
|
|
1670
1752
|
if (mysql_stmt_bind_param(s->stmt, s->param.bind))
|
1671
1753
|
mysql_stmt_raise(s->stmt);
|
1672
1754
|
}
|
1673
|
-
if (mysql_stmt_send_long_data(s->stmt, c,
|
1755
|
+
if (mysql_stmt_send_long_data(s->stmt, c, RSTRING_PTR(data), RSTRING_LEN(data)))
|
1674
1756
|
mysql_stmt_raise(s->stmt);
|
1675
1757
|
return obj;
|
1676
1758
|
}
|
@@ -1700,6 +1782,7 @@ static VALUE time_initialize(int argc, VALUE* argv, VALUE obj)
|
|
1700
1782
|
rb_iv_set(obj, "second", NILorFIXvalue(second));
|
1701
1783
|
rb_iv_set(obj, "neg", (neg == Qnil || neg == Qfalse) ? Qfalse : Qtrue);
|
1702
1784
|
rb_iv_set(obj, "second_part", NILorFIXvalue(second_part));
|
1785
|
+
return obj;
|
1703
1786
|
}
|
1704
1787
|
|
1705
1788
|
static VALUE time_inspect(VALUE obj)
|
@@ -1799,7 +1882,7 @@ static VALUE error_sqlstate(VALUE obj)
|
|
1799
1882
|
* Initialize
|
1800
1883
|
*/
|
1801
1884
|
|
1802
|
-
void
|
1885
|
+
void Init_mysql_api(void)
|
1803
1886
|
{
|
1804
1887
|
cMysql = rb_define_class("Mysql", rb_cObject);
|
1805
1888
|
cMysqlRes = rb_define_class_under(cMysql, "Result", rb_cObject);
|
@@ -2080,6 +2163,10 @@ void Init_mysql(void)
|
|
2080
2163
|
rb_define_const(cMysqlField, "TYPE_DATETIME", INT2NUM(FIELD_TYPE_DATETIME));
|
2081
2164
|
#if MYSQL_VERSION_ID >= 32130
|
2082
2165
|
rb_define_const(cMysqlField, "TYPE_YEAR", INT2NUM(FIELD_TYPE_YEAR));
|
2166
|
+
#endif
|
2167
|
+
#if MYSQL_VERSION_ID >= 50003
|
2168
|
+
rb_define_const(cMysqlField, "TYPE_BIT", INT2NUM(FIELD_TYPE_BIT));
|
2169
|
+
rb_define_const(cMysqlField, "TYPE_NEWDECIMAL", INT2NUM(FIELD_TYPE_NEWDECIMAL));
|
2083
2170
|
#endif
|
2084
2171
|
rb_define_const(cMysqlField, "TYPE_SET", INT2NUM(FIELD_TYPE_SET));
|
2085
2172
|
rb_define_const(cMysqlField, "TYPE_BLOB", INT2NUM(FIELD_TYPE_BLOB));
|
@@ -2181,4 +2268,6 @@ void Init_mysql(void)
|
|
2181
2268
|
rb_define_method(eMysql, "sqlstate", error_sqlstate, 0);
|
2182
2269
|
|
2183
2270
|
/* Mysql::Error constant */
|
2271
|
+
#define rb_define_mysql_const(s) rb_define_const(eMysql, #s, INT2NUM(s))
|
2272
|
+
#include "error_const.h"
|
2184
2273
|
}
|