mysql 2.6 → 2.7

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.
Files changed (7) hide show
  1. data/README.html +228 -12
  2. data/README_ja.html +273 -14
  3. data/mysql.c.in +783 -8
  4. data/mysql.gemspec +34 -11
  5. data/test.rb +1022 -22
  6. data/tommy.css +6 -0
  7. metadata +13 -11
data/mysql.c.in CHANGED
@@ -1,5 +1,5 @@
1
1
  /* ruby mysql module
2
- * $Id: mysql.c.in,v 1.16 2005/04/19 14:20:03 tommy Exp $
2
+ * $Id: mysql.c.in,v 1.30 2005/08/21 15:15:38 tommy Exp $
3
3
  */
4
4
 
5
5
  #include "ruby.h"
@@ -14,6 +14,8 @@
14
14
  #include <mysql/mysqld_error.h>
15
15
  #endif
16
16
 
17
+ #define MYSQL_RUBY_VERSION 20700
18
+
17
19
  #define GC_STORE_RESULT_LIMIT 20
18
20
 
19
21
  #ifndef Qtrue /* ruby 1.2.x ? */
@@ -42,10 +44,14 @@
42
44
  #define GetMysqlStruct(obj) (Check_Type(obj, T_DATA), (struct mysql*)DATA_PTR(obj))
43
45
  #define GetHandler(obj) (Check_Type(obj, T_DATA), &(((struct mysql*)DATA_PTR(obj))->handler))
44
46
  #define GetMysqlRes(obj) (Check_Type(obj, T_DATA), ((struct mysql_res*)DATA_PTR(obj))->res)
47
+ #define GetMysqlStmt(obj) (Check_Type(obj, T_DATA), ((struct mysql_stmt*)DATA_PTR(obj))->stmt)
45
48
 
46
49
  VALUE cMysql;
47
50
  VALUE cMysqlRes;
48
51
  VALUE cMysqlField;
52
+ VALUE cMysqlStmt;
53
+ VALUE cMysqlRowOffset;
54
+ VALUE cMysqlTime;
49
55
  VALUE eMysql;
50
56
 
51
57
  static int store_result_count = 0;
@@ -61,6 +67,25 @@ struct mysql_res {
61
67
  char freed;
62
68
  };
63
69
 
70
+ #if MYSQL_VERSION_ID >= 40101
71
+ struct mysql_stmt {
72
+ MYSQL_STMT *stmt;
73
+ char closed;
74
+ struct {
75
+ int n;
76
+ MYSQL_BIND *bind;
77
+ unsigned long *length;
78
+ MYSQL_TIME *buffer;
79
+ } param;
80
+ struct {
81
+ int n;
82
+ MYSQL_BIND *bind;
83
+ my_bool *is_null;
84
+ unsigned long *length;
85
+ } result;
86
+ MYSQL_RES *res;
87
+ };
88
+ #endif
64
89
 
65
90
  /* free Mysql class object */
66
91
  static void free_mysql(struct mysql* my)
@@ -79,10 +104,64 @@ static void free_mysqlres(struct mysql_res* resp)
79
104
  free(resp);
80
105
  }
81
106
 
107
+ #if MYSQL_VERSION_ID >= 40101
108
+ static void free_mysqlstmt_memory(struct mysql_stmt *s)
109
+ {
110
+ if (s->param.bind) {
111
+ xfree(s->param.bind);
112
+ s->param.bind = NULL;
113
+ }
114
+ if (s->param.length) {
115
+ xfree(s->param.length);
116
+ s->param.length = NULL;
117
+ }
118
+ if (s->param.buffer) {
119
+ xfree(s->param.buffer);
120
+ s->param.buffer = NULL;
121
+ }
122
+ s->param.n = 0;
123
+ if (s->res) {
124
+ mysql_free_result(s->res);
125
+ s->res = NULL;
126
+ }
127
+ if (s->result.bind) {
128
+ int i;
129
+ for (i = 0; i < s->result.n; i++) {
130
+ if (s->result.bind[i].buffer)
131
+ xfree(s->result.bind[i].buffer);
132
+ }
133
+ xfree(s->result.bind);
134
+ s->result.bind = NULL;
135
+ }
136
+ if (s->result.is_null) {
137
+ xfree(s->result.is_null);
138
+ s->result.is_null = NULL;
139
+ }
140
+ if (s->result.length) {
141
+ xfree(s->result.length);
142
+ s->result.length = NULL;
143
+ }
144
+ s->result.n = 0;
145
+ }
146
+
147
+ static void free_mysqlstmt(struct mysql_stmt* s)
148
+ {
149
+ free_mysqlstmt_memory(s);
150
+ if (s->closed == Qfalse)
151
+ mysql_stmt_close(s->stmt);
152
+ if (s->res)
153
+ mysql_free_result(s->res);
154
+ free(s);
155
+ }
156
+ #endif
157
+
82
158
  static void mysql_raise(MYSQL* m)
83
159
  {
84
160
  VALUE e = rb_exc_new2(eMysql, mysql_error(m));
85
161
  rb_iv_set(e, "errno", INT2FIX(mysql_errno(m)));
162
+ #if MYSQL_VERSION_ID >= 40101
163
+ rb_iv_set(e, "sqlstate", rb_tainted_str_new2(mysql_sqlstate(m)));
164
+ #endif
86
165
  rb_exc_raise(e);
87
166
  }
88
167
 
