mysql 2.7 → 2.8.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|