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.
@@ -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)
@@ -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
@@ -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.
@@ -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.in,v 1.30 2005/08/21 15:15:38 tommy Exp $
2
+ * $Id: mysql.c 244 2009-02-01 08:43:39Z tommy $
3
3
  */
4
4
 
5
- #include "ruby.h"
6
- #include "version.h"
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 20700
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
- free(my);
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
- free(resp);
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
- free(s);
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
- mysql_raise(&myp->handler);
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, (RSTRING(str)->len)*2+1);
268
- RSTRING(ret)->len = mysql_escape_string(RSTRING(ret)->ptr, RSTRING(str)->ptr, RSTRING(str)->len);
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
- if (mysql_real_connect(m, h, u, p, d, pp, s, f) == NULL)
317
- mysql_raise(m);
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, (RSTRING(str)->len)*2+1);
402
- RSTRING(ret)->len = mysql_real_escape_string(m, RSTRING(ret)->ptr, RSTRING(str)->ptr, RSTRING(str)->len);
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
- #if MYSQL_VERSION_ID >= 40101
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
- while (mysql_next_result(m) == 0);
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, RSTRING(sql)->ptr, RSTRING(sql)->len) != 0)
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
- VALUE col;
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, RSTRING(n)->len + 16);
1158
- sprintf(RSTRING(s)->ptr, "#<Mysql::Field:%s>", RSTRING(n)->ptr);
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
- s->result.bind[i].buffer_type = buffer_type(&field[i]);
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", RSTRING(rb_inspect(argv[i]))->ptr);
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
- memset(s->param.bind, 0, sizeof(*(s->param.bind))*argc);
1323
- for (i = 0; i < argc; i++) {
1324
- switch (TYPE(argv[i])) {
1325
- case T_NIL:
1326
- s->param.bind[i].buffer_type = MYSQL_TYPE_NULL;
1327
- s->param.bind[i].is_null = &true;
1328
- break;
1329
- case T_FIXNUM:
1330
- s->param.bind[i].buffer_type = MYSQL_TYPE_LONG;
1331
- s->param.bind[i].buffer = &(s->param.buffer[i]);
1332
- *(long*)(s->param.bind[i].buffer) = FIX2INT(argv[i]);
1333
- break;
1334
- case T_BIGNUM:
1335
- s->param.bind[i].buffer_type = MYSQL_TYPE_LONGLONG;
1336
- s->param.bind[i].buffer = &(s->param.buffer[i]);
1337
- *(long long*)(s->param.bind[i].buffer) = rb_big2ll(argv[i]);
1338
- break;
1339
- case T_FLOAT:
1340
- s->param.bind[i].buffer_type = MYSQL_TYPE_DOUBLE;
1341
- s->param.bind[i].buffer = &(s->param.buffer[i]);
1342
- *(double*)(s->param.bind[i].buffer) = NUM2DBL(argv[i]);
1343
- break;
1344
- case T_STRING:
1345
- s->param.bind[i].buffer_type = MYSQL_TYPE_STRING;
1346
- s->param.bind[i].buffer = RSTRING(argv[i])->ptr;
1347
- s->param.bind[i].buffer_length = RSTRING(argv[i])->len;
1348
- s->param.length[i] = RSTRING(argv[i])->len;
1349
- s->param.bind[i].length = &(s->param.length[i]);
1350
- break;
1351
- default:
1352
- if (CLASS_OF(argv[i]) == rb_cTime) {
1353
- MYSQL_TIME t;
1354
- VALUE a = rb_funcall(argv[i], rb_intern("to_a"), 0);
1355
- s->param.bind[i].buffer_type = MYSQL_TYPE_DATETIME;
1356
- s->param.bind[i].buffer = &(s->param.buffer[i]);
1357
- t.second_part = 0;
1358
- t.neg = 0;
1359
- t.second = FIX2INT(RARRAY(a)->ptr[0]);
1360
- t.minute = FIX2INT(RARRAY(a)->ptr[1]);
1361
- t.hour = FIX2INT(RARRAY(a)->ptr[2]);
1362
- t.day = FIX2INT(RARRAY(a)->ptr[3]);
1363
- t.month = FIX2INT(RARRAY(a)->ptr[4]);
1364
- t.year = FIX2INT(RARRAY(a)->ptr[5]);
1365
- *(MYSQL_TIME*)&(s->param.buffer[i]) = t;
1366
- } else if (CLASS_OF(argv[i]) == cMysqlTime) {
1367
- MYSQL_TIME t;
1368
- s->param.bind[i].buffer_type = MYSQL_TYPE_DATETIME;
1369
- s->param.bind[i].buffer = &(s->param.buffer[i]);
1370
- t.second_part = 0;
1371
- t.neg = 0;
1372
- t.second = NUM2INT(rb_iv_get(argv[i], "second"));
1373
- t.minute = NUM2INT(rb_iv_get(argv[i], "minute"));
1374
- t.hour = NUM2INT(rb_iv_get(argv[i], "hour"));
1375
- t.day = NUM2INT(rb_iv_get(argv[i], "day"));
1376
- t.month = NUM2INT(rb_iv_get(argv[i], "month"));
1377
- t.year = NUM2INT(rb_iv_get(argv[i], "year"));
1378
- *(MYSQL_TIME*)&(s->param.buffer[i]) = t;
1379
- } else
1380
- rb_raise(rb_eTypeError, "unsupported type: %d", TYPE(argv[i]));
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
- if (s->result.bind[i].buffer_type == MYSQL_TYPE_STRING ||
1395
- s->result.bind[i].buffer_type == MYSQL_TYPE_BLOB) {
1396
- s->result.bind[i].buffer = xmalloc(field[i].max_length);
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
- s->result.bind[i].buffer_length = field[i].max_length;
1399
- } else {
1400
- s->result.bind[i].buffer = xmalloc(sizeof(MYSQL_TIME));
1401
- s->result.bind[i].buffer_length = sizeof(MYSQL_TIME);
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
- case MYSQL_TYPE_LONG:
1435
- v = INT2NUM(*(long*)s->result.bind[i].buffer);
1436
- break;
1437
- case MYSQL_TYPE_LONGLONG:
1438
- v = rb_ll2inum(*(long long*)s->result.bind[i].buffer);
1439
- break;
1440
- case MYSQL_TYPE_DOUBLE:
1441
- v = rb_float_new(*(double*)s->result.bind[i].buffer);
1442
- break;
1443
- case MYSQL_TYPE_TIMESTAMP:
1444
- case MYSQL_TYPE_DATE:
1445
- case MYSQL_TYPE_TIME:
1446
- case MYSQL_TYPE_DATETIME:
1447
- t = (MYSQL_TIME*)s->result.bind[i].buffer;
1448
- v = rb_obj_alloc(cMysqlTime);
1449
- rb_funcall(v, rb_intern("initialize"), 8,
1450
- INT2FIX(t->year), INT2FIX(t->month),
1451
- INT2FIX(t->day), INT2FIX(t->hour),
1452
- INT2FIX(t->minute), INT2FIX(t->second),
1453
- (t->neg ? Qtrue : Qfalse),
1454
- INT2FIX(t->second_part));
1455
- break;
1456
- case MYSQL_TYPE_STRING:
1457
- case MYSQL_TYPE_BLOB:
1458
- v = rb_tainted_str_new(s->result.bind[i].buffer, s->result.length[i]);
1459
- break;
1460
- default:
1461
- rb_raise(rb_eTypeError, "unknown buffer_type: %d", s->result.bind[i].buffer_type);
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, RSTRING(query)->ptr, RSTRING(query)->len))
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
- s->result.bind[i].buffer_type = buffer_type(&field[i]);
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 && mysql_stmt_errno(s->stmt) != 0)
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, RSTRING(data)->ptr, RSTRING(data)->len))
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 Init_mysql(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
  }