@@ -275,6 +354,9 @@ static VALUE options(int argc, VALUE* argv, VALUE obj)
275
354
  #endif
276
355
  #if MYSQL_VERSION_ID >= 40100
277
356
  case MYSQL_SHARED_MEMORY_BASE_NAME:
357
+ #endif
358
+ #if MYSQL_VERSION_ID >= 40101
359
+ case MYSQL_SET_CLIENT_IP:
278
360
  #endif
279
361
  if (val == Qnil)
280
362
  rb_raise(rb_eArgError, "wrong # of arguments(1 for 2)");
@@ -614,6 +696,7 @@ static VALUE use_result(VALUE obj)
614
696
  return mysqlres2obj(res);
615
697
  }
616
698
 
699
+ static VALUE res_free(VALUE);
617
700
  /* query(sql) */
618
701
  static VALUE query(VALUE obj, VALUE sql)
619
702
  {
@@ -621,7 +704,7 @@ static VALUE query(VALUE obj, VALUE sql)
621
704
  Check_Type(sql, T_STRING);
622
705
  if (rb_block_given_p()) {
623
706
  #if MYSQL_VERSION_ID >= 40101
624
- if (mysql_set_server_option(m, MYSQL_OPTION_MULTI_STATEMENTS_ON) != 0)
707
+ if (mysql_get_server_version(m) >= 40101 && mysql_set_server_option(m, MYSQL_OPTION_MULTI_STATEMENTS_ON) != 0)
625
708
  mysql_raise(m);
626
709
  #endif
627
710
  if (mysql_real_query(m, RSTRING(sql)->ptr, RSTRING(sql)->len) != 0)
@@ -632,7 +715,6 @@ static VALUE query(VALUE obj, VALUE sql)
632
715
  if (mysql_field_count(m) != 0)
633
716
  mysql_raise(m);
634
717
  } else {
635
- static VALUE res_free(VALUE);
636
718
  VALUE robj = mysqlres2obj(res);
637
719
  rb_ensure(rb_yield, robj, res_free, robj);
638
720
  }
@@ -755,6 +837,37 @@ static VALUE sqlstate(VALUE obj)
755
837
  }
756
838
  #endif
757
839
 
840
+ #if MYSQL_VERSION_ID >= 40102
841
+ /* stmt_init() */
842
+ static VALUE stmt_init(VALUE obj)
843
+ {
844
+ MYSQL *m = GetHandler(obj);
845
+ MYSQL_STMT *s;
846
+ struct mysql_stmt* stmt;
847
+ my_bool true = 1;
848
+ VALUE st_obj;
849
+
850
+ if ((s = mysql_stmt_init(m)) == NULL)
851
+ mysql_raise(m);
852
+ if (mysql_stmt_attr_set(s, STMT_ATTR_UPDATE_MAX_LENGTH, &true))
853
+ rb_raise(rb_eArgError, "mysql_stmt_attr_set() failed");
854
+ st_obj = Data_Make_Struct(cMysqlStmt, struct mysql_stmt, 0, free_mysqlstmt, stmt);
855
+ memset(stmt, 0, sizeof(*stmt));
856
+ stmt->stmt = s;
857
+ stmt->closed = Qfalse;
858
+ return st_obj;
859
+ }
860
+
861
+ static VALUE stmt_prepare(VALUE obj, VALUE query);
862
+ /* prepare(query) */
863
+ static VALUE prepare(VALUE obj, VALUE query)
864
+ {
865
+ VALUE st;
866
+ st = stmt_init(obj);
867
+ return stmt_prepare(st, query);
868
+ }
869
+ #endif
870
+
758
871
  /* query_with_result() */
759
872
  static VALUE query_with_result(VALUE obj)
