mysql 2.7 → 2.8.1

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