jrmey-mysqlplus 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/ext/mysql.c ADDED
@@ -0,0 +1,2828 @@
1
+ /* ruby mysql module
2
+ * $Id: mysql.c 229 2008-06-20 07:44:04Z tommy $
3
+ * modified 2008-08-26 Muhammad A. Ali
4
+ * added an async interface
5
+ */
6
+
7
+ #include <ruby.h>
8
+ #include <errno.h>
9
+ #include <stdarg.h>
10
+ #ifndef RSTRING_PTR
11
+ #define RSTRING_PTR(str) RSTRING(str)->ptr
12
+ #endif
13
+ #ifndef RSTRING_LEN
14
+ #define RSTRING_LEN(str) RSTRING(str)->len
15
+ #endif
16
+ #ifndef RARRAY_PTR
17
+ #define RARRAY_PTR(ary) RARRAY(ary)->ptr
18
+ #endif
19
+ #ifndef HAVE_RB_STR_SET_LEN
20
+ #define rb_str_set_len(str, length) (RSTRING_LEN(str) = (length))
21
+ #endif
22
+
23
+ #ifdef RUBY19
24
+ #include <ruby/encoding.h>
25
+ #define DEFAULT_ENCODING (rb_enc_get(rb_enc_default_external()))
26
+ #else
27
+ #define DEFAULT_ENCODING NULL
28
+ #define rb_enc_str_new(ptr, len, enc) rb_str_new(ptr, len)
29
+ #endif
30
+
31
+ VALUE
32
+ rb_enc_tainted_str_new(const char *ptr, long len)
33
+ {
34
+ VALUE str = rb_enc_str_new(ptr, len, DEFAULT_ENCODING);
35
+
36
+ OBJ_TAINT(str);
37
+ return str;
38
+ }
39
+
40
+ VALUE
41
+ rb_enc_tainted_str_new2(const char *ptr)
42
+ {
43
+ VALUE str = rb_enc_str_new(ptr, strlen(ptr), DEFAULT_ENCODING);
44
+
45
+ OBJ_TAINT(str);
46
+ return str;
47
+ }
48
+
49
+
50
+
51
+
52
+ #ifdef HAVE_MYSQL_H
53
+ #include <mysql.h>
54
+ #include <mysql_com.h>
55
+ //#include <violite.h>
56
+ #include <errmsg.h>
57
+ #include <mysqld_error.h>
58
+ #else
59
+ #include <mysql/mysql.h>
60
+ #include <mysql/mysql_com.h>
61
+ //#include <mysql/violite.h>
62
+ #include <mysql/errmsg.h>
63
+ #include <mysql/mysqld_error.h>
64
+ #endif
65
+
66
+ #define MYSQL_RUBY_VERSION 20800
67
+
68
+ #define GC_STORE_RESULT_LIMIT 20
69
+
70
+ #if MYSQL_VERSION_ID < 32224
71
+ #define mysql_field_count mysql_num_fields
72
+ #endif
73
+
74
+ #define NILorSTRING(obj) (NIL_P(obj)? NULL: StringValuePtr(obj))
75
+ #define NILorINT(obj) (NIL_P(obj)? 0: NUM2INT(obj))
76
+
77
+ #define GetMysqlStruct(obj) (Check_Type(obj, T_DATA), (struct mysql*)DATA_PTR(obj))
78
+ #define GetHandler(obj) (Check_Type(obj, T_DATA), &(((struct mysql*)DATA_PTR(obj))->handler))
79
+ #define GetMysqlRes(obj) (Check_Type(obj, T_DATA), ((struct mysql_res*)DATA_PTR(obj))->res)
80
+ #define GetMysqlStmt(obj) (Check_Type(obj, T_DATA), ((struct mysql_stmt*)DATA_PTR(obj))->stmt)
81
+
82
+ VALUE cMysql;
83
+ VALUE cMysqlRes;
84
+ VALUE cMysqlField;
85
+ VALUE cMysqlStmt;
86
+ VALUE cMysqlRowOffset;
87
+ VALUE cMysqlTime;
88
+ VALUE eMysql;
89
+
90
+ static int store_result_count = 0;
91
+
92
+ struct mysql {
93
+ MYSQL handler;
94
+ char connection;
95
+ char query_with_result;
96
+ char gc_disabled;
97
+ char blocking;
98
+ int async_in_progress;
99
+ char busy;
100
+ };
101
+
102
+ // a wrapper for mysql_res's so we can detect double frees
103
+ struct mysql_res {
104
+ MYSQL_RES* res;
105
+ char freed;
106
+ };
107
+
108
+ #if MYSQL_VERSION_ID >= 40101
109
+ struct mysql_stmt {
110
+ MYSQL_STMT *stmt;
111
+ char closed;
112
+ struct {
113
+ int n;
114
+ MYSQL_BIND *bind;
115
+ unsigned long *length;
116
+ MYSQL_TIME *buffer;
117
+ } param;
118
+ struct {
119
+ int n;
120
+ MYSQL_BIND *bind;
121
+ my_bool *is_null;
122
+ unsigned long *length;
123
+ } result;
124
+ MYSQL_RES *res;
125
+ };
126
+ #endif
127
+
128
+ /* free Mysql class object */
129
+ static void free_mysql(struct mysql* my)
130
+ {
131
+ if (my->connection == Qtrue)
132
+ mysql_close(&my->handler);
133
+ xfree(my);
134
+ }
135
+
136
+ static void free_mysqlres(struct mysql_res* resp)
137
+ {
138
+ if (resp->freed == Qfalse) {
139
+ mysql_free_result(resp->res);
140
+ store_result_count--;
141
+ }
142
+ xfree(resp);
143
+ }
144
+
145
+ #if MYSQL_VERSION_ID >= 40101
146
+ static void free_mysqlstmt_memory(struct mysql_stmt *s)
147
+ {
148
+ if (s->param.bind) {
149
+ xfree(s->param.bind);
150
+ s->param.bind = NULL;
151
+ }
152
+ if (s->param.length) {
153
+ xfree(s->param.length);
154
+ s->param.length = NULL;
155
+ }
156
+ if (s->param.buffer) {
157
+ xfree(s->param.buffer);
158
+ s->param.buffer = NULL;
159
+ }
160
+ s->param.n = 0;
161
+ if (s->res) {
162
+ mysql_free_result(s->res);
163
+ s->res = NULL;
164
+ }
165
+ if (s->result.bind) {
166
+ int i;
167
+ for (i = 0; i < s->result.n; i++) {
168
+ if (s->result.bind[i].buffer)
169
+ xfree(s->result.bind[i].buffer);
170
+ s->result.bind[i].buffer = NULL;
171
+ }
172
+ xfree(s->result.bind);
173
+ s->result.bind = NULL;
174
+ }
175
+ if (s->result.is_null) {
176
+ xfree(s->result.is_null);
177
+ s->result.is_null = NULL;
178
+ }
179
+ if (s->result.length) {
180
+ xfree(s->result.length);
181
+ s->result.length = NULL;
182
+ }
183
+ s->result.n = 0;
184
+ }
185
+
186
+ static void free_execute_memory(struct mysql_stmt *s)
187
+ {
188
+ if (s->res && s->result.bind) {
189
+ int i;
190
+ for (i = 0; i < s->result.n; i++) {
191
+ if (s->result.bind[i].buffer)
192
+ xfree(s->result.bind[i].buffer);
193
+ s->result.bind[i].buffer = NULL;
194
+ }
195
+ }
196
+ mysql_stmt_free_result(s->stmt);
197
+ }
198
+
199
+ static void free_mysqlstmt(struct mysql_stmt* s)
200
+ {
201
+ free_mysqlstmt_memory(s);
202
+ if (s->closed == Qfalse)
203
+ mysql_stmt_close(s->stmt);
204
+ if (s->res)
205
+ mysql_free_result(s->res);
206
+ xfree(s);
207
+ }
208
+ #endif
209
+
210
+ static void mysql_raise(MYSQL* m)
211
+ {
212
+ VALUE e = rb_exc_new2(eMysql, mysql_error(m));
213
+ rb_iv_set(e, "errno", INT2FIX(mysql_errno(m)));
214
+ #if MYSQL_VERSION_ID >= 40101
215
+ rb_iv_set(e, "sqlstate", rb_enc_tainted_str_new2(mysql_sqlstate(m)));
216
+ #endif
217
+ rb_exc_raise(e);
218
+ }
219
+
220
+ static VALUE mysqlres2obj(MYSQL_RES* res, VALUE gc_disabled)
221
+ {
222
+ VALUE obj;
223
+ struct mysql_res* resp;
224
+ obj = Data_Make_Struct(cMysqlRes, struct mysql_res, 0, free_mysqlres, resp);
225
+ rb_iv_set(obj, "colname", Qnil);
226
+ rb_iv_set(obj, "tblcolname", Qnil);
227
+ resp->res = res;
228
+ resp->freed = Qfalse;
229
+ rb_obj_call_init(obj, 0, NULL);
230
+ /* disabled until it can be reviewed further--rely on the normal GC for now.
231
+ if (++store_result_count > GC_STORE_RESULT_LIMIT)
232
+ rb_gc();
233
+ */
234
+ return obj;
235
+ }
236
+
237
+ /* make Mysql::Field object */
238
+ static VALUE make_field_obj(MYSQL_FIELD* f)
239
+ {
240
+ VALUE obj;
241
+ if (f == NULL)
242
+ return Qnil;
243
+ obj = rb_obj_alloc(cMysqlField);
244
+ rb_iv_set(obj, "name", f->name? rb_str_freeze(rb_enc_tainted_str_new2(f->name)): Qnil);
245
+ rb_iv_set(obj, "table", f->table? rb_str_freeze(rb_enc_tainted_str_new2(f->table)): Qnil);
246
+ rb_iv_set(obj, "def", f->def? rb_str_freeze(rb_enc_tainted_str_new2(f->def)): Qnil);
247
+ rb_iv_set(obj, "type", INT2NUM(f->type));
248
+ rb_iv_set(obj, "length", INT2NUM(f->length));
249
+ rb_iv_set(obj, "max_length", INT2NUM(f->max_length));
250
+ rb_iv_set(obj, "flags", INT2NUM(f->flags));
251
+ rb_iv_set(obj, "decimals", INT2NUM(f->decimals));
252
+ return obj;
253
+ }
254
+
255
+ /*-------------------------------
256
+ * Mysql class method
257
+ */
258
+
259
+ /* init() */
260
+ static VALUE init(VALUE klass)
261
+ {
262
+ struct mysql* myp;
263
+ VALUE obj;
264
+
265
+ obj = Data_Make_Struct(klass, struct mysql, 0, free_mysql, myp);
266
+ mysql_init(&myp->handler);
267
+ myp->connection = Qfalse;
268
+ myp->query_with_result = Qtrue;
269
+ myp->gc_disabled = Qtrue;
270
+ rb_obj_call_init(obj, 0, NULL);
271
+ return obj;
272
+ }
273
+
274
+ // =========== a 1.9 rb_thread_blocking_region simplifier attempt
275
+ #ifdef HAVE_TBR
276
+
277
+ typedef struct
278
+ {
279
+ void *func_pointer;
280
+ int param_count;
281
+ void *args[10];
282
+ } arg_holder, *arg_holder2;
283
+
284
+ // here's how to make rb_thread_blocking_region much cleaner and easier
285
+ // syntax: param_count+2, func_pointer to call, [RUBY_UBF_IO or RUBY_UBF_PROCESS], param1, param2...
286
+ // the third parameter is the interuptor--possible values appear to be RUBY_UBF_IO or RUBY_UBF_PROCESS http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/ad8c1326b2a8e404/00447b9aa15979be?lnk=raot
287
+ // ex: (int) returned_this = rb_thread_blocking_region_variable_params(10, &method_name, RUBY_UBF_IO, param1, param2, param3, param4, param5, param6, param7, param8)
288
+
289
+ static void *call_single_function_rb_thread_blocking_region(void *arg_holder_in);
290
+
291
+ void *rb_thread_blocking_region_variable_params(int number, ...)
292
+ {
293
+ va_list param_pt;
294
+ va_start(param_pt, number);
295
+ int index;
296
+ arg_holder param_storer;
297
+ void *func_pointer = va_arg(param_pt, void *);
298
+ void *interrupter = va_arg(param_pt, void *);
299
+ param_storer.func_pointer = func_pointer;
300
+ int real_param_count = number - 2;
301
+ param_storer.param_count = real_param_count;
302
+ for(index = 0 ; index < real_param_count ; index++)
303
+ {
304
+ void *arg = va_arg(param_pt, void *);
305
+ param_storer.args[index] = arg;
306
+
307
+ }
308
+ va_end(param_pt);
309
+
310
+ return (void *) rb_thread_blocking_region((rb_blocking_function_t *)call_single_function_rb_thread_blocking_region, (void *) &param_storer, interrupter, 0);
311
+
312
+ }
313
+
314
+ // used internally
315
+ static void * call_single_function_rb_thread_blocking_region(void *arg_holder_in)
316
+ {
317
+ arg_holder *params_and_func = (arg_holder *) arg_holder_in;
318
+ int param_count = params_and_func->param_count;
319
+ void *result;
320
+ switch(param_count)
321
+ {
322
+ case 3:;
323
+ void * (*pt3Func)(void *, void *, void *) = params_and_func->func_pointer;
324
+ result = (*pt3Func)(params_and_func->args[0], params_and_func->args[1], params_and_func->args[2]);
325
+ break;
326
+ case 6:;
327
+ void * (*pt6Func)(void *, void *, void *, void *, void *, void *) = params_and_func->func_pointer;
328
+ result = (*pt6Func)(params_and_func->args[0], params_and_func->args[1], params_and_func->args[2], params_and_func->args[3], params_and_func->args[4], params_and_func->args[5]);
329
+ break;
330
+ case 8:;
331
+ void * (*pt8Func)(void *, void *, void *, void *, void *, void *, void *, void *) = params_and_func->func_pointer;
332
+ result = (*pt8Func)(params_and_func->args[0], params_and_func->args[1], params_and_func->args[2], params_and_func->args[3], params_and_func->args[4], params_and_func->args[5], params_and_func->args[6], params_and_func->args[7]);
333
+ break;
334
+ default:;
335
+ printf("UNknown param count--please add it! %d\n", param_count);
336
+ result = (void *) Qnil;
337
+ }
338
+
339
+ return result;
340
+ }
341
+
342
+ #endif
343
+
344
+ static VALUE connection_identifier( VALUE obj )
345
+ {
346
+ MYSQL* m = GetHandler(obj);
347
+ return mysql_thread_id( m );
348
+ }
349
+
350
+ static VALUE async_in_progress( VALUE obj )
351
+ {
352
+ struct mysql* m = GetMysqlStruct(obj);
353
+ return ( m->async_in_progress == connection_identifier(obj) ) ? Qtrue : Qfalse;
354
+ }
355
+
356
+ static VALUE async_in_progress_set( VALUE obj, VALUE flag )
357
+ {
358
+ struct mysql* m = GetMysqlStruct(obj);
359
+ m->async_in_progress = (flag == Qnil || flag == Qfalse) ? 0 : connection_identifier(obj);
360
+ return flag;
361
+ }
362
+
363
+ // does this actually really do anything helpful? Not sure.
364
+ static void optimize_for_async( VALUE obj )
365
+ {
366
+ struct mysql* m = GetMysqlStruct(obj);
367
+ my_bool was_blocking;
368
+ vio_blocking(m->handler.net.vio, 0, &was_blocking);
369
+ m->blocking = vio_is_blocking( m->handler.net.vio );
370
+
371
+ vio_fastsend( m->handler.net.vio );
372
+ async_in_progress_set( obj, Qfalse );
373
+ }
374
+
375
+ // TODO does nothing currently
376
+ static void schedule_connect(VALUE obj )
377
+ {
378
+ /* TODO is this old?
379
+ MYSQL* m = GetHandler(obj);
380
+ fd_set read;
381
+
382
+ struct timeval tv = { tv_sec: m->options.connect_timeout, tv_usec: 0 };
383
+ if (rb_thread_select(0, NULL, NULL, NULL, &tv) < 0) {
384
+ rb_raise(eMysql, "connect: timeout");
385
+ }
386
+ */
387
+
388
+ /*
389
+ FD_ZERO(&read);
390
+ FD_SET(m->net.fd, &read);
391
+
392
+ if (rb_thread_select(m->net.fd + 1, &read, NULL, NULL, &tv) < 0) {
393
+ rb_raise(eMysql, "connect: timeout");
394
+ }
395
+ */
396
+ }
397
+
398
+ /* real_connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil) */
399
+ static VALUE real_connect(int argc, VALUE* argv, VALUE klass)
400
+ {
401
+ VALUE host, user, passwd, db, port, sock, flag;
402
+ char *h, *u, *p, *d, *s;
403
+ unsigned int pp, f;
404
+ struct mysql* myp;
405
+ VALUE obj;
406
+
407
+ #if MYSQL_VERSION_ID >= 32200
408
+ rb_scan_args(argc, argv, "07", &host, &user, &passwd, &db, &port, &sock, &flag);
409
+ d = NILorSTRING(db);
410
+ f = NILorINT(flag);
411
+ #elif MYSQL_VERSION_ID >= 32115
412
+ rb_scan_args(argc, argv, "06", &host, &user, &passwd, &port, &sock, &flag);
413
+ f = NILorINT(flag);
414
+ #else
415
+ rb_scan_args(argc, argv, "05", &host, &user, &passwd, &port, &sock);
416
+ #endif
417
+ h = NILorSTRING(host);
418
+ u = NILorSTRING(user);
419
+ p = NILorSTRING(passwd);
420
+ pp = NILorINT(port);
421
+ s = NILorSTRING(sock);
422
+
423
+ obj = Data_Make_Struct(klass, struct mysql, 0, free_mysql, myp);
424
+ #if MYSQL_VERSION_ID >= 32200
425
+ mysql_init(&myp->handler); /* we get here */
426
+ # ifdef HAVE_TBR
427
+ if( (MYSQL *) rb_thread_blocking_region_variable_params(10, &mysql_real_connect, RUBY_UBF_IO, &myp->handler, h, u, p, d, pp, s, f) == NULL)
428
+ # else
429
+ if(mysql_real_connect(&myp->handler, h, u, p, d, pp, s, f) == NULL)
430
+ # endif
431
+ #elif MYSQL_VERSION_ID >= 32115
432
+ if (mysql_real_connect(&myp->handler, h, u, p, pp, s, f) == NULL)
433
+ #else
434
+ if (mysql_real_connect(&myp->handler, h, u, p, pp, s) == NULL)
435
+ #endif
436
+ mysql_raise(&myp->handler);
437
+
438
+ myp->handler.reconnect = 0;
439
+ myp->connection = Qtrue;
440
+
441
+ optimize_for_async(obj);
442
+
443
+ myp->query_with_result = Qtrue;
444
+ rb_obj_call_init(obj, argc, argv);
445
+
446
+ //schedule_connect(obj);
447
+
448
+ return obj;
449
+ }
450
+
451
+ /* escape_string(string) */
452
+ static VALUE escape_string(VALUE klass, VALUE str)
453
+ {
454
+ VALUE ret;
455
+ Check_Type(str, T_STRING);
456
+ ret = rb_enc_str_new(0, (RSTRING_LEN(str))*2+1, DEFAULT_ENCODING);
457
+ rb_str_set_len(ret, mysql_escape_string(RSTRING_PTR(ret), RSTRING_PTR(str), RSTRING_LEN(str)));
458
+ return ret;
459
+ }
460
+
461
+ /* client_info() */
462
+ static VALUE client_info(VALUE klass)
463
+ {
464
+ return rb_enc_tainted_str_new2(mysql_get_client_info());
465
+ }
466
+
467
+ #if MYSQL_VERSION_ID >= 32332
468
+ /* my_debug(string) */
469
+ static VALUE my_debug(VALUE obj, VALUE str)
470
+ {
471
+ mysql_debug(StringValuePtr(str));
472
+ return obj;
473
+ }
474
+ #endif
475
+
476
+ #if MYSQL_VERSION_ID >= 40000
477
+ /* client_version() */
478
+ static VALUE client_version(VALUE obj)
479
+ {
480
+ return INT2NUM(mysql_get_client_version());
481
+ }
482
+ #endif
483
+
484
+ /*-------------------------------
485
+ * Mysql object method
486
+ */
487
+
488
+ #if MYSQL_VERSION_ID >= 32200
489
+ /* real_connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil) */
490
+ static VALUE real_connect2(int argc, VALUE* argv, VALUE obj)
491
+ {
492
+ VALUE host, user, passwd, db, port, sock, flag;
493
+ char *h, *u, *p, *d, *s;
494
+ unsigned int pp, f;
495
+ MYSQL* m = GetHandler(obj);
496
+ rb_scan_args(argc, argv, "07", &host, &user, &passwd, &db, &port, &sock, &flag);
497
+ d = NILorSTRING(db);
498
+ f = NILorINT(flag);
499
+ h = NILorSTRING(host);
500
+ u = NILorSTRING(user);
501
+ p = NILorSTRING(passwd);
502
+ pp = NILorINT(port);
503
+ s = NILorSTRING(sock);
504
+
505
+ if (mysql_real_connect(m, h, u, p, d, pp, s, f) == NULL)
506
+ mysql_raise(m);
507
+ m->reconnect = 0;
508
+ GetMysqlStruct(obj)->connection = Qtrue;
509
+
510
+ optimize_for_async(obj);
511
+ //schedule_connect(obj);
512
+
513
+ return obj;
514
+ }
515
+
516
+ /* options(opt, value=nil) */
517
+ static VALUE options(int argc, VALUE* argv, VALUE obj)
518
+ {
519
+ VALUE opt, val;
520
+ int n;
521
+ my_bool b;
522
+ char* v;
523
+ MYSQL* m = GetHandler(obj);
524
+
525
+ rb_scan_args(argc, argv, "11", &opt, &val);
526
+ switch(NUM2INT(opt)) {
527
+ case MYSQL_OPT_CONNECT_TIMEOUT:
528
+ #if MYSQL_VERSION_ID >= 40100
529
+ case MYSQL_OPT_PROTOCOL:
530
+ #endif
531
+ #if MYSQL_VERSION_ID >= 40101
532
+ case MYSQL_OPT_READ_TIMEOUT:
533
+ case MYSQL_OPT_WRITE_TIMEOUT:
534
+ #endif
535
+ if (val == Qnil)
536
+ rb_raise(rb_eArgError, "wrong # of arguments(1 for 2)");
537
+ n = NUM2INT(val);
538
+ v = (char*)&n;
539
+ break;
540
+ case MYSQL_INIT_COMMAND:
541
+ case MYSQL_READ_DEFAULT_FILE:
542
+ case MYSQL_READ_DEFAULT_GROUP:
543
+ #if MYSQL_VERSION_ID >= 32349
544
+ case MYSQL_SET_CHARSET_DIR:
545
+ case MYSQL_SET_CHARSET_NAME:
546
+ #endif
547
+ #if MYSQL_VERSION_ID >= 40100
548
+ case MYSQL_SHARED_MEMORY_BASE_NAME:
549
+ #endif
550
+ #if MYSQL_VERSION_ID >= 40101
551
+ case MYSQL_SET_CLIENT_IP:
552
+ #endif
553
+ if (val == Qnil)
554
+ rb_raise(rb_eArgError, "wrong # of arguments(1 for 2)");
555
+ v = StringValuePtr(val);
556
+ break;
557
+ #if MYSQL_VERSION_ID >= 40101
558
+ case MYSQL_SECURE_AUTH:
559
+ if (val == Qnil || val == Qfalse)
560
+ b = 1;
561
+ else
562
+ b = 0;
563
+ v = (char*)&b;
564
+ break;
565
+ #endif
566
+ #if MYSQL_VERSION_ID >= 32349
567
+ case MYSQL_OPT_LOCAL_INFILE:
568
+ if (val == Qnil || val == Qfalse)
569
+ v = NULL;
570
+ else {
571
+ n = 1;
572
+ v = (char*)&n;
573
+ }
574
+ break;
575
+ #endif
576
+ default:
577
+ v = NULL;
578
+ }
579
+
580
+ if (mysql_options(m, NUM2INT(opt), v) != 0)
581
+ rb_raise(eMysql, "unknown option: %d", NUM2INT(opt));
582
+ return obj;
583
+ }
584
+ #endif
585
+
586
+ #if MYSQL_VERSION_ID >= 32332
587
+ /* real_escape_string(string) */
588
+ static VALUE real_escape_string(VALUE obj, VALUE str)
589
+ {
590
+ MYSQL* m = GetHandler(obj);
591
+ VALUE ret;
592
+ Check_Type(str, T_STRING);
593
+ ret = rb_enc_str_new(0, (RSTRING_LEN(str))*2+1, DEFAULT_ENCODING);
594
+ rb_str_set_len(ret, mysql_real_escape_string(m, RSTRING_PTR(ret), RSTRING_PTR(str), RSTRING_LEN(str)));
595
+ return ret;
596
+ }
597
+ #endif
598
+
599
+ /* initialize() */
600
+ static VALUE initialize(int argc, VALUE* argv, VALUE obj)
601
+ {
602
+ return obj;
603
+ }
604
+
605
+ /* affected_rows() */
606
+ static VALUE affected_rows(VALUE obj)
607
+ {
608
+ return INT2NUM(mysql_affected_rows(GetHandler(obj)));
609
+ }
610
+
611
+ #if MYSQL_VERSION_ID >= 32303
612
+ /* change_user(user=nil, passwd=nil, db=nil) */
613
+ static VALUE change_user(int argc, VALUE* argv, VALUE obj)
614
+ {
615
+ VALUE user, passwd, db;
616
+ char *u, *p, *d;
617
+ MYSQL* m = GetHandler(obj);
618
+ rb_scan_args(argc, argv, "03", &user, &passwd, &db);
619
+ u = NILorSTRING(user);
620
+ p = NILorSTRING(passwd);
621
+ d = NILorSTRING(db);
622
+ if (mysql_change_user(m, u, p, d) != 0)
623
+ mysql_raise(m);
624
+ return obj;
625
+ }
626
+ #endif
627
+
628
+ #if MYSQL_VERSION_ID >= 32321
629
+ /* character_set_name() */
630
+ static VALUE character_set_name(VALUE obj)
631
+ {
632
+ return rb_enc_tainted_str_new2(mysql_character_set_name(GetHandler(obj)));
633
+ }
634
+ #endif
635
+
636
+ /* close() */
637
+ static VALUE my_close(VALUE obj)
638
+ {
639
+ MYSQL* m = GetHandler(obj);
640
+ mysql_close(m);
641
+ GetMysqlStruct(obj)->connection = Qfalse;
642
+ return obj;
643
+ }
644
+
645
+ #if MYSQL_VERSION_ID < 40000
646
+ /* create_db(db) */
647
+ static VALUE create_db(VALUE obj, VALUE db)
648
+ {
649
+ MYSQL* m = GetHandler(obj);
650
+ if (mysql_create_db(m, StringValuePtr(db)) != 0)
651
+ mysql_raise(m);
652
+ return obj;
653
+ }
654
+
655
+ /* drop_db(db) */
656
+ static VALUE drop_db(VALUE obj, VALUE db)
657
+ {
658
+ MYSQL* m = GetHandler(obj);
659
+ if (mysql_drop_db(m, StringValuePtr(db)) != 0)
660
+ mysql_raise(m);
661
+ return obj;
662
+ }
663
+ #endif
664
+
665
+ #if MYSQL_VERSION_ID >= 32332
666
+ /* dump_debug_info() */
667
+ static VALUE dump_debug_info(VALUE obj)
668
+ {
669
+ MYSQL* m = GetHandler(obj);
670
+ if (mysql_dump_debug_info(m) != 0)
671
+ mysql_raise(m);
672
+ return obj;
673
+ }
674
+ #endif
675
+
676
+ /* errno() */
677
+ static VALUE my_errno(VALUE obj)
678
+ {
679
+ return INT2NUM(mysql_errno(GetHandler(obj)));
680
+ }
681
+
682
+ /* error() */
683
+ static VALUE my_error(VALUE obj)
684
+ {
685
+ return rb_str_new2(mysql_error(GetHandler(obj)));
686
+ }
687
+
688
+ /* field_count() */
689
+ static VALUE field_count(VALUE obj)
690
+ {
691
+ return INT2NUM(mysql_field_count(GetHandler(obj)));
692
+ }
693
+
694
+ /* host_info() */
695
+ static VALUE host_info(VALUE obj)
696
+ {
697
+ return rb_enc_tainted_str_new2(mysql_get_host_info(GetHandler(obj)));
698
+ }
699
+
700
+ /* proto_info() */
701
+ static VALUE proto_info(VALUE obj)
702
+ {
703
+ return INT2NUM(mysql_get_proto_info(GetHandler(obj)));
704
+ }
705
+
706
+ /* server_info() */
707
+ static VALUE server_info(VALUE obj)
708
+ {
709
+ return rb_enc_tainted_str_new2(mysql_get_server_info(GetHandler(obj)));
710
+ }
711
+
712
+ /* info() */
713
+ static VALUE info(VALUE obj)
714
+ {
715
+ const char* p = mysql_info(GetHandler(obj));
716
+ return p? rb_enc_tainted_str_new2(p): Qnil;
717
+ }
718
+
719
+ /* insert_id() */
720
+ static VALUE insert_id(VALUE obj)
721
+ {
722
+ return INT2NUM(mysql_insert_id(GetHandler(obj)));
723
+ }
724
+
725
+ /* kill(pid) */
726
+ static VALUE my_kill(VALUE obj, VALUE pid)
727
+ {
728
+ int p = NUM2INT(pid);
729
+ MYSQL* m = GetHandler(obj);
730
+ if (mysql_kill(m, p) != 0)
731
+ mysql_raise(m);
732
+ return obj;
733
+ }
734
+
735
+ /* list_dbs(db=nil) */
736
+ static VALUE list_dbs(int argc, VALUE* argv, VALUE obj)
737
+ {
738
+ unsigned int i, n;
739
+ VALUE db, ret;
740
+ MYSQL* m = GetHandler(obj);
741
+ MYSQL_RES* res;
742
+
743
+ rb_scan_args(argc, argv, "01", &db);
744
+ res = mysql_list_dbs(m, NILorSTRING(db));
745
+ if (res == NULL)
746
+ mysql_raise(m);
747
+
748
+ n = mysql_num_rows(res);
749
+ ret = rb_ary_new2(n);
750
+ for (i=0; i<n; i++)
751
+ rb_ary_store(ret, i, rb_enc_tainted_str_new2(mysql_fetch_row(res)[0]));
752
+ mysql_free_result(res);
753
+ return ret;
754
+ }
755
+
756
+ /* list_fields(table, field=nil) */
757
+ static VALUE list_fields(int argc, VALUE* argv, VALUE obj)
758
+ {
759
+ VALUE table, field;
760
+ MYSQL* m = GetHandler(obj);
761
+ MYSQL_RES* res;
762
+ rb_scan_args(argc, argv, "11", &table, &field);
763
+ res = mysql_list_fields(m, StringValuePtr(table), NILorSTRING(field));
764
+ if (res == NULL)
765
+ mysql_raise(m);
766
+ return mysqlres2obj(res, GetMysqlStruct(obj)->gc_disabled);
767
+ }
768
+
769
+ /* list_processes() */
770
+ static VALUE list_processes(VALUE obj)
771
+ {
772
+ MYSQL* m = GetHandler(obj);
773
+ MYSQL_RES* res = mysql_list_processes(m);
774
+ if (res == NULL)
775
+ mysql_raise(m);
776
+ return mysqlres2obj(res, GetMysqlStruct(obj)->gc_disabled);
777
+ }
778
+
779
+ /* list_tables(table=nil) */
780
+ static VALUE list_tables(int argc, VALUE* argv, VALUE obj)
781
+ {
782
+ VALUE table;
783
+ MYSQL* m = GetHandler(obj);
784
+ MYSQL_RES* res;
785
+ unsigned int i, n;
786
+ VALUE ret;
787
+
788
+ rb_scan_args(argc, argv, "01", &table);
789
+ res = mysql_list_tables(m, NILorSTRING(table));
790
+ if (res == NULL)
791
+ mysql_raise(m);
792
+
793
+ n = mysql_num_rows(res);
794
+ ret = rb_ary_new2(n);
795
+ for (i=0; i<n; i++)
796
+ rb_ary_store(ret, i, rb_enc_tainted_str_new2(mysql_fetch_row(res)[0]));
797
+ mysql_free_result(res);
798
+ return ret;
799
+ }
800
+
801
+ /* ping() */
802
+ static VALUE ping(VALUE obj)
803
+ {
804
+ MYSQL* m = GetHandler(obj);
805
+ if (mysql_ping(m) != 0)
806
+ mysql_raise(m);
807
+ return obj;
808
+ }
809
+
810
+ /* refresh(r) */
811
+ static VALUE refresh(VALUE obj, VALUE r)
812
+ {
813
+ MYSQL* m = GetHandler(obj);
814
+ if (mysql_refresh(m, NUM2INT(r)) != 0)
815
+ mysql_raise(m);
816
+ return obj;
817
+ }
818
+
819
+ /* reload() */
820
+ static VALUE reload(VALUE obj)
821
+ {
822
+ MYSQL* m = GetHandler(obj);
823
+ if (mysql_reload(m) != 0)
824
+ mysql_raise(m);
825
+ return obj;
826
+ }
827
+
828
+ /* select_db(db) */
829
+ static VALUE select_db(VALUE obj, VALUE db)
830
+ {
831
+ MYSQL* m = GetHandler(obj);
832
+ if (mysql_select_db(m, StringValuePtr(db)) != 0)
833
+ mysql_raise(m);
834
+ return obj;
835
+ }
836
+
837
+ /* shutdown() */
838
+ static VALUE my_shutdown(int argc, VALUE* argv, VALUE obj)
839
+ {
840
+ MYSQL* m = GetHandler(obj);
841
+ VALUE level;
842
+
843
+ rb_scan_args(argc, argv, "01", &level);
844
+ #if MYSQL_VERSION_ID >= 40103
845
+ if (mysql_shutdown(m, NIL_P(level) ? SHUTDOWN_DEFAULT : NUM2INT(level)) != 0)
846
+ #else
847
+ if (mysql_shutdown(m) != 0)
848
+ #endif
849
+ mysql_raise(m);
850
+ return obj;
851
+ }
852
+
853
+ /* stat() */
854
+ static VALUE my_stat(VALUE obj)
855
+ {
856
+ MYSQL* m = GetHandler(obj);
857
+ const char* s = mysql_stat(m);
858
+ if (s == NULL)
859
+ mysql_raise(m);
860
+ return rb_enc_tainted_str_new2(s);
861
+ }
862
+
863
+ // 1.9 friendly
864
+ typedef struct
865
+ {
866
+ MYSQL *mysql_instance;
867
+ MYSQL_RES **store_it_here;
868
+
869
+ } mysql_result_to_here_t,
870
+ *shared_stuff_p;
871
+
872
+ static VALUE store_result_to_location(void *settings_in)
873
+ {
874
+ mysql_result_to_here_t *settings = (mysql_result_to_here_t *) settings_in;
875
+ *(settings->store_it_here) = mysql_store_result(settings->mysql_instance); // this one line runs a good long while for very large queries
876
+ return Qnil;
877
+ }
878
+
879
+ /* store_result() */
880
+ static VALUE store_result(VALUE obj)
881
+ {
882
+ MYSQL* m = GetHandler(obj);
883
+ MYSQL_RES* res = NULL;
884
+ #ifndef HAVE_TBR
885
+ res = mysql_store_result(m);
886
+ #else
887
+ mysql_result_to_here_t linker;
888
+ linker.mysql_instance = m;
889
+ linker.store_it_here = &res;
890
+ rb_thread_blocking_region(store_result_to_location, (void *) &linker, RUBY_UBF_IO, 0);
891
+ #endif
892
+
893
+ if (res == NULL)
894
+ mysql_raise(m);
895
+
896
+ return mysqlres2obj(res, GetMysqlStruct(obj)->gc_disabled);
897
+ }
898
+
899
+ /* thread_id() */
900
+ static VALUE thread_id(VALUE obj)
901
+ {
902
+ return INT2NUM(mysql_thread_id(GetHandler(obj)));
903
+ }
904
+
905
+ /* use_result() */
906
+ static VALUE use_result(VALUE obj)
907
+ {
908
+ MYSQL* m = GetHandler(obj);
909
+ MYSQL_RES* res = mysql_use_result(m);
910
+ if (res == NULL)
911
+ mysql_raise(m);
912
+ return mysqlres2obj(res, GetMysqlStruct(obj)->gc_disabled);
913
+ }
914
+
915
+ static VALUE res_free(VALUE);
916
+
917
+ typedef struct {
918
+ MYSQL *m;
919
+ const char *data;
920
+ unsigned long len;
921
+ } QueryArgs;
922
+
923
+ static VALUE blocking_query(void *data)
924
+ {
925
+ QueryArgs *args = (QueryArgs *) data;
926
+ return (VALUE) mysql_real_query(args->m, args->data, args->len);
927
+ }
928
+
929
+ /* query(sql) */
930
+ static VALUE query(VALUE obj, VALUE sql)
931
+ {
932
+ int loop = 0;
933
+ MYSQL* m = GetHandler(obj);
934
+ QueryArgs args;
935
+ int result;
936
+
937
+ Check_Type(sql, T_STRING);
938
+ if (GetMysqlStruct(obj)->connection == Qfalse) {
939
+ rb_raise(eMysql, "query: not connected");
940
+ }
941
+ if (rb_block_given_p()) {
942
+ #ifdef RUBY_VM
943
+ args.m = m;
944
+ args.data = RSTRING_PTR(sql);
945
+ args.len = RSTRING_LEN(sql);
946
+ result = (int) rb_thread_blocking_region(blocking_query, &args, RUBY_UBF_PROCESS, 0);
947
+ #else
948
+ result = mysql_real_query(m, RSTRING_PTR(sql), RSTRING_LEN(sql));
949
+ #endif
950
+ if (result != 0)
951
+ mysql_raise(m);
952
+
953
+ do {
954
+ MYSQL_RES* res = mysql_store_result(m);
955
+ if (res == NULL) {
956
+ if (mysql_field_count(m) != 0)
957
+ mysql_raise(m);
958
+ } else {
959
+ VALUE robj = mysqlres2obj(res, GetMysqlStruct(obj)->gc_disabled);
960
+ rb_ensure(rb_yield, robj, res_free, robj);
961
+ }
962
+ #if MYSQL_VERSION_ID >= 40101
963
+ if ((loop = mysql_next_result(m)) > 0)
964
+ mysql_raise(m);
965
+ } while (loop == 0);
966
+ #else
967
+ } while (0);
968
+ #endif
969
+ return obj;
970
+ }
971
+
972
+ #ifdef RUBY_VM
973
+ args.m = m;
974
+ args.data = RSTRING_PTR(sql);
975
+ args.len = RSTRING_LEN(sql);
976
+ result = (int) rb_thread_blocking_region(blocking_query, &args, RUBY_UBF_PROCESS, 0);
977
+ #else
978
+ result = mysql_real_query(m, RSTRING_PTR(sql), RSTRING_LEN(sql));
979
+ #endif
980
+ if (result != 0)
981
+ mysql_raise(m);
982
+ if (GetMysqlStruct(obj)->query_with_result == Qfalse)
983
+ return obj;
984
+ if (mysql_field_count(m) == 0)
985
+ return Qnil;
986
+ return store_result(obj);
987
+ }
988
+
989
+ /* socket */
990
+ static VALUE socket(VALUE obj)
991
+ {
992
+ MYSQL* m = GetHandler(obj);
993
+ return INT2NUM(m->net.fd);
994
+ }
995
+
996
+ /* socket_type --currently returns true or false, needs some work */
997
+ static VALUE socket_type(VALUE obj)
998
+ {
999
+ MYSQL* m = GetHandler(obj);
1000
+ if(vio_description(m->net.vio))
1001
+ return Qtrue; // TODO return a ruby string
1002
+ else
1003
+ return Qnil;
1004
+ }
1005
+
1006
+ /* blocking */
1007
+ static VALUE blocking(VALUE obj){
1008
+ return ( GetMysqlStruct(obj)->blocking ? Qtrue : Qfalse );
1009
+ }
1010
+
1011
+ /* is_busy */
1012
+ static VALUE is_busy(VALUE obj){
1013
+ return ( GetMysqlStruct(obj)->busy ? Qtrue : Qfalse );
1014
+ }
1015
+
1016
+ static VALUE is_idle(VALUE obj){
1017
+ return ( is_busy(obj) == Qtrue ) ? Qfalse : Qtrue;
1018
+ }
1019
+
1020
+ /* busy(true|false) */
1021
+ static VALUE busy_set(VALUE obj, VALUE flag)
1022
+ {
1023
+ if (TYPE(flag) != T_TRUE && TYPE(flag) != T_FALSE)
1024
+ rb_raise(rb_eTypeError, "invalid type, required true or false.");
1025
+ GetMysqlStruct(obj)->busy = flag;
1026
+ return flag;
1027
+ }
1028
+
1029
+ static void busy( VALUE obj ){
1030
+ busy_set( obj, Qtrue );
1031
+ }
1032
+
1033
+ static void idle( VALUE obj ){
1034
+ busy_set( obj, Qfalse );
1035
+ }
1036
+
1037
+ /* readable(timeout=nil) */
1038
+ static VALUE readable( int argc, VALUE* argv, VALUE obj )
1039
+ {
1040
+ MYSQL* m = GetHandler(obj);
1041
+
1042
+ VALUE timeout;
1043
+
1044
+ rb_scan_args(argc, argv, "01", &timeout);
1045
+
1046
+ if ( NIL_P( timeout ) ){
1047
+ timeout = m->net.read_timeout;
1048
+ }
1049
+ // todo could do a rb_blocking_region here
1050
+ return ( vio_poll_read( m->net.vio, INT2NUM(timeout) ) == 0 ? Qtrue : Qfalse );
1051
+ }
1052
+
1053
+ /* retry */
1054
+ static VALUE retry( VALUE obj )
1055
+ {
1056
+ MYSQL* m = GetHandler(obj);
1057
+ return ( vio_should_retry( m->net.vio ) == 1 ? Qtrue : Qfalse );
1058
+ }
1059
+
1060
+ /* interrupted */
1061
+ static VALUE interrupted( VALUE obj )
1062
+ {
1063
+ MYSQL* m = GetHandler(obj);
1064
+ return ( vio_was_interrupted( m->net.vio ) == 1 ? Qtrue : Qfalse );
1065
+ }
1066
+
1067
+ /* reconnected */
1068
+ static VALUE reconnected( VALUE obj ){
1069
+ MYSQL* m = GetHandler(obj);
1070
+ int current_connection_id = mysql_thread_id( m );
1071
+ mysql_ping(m);
1072
+ return ( current_connection_id == mysql_thread_id( m ) ) ? Qfalse : Qtrue;
1073
+ }
1074
+
1075
+ /* disable_gc(true|false) */
1076
+ static VALUE disable_gc_set(VALUE obj, VALUE flag)
1077
+ {
1078
+ if (TYPE(flag) != T_TRUE && TYPE(flag) != T_FALSE)
1079
+ rb_raise(rb_eTypeError, "invalid type, required true or false.");
1080
+ GetMysqlStruct(obj)->gc_disabled = flag;
1081
+ return flag;
1082
+ }
1083
+
1084
+ /* gc_disabled */
1085
+ static VALUE gc_disabled( VALUE obj ){
1086
+ return GetMysqlStruct(obj)->gc_disabled ? Qtrue: Qfalse;
1087
+ }
1088
+
1089
+ static void validate_async_query( VALUE obj )
1090
+ {
1091
+ if( async_in_progress(obj) == Qtrue ){
1092
+ async_in_progress_set(obj, Qfalse);
1093
+ rb_raise(eMysql, "Query out of sequence: Each call to Mysql#send_query requires a successive Mysql#get_result.");
1094
+ }
1095
+ }
1096
+
1097
+ /* for testing */
1098
+ static VALUE simulate_disconnect( VALUE obj )
1099
+ {
1100
+ MYSQL* m = GetHandler(obj);
1101
+ mysql_library_end();
1102
+ return Qnil;
1103
+ }
1104
+
1105
+
1106
+ /* send_query(sql) */
1107
+ static VALUE send_query(VALUE obj, VALUE sql)
1108
+ {
1109
+ MYSQL* m = GetHandler(obj);
1110
+
1111
+ Check_Type(sql, T_STRING);
1112
+
1113
+ if (GetMysqlStruct(obj)->connection == Qfalse && async_in_progress(obj) == Qtrue ) {
1114
+ idle( obj );
1115
+ rb_raise(eMysql, "query: not connected");
1116
+ }
1117
+
1118
+ validate_async_query(obj);
1119
+
1120
+ if (mysql_send_query(m, RSTRING_PTR(sql), RSTRING_LEN(sql)) != 0){
1121
+ idle( obj );
1122
+ mysql_raise(m);
1123
+ }
1124
+ async_in_progress_set( obj, Qtrue );
1125
+
1126
+ return Qnil;
1127
+ }
1128
+
1129
+ /*
1130
+ get_result
1131
+ returns the mysql_result set (default) [i.e. all rows in said said]
1132
+ or nil if query_with_result == false
1133
+ */
1134
+ static VALUE get_result(VALUE obj)
1135
+ {
1136
+ MYSQL* m = GetHandler(obj);
1137
+
1138
+ async_in_progress_set( obj, Qfalse );
1139
+
1140
+ if (GetMysqlStruct(obj)->connection == Qfalse) {
1141
+ idle( obj );
1142
+ rb_raise(eMysql, "query: not connected");
1143
+ }
1144
+ if (mysql_read_query_result(m) != 0){
1145
+ idle( obj );
1146
+ mysql_raise(m);
1147
+ }
1148
+
1149
+ if (GetMysqlStruct(obj)->query_with_result == Qfalse)
1150
+ return obj;
1151
+
1152
+ if (mysql_field_count(m) == 0)
1153
+ return Qnil;
1154
+
1155
+ return store_result(obj);
1156
+ }
1157
+
1158
+ static void schedule_query(VALUE obj, VALUE timeout)
1159
+ {
1160
+ MYSQL* m = GetHandler(obj);
1161
+ fd_set read;
1162
+ int ret;
1163
+
1164
+ timeout = ( NIL_P(timeout) ? m->net.read_timeout : INT2NUM(timeout) );
1165
+
1166
+ struct timeval tv = { tv_sec: timeout, tv_usec: 0 };
1167
+
1168
+ for(;;){
1169
+ FD_ZERO(&read);
1170
+ FD_SET(m->net.fd, &read);
1171
+
1172
+ ret = rb_thread_select(m->net.fd + 1, &read, NULL, NULL, &tv);
1173
+ if (ret < 0) {
1174
+ idle( obj );
1175
+ rb_raise(eMysql, "query: timeout");
1176
+ }
1177
+
1178
+ if (ret == 0) {
1179
+ continue;
1180
+ }
1181
+
1182
+ if (m->status == MYSQL_STATUS_READY){
1183
+ break;
1184
+ }
1185
+ }
1186
+ }
1187
+
1188
+ static int should_schedule_query(){
1189
+ return rb_thread_alone() != 1;
1190
+ }
1191
+
1192
+ /* async_query(sql,timeout=nil)
1193
+ optionally take a block
1194
+ */
1195
+ static VALUE async_query(int argc, VALUE* argv, VALUE obj)
1196
+ {
1197
+ MYSQL* m = GetHandler(obj);
1198
+ VALUE sql, timeout;
1199
+
1200
+ rb_scan_args(argc, argv, "11", &sql, &timeout);
1201
+
1202
+ async_in_progress_set( obj, Qfalse );
1203
+
1204
+ busy(obj);
1205
+
1206
+ send_query( obj, sql );
1207
+
1208
+ if ( should_schedule_query() ){
1209
+ schedule_query(obj, timeout);
1210
+ }
1211
+
1212
+ if (rb_block_given_p()) {
1213
+ rb_yield( get_result(obj) );
1214
+ idle( obj );
1215
+ return obj;
1216
+ }else{
1217
+ idle( obj );
1218
+ return get_result(obj);
1219
+ }
1220
+ }
1221
+
1222
+ #if MYSQL_VERSION_ID >= 40100
1223
+ /* server_version() */
1224
+ static VALUE server_version(VALUE obj)
1225
+ {
1226
+ return INT2NUM(mysql_get_server_version(GetHandler(obj)));
1227
+ }
1228
+
1229
+ /* warning_count() */
1230
+ static VALUE warning_count(VALUE obj)
1231
+ {
1232
+ return INT2NUM(mysql_warning_count(GetHandler(obj)));
1233
+ }
1234
+
1235
+ /* commit() */
1236
+ static VALUE commit(VALUE obj)
1237
+ {
1238
+ MYSQL* m = GetHandler(obj);
1239
+ if (mysql_commit(m) != 0)
1240
+ mysql_raise(m);
1241
+ return obj;
1242
+ }
1243
+
1244
+ /* rollback() */
1245
+ static VALUE rollback(VALUE obj)
1246
+ {
1247
+ MYSQL* m = GetHandler(obj);
1248
+ if (mysql_rollback(m) != 0)
1249
+ mysql_raise(m);
1250
+ return obj;
1251
+ }
1252
+
1253
+ /* autocommit() */
1254
+ static VALUE autocommit(VALUE obj, VALUE mode)
1255
+ {
1256
+ MYSQL* m = GetHandler(obj);
1257
+ int f;
1258
+ f = (mode == Qnil || mode == Qfalse || (rb_type(mode) == T_FIXNUM && NUM2INT(mode) == 0)) ? 0 : 1;
1259
+ if (mysql_autocommit(m, f) != 0)
1260
+ mysql_raise(m);
1261
+ return obj;
1262
+ }
1263
+ #endif
1264
+
1265
+ #ifdef HAVE_MYSQL_SSL_SET
1266
+ /* ssl_set(key=nil, cert=nil, ca=nil, capath=nil, cipher=nil) */
1267
+ static VALUE ssl_set(int argc, VALUE* argv, VALUE obj)
1268
+ {
1269
+ VALUE key, cert, ca, capath, cipher;
1270
+ char *s_key, *s_cert, *s_ca, *s_capath, *s_cipher;
1271
+ MYSQL* m = GetHandler(obj);
1272
+ rb_scan_args(argc, argv, "05", &key, &cert, &ca, &capath, &cipher);
1273
+ s_key = NILorSTRING(key);
1274
+ s_cert = NILorSTRING(cert);
1275
+ s_ca = NILorSTRING(ca);
1276
+ s_capath = NILorSTRING(capath);
1277
+ s_cipher = NILorSTRING(cipher);
1278
+ mysql_ssl_set(m, s_key, s_cert, s_ca, s_capath, s_cipher);
1279
+ return obj;
1280
+ }
1281
+ #endif
1282
+
1283
+ #if MYSQL_VERSION_ID >= 40100
1284
+ /* more_results() */
1285
+ static VALUE more_results(VALUE obj)
1286
+ {
1287
+ if (mysql_more_results(GetHandler(obj)) == 0)
1288
+ return Qfalse;
1289
+ else
1290
+ return Qtrue;
1291
+ }
1292
+
1293
+ static VALUE next_result(VALUE obj)
1294
+ {
1295
+ MYSQL* m = GetHandler(obj);
1296
+ int ret;
1297
+ ret = mysql_next_result(m);
1298
+ if (ret > 0)
1299
+ mysql_raise(m);
1300
+ if (ret == 0)
1301
+ return Qtrue;
1302
+ return Qfalse;
1303
+ }
1304
+ #endif
1305
+
1306
+ #if MYSQL_VERSION_ID >= 40101
1307
+ /* set_server_option(option) */
1308
+ static VALUE set_server_option(VALUE obj, VALUE option)
1309
+ {
1310
+ MYSQL *m = GetHandler(obj);
1311
+ if (mysql_set_server_option(m, NUM2INT(option)) != 0)
1312
+ mysql_raise(m);
1313
+ return obj;
1314
+ }
1315
+
1316
+ /* sqlstate() */
1317
+ static VALUE sqlstate(VALUE obj)
1318
+ {
1319
+ MYSQL *m = GetHandler(obj);
1320
+ return rb_enc_tainted_str_new2(mysql_sqlstate(m));
1321
+ }
1322
+ #endif
1323
+
1324
+ #if MYSQL_VERSION_ID >= 40102
1325
+ /* stmt_init() */
1326
+ static VALUE stmt_init(VALUE obj)
1327
+ {
1328
+ MYSQL *m = GetHandler(obj);
1329
+ MYSQL_STMT *s;
1330
+ struct mysql_stmt* stmt;
1331
+ my_bool true = 1;
1332
+ VALUE st_obj;
1333
+
1334
+ if ((s = mysql_stmt_init(m)) == NULL)
1335
+ mysql_raise(m);
1336
+ if (mysql_stmt_attr_set(s, STMT_ATTR_UPDATE_MAX_LENGTH, &true))
1337
+ rb_raise(rb_eArgError, "mysql_stmt_attr_set() failed");
1338
+ st_obj = Data_Make_Struct(cMysqlStmt, struct mysql_stmt, 0, free_mysqlstmt, stmt);
1339
+ memset(stmt, 0, sizeof(*stmt));
1340
+ stmt->stmt = s;
1341
+ stmt->closed = Qfalse;
1342
+ return st_obj;
1343
+ }
1344
+
1345
+ static VALUE stmt_prepare(VALUE obj, VALUE query);
1346
+ /* prepare(query) */
1347
+ static VALUE prepare(VALUE obj, VALUE query)
1348
+ {
1349
+ VALUE st;
1350
+ st = stmt_init(obj);
1351
+ return stmt_prepare(st, query);
1352
+ }
1353
+ #endif
1354
+
1355
+ /* query_with_result() */
1356
+ static VALUE query_with_result(VALUE obj)
1357
+ {
1358
+ return GetMysqlStruct(obj)->query_with_result? Qtrue: Qfalse;
1359
+ }
1360
+
1361
+ /* query_with_result=(flag) */
1362
+ static VALUE query_with_result_set(VALUE obj, VALUE flag)
1363
+ {
1364
+ if (TYPE(flag) != T_TRUE && TYPE(flag) != T_FALSE)
1365
+ rb_raise(rb_eTypeError, "invalid type, required true or false.");
1366
+ GetMysqlStruct(obj)->query_with_result = flag;
1367
+ return flag;
1368
+ }
1369
+
1370
+ /* reconnect() */
1371
+ static VALUE reconnect(VALUE obj)
1372
+ {
1373
+ return GetHandler(obj)->reconnect ? Qtrue : Qfalse;
1374
+ }
1375
+
1376
+ /* reconnect=(flag) */
1377
+ static VALUE reconnect_set(VALUE obj, VALUE flag)
1378
+ {
1379
+ GetHandler(obj)->reconnect = (flag == Qnil || flag == Qfalse) ? 0 : 1;
1380
+ return flag;
1381
+ }
1382
+
1383
+ /*-------------------------------
1384
+ * Mysql::Result object method
1385
+ */
1386
+
1387
+ /* check if already freed */
1388
+ static void check_free(VALUE obj)
1389
+ {
1390
+ struct mysql_res* resp = DATA_PTR(obj);
1391
+ if (resp->freed == Qtrue)
1392
+ rb_raise(eMysql, "Mysql::Result object is already freed");
1393
+ }
1394
+
1395
+ /* data_seek(offset) */
1396
+ static VALUE data_seek(VALUE obj, VALUE offset)
1397
+ {
1398
+ check_free(obj);
1399
+ mysql_data_seek(GetMysqlRes(obj), NUM2INT(offset));
1400
+ return obj;
1401
+ }
1402
+
1403
+ /* fetch_field() */
1404
+ static VALUE fetch_field(VALUE obj)
1405
+ {
1406
+ check_free(obj);
1407
+ return make_field_obj(mysql_fetch_field(GetMysqlRes(obj)));
1408
+ }
1409
+
1410
+ /* fetch_fields() */
1411
+ static VALUE fetch_fields(VALUE obj)
1412
+ {
1413
+ MYSQL_RES* res;
1414
+ MYSQL_FIELD* f;
1415
+ unsigned int n;
1416
+ VALUE ret;
1417
+ unsigned int i;
1418
+ check_free(obj);
1419
+ res = GetMysqlRes(obj);
1420
+ f = mysql_fetch_fields(res);
1421
+ n = mysql_num_fields(res);
1422
+ ret = rb_ary_new2(n);
1423
+ for (i=0; i<n; i++)
1424
+ rb_ary_store(ret, i, make_field_obj(&f[i]));
1425
+ return ret;
1426
+ }
1427
+
1428
+ /* fetch_field_direct(nr) */
1429
+ static VALUE fetch_field_direct(VALUE obj, VALUE nr)
1430
+ {
1431
+ MYSQL_RES* res;
1432
+ unsigned int max;
1433
+ unsigned int n;
1434
+ check_free(obj);
1435
+ res = GetMysqlRes(obj);
1436
+ max = mysql_num_fields(res);
1437
+ n = NUM2INT(nr);
1438
+ if (n >= max)
1439
+ rb_raise(eMysql, "%d: out of range (max: %d)", n, max-1);
1440
+ #if MYSQL_VERSION_ID >= 32226
1441
+ return make_field_obj(mysql_fetch_field_direct(res, n));
1442
+ #else
1443
+ return make_field_obj(&mysql_fetch_field_direct(res, n));
1444
+ #endif
1445
+ }
1446
+
1447
+ /* fetch_lengths() */
1448
+ static VALUE fetch_lengths(VALUE obj)
1449
+ {
1450
+ MYSQL_RES* res;
1451
+ unsigned int n;
1452
+ unsigned long* lengths;
1453
+ VALUE ary;
1454
+ unsigned int i;
1455
+ check_free(obj);
1456
+ res = GetMysqlRes(obj);
1457
+ n = mysql_num_fields(res);
1458
+ lengths = mysql_fetch_lengths(res);
1459
+ if (lengths == NULL)
1460
+ return Qnil;
1461
+ ary = rb_ary_new2(n);
1462
+ for (i=0; i<n; i++)
1463
+ rb_ary_store(ary, i, INT2NUM(lengths[i]));
1464
+ return ary;
1465
+ }
1466
+
1467
+ /* fetch_row() */
1468
+ static VALUE fetch_row(VALUE obj)
1469
+ {
1470
+ MYSQL_RES* res;
1471
+ unsigned int n;
1472
+ MYSQL_ROW row;
1473
+ unsigned long* lengths;
1474
+ VALUE ary;
1475
+ unsigned int i;
1476
+ check_free(obj);
1477
+ res = GetMysqlRes(obj);
1478
+ n = mysql_num_fields(res);
1479
+ row = mysql_fetch_row(res);
1480
+ lengths = mysql_fetch_lengths(res);
1481
+ if (row == NULL)
1482
+ return Qnil;
1483
+ ary = rb_ary_new2(n);
1484
+ for (i=0; i<n; i++)
1485
+ rb_ary_store(ary, i, row[i]? rb_enc_tainted_str_new(row[i], lengths[i]): Qnil);
1486
+ return ary;
1487
+ }
1488
+
1489
+ /* process_all_hashes (internal helper) */
1490
+ static VALUE process_all_hashes(VALUE obj, VALUE with_table, int build_array, int yield)
1491
+ {
1492
+ MYSQL_RES* res = GetMysqlRes(obj);
1493
+ unsigned int n = mysql_num_fields(res);
1494
+ VALUE ary = Qnil;
1495
+ if(build_array)
1496
+ ary = rb_ary_new();
1497
+ MYSQL_ROW row = mysql_fetch_row(res); // grab one off the top, to determine the rows
1498
+ if (row == NULL){
1499
+ if(build_array){
1500
+ return ary;
1501
+ }else{
1502
+ return Qnil;
1503
+ }
1504
+ }
1505
+ MYSQL_FIELD* fields = mysql_fetch_fields(res);
1506
+ unsigned int i;
1507
+ VALUE hash;
1508
+ VALUE colname;
1509
+
1510
+ if (with_table == Qfalse) {
1511
+ colname = rb_iv_get(obj, "colname");
1512
+ if (colname == Qnil) {
1513
+ colname = rb_ary_new2(n);
1514
+ for (i=0; i<n; i++) {
1515
+ VALUE s = rb_enc_tainted_str_new2(fields[i].name);
1516
+ rb_obj_freeze(s);
1517
+ rb_ary_store(colname, i, s);
1518
+ }
1519
+ rb_obj_freeze(colname);
1520
+ rb_iv_set(obj, "colname", colname);
1521
+ }
1522
+ } else {
1523
+ colname = rb_iv_get(obj, "tblcolname");
1524
+ if (colname == Qnil) {
1525
+ colname = rb_ary_new2(n);
1526
+ for (i=0; i<n; i++) {
1527
+ int len = strlen(fields[i].table)+strlen(fields[i].name)+1;
1528
+ VALUE s = rb_enc_tainted_str_new(NULL, len);
1529
+ snprintf(RSTRING_PTR(s), len+1, "%s.%s", fields[i].table, fields[i].name);
1530
+ rb_obj_freeze(s);
1531
+ rb_ary_store(colname, i, s);
1532
+ }
1533
+ rb_obj_freeze(colname);
1534
+ rb_iv_set(obj, "tblcolname", colname);
1535
+ }
1536
+ }
1537
+
1538
+ unsigned long* lengths = NULL;
1539
+ while(row != NULL)
1540
+ {
1541
+ hash = rb_hash_new();
1542
+ lengths = mysql_fetch_lengths(res);
1543
+ for (i=0; i<n; i++) {
1544
+ rb_hash_aset(hash, rb_ary_entry(colname, i), row[i]? rb_enc_tainted_str_new(row[i], lengths[i]): Qnil);
1545
+ }
1546
+ if(build_array)
1547
+ rb_ary_push(ary, hash);
1548
+
1549
+ if(yield)
1550
+ rb_yield(hash);
1551
+
1552
+ row = mysql_fetch_row(res);
1553
+ }
1554
+
1555
+ /* pass back apropriate return values */
1556
+ if(build_array)
1557
+ return ary;
1558
+
1559
+ if(yield)
1560
+ return obj;
1561
+
1562
+ return Qnil; /* we should never get here -- this takes out a compiler warning */
1563
+ }
1564
+
1565
+ /* fetch_hash2 (internal) */
1566
+ static VALUE fetch_hash2(VALUE obj, VALUE with_table)
1567
+ {
1568
+ MYSQL_RES* res = GetMysqlRes(obj);
1569
+ unsigned int n = mysql_num_fields(res);
1570
+ MYSQL_ROW row = mysql_fetch_row(res);
1571
+ unsigned long* lengths = mysql_fetch_lengths(res);
1572
+ MYSQL_FIELD* fields = mysql_fetch_fields(res);
1573
+ unsigned int i;
1574
+ VALUE hash;
1575
+ VALUE colname;
1576
+ if (row == NULL)
1577
+ return Qnil;
1578
+ hash = rb_hash_new();
1579
+
1580
+ if (with_table == Qnil || with_table == Qfalse) {
1581
+ colname = rb_iv_get(obj, "colname");
1582
+ if (colname == Qnil) {
1583
+ colname = rb_ary_new2(n);
1584
+ for (i=0; i<n; i++) {
1585
+ VALUE s = rb_enc_tainted_str_new2(fields[i].name);
1586
+ rb_obj_freeze(s);
1587
+ rb_ary_store(colname, i, s);
1588
+ }
1589
+ rb_obj_freeze(colname);
1590
+ rb_iv_set(obj, "colname", colname);
1591
+ }
1592
+ } else {
1593
+ colname = rb_iv_get(obj, "tblcolname");
1594
+ if (colname == Qnil) {
1595
+ colname = rb_ary_new2(n);
1596
+ for (i=0; i<n; i++) {
1597
+ int len = strlen(fields[i].table)+strlen(fields[i].name)+1;
1598
+ VALUE s = rb_enc_tainted_str_new(NULL, len);
1599
+ snprintf(RSTRING_PTR(s), len+1, "%s.%s", fields[i].table, fields[i].name);
1600
+ rb_obj_freeze(s);
1601
+ rb_ary_store(colname, i, s);
1602
+ }
1603
+ rb_obj_freeze(colname);
1604
+ rb_iv_set(obj, "tblcolname", colname);
1605
+ }
1606
+ }
1607
+ for (i=0; i<n; i++) {
1608
+ rb_hash_aset(hash, rb_ary_entry(colname, i), row[i]? rb_enc_tainted_str_new(row[i], lengths[i]): Qnil);
1609
+ }
1610
+ return hash;
1611
+ }
1612
+
1613
+ /* fetch_hash(with_table=false) */
1614
+ static VALUE fetch_hash(int argc, VALUE* argv, VALUE obj)
1615
+ {
1616
+ VALUE with_table;
1617
+ check_free(obj);
1618
+ rb_scan_args(argc, argv, "01", &with_table);
1619
+ if (with_table == Qnil)
1620
+ with_table = Qfalse;
1621
+ return fetch_hash2(obj, with_table);
1622
+ }
1623
+
1624
+ /* field_seek(offset) */
1625
+ static VALUE field_seek(VALUE obj, VALUE offset)
1626
+ {
1627
+ check_free(obj);
1628
+ return INT2NUM(mysql_field_seek(GetMysqlRes(obj), NUM2INT(offset)));
1629
+ }
1630
+
1631
+ /* field_tell() */
1632
+ static VALUE field_tell(VALUE obj)
1633
+ {
1634
+ check_free(obj);
1635
+ return INT2NUM(mysql_field_tell(GetMysqlRes(obj)));
1636
+ }
1637
+
1638
+ /* free() */
1639
+ static VALUE res_free(VALUE obj)
1640
+ {
1641
+ struct mysql_res* resp = DATA_PTR(obj);
1642
+ check_free(obj);
1643
+ mysql_free_result(resp->res);
1644
+ resp->freed = Qtrue;
1645
+ store_result_count--;
1646
+ return Qnil;
1647
+ }
1648
+
1649
+ /* num_fields() */
1650
+ static VALUE num_fields(VALUE obj)
1651
+ {
1652
+ check_free(obj);
1653
+ return INT2NUM(mysql_num_fields(GetMysqlRes(obj)));
1654
+ }
1655
+
1656
+ /* num_rows() */
1657
+ static VALUE num_rows(VALUE obj)
1658
+ {
1659
+ check_free(obj);
1660
+ return INT2NUM(mysql_num_rows(GetMysqlRes(obj)));
1661
+ }
1662
+
1663
+ /* row_seek(offset) */
1664
+ static VALUE row_seek(VALUE obj, VALUE offset)
1665
+ {
1666
+ MYSQL_ROW_OFFSET prev_offset;
1667
+ if (CLASS_OF(offset) != cMysqlRowOffset)
1668
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Mysql::RowOffset)", rb_obj_classname(offset));
1669
+ check_free(obj);
1670
+ prev_offset = mysql_row_seek(GetMysqlRes(obj), DATA_PTR(offset));
1671
+ return Data_Wrap_Struct(cMysqlRowOffset, 0, NULL, prev_offset);
1672
+ }
1673
+
1674
+ /* row_tell() */
1675
+ static VALUE row_tell(VALUE obj)
1676
+ {
1677
+ MYSQL_ROW_OFFSET offset;
1678
+ check_free(obj);
1679
+ offset = mysql_row_tell(GetMysqlRes(obj));
1680
+ return Data_Wrap_Struct(cMysqlRowOffset, 0, NULL, offset);
1681
+ }
1682
+
1683
+ /* each {...} */
1684
+ static VALUE each(VALUE obj)
1685
+ {
1686
+ VALUE row;
1687
+ check_free(obj);
1688
+ while ((row = fetch_row(obj)) != Qnil)
1689
+ rb_yield(row);
1690
+ return obj;
1691
+ }
1692
+
1693
+ /* each_hash(with_table=false) {...} */
1694
+ static VALUE each_hash(int argc, VALUE* argv, VALUE obj)
1695
+ {
1696
+ VALUE with_table;
1697
+ check_free(obj);
1698
+ rb_scan_args(argc, argv, "01", &with_table);
1699
+ if (with_table == Qnil)
1700
+ with_table = Qfalse;
1701
+ process_all_hashes(obj, with_table, 0, 1);
1702
+ return obj;
1703
+ }
1704
+
1705
+ /* all_hashes(with_table=false) -- returns an array of hashes, one hash per row */
1706
+ static VALUE all_hashes(int argc, VALUE* argv, VALUE obj)
1707
+ {
1708
+ VALUE with_table;
1709
+ check_free(obj);
1710
+ rb_scan_args(argc, argv, "01", &with_table);
1711
+ if (with_table == Qnil)
1712
+ with_table = Qfalse;
1713
+ return process_all_hashes(obj, with_table, 1, 0);
1714
+ }
1715
+
1716
+
1717
+ /*-------------------------------
1718
+ * Mysql::Field object method
1719
+ */
1720
+
1721
+ /* hash */
1722
+ static VALUE field_hash(VALUE obj)
1723
+ {
1724
+ VALUE h = rb_hash_new();
1725
+ rb_hash_aset(h, rb_str_new2("name"), rb_iv_get(obj, "name"));
1726
+ rb_hash_aset(h, rb_str_new2("table"), rb_iv_get(obj, "table"));
1727
+ rb_hash_aset(h, rb_str_new2("def"), rb_iv_get(obj, "def"));
1728
+ rb_hash_aset(h, rb_str_new2("type"), rb_iv_get(obj, "type"));
1729
+ rb_hash_aset(h, rb_str_new2("length"), rb_iv_get(obj, "length"));
1730
+ rb_hash_aset(h, rb_str_new2("max_length"), rb_iv_get(obj, "max_length"));
1731
+ rb_hash_aset(h, rb_str_new2("flags"), rb_iv_get(obj, "flags"));
1732
+ rb_hash_aset(h, rb_str_new2("decimals"), rb_iv_get(obj, "decimals"));
1733
+ return h;
1734
+ }
1735
+
1736
+ /* inspect */
1737
+ static VALUE field_inspect(VALUE obj)
1738
+ {
1739
+ VALUE n = rb_iv_get(obj, "name");
1740
+ VALUE s = rb_enc_str_new(0, RSTRING_LEN(n) + 16, DEFAULT_ENCODING);
1741
+ sprintf(RSTRING_PTR(s), "#<Mysql::Field:%s>", RSTRING_PTR(n));
1742
+ return s;
1743
+ }
1744
+
1745
+ #define DefineMysqlFieldMemberMethod(m)\
1746
+ static VALUE field_##m(VALUE obj)\
1747
+ {return rb_iv_get(obj, #m);}
1748
+
1749
+ DefineMysqlFieldMemberMethod(name)
1750
+ DefineMysqlFieldMemberMethod(table)
1751
+ DefineMysqlFieldMemberMethod(def)
1752
+ DefineMysqlFieldMemberMethod(type)
1753
+ DefineMysqlFieldMemberMethod(length)
1754
+ DefineMysqlFieldMemberMethod(max_length)
1755
+ DefineMysqlFieldMemberMethod(flags)
1756
+ DefineMysqlFieldMemberMethod(decimals)
1757
+
1758
+ #ifdef IS_NUM
1759
+ /* is_num? */
1760
+ static VALUE field_is_num(VALUE obj)
1761
+ {
1762
+ return IS_NUM(NUM2INT(rb_iv_get(obj, "type"))) ? Qtrue : Qfalse;
1763
+ }
1764
+ #endif
1765
+
1766
+ #ifdef IS_NOT_NULL
1767
+ /* is_not_null? */
1768
+ static VALUE field_is_not_null(VALUE obj)
1769
+ {
1770
+ return IS_NOT_NULL(NUM2INT(rb_iv_get(obj, "flags"))) ? Qtrue : Qfalse;
1771
+ }
1772
+ #endif
1773
+
1774
+ #ifdef IS_PRI_KEY
1775
+ /* is_pri_key? */
1776
+ static VALUE field_is_pri_key(VALUE obj)
1777
+ {
1778
+ return IS_PRI_KEY(NUM2INT(rb_iv_get(obj, "flags"))) ? Qtrue : Qfalse;
1779
+ }
1780
+ #endif
1781
+
1782
+ #if MYSQL_VERSION_ID >= 40102
1783
+ /*-------------------------------
1784
+ * Mysql::Stmt object method
1785
+ */
1786
+
1787
+ /* check if stmt is already closed */
1788
+ static void check_stmt_closed(VALUE obj)
1789
+ {
1790
+ struct mysql_stmt* s = DATA_PTR(obj);
1791
+ if (s->closed == Qtrue)
1792
+ rb_raise(eMysql, "Mysql::Stmt object is already closed");
1793
+ }
1794
+
1795
+ static void mysql_stmt_raise(MYSQL_STMT* s)
1796
+ {
1797
+ VALUE e = rb_exc_new2(eMysql, mysql_stmt_error(s));
1798
+ rb_iv_set(e, "errno", INT2FIX(mysql_stmt_errno(s)));
1799
+ rb_iv_set(e, "sqlstate", rb_enc_tainted_str_new2(mysql_stmt_sqlstate(s)));
1800
+ rb_exc_raise(e);
1801
+ }
1802
+
1803
+ /* affected_rows() */
1804
+ static VALUE stmt_affected_rows(VALUE obj)
1805
+ {
1806
+ struct mysql_stmt* s = DATA_PTR(obj);
1807
+ my_ulonglong n;
1808
+ check_stmt_closed(obj);
1809
+ n = mysql_stmt_affected_rows(s->stmt);
1810
+ return INT2NUM(n);
1811
+ }
1812
+
1813
+ #if 0
1814
+ /* attr_get(option) */
1815
+ static VALUE stmt_attr_get(VALUE obj, VALUE opt)
1816
+ {
1817
+ struct mysql_stmt* s = DATA_PTR(obj);
1818
+ check_stmt_closed(obj);
1819
+ if (NUM2INT(opt) == STMT_ATTR_UPDATE_MAX_LENGTH) {
1820
+ my_bool arg;
1821
+ mysql_stmt_attr_get(s->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &arg);
1822
+ return arg == 1 ? Qtrue : Qfalse;
1823
+ }
1824
+ rb_raise(eMysql, "unknown option: %d", NUM2INT(opt));
1825
+ }
1826
+
1827
+ /* attr_set(option, arg) */
1828
+ static VALUE stmt_attr_set(VALUE obj, VALUE opt, VALUE val)
1829
+ {
1830
+ struct mysql_stmt* s = DATA_PTR(obj);
1831
+ check_stmt_closed(obj);
1832
+ if (NUM2INT(opt) == STMT_ATTR_UPDATE_MAX_LENGTH) {
1833
+ my_bool arg;
1834
+ arg = (val == Qnil || val == Qfalse) ? 0 : 1;
1835
+ mysql_stmt_attr_set(s->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &arg);
1836
+ return obj;
1837
+ }
1838
+ rb_raise(eMysql, "unknown option: %d", NUM2INT(opt));
1839
+ }
1840
+ #endif
1841
+
1842
+ /* bind_result(bind,...) */
1843
+ static VALUE stmt_bind_result(int argc, VALUE *argv, VALUE obj)
1844
+ {
1845
+ struct mysql_stmt* s = DATA_PTR(obj);
1846
+ int i;
1847
+ MYSQL_FIELD *field;
1848
+
1849
+ check_stmt_closed(obj);
1850
+ if (argc != s->result.n)
1851
+ rb_raise(eMysql, "bind_result: result value count(%d) != number of argument(%d)", s->result.n, argc);
1852
+ for (i = 0; i < argc; i++) {
1853
+ if (argv[i] == Qnil || argv[i] == rb_cNilClass) {
1854
+ field = mysql_fetch_fields(s->res);
1855
+ s->result.bind[i].buffer_type = field[i].type;
1856
+ }
1857
+ else if (argv[i] == rb_cString)
1858
+ s->result.bind[i].buffer_type = MYSQL_TYPE_STRING;
1859
+ else if (argv[i] == rb_cNumeric || argv[i] == rb_cInteger || argv[i] == rb_cFixnum)
1860
+ s->result.bind[i].buffer_type = MYSQL_TYPE_LONGLONG;
1861
+ else if (argv[i] == rb_cFloat)
1862
+ s->result.bind[i].buffer_type = MYSQL_TYPE_DOUBLE;
1863
+ else if (argv[i] == cMysqlTime)
1864
+ s->result.bind[i].buffer_type = MYSQL_TYPE_DATETIME;
1865
+ else
1866
+ rb_raise(rb_eTypeError, "unrecognized class: %s", RSTRING_PTR(rb_inspect(argv[i])));
1867
+ if (mysql_stmt_bind_result(s->stmt, s->result.bind))
1868
+ mysql_stmt_raise(s->stmt);
1869
+ }
1870
+ return obj;
1871
+ }
1872
+
1873
+ /* close() */
1874
+ static VALUE stmt_close(VALUE obj)
1875
+ {
1876
+ struct mysql_stmt* s = DATA_PTR(obj);
1877
+ check_stmt_closed(obj);
1878
+ mysql_stmt_close(s->stmt);
1879
+ s->closed = Qtrue;
1880
+ return Qnil;
1881
+ }
1882
+
1883
+ /* data_seek(offset) */
1884
+ static VALUE stmt_data_seek(VALUE obj, VALUE offset)
1885
+ {
1886
+ struct mysql_stmt* s = DATA_PTR(obj);
1887
+ check_stmt_closed(obj);
1888
+ mysql_stmt_data_seek(s->stmt, NUM2INT(offset));
1889
+ return obj;
1890
+ }
1891
+
1892
+ /* execute(arg,...) */
1893
+ static VALUE stmt_execute(int argc, VALUE *argv, VALUE obj)
1894
+ {
1895
+ struct mysql_stmt *s = DATA_PTR(obj);
1896
+ MYSQL_STMT *stmt = s->stmt;
1897
+ int i;
1898
+
1899
+ check_stmt_closed(obj);
1900
+ free_execute_memory(s);
1901
+ if (s->param.n != argc)
1902
+ rb_raise(eMysql, "execute: param_count(%d) != number of argument(%d)", s->param.n, argc);
1903
+ if (argc > 0) {
1904
+ memset(s->param.bind, 0, sizeof(*(s->param.bind))*argc);
1905
+ for (i = 0; i < argc; i++) {
1906
+ switch (TYPE(argv[i])) {
1907
+ case T_NIL:
1908
+ s->param.bind[i].buffer_type = MYSQL_TYPE_NULL;
1909
+ break;
1910
+ case T_FIXNUM:
1911
+ #if SIZEOF_INT < SIZEOF_LONG
1912
+ s->param.bind[i].buffer_type = MYSQL_TYPE_LONGLONG;
1913
+ s->param.bind[i].buffer = &(s->param.buffer[i]);
1914
+ *(LONG_LONG*)(s->param.bind[i].buffer) = FIX2LONG(argv[i]);
1915
+ #else
1916
+ s->param.bind[i].buffer_type = MYSQL_TYPE_LONG;
1917
+ s->param.bind[i].buffer = &(s->param.buffer[i]);
1918
+ *(int*)(s->param.bind[i].buffer) = FIX2INT(argv[i]);
1919
+ #endif
1920
+ break;
1921
+ case T_BIGNUM:
1922
+ s->param.bind[i].buffer_type = MYSQL_TYPE_LONGLONG;
1923
+ s->param.bind[i].buffer = &(s->param.buffer[i]);
1924
+ *(LONG_LONG*)(s->param.bind[i].buffer) = rb_big2ll(argv[i]);
1925
+ break;
1926
+ case T_FLOAT:
1927
+ s->param.bind[i].buffer_type = MYSQL_TYPE_DOUBLE;
1928
+ s->param.bind[i].buffer = &(s->param.buffer[i]);
1929
+ *(double*)(s->param.bind[i].buffer) = NUM2DBL(argv[i]);
1930
+ break;
1931
+ case T_STRING:
1932
+ s->param.bind[i].buffer_type = MYSQL_TYPE_STRING;
1933
+ s->param.bind[i].buffer = RSTRING_PTR(argv[i]);
1934
+ s->param.bind[i].buffer_length = RSTRING_LEN(argv[i]);
1935
+ s->param.length[i] = RSTRING_LEN(argv[i]);
1936
+ s->param.bind[i].length = &(s->param.length[i]);
1937
+ break;
1938
+ default:
1939
+ if (CLASS_OF(argv[i]) == rb_cTime) {
1940
+ MYSQL_TIME t;
1941
+ VALUE a = rb_funcall(argv[i], rb_intern("to_a"), 0);
1942
+ s->param.bind[i].buffer_type = MYSQL_TYPE_DATETIME;
1943
+ s->param.bind[i].buffer = &(s->param.buffer[i]);
1944
+ t.second_part = 0;
1945
+ t.neg = 0;
1946
+ t.second = FIX2INT(rb_ary_entry(a, 0));
1947
+ t.minute = FIX2INT(rb_ary_entry(a, 1));
1948
+ t.hour = FIX2INT(rb_ary_entry(a, 2));
1949
+ t.day = FIX2INT(rb_ary_entry(a, 3));
1950
+ t.month = FIX2INT(rb_ary_entry(a, 4));
1951
+ t.year = FIX2INT(rb_ary_entry(a, 5));
1952
+ *(MYSQL_TIME*)&(s->param.buffer[i]) = t;
1953
+ } else if (CLASS_OF(argv[i]) == cMysqlTime) {
1954
+ MYSQL_TIME t;
1955
+ s->param.bind[i].buffer_type = MYSQL_TYPE_DATETIME;
1956
+ s->param.bind[i].buffer = &(s->param.buffer[i]);
1957
+ t.second_part = 0;
1958
+ t.neg = 0;
1959
+ t.second = NUM2INT(rb_iv_get(argv[i], "second"));
1960
+ t.minute = NUM2INT(rb_iv_get(argv[i], "minute"));
1961
+ t.hour = NUM2INT(rb_iv_get(argv[i], "hour"));
1962
+ t.day = NUM2INT(rb_iv_get(argv[i], "day"));
1963
+ t.month = NUM2INT(rb_iv_get(argv[i], "month"));
1964
+ t.year = NUM2INT(rb_iv_get(argv[i], "year"));
1965
+ *(MYSQL_TIME*)&(s->param.buffer[i]) = t;
1966
+ } else
1967
+ rb_raise(rb_eTypeError, "unsupported type: %d", TYPE(argv[i]));
1968
+ }
1969
+ }
1970
+ if (mysql_stmt_bind_param(stmt, s->param.bind))
1971
+ mysql_stmt_raise(stmt);
1972
+ }
1973
+
1974
+ if (mysql_stmt_execute(stmt))
1975
+ mysql_stmt_raise(stmt);
1976
+ if (s->res) {
1977
+ MYSQL_FIELD *field;
1978
+ if (mysql_stmt_store_result(stmt))
1979
+ mysql_stmt_raise(stmt);
1980
+ field = mysql_fetch_fields(s->res);
1981
+ for (i = 0; i < s->result.n; i++) {
1982
+ switch(s->result.bind[i].buffer_type) {
1983
+ case MYSQL_TYPE_NULL:
1984
+ break;
1985
+ case MYSQL_TYPE_TINY:
1986
+ case MYSQL_TYPE_SHORT:
1987
+ case MYSQL_TYPE_YEAR:
1988
+ case MYSQL_TYPE_INT24:
1989
+ case MYSQL_TYPE_LONG:
1990
+ case MYSQL_TYPE_LONGLONG:
1991
+ case MYSQL_TYPE_FLOAT:
1992
+ case MYSQL_TYPE_DOUBLE:
1993
+ s->result.bind[i].buffer = xmalloc(8);
1994
+ s->result.bind[i].buffer_length = 8;
1995
+ memset(s->result.bind[i].buffer, 0, 8);
1996
+ break;
1997
+ case MYSQL_TYPE_DECIMAL:
1998
+ case MYSQL_TYPE_STRING:
1999
+ case MYSQL_TYPE_VAR_STRING:
2000
+ case MYSQL_TYPE_TINY_BLOB:
2001
+ case MYSQL_TYPE_BLOB:
2002
+ case MYSQL_TYPE_MEDIUM_BLOB:
2003
+ case MYSQL_TYPE_LONG_BLOB:
2004
+ #if MYSQL_VERSION_ID >= 50003
2005
+ case MYSQL_TYPE_NEWDECIMAL:
2006
+ case MYSQL_TYPE_BIT:
2007
+ #endif
2008
+ s->result.bind[i].buffer = xmalloc(field[i].max_length);
2009
+ memset(s->result.bind[i].buffer, 0, field[i].max_length);
2010
+ s->result.bind[i].buffer_length = field[i].max_length;
2011
+ break;
2012
+ case MYSQL_TYPE_TIME:
2013
+ case MYSQL_TYPE_DATE:
2014
+ case MYSQL_TYPE_DATETIME:
2015
+ case MYSQL_TYPE_TIMESTAMP:
2016
+ s->result.bind[i].buffer = xmalloc(sizeof(MYSQL_TIME));
2017
+ s->result.bind[i].buffer_length = sizeof(MYSQL_TIME);
2018
+ memset(s->result.bind[i].buffer, 0, sizeof(MYSQL_TIME));
2019
+ break;
2020
+ default:
2021
+ rb_raise(rb_eTypeError, "unknown buffer_type: %d", s->result.bind[i].buffer_type);
2022
+ }
2023
+ }
2024
+ if (mysql_stmt_bind_result(s->stmt, s->result.bind))
2025
+ mysql_stmt_raise(s->stmt);
2026
+ }
2027
+ return obj;
2028
+ }
2029
+
2030
+ /* fetch() */
2031
+ static VALUE stmt_fetch(VALUE obj)
2032
+ {
2033
+ struct mysql_stmt* s = DATA_PTR(obj);
2034
+ VALUE ret;
2035
+ int i;
2036
+ int r;
2037
+
2038
+ check_stmt_closed(obj);
2039
+ r = mysql_stmt_fetch(s->stmt);
2040
+ if (r == MYSQL_NO_DATA)
2041
+ return Qnil;
2042
+ #ifdef MYSQL_DATA_TRUNCATED
2043
+ if (r == MYSQL_DATA_TRUNCATED)
2044
+ rb_raise(rb_eRuntimeError, "unexpectedly data truncated");
2045
+ #endif
2046
+ if (r == 1)
2047
+ mysql_stmt_raise(s->stmt);
2048
+
2049
+ ret = rb_ary_new2(s->result.n);
2050
+ for (i = 0; i < s->result.n; i++) {
2051
+ if (s->result.is_null[i])
2052
+ rb_ary_push(ret, Qnil);
2053
+ else {
2054
+ VALUE v;
2055
+ MYSQL_TIME *t;
2056
+ switch (s->result.bind[i].buffer_type) {
2057
+ case MYSQL_TYPE_TINY:
2058
+ if (s->result.bind[i].is_unsigned)
2059
+ v = UINT2NUM(*(unsigned char *)s->result.bind[i].buffer);
2060
+ else
2061
+ v = INT2NUM(*(signed char *)s->result.bind[i].buffer);
2062
+ break;
2063
+ case MYSQL_TYPE_SHORT:
2064
+ case MYSQL_TYPE_YEAR:
2065
+ if (s->result.bind[i].is_unsigned)
2066
+ v = UINT2NUM(*(unsigned short *)s->result.bind[i].buffer);
2067
+ else
2068
+ v = INT2NUM(*(short *)s->result.bind[i].buffer);
2069
+ break;
2070
+ case MYSQL_TYPE_INT24:
2071
+ case MYSQL_TYPE_LONG:
2072
+ if (s->result.bind[i].is_unsigned)
2073
+ v = UINT2NUM(*(unsigned int *)s->result.bind[i].buffer);
2074
+ else
2075
+ v = INT2NUM(*(int *)s->result.bind[i].buffer);
2076
+ break;
2077
+ case MYSQL_TYPE_LONGLONG:
2078
+ if (s->result.bind[i].is_unsigned)
2079
+ v = ULL2NUM(*(unsigned long long *)s->result.bind[i].buffer);
2080
+ else
2081
+ v = LL2NUM(*(long long *)s->result.bind[i].buffer);
2082
+ break;
2083
+ case MYSQL_TYPE_FLOAT:
2084
+ v = rb_float_new((double)(*(float *)s->result.bind[i].buffer));
2085
+ break;
2086
+ case MYSQL_TYPE_DOUBLE:
2087
+ v = rb_float_new(*(double *)s->result.bind[i].buffer);
2088
+ break;
2089
+ case MYSQL_TYPE_TIME:
2090
+ case MYSQL_TYPE_DATE:
2091
+ case MYSQL_TYPE_DATETIME:
2092
+ case MYSQL_TYPE_TIMESTAMP:
2093
+ t = (MYSQL_TIME *)s->result.bind[i].buffer;
2094
+ v = rb_obj_alloc(cMysqlTime);
2095
+ rb_funcall(v, rb_intern("initialize"), 8,
2096
+ INT2FIX(t->year), INT2FIX(t->month),
2097
+ INT2FIX(t->day), INT2FIX(t->hour),
2098
+ INT2FIX(t->minute), INT2FIX(t->second),
2099
+ (t->neg ? Qtrue : Qfalse),
2100
+ INT2FIX(t->second_part));
2101
+ break;
2102
+ case MYSQL_TYPE_DECIMAL:
2103
+ case MYSQL_TYPE_STRING:
2104
+ case MYSQL_TYPE_VAR_STRING:
2105
+ case MYSQL_TYPE_TINY_BLOB:
2106
+ case MYSQL_TYPE_BLOB:
2107
+ case MYSQL_TYPE_MEDIUM_BLOB:
2108
+ case MYSQL_TYPE_LONG_BLOB:
2109
+ #if MYSQL_VERSION_ID >= 50003
2110
+ case MYSQL_TYPE_NEWDECIMAL:
2111
+ case MYSQL_TYPE_BIT:
2112
+ #endif
2113
+ v = rb_enc_tainted_str_new(s->result.bind[i].buffer, s->result.length[i]);
2114
+ break;
2115
+ default:
2116
+ rb_raise(rb_eTypeError, "unknown buffer_type: %d", s->result.bind[i].buffer_type);
2117
+ }
2118
+ rb_ary_push(ret, v);
2119
+ }
2120
+ }
2121
+ return ret;
2122
+ }
2123
+
2124
+ /* each {...} */
2125
+ static VALUE stmt_each(VALUE obj)
2126
+ {
2127
+ VALUE row;
2128
+ check_stmt_closed(obj);
2129
+ while ((row = stmt_fetch(obj)) != Qnil)
2130
+ rb_yield(row);
2131
+ return obj;
2132
+ }
2133
+
2134
+ /* field_count() */
2135
+ static VALUE stmt_field_count(VALUE obj)
2136
+ {
2137
+ struct mysql_stmt* s = DATA_PTR(obj);
2138
+ unsigned int n;
2139
+ check_stmt_closed(obj);
2140
+ n = mysql_stmt_field_count(s->stmt);
2141
+ return INT2NUM(n);
2142
+ }
2143
+
2144
+ /* free_result() */
2145
+ static VALUE stmt_free_result(VALUE obj)
2146
+ {
2147
+ struct mysql_stmt* s = DATA_PTR(obj);
2148
+ check_stmt_closed(obj);
2149
+ if (mysql_stmt_free_result(s->stmt))
2150
+ mysql_stmt_raise(s->stmt);
2151
+ return obj;
2152
+ }
2153
+
2154
+ /* insert_id() */
2155
+ static VALUE stmt_insert_id(VALUE obj)
2156
+ {
2157
+ struct mysql_stmt* s = DATA_PTR(obj);
2158
+ my_ulonglong n;
2159
+ check_stmt_closed(obj);
2160
+ n = mysql_stmt_insert_id(s->stmt);
2161
+ return INT2NUM(n);
2162
+ }
2163
+
2164
+ /* num_rows() */
2165
+ static VALUE stmt_num_rows(VALUE obj)
2166
+ {
2167
+ struct mysql_stmt* s = DATA_PTR(obj);
2168
+ my_ulonglong n;
2169
+ check_stmt_closed(obj);
2170
+ n = mysql_stmt_num_rows(s->stmt);
2171
+ return INT2NUM(n);
2172
+ }
2173
+
2174
+ /* param_count() */
2175
+ static VALUE stmt_param_count(VALUE obj)
2176
+ {
2177
+ struct mysql_stmt* s = DATA_PTR(obj);
2178
+ unsigned long n;
2179
+ check_stmt_closed(obj);
2180
+ n = mysql_stmt_param_count(s->stmt);
2181
+ return INT2NUM(n);
2182
+ }
2183
+
2184
+ /* prepare(query) */
2185
+ static VALUE stmt_prepare(VALUE obj, VALUE query)
2186
+ {
2187
+ struct mysql_stmt* s = DATA_PTR(obj);
2188
+ int n;
2189
+ int i;
2190
+ MYSQL_FIELD *field;
2191
+
2192
+ free_mysqlstmt_memory(s);
2193
+ check_stmt_closed(obj);
2194
+ Check_Type(query, T_STRING);
2195
+ if (mysql_stmt_prepare(s->stmt, RSTRING_PTR(query), RSTRING_LEN(query)))
2196
+ mysql_stmt_raise(s->stmt);
2197
+
2198
+ n = mysql_stmt_param_count(s->stmt);
2199
+ s->param.n = n;
2200
+ s->param.bind = xmalloc(sizeof(s->param.bind[0]) * n);
2201
+ s->param.length = xmalloc(sizeof(s->param.length[0]) * n);
2202
+ s->param.buffer = xmalloc(sizeof(s->param.buffer[0]) * n);
2203
+
2204
+ s->res = mysql_stmt_result_metadata(s->stmt);
2205
+ if (s->res) {
2206
+ n = s->result.n = mysql_num_fields(s->res);
2207
+ s->result.bind = xmalloc(sizeof(s->result.bind[0]) * n);
2208
+ s->result.is_null = xmalloc(sizeof(s->result.is_null[0]) * n);
2209
+ s->result.length = xmalloc(sizeof(s->result.length[0]) * n);
2210
+ field = mysql_fetch_fields(s->res);
2211
+ memset(s->result.bind, 0, sizeof(s->result.bind[0]) * n);
2212
+ for (i = 0; i < n; i++) {
2213
+ s->result.bind[i].buffer_type = field[i].type;
2214
+ #if MYSQL_VERSION_ID < 50003
2215
+ if (field[i].type == MYSQL_TYPE_DECIMAL)
2216
+ s->result.bind[i].buffer_type = MYSQL_TYPE_STRING;
2217
+ #endif
2218
+ s->result.bind[i].is_null = &(s->result.is_null[i]);
2219
+ s->result.bind[i].length = &(s->result.length[i]);
2220
+ s->result.bind[i].is_unsigned = ((field[i].flags & UNSIGNED_FLAG) != 0);
2221
+ }
2222
+ } else {
2223
+ if (mysql_stmt_errno(s->stmt))
2224
+ mysql_stmt_raise(s->stmt);
2225
+ }
2226
+
2227
+ return obj;
2228
+ }
2229
+
2230
+ #if 0
2231
+ /* reset() */
2232
+ static VALUE stmt_reset(VALUE obj)
2233
+ {
2234
+ struct mysql_stmt* s = DATA_PTR(obj);
2235
+ check_stmt_closed(obj);
2236
+ if (mysql_stmt_reset(s->stmt))
2237
+ mysql_stmt_raise(s->stmt);
2238
+ return obj;
2239
+ }
2240
+ #endif
2241
+
2242
+ /* result_metadata() */
2243
+ static VALUE stmt_result_metadata(VALUE obj)
2244
+ {
2245
+ struct mysql_stmt* s = DATA_PTR(obj);
2246
+ MYSQL_RES *res;
2247
+ check_stmt_closed(obj);
2248
+ res = mysql_stmt_result_metadata(s->stmt);
2249
+ if (res == NULL) {
2250
+ if (mysql_stmt_errno(s->stmt) != 0)
2251
+ mysql_stmt_raise(s->stmt);
2252
+ return Qnil;
2253
+ }
2254
+ return mysqlres2obj(res, Qfalse);
2255
+ }
2256
+
2257
+ /* row_seek(offset) */
2258
+ static VALUE stmt_row_seek(VALUE obj, VALUE offset)
2259
+ {
2260
+ struct mysql_stmt* s = DATA_PTR(obj);
2261
+ MYSQL_ROW_OFFSET prev_offset;
2262
+ if (CLASS_OF(offset) != cMysqlRowOffset)
2263
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Mysql::RowOffset)", rb_obj_classname(offset));
2264
+ check_stmt_closed(obj);
2265
+ prev_offset = mysql_stmt_row_seek(s->stmt, DATA_PTR(offset));
2266
+ return Data_Wrap_Struct(cMysqlRowOffset, 0, NULL, prev_offset);
2267
+ }
2268
+
2269
+ /* row_tell() */
2270
+ static VALUE stmt_row_tell(VALUE obj)
2271
+ {
2272
+ struct mysql_stmt* s = DATA_PTR(obj);
2273
+ MYSQL_ROW_OFFSET offset;
2274
+ check_stmt_closed(obj);
2275
+ offset = mysql_stmt_row_tell(s->stmt);
2276
+ return Data_Wrap_Struct(cMysqlRowOffset, 0, NULL, offset);
2277
+ }
2278
+
2279
+ #if 0
2280
+ /* send_long_data(col, data) */
2281
+ static VALUE stmt_send_long_data(VALUE obj, VALUE col, VALUE data)
2282
+ {
2283
+ struct mysql_stmt* s = DATA_PTR(obj);
2284
+ int c;
2285
+ check_stmt_closed(obj);
2286
+ c = NUM2INT(col);
2287
+ if (0 <= c && c < s->param.n) {
2288
+ s->param.bind[c].buffer_type = MYSQL_TYPE_STRING;
2289
+ if (mysql_stmt_bind_param(s->stmt, s->param.bind))
2290
+ mysql_stmt_raise(s->stmt);
2291
+ }
2292
+ if (mysql_stmt_send_long_data(s->stmt, c, RSTRING_PTR(data), RSTRING_LEN(data)))
2293
+ mysql_stmt_raise(s->stmt);
2294
+ return obj;
2295
+ }
2296
+ #endif
2297
+
2298
+ /* sqlstate() */
2299
+ static VALUE stmt_sqlstate(VALUE obj)
2300
+ {
2301
+ struct mysql_stmt* s = DATA_PTR(obj);
2302
+ return rb_enc_tainted_str_new2(mysql_stmt_sqlstate(s->stmt));
2303
+ }
2304
+
2305
+ /*-------------------------------
2306
+ * Mysql::Time object method
2307
+ */
2308
+
2309
+ static VALUE time_initialize(int argc, VALUE* argv, VALUE obj)
2310
+ {
2311
+ VALUE year, month, day, hour, minute, second, neg, second_part;
2312
+ rb_scan_args(argc, argv, "08", &year, &month, &day, &hour, &minute, &second, &neg, &second_part);
2313
+ #define NILorFIXvalue(o) (NIL_P(o) ? INT2FIX(0) : (Check_Type(o, T_FIXNUM), o))
2314
+ rb_iv_set(obj, "year", NILorFIXvalue(year));
2315
+ rb_iv_set(obj, "month", NILorFIXvalue(month));
2316
+ rb_iv_set(obj, "day", NILorFIXvalue(day));
2317
+ rb_iv_set(obj, "hour", NILorFIXvalue(hour));
2318
+ rb_iv_set(obj, "minute", NILorFIXvalue(minute));
2319
+ rb_iv_set(obj, "second", NILorFIXvalue(second));
2320
+ rb_iv_set(obj, "neg", (neg == Qnil || neg == Qfalse) ? Qfalse : Qtrue);
2321
+ rb_iv_set(obj, "second_part", NILorFIXvalue(second_part));
2322
+ return obj;
2323
+ }
2324
+
2325
+ static VALUE time_inspect(VALUE obj)
2326
+ {
2327
+ char buf[36];
2328
+ sprintf(buf, "#<Mysql::Time:%04d-%02d-%02d %02d:%02d:%02d>",
2329
+ NUM2INT(rb_iv_get(obj, "year")),
2330
+ NUM2INT(rb_iv_get(obj, "month")),
2331
+ NUM2INT(rb_iv_get(obj, "day")),
2332
+ NUM2INT(rb_iv_get(obj, "hour")),
2333
+ NUM2INT(rb_iv_get(obj, "minute")),
2334
+ NUM2INT(rb_iv_get(obj, "second")));
2335
+ return rb_str_new2(buf);
2336
+ }
2337
+
2338
+ static VALUE time_to_s(VALUE obj)
2339
+ {
2340
+ char buf[20];
2341
+ sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d",
2342
+ NUM2INT(rb_iv_get(obj, "year")),
2343
+ NUM2INT(rb_iv_get(obj, "month")),
2344
+ NUM2INT(rb_iv_get(obj, "day")),
2345
+ NUM2INT(rb_iv_get(obj, "hour")),
2346
+ NUM2INT(rb_iv_get(obj, "minute")),
2347
+ NUM2INT(rb_iv_get(obj, "second")));
2348
+ return rb_str_new2(buf);
2349
+ }
2350
+
2351
+ #define DefineMysqlTimeGetMethod(m)\
2352
+ static VALUE time_get_##m(VALUE obj)\
2353
+ {return rb_iv_get(obj, #m);}
2354
+
2355
+ DefineMysqlTimeGetMethod(year)
2356
+ DefineMysqlTimeGetMethod(month)
2357
+ DefineMysqlTimeGetMethod(day)
2358
+ DefineMysqlTimeGetMethod(hour)
2359
+ DefineMysqlTimeGetMethod(minute)
2360
+ DefineMysqlTimeGetMethod(second)
2361
+ DefineMysqlTimeGetMethod(neg)
2362
+ DefineMysqlTimeGetMethod(second_part)
2363
+
2364
+ #define DefineMysqlTimeSetMethod(m)\
2365
+ static VALUE time_set_##m(VALUE obj, VALUE v)\
2366
+ {rb_iv_set(obj, #m, NILorFIXvalue(v)); return v;}
2367
+
2368
+ DefineMysqlTimeSetMethod(year)
2369
+ DefineMysqlTimeSetMethod(month)
2370
+ DefineMysqlTimeSetMethod(day)
2371
+ DefineMysqlTimeSetMethod(hour)
2372
+ DefineMysqlTimeSetMethod(minute)
2373
+ DefineMysqlTimeSetMethod(second)
2374
+ DefineMysqlTimeSetMethod(second_part)
2375
+
2376
+ static VALUE time_set_neg(VALUE obj, VALUE v)
2377
+ {
2378
+ rb_iv_set(obj, "neg", (v == Qnil || v == Qfalse) ? Qfalse : Qtrue);
2379
+ return v;
2380
+ }
2381
+
2382
+ static VALUE time_equal(VALUE obj, VALUE v)
2383
+ {
2384
+ if (CLASS_OF(v) == cMysqlTime &&
2385
+ NUM2INT(rb_iv_get(obj, "year")) == NUM2INT(rb_iv_get(v, "year")) &&
2386
+ NUM2INT(rb_iv_get(obj, "month")) == NUM2INT(rb_iv_get(v, "month")) &&
2387
+ NUM2INT(rb_iv_get(obj, "day")) == NUM2INT(rb_iv_get(v, "day")) &&
2388
+ NUM2INT(rb_iv_get(obj, "hour")) == NUM2INT(rb_iv_get(v, "hour")) &&
2389
+ NUM2INT(rb_iv_get(obj, "minute")) == NUM2INT(rb_iv_get(v, "minute")) &&
2390
+ NUM2INT(rb_iv_get(obj, "second")) == NUM2INT(rb_iv_get(v, "second")) &&
2391
+ rb_iv_get(obj, "neg") == rb_iv_get(v, "neg") &&
2392
+ NUM2INT(rb_iv_get(obj, "second_part")) == NUM2INT(rb_iv_get(v, "second_part")))
2393
+ return Qtrue;
2394
+ return Qfalse;
2395
+ }
2396
+
2397
+ #endif
2398
+
2399
+ /*-------------------------------
2400
+ * Mysql::Error object method
2401
+ */
2402
+
2403
+ static VALUE error_error(VALUE obj)
2404
+ {
2405
+ return rb_iv_get(obj, "mesg");
2406
+ }
2407
+
2408
+ static VALUE error_errno(VALUE obj)
2409
+ {
2410
+ return rb_iv_get(obj, "errno");
2411
+ }
2412
+
2413
+ static VALUE error_sqlstate(VALUE obj)
2414
+ {
2415
+ return rb_iv_get(obj, "sqlstate");
2416
+ }
2417
+
2418
+ /*-------------------------------
2419
+ * Initialize
2420
+ */
2421
+
2422
+ void Init_mysql(void)
2423
+ {
2424
+ cMysql = rb_define_class("Mysql", rb_cObject);
2425
+ cMysqlRes = rb_define_class_under(cMysql, "Result", rb_cObject);
2426
+ cMysqlField = rb_define_class_under(cMysql, "Field", rb_cObject);
2427
+ #if MYSQL_VERSION_ID >= 40102
2428
+ cMysqlStmt = rb_define_class_under(cMysql, "Stmt", rb_cObject);
2429
+ cMysqlRowOffset = rb_define_class_under(cMysql, "RowOffset", rb_cObject);
2430
+ cMysqlTime = rb_define_class_under(cMysql, "Time", rb_cObject);
2431
+ #endif
2432
+ eMysql = rb_define_class_under(cMysql, "Error", rb_eStandardError);
2433
+
2434
+ rb_define_global_const("MysqlRes", cMysqlRes);
2435
+ rb_define_global_const("MysqlField", cMysqlField);
2436
+ rb_define_global_const("MysqlError", eMysql);
2437
+
2438
+ /* Mysql class method */
2439
+ rb_define_singleton_method(cMysql, "init", init, 0);
2440
+ rb_define_singleton_method(cMysql, "real_connect", real_connect, -1);
2441
+ rb_define_singleton_method(cMysql, "connect", real_connect, -1);
2442
+ rb_define_singleton_method(cMysql, "new", real_connect, -1);
2443
+ rb_define_singleton_method(cMysql, "escape_string", escape_string, 1);
2444
+ rb_define_singleton_method(cMysql, "quote", escape_string, 1);
2445
+ rb_define_singleton_method(cMysql, "client_info", client_info, 0);
2446
+ rb_define_singleton_method(cMysql, "get_client_info", client_info, 0);
2447
+ #if MYSQL_VERSION_ID >= 32332
2448
+ rb_define_singleton_method(cMysql, "debug", my_debug, 1);
2449
+ #endif
2450
+ #if MYSQL_VERSION_ID >= 40000
2451
+ rb_define_singleton_method(cMysql, "get_client_version", client_version, 0);
2452
+ rb_define_singleton_method(cMysql, "client_version", client_version, 0);
2453
+ #endif
2454
+
2455
+ /* Mysql object method */
2456
+ #if MYSQL_VERSION_ID >= 32200
2457
+ rb_define_method(cMysql, "real_connect", real_connect2, -1);
2458
+ rb_define_method(cMysql, "connect", real_connect2, -1);
2459
+ rb_define_method(cMysql, "options", options, -1);
2460
+ #endif
2461
+ rb_define_method(cMysql, "initialize", initialize, -1);
2462
+ #if MYSQL_VERSION_ID >= 32332
2463
+ rb_define_method(cMysql, "escape_string", real_escape_string, 1);
2464
+ rb_define_method(cMysql, "quote", real_escape_string, 1);
2465
+ #else
2466
+ rb_define_method(cMysql, "escape_string", escape_string, 1);
2467
+ rb_define_method(cMysql, "quote", escape_string, 1);
2468
+ #endif
2469
+ rb_define_method(cMysql, "client_info", client_info, 0);
2470
+ rb_define_method(cMysql, "get_client_info", client_info, 0);
2471
+ rb_define_method(cMysql, "affected_rows", affected_rows, 0);
2472
+ #if MYSQL_VERSION_ID >= 32303
2473
+ rb_define_method(cMysql, "change_user", change_user, -1);
2474
+ #endif
2475
+ #if MYSQL_VERSION_ID >= 32321
2476
+ rb_define_method(cMysql, "character_set_name", character_set_name, 0);
2477
+ #endif
2478
+ rb_define_method(cMysql, "close", my_close, 0);
2479
+ #if MYSQL_VERSION_ID < 40000
2480
+ rb_define_method(cMysql, "create_db", create_db, 1);
2481
+ rb_define_method(cMysql, "drop_db", drop_db, 1);
2482
+ #endif
2483
+ #if MYSQL_VERSION_ID >= 32332
2484
+ rb_define_method(cMysql, "dump_debug_info", dump_debug_info, 0);
2485
+ #endif
2486
+ rb_define_method(cMysql, "errno", my_errno, 0);
2487
+ rb_define_method(cMysql, "error", my_error, 0);
2488
+ rb_define_method(cMysql, "field_count", field_count, 0);
2489
+ #if MYSQL_VERSION_ID >= 40000
2490
+ rb_define_method(cMysql, "get_client_version", client_version, 0);
2491
+ rb_define_method(cMysql, "client_version", client_version, 0);
2492
+ #endif
2493
+ rb_define_method(cMysql, "get_host_info", host_info, 0);
2494
+ rb_define_method(cMysql, "host_info", host_info, 0);
2495
+ rb_define_method(cMysql, "get_proto_info", proto_info, 0);
2496
+ rb_define_method(cMysql, "proto_info", proto_info, 0);
2497
+ rb_define_method(cMysql, "get_server_info", server_info, 0);
2498
+ rb_define_method(cMysql, "server_info", server_info, 0);
2499
+ rb_define_method(cMysql, "info", info, 0);
2500
+ rb_define_method(cMysql, "insert_id", insert_id, 0);
2501
+ rb_define_method(cMysql, "kill", my_kill, 1);
2502
+ rb_define_method(cMysql, "list_dbs", list_dbs, -1);
2503
+ rb_define_method(cMysql, "list_fields", list_fields, -1);
2504
+ rb_define_method(cMysql, "list_processes", list_processes, 0);
2505
+ rb_define_method(cMysql, "list_tables", list_tables, -1);
2506
+ #if MYSQL_VERSION_ID >= 32200
2507
+ rb_define_method(cMysql, "ping", ping, 0);
2508
+ #endif
2509
+ rb_define_method(cMysql, "query", query, 1);
2510
+ rb_define_method(cMysql, "real_query", query, 1);
2511
+ rb_define_method(cMysql, "c_async_query", async_query, -1);
2512
+ rb_define_method(cMysql, "async_in_progress?", async_in_progress, 0);
2513
+ rb_define_method(cMysql, "async_in_progress=", async_in_progress_set, 1);
2514
+ rb_define_method(cMysql, "send_query", send_query, 1);
2515
+ rb_define_method(cMysql, "simulate_disconnect", simulate_disconnect, 0);
2516
+ rb_define_method(cMysql, "reconnected?", reconnected, 0);
2517
+ rb_define_method(cMysql, "get_result", get_result, 0);
2518
+ rb_define_method(cMysql, "readable?", readable, -1);
2519
+ rb_define_method(cMysql, "retry?", retry, 0);
2520
+ rb_define_method(cMysql, "interrupted?", interrupted, 0);
2521
+ rb_define_method(cMysql, "blocking?", blocking, 0);
2522
+ rb_define_method(cMysql, "gc_disabled?", gc_disabled, 0);
2523
+ rb_define_method(cMysql, "disable_gc=", disable_gc_set, 1);
2524
+ rb_define_method(cMysql, "busy?", is_busy, 0);
2525
+ rb_define_method(cMysql, "idle?", is_idle, 0);
2526
+ rb_define_method(cMysql, "busy=", busy_set, 1);
2527
+ rb_define_method(cMysql, "socket", socket, 0);
2528
+ rb_define_method(cMysql, "refresh", refresh, 1);
2529
+ rb_define_method(cMysql, "reload", reload, 0);
2530
+ rb_define_method(cMysql, "select_db", select_db, 1);
2531
+ rb_define_method(cMysql, "shutdown", my_shutdown, -1);
2532
+ rb_define_method(cMysql, "stat", my_stat, 0);
2533
+ rb_define_method(cMysql, "store_result", store_result, 0);
2534
+ rb_define_method(cMysql, "thread_id", thread_id, 0);
2535
+ rb_define_method(cMysql, "use_result", use_result, 0);
2536
+ #if MYSQL_VERSION_ID >= 40100
2537
+ rb_define_method(cMysql, "get_server_version", server_version, 0);
2538
+ rb_define_method(cMysql, "server_version", server_version, 0);
2539
+ rb_define_method(cMysql, "warning_count", warning_count, 0);
2540
+ rb_define_method(cMysql, "commit", commit, 0);
2541
+ rb_define_method(cMysql, "rollback", rollback, 0);
2542
+ rb_define_method(cMysql, "autocommit", autocommit, 1);
2543
+ #endif
2544
+ #ifdef HAVE_MYSQL_SSL_SET
2545
+ rb_define_method(cMysql, "ssl_set", ssl_set, -1);
2546
+ #endif
2547
+ #if MYSQL_VERSION_ID >= 40102
2548
+ rb_define_method(cMysql, "stmt_init", stmt_init, 0);
2549
+ rb_define_method(cMysql, "prepare", prepare, 1);
2550
+ #endif
2551
+ #if MYSQL_VERSION_ID >= 40100
2552
+ rb_define_method(cMysql, "more_results", more_results, 0);
2553
+ rb_define_method(cMysql, "more_results?", more_results, 0);
2554
+ rb_define_method(cMysql, "next_result", next_result, 0);
2555
+ #endif
2556
+ #if MYSQL_VERSION_ID >= 40101
2557
+ rb_define_method(cMysql, "set_server_option", set_server_option, 1);
2558
+ rb_define_method(cMysql, "sqlstate", sqlstate, 0);
2559
+ #endif
2560
+ rb_define_method(cMysql, "query_with_result", query_with_result, 0);
2561
+ rb_define_method(cMysql, "query_with_result=", query_with_result_set, 1);
2562
+
2563
+ rb_define_method(cMysql, "reconnect", reconnect, 0);
2564
+ rb_define_method(cMysql, "reconnect=", reconnect_set, 1);
2565
+
2566
+ /* Mysql constant */
2567
+ rb_define_const(cMysql, "VERSION", INT2FIX(MYSQL_RUBY_VERSION));
2568
+ #if MYSQL_VERSION_ID >= 32200
2569
+ rb_define_const(cMysql, "OPT_CONNECT_TIMEOUT", INT2NUM(MYSQL_OPT_CONNECT_TIMEOUT));
2570
+ rb_define_const(cMysql, "OPT_COMPRESS", INT2NUM(MYSQL_OPT_COMPRESS));
2571
+ rb_define_const(cMysql, "OPT_NAMED_PIPE", INT2NUM(MYSQL_OPT_NAMED_PIPE));
2572
+ rb_define_const(cMysql, "INIT_COMMAND", INT2NUM(MYSQL_INIT_COMMAND));
2573
+ rb_define_const(cMysql, "READ_DEFAULT_FILE", INT2NUM(MYSQL_READ_DEFAULT_FILE));
2574
+ rb_define_const(cMysql, "READ_DEFAULT_GROUP", INT2NUM(MYSQL_READ_DEFAULT_GROUP));
2575
+ #endif
2576
+ #if MYSQL_VERSION_ID >= 32349
2577
+ rb_define_const(cMysql, "SET_CHARSET_DIR", INT2NUM(MYSQL_SET_CHARSET_DIR));
2578
+ rb_define_const(cMysql, "SET_CHARSET_NAME", INT2NUM(MYSQL_SET_CHARSET_NAME));
2579
+ rb_define_const(cMysql, "OPT_LOCAL_INFILE", INT2NUM(MYSQL_OPT_LOCAL_INFILE));
2580
+ #endif
2581
+ #if MYSQL_VERSION_ID >= 40100
2582
+ rb_define_const(cMysql, "OPT_PROTOCOL", INT2NUM(MYSQL_OPT_PROTOCOL));
2583
+ rb_define_const(cMysql, "SHARED_MEMORY_BASE_NAME", INT2NUM(MYSQL_SHARED_MEMORY_BASE_NAME));
2584
+ #endif
2585
+ #if MYSQL_VERSION_ID >= 40101
2586
+ rb_define_const(cMysql, "OPT_READ_TIMEOUT", INT2NUM(MYSQL_OPT_READ_TIMEOUT));
2587
+ rb_define_const(cMysql, "OPT_WRITE_TIMEOUT", INT2NUM(MYSQL_OPT_WRITE_TIMEOUT));
2588
+ rb_define_const(cMysql, "SECURE_AUTH", INT2NUM(MYSQL_SECURE_AUTH));
2589
+ rb_define_const(cMysql, "OPT_GUESS_CONNECTION", INT2NUM(MYSQL_OPT_GUESS_CONNECTION));
2590
+ rb_define_const(cMysql, "OPT_USE_EMBEDDED_CONNECTION", INT2NUM(MYSQL_OPT_USE_EMBEDDED_CONNECTION));
2591
+ rb_define_const(cMysql, "OPT_USE_REMOTE_CONNECTION", INT2NUM(MYSQL_OPT_USE_REMOTE_CONNECTION));
2592
+ rb_define_const(cMysql, "SET_CLIENT_IP", INT2NUM(MYSQL_SET_CLIENT_IP));
2593
+ #endif
2594
+ rb_define_const(cMysql, "REFRESH_GRANT", INT2NUM(REFRESH_GRANT));
2595
+ rb_define_const(cMysql, "REFRESH_LOG", INT2NUM(REFRESH_LOG));
2596
+ rb_define_const(cMysql, "REFRESH_TABLES", INT2NUM(REFRESH_TABLES));
2597
+ #ifdef REFRESH_HOSTS
2598
+ rb_define_const(cMysql, "REFRESH_HOSTS", INT2NUM(REFRESH_HOSTS));
2599
+ #endif
2600
+ #ifdef REFRESH_STATUS
2601
+ rb_define_const(cMysql, "REFRESH_STATUS", INT2NUM(REFRESH_STATUS));
2602
+ #endif
2603
+ #ifdef REFRESH_THREADS
2604
+ rb_define_const(cMysql, "REFRESH_THREADS", INT2NUM(REFRESH_THREADS));
2605
+ #endif
2606
+ #ifdef REFRESH_SLAVE
2607
+ rb_define_const(cMysql, "REFRESH_SLAVE", INT2NUM(REFRESH_SLAVE));
2608
+ #endif
2609
+ #ifdef REFRESH_MASTER
2610
+ rb_define_const(cMysql, "REFRESH_MASTER", INT2NUM(REFRESH_MASTER));
2611
+ #endif
2612
+ #ifdef CLIENT_LONG_PASSWORD
2613
+ #endif
2614
+ #ifdef CLIENT_FOUND_ROWS
2615
+ rb_define_const(cMysql, "CLIENT_FOUND_ROWS", INT2NUM(CLIENT_FOUND_ROWS));
2616
+ #endif
2617
+ #ifdef CLIENT_LONG_FLAG
2618
+ #endif
2619
+ #ifdef CLIENT_CONNECT_WITH_DB
2620
+ #endif
2621
+ #ifdef CLIENT_NO_SCHEMA
2622
+ rb_define_const(cMysql, "CLIENT_NO_SCHEMA", INT2NUM(CLIENT_NO_SCHEMA));
2623
+ #endif
2624
+ #ifdef CLIENT_COMPRESS
2625
+ rb_define_const(cMysql, "CLIENT_COMPRESS", INT2NUM(CLIENT_COMPRESS));
2626
+ #endif
2627
+ #ifdef CLIENT_ODBC
2628
+ rb_define_const(cMysql, "CLIENT_ODBC", INT2NUM(CLIENT_ODBC));
2629
+ #endif
2630
+ #ifdef CLIENT_LOCAL_FILES
2631
+ rb_define_const(cMysql, "CLIENT_LOCAL_FILES", INT2NUM(CLIENT_LOCAL_FILES));
2632
+ #endif
2633
+ #ifdef CLIENT_IGNORE_SPACE
2634
+ rb_define_const(cMysql, "CLIENT_IGNORE_SPACE", INT2NUM(CLIENT_IGNORE_SPACE));
2635
+ #endif
2636
+ #ifdef CLIENT_CHANGE_USER
2637
+ rb_define_const(cMysql, "CLIENT_CHANGE_USER", INT2NUM(CLIENT_CHANGE_USER));
2638
+ #endif
2639
+ #ifdef CLIENT_INTERACTIVE
2640
+ rb_define_const(cMysql, "CLIENT_INTERACTIVE", INT2NUM(CLIENT_INTERACTIVE));
2641
+ #endif
2642
+ #ifdef CLIENT_SSL
2643
+ rb_define_const(cMysql, "CLIENT_SSL", INT2NUM(CLIENT_SSL));
2644
+ #endif
2645
+ #ifdef CLIENT_IGNORE_SIGPIPE
2646
+ rb_define_const(cMysql, "CLIENT_IGNORE_SIGPIPE", INT2NUM(CLIENT_IGNORE_SIGPIPE));
2647
+ #endif
2648
+ #ifdef CLIENT_TRANSACTIONS
2649
+ rb_define_const(cMysql, "CLIENT_TRANSACTIONS", INT2NUM(CLIENT_TRANSACTIONS));
2650
+ #endif
2651
+ #ifdef CLIENT_MULTI_STATEMENTS
2652
+ rb_define_const(cMysql, "CLIENT_MULTI_STATEMENTS", INT2NUM(CLIENT_MULTI_STATEMENTS));
2653
+ #endif
2654
+ #ifdef CLIENT_MULTI_RESULTS
2655
+ rb_define_const(cMysql, "CLIENT_MULTI_RESULTS", INT2NUM(CLIENT_MULTI_RESULTS));
2656
+ #endif
2657
+ #if MYSQL_VERSION_ID >= 40101
2658
+ rb_define_const(cMysql, "OPTION_MULTI_STATEMENTS_ON", INT2NUM(MYSQL_OPTION_MULTI_STATEMENTS_ON));
2659
+ rb_define_const(cMysql, "OPTION_MULTI_STATEMENTS_OFF", INT2NUM(MYSQL_OPTION_MULTI_STATEMENTS_OFF));
2660
+ #endif
2661
+
2662
+ /* Mysql::Result object method */
2663
+ rb_define_method(cMysqlRes, "data_seek", data_seek, 1);
2664
+ rb_define_method(cMysqlRes, "fetch_field", fetch_field, 0);
2665
+ rb_define_method(cMysqlRes, "fetch_fields", fetch_fields, 0);
2666
+ rb_define_method(cMysqlRes, "fetch_field_direct", fetch_field_direct, 1);
2667
+ rb_define_method(cMysqlRes, "fetch_lengths", fetch_lengths, 0);
2668
+ rb_define_method(cMysqlRes, "fetch_row", fetch_row, 0);
2669
+ rb_define_method(cMysqlRes, "fetch_hash", fetch_hash, -1);
2670
+ rb_define_method(cMysqlRes, "field_seek", field_seek, 1);
2671
+ rb_define_method(cMysqlRes, "field_tell", field_tell, 0);
2672
+ rb_define_method(cMysqlRes, "free", res_free, 0);
2673
+ rb_define_method(cMysqlRes, "num_fields", num_fields, 0);
2674
+ rb_define_method(cMysqlRes, "num_rows", num_rows, 0);
2675
+ rb_define_method(cMysqlRes, "row_seek", row_seek, 1);
2676
+ rb_define_method(cMysqlRes, "row_tell", row_tell, 0);
2677
+ rb_define_method(cMysqlRes, "each", each, 0);
2678
+ rb_define_method(cMysqlRes, "each_hash", each_hash, -1);
2679
+ rb_define_method(cMysqlRes, "all_hashes", all_hashes, -1);
2680
+
2681
+ /* MysqlField object method */
2682
+ rb_define_method(cMysqlField, "name", field_name, 0);
2683
+ rb_define_method(cMysqlField, "table", field_table, 0);
2684
+ rb_define_method(cMysqlField, "def", field_def, 0);
2685
+ rb_define_method(cMysqlField, "type", field_type, 0);
2686
+ rb_define_method(cMysqlField, "length", field_length, 0);
2687
+ rb_define_method(cMysqlField, "max_length", field_max_length, 0);
2688
+ rb_define_method(cMysqlField, "flags", field_flags, 0);
2689
+ rb_define_method(cMysqlField, "decimals", field_decimals, 0);
2690
+ rb_define_method(cMysqlField, "hash", field_hash, 0);
2691
+ rb_define_method(cMysqlField, "inspect", field_inspect, 0);
2692
+ #ifdef IS_NUM
2693
+ rb_define_method(cMysqlField, "is_num?", field_is_num, 0);
2694
+ #endif
2695
+ #ifdef IS_NOT_NULL
2696
+ rb_define_method(cMysqlField, "is_not_null?", field_is_not_null, 0);
2697
+ #endif
2698
+ #ifdef IS_PRI_KEY
2699
+ rb_define_method(cMysqlField, "is_pri_key?", field_is_pri_key, 0);
2700
+ #endif
2701
+
2702
+ /* Mysql::Field constant: TYPE */
2703
+ rb_define_const(cMysqlField, "TYPE_TINY", INT2NUM(FIELD_TYPE_TINY));
2704
+ #if MYSQL_VERSION_ID >= 32115
2705
+ rb_define_const(cMysqlField, "TYPE_ENUM", INT2NUM(FIELD_TYPE_ENUM));
2706
+ #endif
2707
+ rb_define_const(cMysqlField, "TYPE_DECIMAL", INT2NUM(FIELD_TYPE_DECIMAL));
2708
+ rb_define_const(cMysqlField, "TYPE_SHORT", INT2NUM(FIELD_TYPE_SHORT));
2709
+ rb_define_const(cMysqlField, "TYPE_LONG", INT2NUM(FIELD_TYPE_LONG));
2710
+ rb_define_const(cMysqlField, "TYPE_FLOAT", INT2NUM(FIELD_TYPE_FLOAT));
2711
+ rb_define_const(cMysqlField, "TYPE_DOUBLE", INT2NUM(FIELD_TYPE_DOUBLE));
2712
+ rb_define_const(cMysqlField, "TYPE_NULL", INT2NUM(FIELD_TYPE_NULL));
2713
+ rb_define_const(cMysqlField, "TYPE_TIMESTAMP", INT2NUM(FIELD_TYPE_TIMESTAMP));
2714
+ rb_define_const(cMysqlField, "TYPE_LONGLONG", INT2NUM(FIELD_TYPE_LONGLONG));
2715
+ rb_define_const(cMysqlField, "TYPE_INT24", INT2NUM(FIELD_TYPE_INT24));
2716
+ rb_define_const(cMysqlField, "TYPE_DATE", INT2NUM(FIELD_TYPE_DATE));
2717
+ rb_define_const(cMysqlField, "TYPE_TIME", INT2NUM(FIELD_TYPE_TIME));
2718
+ rb_define_const(cMysqlField, "TYPE_DATETIME", INT2NUM(FIELD_TYPE_DATETIME));
2719
+ #if MYSQL_VERSION_ID >= 32130
2720
+ rb_define_const(cMysqlField, "TYPE_YEAR", INT2NUM(FIELD_TYPE_YEAR));
2721
+ #endif
2722
+ #if MYSQL_VERSION_ID >= 50003
2723
+ rb_define_const(cMysqlField, "TYPE_BIT", INT2NUM(FIELD_TYPE_BIT));
2724
+ rb_define_const(cMysqlField, "TYPE_NEWDECIMAL", INT2NUM(FIELD_TYPE_NEWDECIMAL));
2725
+ #endif
2726
+ rb_define_const(cMysqlField, "TYPE_SET", INT2NUM(FIELD_TYPE_SET));
2727
+ rb_define_const(cMysqlField, "TYPE_BLOB", INT2NUM(FIELD_TYPE_BLOB));
2728
+ rb_define_const(cMysqlField, "TYPE_STRING", INT2NUM(FIELD_TYPE_STRING));
2729
+ #if MYSQL_VERSION_ID >= 40000
2730
+ rb_define_const(cMysqlField, "TYPE_VAR_STRING", INT2NUM(FIELD_TYPE_VAR_STRING));
2731
+ #endif
2732
+ rb_define_const(cMysqlField, "TYPE_CHAR", INT2NUM(FIELD_TYPE_CHAR));
2733
+
2734
+ /* Mysql::Field constant: FLAG */
2735
+ rb_define_const(cMysqlField, "NOT_NULL_FLAG", INT2NUM(NOT_NULL_FLAG));
2736
+ rb_define_const(cMysqlField, "PRI_KEY_FLAG", INT2NUM(PRI_KEY_FLAG));
2737
+ rb_define_const(cMysqlField, "UNIQUE_KEY_FLAG", INT2NUM(UNIQUE_KEY_FLAG));
2738
+ rb_define_const(cMysqlField, "MULTIPLE_KEY_FLAG", INT2NUM(MULTIPLE_KEY_FLAG));
2739
+ rb_define_const(cMysqlField, "BLOB_FLAG", INT2NUM(BLOB_FLAG));
2740
+ rb_define_const(cMysqlField, "UNSIGNED_FLAG", INT2NUM(UNSIGNED_FLAG));
2741
+ rb_define_const(cMysqlField, "ZEROFILL_FLAG", INT2NUM(ZEROFILL_FLAG));
2742
+ rb_define_const(cMysqlField, "BINARY_FLAG", INT2NUM(BINARY_FLAG));
2743
+ #ifdef ENUM_FLAG
2744
+ rb_define_const(cMysqlField, "ENUM_FLAG", INT2NUM(ENUM_FLAG));
2745
+ #endif
2746
+ #ifdef AUTO_INCREMENT_FLAG
2747
+ rb_define_const(cMysqlField, "AUTO_INCREMENT_FLAG", INT2NUM(AUTO_INCREMENT_FLAG));
2748
+ #endif
2749
+ #ifdef TIMESTAMP_FLAG
2750
+ rb_define_const(cMysqlField, "TIMESTAMP_FLAG", INT2NUM(TIMESTAMP_FLAG));
2751
+ #endif
2752
+ #ifdef SET_FLAG
2753
+ rb_define_const(cMysqlField, "SET_FLAG", INT2NUM(SET_FLAG));
2754
+ #endif
2755
+ #ifdef NUM_FLAG
2756
+ rb_define_const(cMysqlField, "NUM_FLAG", INT2NUM(NUM_FLAG));
2757
+ #endif
2758
+ #ifdef PART_KEY_FLAG
2759
+ rb_define_const(cMysqlField, "PART_KEY_FLAG", INT2NUM(PART_KEY_FLAG));
2760
+ #endif
2761
+
2762
+ #if MYSQL_VERSION_ID >= 40102
2763
+ /* Mysql::Stmt object method */
2764
+ rb_define_method(cMysqlStmt, "affected_rows", stmt_affected_rows, 0);
2765
+ #if 0
2766
+ rb_define_method(cMysqlStmt, "attr_get", stmt_attr_get, 1);
2767
+ rb_define_method(cMysqlStmt, "attr_set", stmt_attr_set, 2);
2768
+ #endif
2769
+ rb_define_method(cMysqlStmt, "bind_result", stmt_bind_result, -1);
2770
+ rb_define_method(cMysqlStmt, "close", stmt_close, 0);
2771
+ rb_define_method(cMysqlStmt, "data_seek", stmt_data_seek, 1);
2772
+ rb_define_method(cMysqlStmt, "each", stmt_each, 0);
2773
+ rb_define_method(cMysqlStmt, "execute", stmt_execute, -1);
2774
+ rb_define_method(cMysqlStmt, "fetch", stmt_fetch, 0);
2775
+ rb_define_method(cMysqlStmt, "field_count", stmt_field_count, 0);
2776
+ rb_define_method(cMysqlStmt, "free_result", stmt_free_result, 0);
2777
+ rb_define_method(cMysqlStmt, "insert_id", stmt_insert_id, 0);
2778
+ rb_define_method(cMysqlStmt, "num_rows", stmt_num_rows, 0);
2779
+ rb_define_method(cMysqlStmt, "param_count", stmt_param_count, 0);
2780
+ rb_define_method(cMysqlStmt, "prepare", stmt_prepare, 1);
2781
+ #if 0
2782
+ rb_define_method(cMysqlStmt, "reset", stmt_reset, 0);
2783
+ #endif
2784
+ rb_define_method(cMysqlStmt, "result_metadata", stmt_result_metadata, 0);
2785
+ rb_define_method(cMysqlStmt, "row_seek", stmt_row_seek, 1);
2786
+ rb_define_method(cMysqlStmt, "row_tell", stmt_row_tell, 0);
2787
+ #if 0
2788
+ rb_define_method(cMysqlStmt, "send_long_data", stmt_send_long_data, 2);
2789
+ #endif
2790
+ rb_define_method(cMysqlStmt, "sqlstate", stmt_sqlstate, 0);
2791
+
2792
+ #if 0
2793
+ rb_define_const(cMysqlStmt, "ATTR_UPDATE_MAX_LENGTH", INT2NUM(STMT_ATTR_UPDATE_MAX_LENGTH));
2794
+ #endif
2795
+
2796
+ /* Mysql::Time object method */
2797
+ rb_define_method(cMysqlTime, "initialize", time_initialize, -1);
2798
+ rb_define_method(cMysqlTime, "inspect", time_inspect, 0);
2799
+ rb_define_method(cMysqlTime, "to_s", time_to_s, 0);
2800
+ rb_define_method(cMysqlTime, "year", time_get_year, 0);
2801
+ rb_define_method(cMysqlTime, "month", time_get_month, 0);
2802
+ rb_define_method(cMysqlTime, "day", time_get_day, 0);
2803
+ rb_define_method(cMysqlTime, "hour", time_get_hour, 0);
2804
+ rb_define_method(cMysqlTime, "minute", time_get_minute, 0);
2805
+ rb_define_method(cMysqlTime, "second", time_get_second, 0);
2806
+ rb_define_method(cMysqlTime, "neg", time_get_neg, 0);
2807
+ rb_define_method(cMysqlTime, "second_part", time_get_second_part, 0);
2808
+ rb_define_method(cMysqlTime, "year=", time_set_year, 1);
2809
+ rb_define_method(cMysqlTime, "month=", time_set_month, 1);
2810
+ rb_define_method(cMysqlTime, "day=", time_set_day, 1);
2811
+ rb_define_method(cMysqlTime, "hour=", time_set_hour, 1);
2812
+ rb_define_method(cMysqlTime, "minute=", time_set_minute, 1);
2813
+ rb_define_method(cMysqlTime, "second=", time_set_second, 1);
2814
+ rb_define_method(cMysqlTime, "neg=", time_set_neg, 1);
2815
+ rb_define_method(cMysqlTime, "second_part=", time_set_second_part, 1);
2816
+ rb_define_method(cMysqlTime, "==", time_equal, 1);
2817
+
2818
+ #endif
2819
+
2820
+ /* Mysql::Error object method */
2821
+ rb_define_method(eMysql, "error", error_error, 0);
2822
+ rb_define_method(eMysql, "errno", error_errno, 0);
2823
+ rb_define_method(eMysql, "sqlstate", error_sqlstate, 0);
2824
+
2825
+ /* Mysql::Error constant */
2826
+ #define rb_define_mysql_const(s) rb_define_const(eMysql, #s, INT2NUM(s))
2827
+ #include "error_const.h"
2828
+ }