760
873
  {
@@ -791,7 +904,7 @@ static VALUE reconnect_set(VALUE obj, VALUE flag)
791
904
  * Mysql::Result object method
792
905
  */
793
906
 
794
- /* check if alread freed */
907
+ /* check if already freed */
795
908
  static void check_free(VALUE obj)
796
909
  {
797
910
  struct mysql_res* resp = DATA_PTR(obj);
@@ -912,8 +1025,6 @@ static VALUE fetch_hash2(VALUE obj, VALUE with_table)
912
1025
  hash = rb_hash_new();
913
1026
  for (i=0; i<n; i++) {
914
1027
  VALUE col;
915
- if (row[i] == NULL)
916
- continue;
917
1028
  if (with_table == Qnil || with_table == Qfalse)
918
1029
  col = rb_tainted_str_new2(fields[i].name);
919
1030
  else {
@@ -979,15 +1090,21 @@ static VALUE num_rows(VALUE obj)
979
1090
  /* row_seek(offset) */
980
1091
  static VALUE row_seek(VALUE obj, VALUE offset)
981
1092
  {
1093
+ MYSQL_ROW_OFFSET prev_offset;
1094
+ if (CLASS_OF(offset) != cMysqlRowOffset)
1095
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Mysql::RowOffset)", rb_obj_classname(offset));
982
1096
  check_free(obj);
983
- return INT2NUM((int)mysql_row_seek(GetMysqlRes(obj), (MYSQL_ROWS*)NUM2INT(offset)));
1097
+ prev_offset = mysql_row_seek(GetMysqlRes(obj), DATA_PTR(offset));
1098
+ return Data_Wrap_Struct(cMysqlRowOffset, 0, NULL, prev_offset);
984
1099
  }
985
1100
 
986
1101
  /* row_tell() */
987
1102
  static VALUE row_tell(VALUE obj)
988
1103
  {
1104
+ MYSQL_ROW_OFFSET offset;
989
1105
  check_free(obj);
990
- return INT2NUM((int)mysql_row_tell(GetMysqlRes(obj)));
1106
+ offset = mysql_row_tell(GetMysqlRes(obj));
1107
+ return Data_Wrap_Struct(cMysqlRowOffset, 0, NULL, offset);
991
1108
  }
992
1109
 
993
1110
  /* each {...} */
@@ -1079,6 +1196,586 @@ static VALUE field_is_pri_key(VALUE obj)
1079
1196
  }
1080
1197
  #endif
1081
1198
 
1199
+ #if MYSQL_VERSION_ID >= 40102
1200
+ /*-------------------------------
1201
+ * Mysql::Stmt object method
1202
+ */
1203
+
1204
+ /* check if stmt is already closed */
1205
+ static void check_stmt_closed(VALUE obj)
1206
+ {
1207
+ struct mysql_stmt* s = DATA_PTR(obj);
1208
+ if (s->closed == Qtrue)
1209
+ rb_raise(eMysql, "Mysql::Stmt object is already closed");
1210
+ }
1211
+
1212
+ static void mysql_stmt_raise(MYSQL_STMT* s)
1213
+ {
1214
+ VALUE e = rb_exc_new2(eMysql, mysql_stmt_error(s));
1215
+ rb_iv_set(e, "errno", INT2FIX(mysql_stmt_errno(s)));
1216
+ rb_iv_set(e, "sqlstate", rb_tainted_str_new2(mysql_stmt_sqlstate(s)));
1217
+ rb_exc_raise(e);
1218
+ }
1219
+
1220
+ /* affected_rows() */
1221
+ static VALUE stmt_affected_rows(VALUE obj)
1222
+ {
1223
+ struct mysql_stmt* s = DATA_PTR(obj);
1224
+ my_ulonglong n;
1225
+ check_stmt_closed(obj);
1226
+ n = mysql_stmt_affected_rows(s->stmt);
1227
+ return INT2NUM(n);
1228
+ }
1229
+
1230
+ #if 0
1231
+ /* attr_get(option) */
1232
+ static VALUE stmt_attr_get(VALUE obj, VALUE opt)
1233
+ {
1234
+ struct mysql_stmt* s = DATA_PTR(obj);
1235
+ check_stmt_closed(obj);
1236
+ if (NUM2INT(opt) == STMT_ATTR_UPDATE_MAX_LENGTH) {
1237
+ my_bool arg;
1238
+ mysql_stmt_attr_get(s->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &arg);
1239
+ return arg == 1 ? Qtrue : Qfalse;
1240
+ }
1241
+ rb_raise(eMysql, "unknown option: %d", NUM2INT(opt));
1242
+ }
1243
+
1244
+ /* attr_set(option, arg) */
1245
+ static VALUE stmt_attr_set(VALUE obj, VALUE opt, VALUE val)
1246
+ {
1247
+ struct mysql_stmt* s = DATA_PTR(obj);
1248
+ check_stmt_closed(obj);
1249
+ if (NUM2INT(opt) == STMT_ATTR_UPDATE_MAX_LENGTH) {
1250
+ my_bool arg;
1251
+ arg = (val == Qnil || val == Qfalse) ? 0 : 1;
1252
+ mysql_stmt_attr_set(s->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &arg);
1253
+ return obj;
1254
+ }
1255
+ rb_raise(eMysql, "unknown option: %d", NUM2INT(opt));
1256
+ }
1257
+ #endif
1258
+
1259
+ /* bind_result(bind,...) */
1260
+ static enum enum_field_types buffer_type(MYSQL_FIELD *field);
1261
+ static VALUE stmt_bind_result(int argc, VALUE *argv, VALUE obj)
1262
+ {
1263
+ struct mysql_stmt* s = DATA_PTR(obj);
1264
+ int i;
1265
+ MYSQL_FIELD *field;
1266
+
1267
+ check_stmt_closed(obj);
1268
+ if (argc != s->result.n)
1269
+ rb_raise(eMysql, "bind_result: result value count(%d) != number of argument(%d)", s->result.n, argc);
1270
+ for (i = 0; i < argc; i++) {
1271
+ if (argv[i] == Qnil || argv[i] == rb_cNilClass) {
1272
+ field = mysql_fetch_fields(s->res);
1273
+ s->result.bind[i].buffer_type = buffer_type(&field[i]);
1274
+ }
1275
+ else if (argv[i] == rb_cString)
1276
+ s->result.bind[i].buffer_type = MYSQL_TYPE_STRING;
1277
+ else if (argv[i] == rb_cNumeric || argv[i] == rb_cInteger || argv[i] == rb_cFixnum)
1278
+ s->result.bind[i].buffer_type = MYSQL_TYPE_LONGLONG;
1279
+ else if (argv[i] == rb_cFloat)
1280
+ s->result.bind[i].buffer_type = MYSQL_TYPE_DOUBLE;
1281
+ else if (argv[i] == cMysqlTime)
1282
+ s->result.bind[i].buffer_type = MYSQL_TYPE_DATETIME;
1283
+ else
1284
+ rb_raise(rb_eTypeError, "unrecognized class: %s", RSTRING(rb_inspect(argv[i]))->ptr);
1285
+ if (mysql_stmt_bind_result(s->stmt, s->result.bind))
1286
+ mysql_stmt_raise(s->stmt);
1287
+ }
1288
+ return obj;
1289
+ }
1290
+
1291
+ /* close() */
1292
+ static VALUE stmt_close(VALUE obj)
1293
+ {
1294
+ struct mysql_stmt* s = DATA_PTR(obj);
1295
+ check_stmt_closed(obj);
1296
+ mysql_stmt_close(s->stmt);
1297
+ s->closed = Qtrue;
1298
+ return Qnil;
1299
+ }
1300
+
1301
+ /* data_seek(offset) */
1302
+ static VALUE stmt_data_seek(VALUE obj, VALUE offset)
1303
+ {
1304
+ struct mysql_stmt* s = DATA_PTR(obj);
1305
+ check_stmt_closed(obj);
1306
+ mysql_stmt_data_seek(s->stmt, NUM2INT(offset));
1307
+ return obj;
1308
+ }
1309
+
1310
+ /* execute(arg,...) */
1311
+ static VALUE stmt_execute(int argc, VALUE *argv, VALUE obj)
1312
+ {
1313
+ struct mysql_stmt *s = DATA_PTR(obj);
1314
+ MYSQL_STMT *stmt = s->stmt;
1315
+ my_bool true = 1;
1316
+ my_bool false = 0;
1317
+ int i;
1318
+
1319
+ check_stmt_closed(obj);
1320
+ if (s->param.n != argc)
1321
+ 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
+ }
1382
+ }
1383
+ if (mysql_stmt_bind_param(stmt, s->param.bind))
1384
+ mysql_stmt_raise(stmt);
1385
+
1386
+ if (mysql_stmt_execute(stmt))
1387
+ mysql_stmt_raise(stmt);
1388
+ if (s->res) {
1389
+ MYSQL_FIELD *field;
1390
+ if (mysql_stmt_store_result(stmt))
1391
+ mysql_stmt_raise(stmt);
1392
+ field = mysql_fetch_fields(s->res);
1393
+ 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);
1397
+ 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);
1402
+ memset(s->result.bind[i].buffer, 0, sizeof(MYSQL_TIME));
1403
+ }
1404
+ }
1405
+ if (mysql_stmt_bind_result(s->stmt, s->result.bind))
1406
+ mysql_stmt_raise(s->stmt);
1407
+ }
1408
+ return obj;
1409
+ }
1410
+
1411
+ /* fetch() */
1412
+ static VALUE stmt_fetch(VALUE obj)
1413
+ {
1414
+ struct mysql_stmt* s = DATA_PTR(obj);
1415
+ VALUE ret;
1416
+ int i;
1417
+ int r;
1418
+
1419
+ check_stmt_closed(obj);
1420
+ r = mysql_stmt_fetch(s->stmt);
1421
+ if (r == MYSQL_NO_DATA)
1422
+ return Qnil;
1423
+ if (r == 1)
1424
+ mysql_stmt_raise(s->stmt);
1425
+
1426
+ ret = rb_ary_new2(s->result.n);
1427
+ for (i = 0; i < s->result.n; i++) {
1428
+ if (s->result.is_null[i])
1429
+ rb_ary_push(ret, Qnil);
1430
+ else {
1431
+ VALUE v;
1432
+ MYSQL_TIME *t;
1433
+ 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);
1462
+ }
1463
+ rb_ary_push(ret, v);
1464
+ }
1465
+ }
1466
+ return ret;
1467
+ }
1468
+
1469
+ /* each {...} */
1470
+ static VALUE stmt_each(VALUE obj)
1471
+ {
1472
+ VALUE row;
1473
+ check_stmt_closed(obj);
1474
+ while ((row = stmt_fetch(obj)) != Qnil)
1475
+ rb_yield(row);
1476
+ return obj;
1477
+ }
1478
+
1479
+ /* field_count() */
1480
+ static VALUE stmt_field_count(VALUE obj)
1481
+ {
1482
+ struct mysql_stmt* s = DATA_PTR(obj);
1483
+ unsigned int n;
1484
+ check_stmt_closed(obj);
1485
+ n = mysql_stmt_field_count(s->stmt);
1486
+ return INT2NUM(n);
1487
+ }
1488
+
1489
+ /* free_result() */
1490
+ static VALUE stmt_free_result(VALUE obj)
1491
+ {
1492
+ struct mysql_stmt* s = DATA_PTR(obj);
1493
+ check_stmt_closed(obj);
1494
+ if (s->res) {
1495
+ mysql_free_result(s->res);
1496
+ s->res = NULL;
1497
+ }
1498
+ if (mysql_stmt_free_result(s->stmt))
1499
+ mysql_stmt_raise(s->stmt);
1500
+ return obj;
1501
+ }
1502
+
1503
+ /* insert_id() */
1504
+ static VALUE stmt_insert_id(VALUE obj)
1505
+ {
1506
+ struct mysql_stmt* s = DATA_PTR(obj);
1507
+ my_ulonglong n;
1508
+ check_stmt_closed(obj);
1509
+ n = mysql_stmt_insert_id(s->stmt);
1510
+ return INT2NUM(n);
1511
+ }
1512
+
1513
+ /* num_rows() */
1514
+ static VALUE stmt_num_rows(VALUE obj)
1515
+ {
1516
+ struct mysql_stmt* s = DATA_PTR(obj);
1517
+ my_ulonglong n;
1518
+ check_stmt_closed(obj);
1519
+ n = mysql_stmt_num_rows(s->stmt);
1520
+ return INT2NUM(n);
1521
+ }
1522
+
1523
+ /* param_count() */
1524
+ static VALUE stmt_param_count(VALUE obj)
1525
+ {
1526
+ struct mysql_stmt* s = DATA_PTR(obj);
1527
+ unsigned long n;
1528
+ check_stmt_closed(obj);
1529
+ n = mysql_stmt_param_count(s->stmt);
1530
+ return INT2NUM(n);
1531
+ }
1532
+
1533
+ /* 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
+ static VALUE stmt_prepare(VALUE obj, VALUE query)
1575
+ {
1576
+ struct mysql_stmt* s = DATA_PTR(obj);
1577
+ int n;
1578
+ int i;
1579
+ MYSQL_FIELD *field;
1580
+
1581
+ free_mysqlstmt_memory(s);
1582
+ check_stmt_closed(obj);
1583
+ Check_Type(query, T_STRING);
1584
+ if (mysql_stmt_prepare(s->stmt, RSTRING(query)->ptr, RSTRING(query)->len))
1585
+ mysql_stmt_raise(s->stmt);
1586
+
1587
+ n = mysql_stmt_param_count(s->stmt);
1588
+ s->param.n = n;
1589
+ s->param.bind = xmalloc(sizeof(s->param.bind[0]) * n);
1590
+ s->param.length = xmalloc(sizeof(s->param.length[0]) * n);
1591
+ s->param.buffer = xmalloc(sizeof(s->param.buffer[0]) * n);
1592
+
1593
+ s->res = mysql_stmt_result_metadata(s->stmt);
1594
+ if (s->res) {
1595
+ n = s->result.n = mysql_num_fields(s->res);
1596
+ s->result.bind = xmalloc(sizeof(s->result.bind[0]) * n);
1597
+ s->result.is_null = xmalloc(sizeof(s->result.is_null[0]) * n);
1598
+ s->result.length = xmalloc(sizeof(s->result.length[0]) * n);
1599
+ field = mysql_fetch_fields(s->res);
1600
+ memset(s->result.bind, 0, sizeof(s->result.bind[0]) * n);
1601
+ for (i = 0; i < n; i++) {
1602
+ s->result.bind[i].buffer_type = buffer_type(&field[i]);
1603
+ s->result.bind[i].is_null = &(s->result.is_null[i]);
1604
+ s->result.bind[i].length = &(s->result.length[i]);
1605
+ }
1606
+ } else {
1607
+ if (mysql_stmt_errno(s->stmt))
1608
+ mysql_stmt_raise(s->stmt);
1609
+ }
1610
+
1611
+ return obj;
1612
+ }
1613
+
1614
+ #if 0
1615
+ /* reset() */
1616
+ static VALUE stmt_reset(VALUE obj)
1617
+ {
1618
+ struct mysql_stmt* s = DATA_PTR(obj);
1619
+ check_stmt_closed(obj);
1620
+ if (mysql_stmt_reset(s->stmt))
1621
+ mysql_stmt_raise(s->stmt);
1622
+ return obj;
1623
+ }
1624
+ #endif
1625
+
1626
+ /* result_metadata() */
1627
+ static VALUE stmt_result_metadata(VALUE obj)
1628
+ {
1629
+ struct mysql_stmt* s = DATA_PTR(obj);
1630
+ MYSQL_RES *res;
1631
+ check_stmt_closed(obj);
1632
+ res = mysql_stmt_result_metadata(s->stmt);
1633
+ if (res == NULL && mysql_stmt_errno(s->stmt) != 0)
1634
+ mysql_stmt_raise(s->stmt);
1635
+ return mysqlres2obj(res);
1636
+ }
1637
+
1638
+ /* row_seek(offset) */
1639
+ static VALUE stmt_row_seek(VALUE obj, VALUE offset)
1640
+ {
1641
+ struct mysql_stmt* s = DATA_PTR(obj);
1642
+ MYSQL_ROW_OFFSET prev_offset;
1643
+ if (CLASS_OF(offset) != cMysqlRowOffset)
1644
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Mysql::RowOffset)", rb_obj_classname(offset));
1645
+ check_stmt_closed(obj);
1646
+ prev_offset = mysql_stmt_row_seek(s->stmt, DATA_PTR(offset));
1647
+ return Data_Wrap_Struct(cMysqlRowOffset, 0, NULL, prev_offset);
1648
+ }
1649
+
1650
+ /* row_tell() */
1651
+ static VALUE stmt_row_tell(VALUE obj)
1652
+ {
1653
+ struct mysql_stmt* s = DATA_PTR(obj);
1654
+ MYSQL_ROW_OFFSET offset;
1655
+ check_stmt_closed(obj);
1656
+ offset = mysql_stmt_row_tell(s->stmt);
1657
+ return Data_Wrap_Struct(cMysqlRowOffset, 0, NULL, offset);
1658
+ }
1659
+
1660
+ #if 0
1661
+ /* send_long_data(col, data) */
1662
+ static VALUE stmt_send_long_data(VALUE obj, VALUE col, VALUE data)
1663
+ {
1664
+ struct mysql_stmt* s = DATA_PTR(obj);
1665
+ int c;
1666
+ check_stmt_closed(obj);
1667
+ c = NUM2INT(col);
1668
+ if (0 <= c && c < s->param.n) {
1669
+ s->param.bind[c].buffer_type = MYSQL_TYPE_STRING;
1670
+ if (mysql_stmt_bind_param(s->stmt, s->param.bind))
1671
+ mysql_stmt_raise(s->stmt);
1672
+ }
1673
+ if (mysql_stmt_send_long_data(s->stmt, c, RSTRING(data)->ptr, RSTRING(data)->len))
1674
+ mysql_stmt_raise(s->stmt);
1675
+ return obj;
1676
+ }
1677
+ #endif
1678
+
1679
+ /* sqlstate() */
1680
+ static VALUE stmt_sqlstate(VALUE obj)
1681
+ {
1682
+ struct mysql_stmt* s = DATA_PTR(obj);
1683
+ return rb_tainted_str_new2(mysql_stmt_sqlstate(s->stmt));
1684
+ }
1685
+
1686
+ /*-------------------------------
1687
+ * Mysql::Time object method
1688
+ */
1689
+
1690
+ static VALUE time_initialize(int argc, VALUE* argv, VALUE obj)
1691
+ {
1692
+ VALUE year, month, day, hour, minute, second, neg, second_part;
1693
+ rb_scan_args(argc, argv, "08", &year, &month, &day, &hour, &minute, &second, &neg, &second_part);
1694
+ #define NILorFIXvalue(o) (NIL_P(o) ? INT2FIX(0) : (Check_Type(o, T_FIXNUM), o))
1695
+ rb_iv_set(obj, "year", NILorFIXvalue(year));
1696
+ rb_iv_set(obj, "month", NILorFIXvalue(month));
1697
+ rb_iv_set(obj, "day", NILorFIXvalue(day));
1698
+ rb_iv_set(obj, "hour", NILorFIXvalue(hour));
1699
+ rb_iv_set(obj, "minute", NILorFIXvalue(minute));
1700
+ rb_iv_set(obj, "second", NILorFIXvalue(second));
1701
+ rb_iv_set(obj, "neg", (neg == Qnil || neg == Qfalse) ? Qfalse : Qtrue);
1702
+ rb_iv_set(obj, "second_part", NILorFIXvalue(second_part));
1703
+ }
1704
+
1705
+ static VALUE time_inspect(VALUE obj)
1706
+ {
1707
+ char buf[36];
1708
+ sprintf(buf, "#<Mysql::Time:%04d-%02d-%02d %02d:%02d:%02d>",
1709
+ NUM2INT(rb_iv_get(obj, "year")),
1710
+ NUM2INT(rb_iv_get(obj, "month")),
1711
+ NUM2INT(rb_iv_get(obj, "day")),
1712
+ NUM2INT(rb_iv_get(obj, "hour")),
1713
+ NUM2INT(rb_iv_get(obj, "minute")),
1714
+ NUM2INT(rb_iv_get(obj, "second")));
1715
+ return rb_str_new2(buf);
1716
+ }
1717
+
1718
+ static VALUE time_to_s(VALUE obj)
1719
+ {
1720
+ char buf[20];
1721
+ sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d",
1722
+ NUM2INT(rb_iv_get(obj, "year")),
1723
+ NUM2INT(rb_iv_get(obj, "month")),
1724
+ NUM2INT(rb_iv_get(obj, "day")),
1725
+ NUM2INT(rb_iv_get(obj, "hour")),
1726
+ NUM2INT(rb_iv_get(obj, "minute")),
1727
+ NUM2INT(rb_iv_get(obj, "second")));
1728
+ return rb_str_new2(buf);
1729
+ }
1730
+
1731
+ #define DefineMysqlTimeGetMethod(m)\
1732
+ static VALUE time_get_##m(VALUE obj)\
1733
+ {return rb_iv_get(obj, #m);}
1734
+
1735
+ DefineMysqlTimeGetMethod(year)
1736
+ DefineMysqlTimeGetMethod(month)
1737
+ DefineMysqlTimeGetMethod(day)
1738
+ DefineMysqlTimeGetMethod(hour)
1739
+ DefineMysqlTimeGetMethod(minute)
1740
+ DefineMysqlTimeGetMethod(second)
1741
+ DefineMysqlTimeGetMethod(neg)
1742
+ DefineMysqlTimeGetMethod(second_part)
1743
+
1744
+ #define DefineMysqlTimeSetMethod(m)\
1745
+ static VALUE time_set_##m(VALUE obj, VALUE v)\
1746
+ {rb_iv_set(obj, #m, NILorFIXvalue(v)); return v;}
1747
+
1748
+ DefineMysqlTimeSetMethod(year)
1749
+ DefineMysqlTimeSetMethod(month)
1750
+ DefineMysqlTimeSetMethod(day)
1751
+ DefineMysqlTimeSetMethod(hour)
1752
+ DefineMysqlTimeSetMethod(minute)
1753
+ DefineMysqlTimeSetMethod(second)
1754
+ DefineMysqlTimeSetMethod(second_part)
1755
+
1756
+ static VALUE time_set_neg(VALUE obj, VALUE v)
1757
+ {
1758
+ rb_iv_set(obj, "neg", (v == Qnil || v == Qfalse) ? Qfalse : Qtrue);
1759
+ return v;
1760
+ }
1761
+
1762
+ static VALUE time_equal(VALUE obj, VALUE v)
1763
+ {
1764
+ if (CLASS_OF(v) == cMysqlTime &&
1765
+ NUM2INT(rb_iv_get(obj, "year")) == NUM2INT(rb_iv_get(v, "year")) &&
1766
+ NUM2INT(rb_iv_get(obj, "month")) == NUM2INT(rb_iv_get(v, "month")) &&
1767
+ NUM2INT(rb_iv_get(obj, "day")) == NUM2INT(rb_iv_get(v, "day")) &&
1768
+ NUM2INT(rb_iv_get(obj, "hour")) == NUM2INT(rb_iv_get(v, "hour")) &&
1769
+ NUM2INT(rb_iv_get(obj, "minute")) == NUM2INT(rb_iv_get(v, "minute")) &&
1770
+ NUM2INT(rb_iv_get(obj, "second")) == NUM2INT(rb_iv_get(v, "second")) &&
1771
+ rb_iv_get(obj, "neg") == rb_iv_get(v, "neg") &&
1772
+ NUM2INT(rb_iv_get(obj, "second_part")) == NUM2INT(rb_iv_get(v, "second_part")))
1773
+ return Qtrue;
1774
+ return Qfalse;
1775
+ }
1776
+
1777
+ #endif
1778
+
1082
1779
  /*-------------------------------
1083
1780
  * Mysql::Error object method
1084
1781
  */
@@ -1093,6 +1790,11 @@ static VALUE error_errno(VALUE obj)
1093
1790
  return rb_iv_get(obj, "errno");
1094
1791
  }
1095
1792
 
1793
+ static VALUE error_sqlstate(VALUE obj)
1794
+ {
1795
+ return rb_iv_get(obj, "sqlstate");
1796
+ }
1797
+
1096
1798
  /*-------------------------------
1097
1799
  * Initialize
1098
1800
  */
@@ -1102,6 +1804,11 @@ void Init_mysql(void)
1102
1804
  cMysql = rb_define_class("Mysql", rb_cObject);
1103
1805
  cMysqlRes = rb_define_class_under(cMysql, "Result", rb_cObject);
1104
1806
  cMysqlField = rb_define_class_under(cMysql, "Field", rb_cObject);
1807
+ #if MYSQL_VERSION_ID >= 40102
1808
+ cMysqlStmt = rb_define_class_under(cMysql, "Stmt", rb_cObject);
1809
+ cMysqlRowOffset = rb_define_class_under(cMysql, "RowOffset", rb_cObject);
1810
+ cMysqlTime = rb_define_class_under(cMysql, "Time", rb_cObject);
1811
+ #endif
1105
1812
  eMysql = rb_define_class_under(cMysql, "Error", rb_eStandardError);
1106
1813
 
1107
1814
  rb_define_global_const("MysqlRes", cMysqlRes);
@@ -1200,6 +1907,10 @@ void Init_mysql(void)
1200
1907
  #ifdef HAVE_MYSQL_SSL_SET
1201
1908
  rb_define_method(cMysql, "ssl_set", ssl_set, -1);
1202
1909
  #endif
1910
+ #if MYSQL_VERSION_ID >= 40102
1911
+ rb_define_method(cMysql, "stmt_init", stmt_init, 0);
1912
+ rb_define_method(cMysql, "prepare", prepare, 1);
1913
+ #endif
1203
1914
  #if MYSQL_VERSION_ID >= 40100
1204
1915
  rb_define_method(cMysql, "more_results", more_results, 0);
1205
1916
  rb_define_method(cMysql, "more_results?", more_results, 0);
@@ -1216,6 +1927,7 @@ void Init_mysql(void)
1216
1927
  rb_define_method(cMysql, "reconnect=", reconnect_set, 1);
1217
1928
 
1218
1929
  /* Mysql constant */
1930
+ rb_define_const(cMysql, "VERSION", INT2FIX(MYSQL_RUBY_VERSION));
1219
1931
  #if MYSQL_VERSION_ID >= 32200
1220
1932
  rb_define_const(cMysql, "OPT_CONNECT_TIMEOUT", INT2NUM(MYSQL_OPT_CONNECT_TIMEOUT));
1221
1933
  rb_define_const(cMysql, "OPT_COMPRESS", INT2NUM(MYSQL_OPT_COMPRESS));
@@ -1237,6 +1949,10 @@ void Init_mysql(void)
1237
1949
  rb_define_const(cMysql, "OPT_READ_TIMEOUT", INT2NUM(MYSQL_OPT_READ_TIMEOUT));
1238
1950
  rb_define_const(cMysql, "OPT_WRITE_TIMEOUT", INT2NUM(MYSQL_OPT_WRITE_TIMEOUT));
1239
1951
  rb_define_const(cMysql, "SECURE_AUTH", INT2NUM(MYSQL_SECURE_AUTH));
1952
+ rb_define_const(cMysql, "OPT_GUESS_CONNECTION", INT2NUM(MYSQL_OPT_GUESS_CONNECTION));
1953
+ rb_define_const(cMysql, "OPT_USE_EMBEDDED_CONNECTION", INT2NUM(MYSQL_OPT_USE_EMBEDDED_CONNECTION));
1954
+ rb_define_const(cMysql, "OPT_USE_REMOTE_CONNECTION", INT2NUM(MYSQL_OPT_USE_REMOTE_CONNECTION));
1955
+ rb_define_const(cMysql, "SET_CLIENT_IP", INT2NUM(MYSQL_SET_CLIENT_IP));
1240
1956
  #endif
1241
1957
  rb_define_const(cMysql, "REFRESH_GRANT", INT2NUM(REFRESH_GRANT));
1242
1958
  rb_define_const(cMysql, "REFRESH_LOG", INT2NUM(REFRESH_LOG));
@@ -1401,9 +2117,68 @@ void Init_mysql(void)
1401
2117
  rb_define_const(cMysqlField, "PART_KEY_FLAG", INT2NUM(PART_KEY_FLAG));
1402
2118
  #endif
1403
2119
 
2120
+ #if MYSQL_VERSION_ID >= 40102
2121
+ /* Mysql::Stmt object method */
2122
+ rb_define_method(cMysqlStmt, "affected_rows", stmt_affected_rows, 0);
2123
+ #if 0
2124
+ rb_define_method(cMysqlStmt, "attr_get", stmt_attr_get, 1);
2125
+ rb_define_method(cMysqlStmt, "attr_set", stmt_attr_set, 2);
2126
+ #endif
2127
+ rb_define_method(cMysqlStmt, "bind_result", stmt_bind_result, -1);
2128
+ rb_define_method(cMysqlStmt, "close", stmt_close, 0);
2129
+ rb_define_method(cMysqlStmt, "data_seek", stmt_data_seek, 1);
2130
+ rb_define_method(cMysqlStmt, "each", stmt_each, 0);
2131
+ rb_define_method(cMysqlStmt, "execute", stmt_execute, -1);
2132
+ rb_define_method(cMysqlStmt, "fetch", stmt_fetch, 0);
2133
+ rb_define_method(cMysqlStmt, "field_count", stmt_field_count, 0);
2134
+ rb_define_method(cMysqlStmt, "free_result", stmt_free_result, 0);
2135
+ rb_define_method(cMysqlStmt, "insert_id", stmt_insert_id, 0);
2136
+ rb_define_method(cMysqlStmt, "num_rows", stmt_num_rows, 0);
2137
+ rb_define_method(cMysqlStmt, "param_count", stmt_param_count, 0);
2138
+ rb_define_method(cMysqlStmt, "prepare", stmt_prepare, 1);
2139
+ #if 0
2140
+ rb_define_method(cMysqlStmt, "reset", stmt_reset, 0);
2141
+ #endif
2142
+ rb_define_method(cMysqlStmt, "result_metadata", stmt_result_metadata, 0);
2143
+ rb_define_method(cMysqlStmt, "row_seek", stmt_row_seek, 1);
2144
+ rb_define_method(cMysqlStmt, "row_tell", stmt_row_tell, 0);
2145
+ #if 0
2146
+ rb_define_method(cMysqlStmt, "send_long_data", stmt_send_long_data, 2);
2147
+ #endif
2148
+ rb_define_method(cMysqlStmt, "sqlstate", stmt_sqlstate, 0);
2149
+
2150
+ #if 0
2151
+ rb_define_const(cMysqlStmt, "ATTR_UPDATE_MAX_LENGTH", INT2NUM(STMT_ATTR_UPDATE_MAX_LENGTH));
2152
+ #endif
2153
+
2154
+ /* Mysql::Time object method */
2155
+ rb_define_method(cMysqlTime, "initialize", time_initialize, -1);
2156
+ rb_define_method(cMysqlTime, "inspect", time_inspect, 0);
2157
+ rb_define_method(cMysqlTime, "to_s", time_to_s, 0);
2158
+ rb_define_method(cMysqlTime, "year", time_get_year, 0);
2159
+ rb_define_method(cMysqlTime, "month", time_get_month, 0);
2160
+ rb_define_method(cMysqlTime, "day", time_get_day, 0);
2161
+ rb_define_method(cMysqlTime, "hour", time_get_hour, 0);
2162
+ rb_define_method(cMysqlTime, "minute", time_get_minute, 0);
2163
+ rb_define_method(cMysqlTime, "second", time_get_second, 0);
2164
+ rb_define_method(cMysqlTime, "neg", time_get_neg, 0);
2165
+ rb_define_method(cMysqlTime, "second_part", time_get_second_part, 0);
2166
+ rb_define_method(cMysqlTime, "year=", time_set_year, 1);
2167
+ rb_define_method(cMysqlTime, "month=", time_set_month, 1);
2168
+ rb_define_method(cMysqlTime, "day=", time_set_day, 1);
2169
+ rb_define_method(cMysqlTime, "hour=", time_set_hour, 1);
2170
+ rb_define_method(cMysqlTime, "minute=", time_set_minute, 1);
2171
+ rb_define_method(cMysqlTime, "second=", time_set_second, 1);
2172
+ rb_define_method(cMysqlTime, "neg=", time_set_neg, 1);
2173
+ rb_define_method(cMysqlTime, "second_part=", time_set_second_part, 1);
2174
+ rb_define_method(cMysqlTime, "==", time_equal, 1);
2175
+
2176
+ #endif
2177
+
1404
2178
  /* Mysql::Error object method */
1405
2179
  rb_define_method(eMysql, "error", error_error, 0);
1406
2180
  rb_define_method(eMysql, "errno", error_errno, 0);
2181
+ rb_define_method(eMysql, "sqlstate", error_sqlstate, 0);
1407
2182
 
1408
2183
  /* Mysql::Error constant */
1409
2184
  }