ruby-frontbase 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. data/README +88 -0
  2. data/extconf.rb +9 -0
  3. data/frontbase.c +1471 -0
  4. metadata +49 -0
data/README ADDED
@@ -0,0 +1,88 @@
1
+ The extension for FrontBase access version 0.5.2
2
+
3
+ By Cail Borrell (cail@frontbase.com)
4
+
5
+ - What's this ?
6
+
7
+ This is the extension library to access a FrontBase database from Ruby.
8
+
9
+ - Requirements
10
+
11
+ Ruby 1.3.4 or later.
12
+ FrontBase 3.x installed.
13
+
14
+ - How to install ?
15
+
16
+ Follow the instructions below to compile and install:
17
+
18
+ ruby extconf.rb
19
+ make
20
+ su (if necessary)
21
+ make install
22
+
23
+ - How to use ?
24
+
25
+ You need to specify:
26
+
27
+ require "frontbase"
28
+
29
+ at the top of your script.
30
+
31
+ - What functions can I use ?
32
+
33
+ The list of supported functions are below.
34
+
35
+ class FBSQL_Connect:
36
+
37
+ class methods:
38
+ new
39
+ connect
40
+ setdb
41
+ setdblogin
42
+
43
+ methods:
44
+ db
45
+ host
46
+ user
47
+
48
+ database_server_info
49
+ autocommit
50
+ ping
51
+ commit
52
+ rollback
53
+ status
54
+ error
55
+
56
+ exec
57
+ query
58
+ close
59
+ finish
60
+
61
+ create_blob
62
+ create_clob
63
+
64
+ class FBSQL_Result:
65
+
66
+ methods:
67
+ status
68
+ result
69
+ each
70
+ []
71
+ columns
72
+ num_rows
73
+ num_cols
74
+ column_name
75
+ column_type
76
+ column_length
77
+ column_precision
78
+ column_scale
79
+ column_isnullable
80
+ clear
81
+ close
82
+
83
+ class FBSQL_LOB:
84
+
85
+ methods:
86
+ read
87
+ handle
88
+ size
data/extconf.rb ADDED
@@ -0,0 +1,9 @@
1
+ require "mkmf"
2
+
3
+ dir_config('frontbase')
4
+
5
+ $CPPFLAGS = "-I/Library/FrontBase/include"
6
+ $LDFLAGS = "-L/Library/FrontBase/lib"
7
+ $libs = " -lFBCAccess "
8
+ create_makefile("frontbase")
9
+
data/frontbase.c ADDED
@@ -0,0 +1,1471 @@
1
+ /***************************************************
2
+ * Ruby driver for FrontBase
3
+ *
4
+ * author: Cail Borrell
5
+ * modified by Mike Laster for ActiveRecord support
6
+ *
7
+ * version: 1.0.0
8
+ ***************************************************/
9
+
10
+ #define RUBY_BINDINGS_VERSION "1.0.0"
11
+
12
+ #include "ruby.h"
13
+
14
+ #if defined(__APPLE__)
15
+ #include "/Library/FrontBase/include/FBCAccess/FBCAccess.h"
16
+ #else
17
+ #warning I don't know where FBCAccess.h is installed on non-OSX platforms
18
+ #include "/Library/FrontBase/include/FBCAccess/FBCAccess.h"
19
+ #endif
20
+
21
+ #pragma mark --- structure definitions ---
22
+
23
+ typedef struct FBCLob
24
+ {
25
+ unsigned char kind; // 0 => direct, 1 => indirect
26
+ char handleAsString[28]; // @'<24 hex digits>'\0
27
+ } FBCLob;
28
+
29
+ typedef union FBCColumn FBCColumn;
30
+
31
+ union FBCColumn
32
+ {
33
+ char tinyInteger;
34
+ short shortInteger;
35
+ int integer;
36
+ int primaryKey;
37
+ long long longInteger;
38
+ unsigned char boolean;
39
+ char character[0x7fffffff];
40
+ double numeric;
41
+ double real;
42
+ double decimal;
43
+ FBCBitValue bit;
44
+ char date[11]; // YYYY-MM-DD
45
+ int unformattedDate;
46
+ char time[9]; // HH:MM:SS
47
+ char timeTZ[34]; // YYYY-MM-DD HH:MM:SS.sssss+HH:MM
48
+ char timestampTZ[34];
49
+ char timestamp[28];
50
+ char yearMonth[64];
51
+ char dayTime[32]; // days:hh:ss.ffffff
52
+ FBCLob blob;
53
+ FBCLob clob;
54
+ double rawDate;
55
+ FBCUnformattedTime rawTime;
56
+ FBCUnformattedTime rawTimeTZ;
57
+ FBCUnformattedTime rawTimestamp;
58
+ FBCUnformattedTime rawTimestampTZ;
59
+ int rawYearMonth;
60
+ double rawDayTime;
61
+ };
62
+
63
+ typedef FBCColumn* FBCRow;
64
+
65
+ struct fbsqlconnect
66
+ {
67
+ int port;
68
+ char *host;
69
+ char *database;
70
+ char *user;
71
+ char *password;
72
+ char *databasePassword;
73
+
74
+ FBCExecHandler *fbeh;
75
+ FBCDatabaseConnection *fbdc;
76
+ FBCMetaData *meta;
77
+ };
78
+
79
+ struct fbsqlresult
80
+ {
81
+ int rows;
82
+ int cols;
83
+
84
+ FBCRow *row;
85
+ void *rawData;
86
+
87
+ FBCDatabaseConnection *fbdc;
88
+ FBCMetaData *md, *meta;
89
+ FBCRowHandler* rowHandler;
90
+ char* fetchHandle;
91
+ int resultCount;
92
+ int currentResult;
93
+ int rowIndex;
94
+
95
+ int currentRow;
96
+ };
97
+
98
+ struct fbsqllob
99
+ {
100
+ FBCDatabaseConnection *fbdc;
101
+ FBCBlobHandle *handle;
102
+ char* bhandle;
103
+ int size;
104
+ int type;
105
+ };
106
+
107
+ typedef struct fbsqlconnect FBSQL_Connect;
108
+ typedef struct fbsqlresult FBSQL_Result;
109
+ typedef struct fbsqllob FBSQL_LOB;
110
+
111
+ #pragma mark --- Ruby class definitions ---
112
+
113
+ static VALUE rb_cFBConn; // FBSQL_Connect Class
114
+ static VALUE rb_cFBResult; // FBSQL_Result Class
115
+ static VALUE rb_cFBLOB; // FBSQL_LOB Class
116
+ static VALUE rb_cFBError; // FBError Class (Exception)
117
+
118
+ static VALUE fbconn_query _((VALUE, VALUE));
119
+
120
+ static int fetch_fbresult _((FBSQL_Result*, int, int, VALUE*));
121
+ static int fetch_next_row _((FBSQL_Result*, VALUE*));
122
+ static void fetch_convert_value _((FBSQL_Result*, int, VALUE*));
123
+
124
+ static VALUE fbresult_result _((VALUE));
125
+ static VALUE fbresult_clear _((VALUE));
126
+ static VALUE fbresult_query _((VALUE));
127
+
128
+ // Garbage Colleciton Helper prototypes
129
+ static void free_fbconn _((FBSQL_Connect*));
130
+ static void free_fbresult _((FBSQL_Result*));
131
+ static void free_fblob _((FBSQL_LOB*));
132
+
133
+ // helper function prototypes
134
+ static FBSQL_Connect * get_fbconn _((VALUE));
135
+ static FBSQL_Result * get_fbresult _((VALUE));
136
+ static FBSQL_LOB * get_fblob _((VALUE));
137
+ static VALUE checkMetaData _((FBCDatabaseConnection*, FBCMetaData*));
138
+
139
+ #define FRONTBASE_COMMAND_OK 1
140
+ #define FRONTBASE_ROWS_OK 2
141
+ #define FRONTBASE_UNIQUE_OK 3
142
+
143
+ #define FB_ERR_NO_CONNECTION 1
144
+
145
+ #define FETCH_SIZE 4096
146
+
147
+ #pragma mark --- garbage collector helper functions ---
148
+
149
+ //
150
+ // free_fbconn()
151
+ //
152
+
153
+ static void free_fbconn(ptr) FBSQL_Connect *ptr;
154
+ {
155
+ fbcdcClose(ptr->fbdc);
156
+ free(ptr); // !!! Change to use Ruby memory functions
157
+ }
158
+
159
+ //
160
+ // free_fblob()
161
+ //
162
+
163
+ static void free_fblob(ptr) FBSQL_LOB *ptr;
164
+ {
165
+ ptr->fbdc = NULL;
166
+ ptr->bhandle = NULL;
167
+ if (ptr->handle != NULL)
168
+ {
169
+ fbcbhRelease(ptr->handle);
170
+ }
171
+ ptr->handle = NULL;
172
+ ptr->size = 0;
173
+ free(ptr); // !!! Change to use Ruby memory functions
174
+ }
175
+
176
+ //
177
+ // free_fbresult()
178
+ //
179
+
180
+ static void free_fbresult(ptr) FBSQL_Result *ptr;
181
+ {
182
+ fbcmdRelease(ptr->meta);
183
+ free(ptr); // !!! Change to use Ruby memory functions
184
+ }
185
+
186
+ #pragma mark -- private helper functions
187
+
188
+ //
189
+ // get_fbconn()
190
+ //
191
+
192
+ static FBSQL_Connect* get_fbconn(obj) VALUE obj;
193
+ {
194
+ FBSQL_Connect *conn = NULL;
195
+
196
+ Data_Get_Struct(obj, FBSQL_Connect, conn);
197
+ if (conn == NULL)
198
+ {
199
+ rb_raise(rb_cFBError, "closed connection");
200
+ }
201
+
202
+ return conn;
203
+ }
204
+
205
+ //
206
+ // get_fbresult()
207
+ //
208
+
209
+ static FBSQL_Result* get_fbresult(obj) VALUE obj;
210
+ {
211
+ FBSQL_Result *result = NULL;
212
+
213
+ Data_Get_Struct(obj, FBSQL_Result, result);
214
+ if (result == NULL)
215
+ {
216
+ rb_raise(rb_cFBError, "no result available");
217
+ }
218
+
219
+ return result;
220
+ }
221
+
222
+ //
223
+ // checkMetaData()
224
+ //
225
+
226
+ static VALUE checkMetaData(conn, meta) FBCDatabaseConnection* conn; FBCMetaData* meta;
227
+ {
228
+ int result = 1;
229
+
230
+ if (meta == NULL)
231
+ {
232
+ rb_raise(rb_cFBError, "Connection to database server was lost.");
233
+ result = 0;
234
+ }
235
+ else if (fbcmdErrorsFound(meta))
236
+ {
237
+ FBCErrorMetaData* emd = fbcdcErrorMetaData(conn, meta);
238
+ char* emg = fbcemdAllErrorMessages(emd);
239
+
240
+ if (emg != NULL)
241
+ {
242
+ rb_raise(rb_cFBError, emg);
243
+ }
244
+ else
245
+ {
246
+ rb_raise(rb_cFBError, "No message");
247
+ }
248
+
249
+ free(emg); // !!! Use ruby memory functions
250
+ fbcemdRelease(emd);
251
+ result = 0;
252
+ }
253
+
254
+ return result;
255
+ }
256
+
257
+ // FBResult helper functions
258
+
259
+ //
260
+ // fetch_fbresult()
261
+ //
262
+
263
+ static int fetch_fbresult(FBSQL_Result *result, int row_index, int column_index, VALUE *r)
264
+ {
265
+ char* value = NULL;
266
+ int length = 0;
267
+
268
+ if (result->meta == NULL)
269
+ {
270
+ rb_raise(rb_cFBError, "No result to fetch.");
271
+ }
272
+
273
+ if (row_index < 0)
274
+ {
275
+ rb_raise(rb_cFBError, "Invalid row number.");
276
+ }
277
+
278
+ if (result->rawData == NULL)
279
+ {
280
+ result->rawData = fbcdcFetch(result->fbdc, FETCH_SIZE, result->fetchHandle);
281
+
282
+ if (result->rawData == NULL)
283
+ {
284
+ return -1;
285
+ }
286
+
287
+ if (result->rowHandler != NULL)
288
+ {
289
+ fbcrhRelease(result->rowHandler);
290
+ }
291
+
292
+ result->rowHandler = fbcrhInitWith(result->rawData, result->md);
293
+ result->currentRow = -1;
294
+
295
+ if (result->rowHandler == NULL)
296
+ {
297
+ return -1;
298
+ }
299
+ }
300
+
301
+ if (result->rowIndex != row_index)
302
+ {
303
+ result->rowIndex = row_index;
304
+ result->currentRow++;
305
+ result->row = (FBCRow *) fbcrhRowAtIndex(result->rowHandler, result->currentRow);
306
+ }
307
+
308
+ if (result->row == NULL)
309
+ {
310
+ return -1;
311
+ }
312
+
313
+ fetch_convert_value(result, column_index, r);
314
+
315
+ return 1;
316
+ }
317
+
318
+ //
319
+ // fetch_next_row()
320
+ //
321
+
322
+ static int fetch_next_row(FBSQL_Result *result, VALUE *row)
323
+ {
324
+ VALUE value = 0;
325
+ int i = 0;
326
+
327
+ if (!result->meta)
328
+ {
329
+ rb_raise(rb_cFBError, "No result to fetch.");
330
+ }
331
+
332
+ result->row = (FBCRow*) fbcmdFetchRow(result->meta);
333
+
334
+ if (!result->row)
335
+ {
336
+ return -1;
337
+ }
338
+
339
+ for (i=0; i<result->cols; i++)
340
+ {
341
+ fetch_convert_value(result, i, &value);
342
+ rb_ary_push(*row, value);
343
+ }
344
+
345
+ return 1;
346
+ }
347
+
348
+ //
349
+ // fetch_convert_value()
350
+ //
351
+
352
+ static void fetch_convert_value(FBSQL_Result *result, int column_index, VALUE *r)
353
+ {
354
+ char* value = NULL;
355
+ const FBCDatatypeMetaData *dtmd = fbcmdDatatypeMetaDataAtIndex(result->md, column_index);
356
+ unsigned dtc = fbcdmdDatatypeCode(dtmd);
357
+ int length = 0;
358
+
359
+ if (result->row[column_index] == NULL)
360
+ {
361
+ *r = Qnil;
362
+ return;
363
+ }
364
+ else
365
+ {
366
+ switch(dtc)
367
+ {
368
+ case FB_Boolean:
369
+ switch(result->row[column_index]->boolean)
370
+ {
371
+ case 0: *r = Qfalse; break;
372
+ case 1: *r = Qtrue; break;
373
+ default: *r = Qnil; break;
374
+ }
375
+ return;
376
+
377
+ case FB_PrimaryKey: case FB_Integer:
378
+ *r = INT2NUM(result->row[column_index]->integer);
379
+ return;
380
+
381
+ case FB_TinyInteger:
382
+ *r = INT2FIX(result->row[column_index]->tinyInteger);
383
+ return;
384
+
385
+ case FB_SmallInteger:
386
+ *r = INT2FIX(result->row[column_index]->shortInteger);
387
+ return;
388
+
389
+ case FB_LongInteger:
390
+ *r = LL2NUM(result->row[column_index]->longInteger);
391
+ return;
392
+
393
+ case FB_Numeric: case FB_Decimal:
394
+ case FB_Float: case FB_Real: case FB_Double:
395
+ *r = rb_float_new(result->row[column_index]->numeric);
396
+ return;
397
+
398
+ case FB_Character:
399
+ case FB_VCharacter:
400
+ *r = rb_str_new2((char*) result->row[column_index]);
401
+ return;
402
+
403
+ case FB_Bit:
404
+ case FB_VBit:
405
+ {
406
+ const FBCColumnMetaData* clmd = fbcmdColumnMetaDataAtIndex(result->md, column_index);
407
+ const FBCBitValue ptr = result->row[column_index]->bit;
408
+ unsigned nBits = ptr.size * 8;
409
+
410
+ if (dtc == FB_Bit) nBits = fbcdmdLength(fbccmdDatatype(clmd));
411
+
412
+ if (nBits % 8 == 0)
413
+ {
414
+ *r = rb_tainted_str_new((char *)ptr.bytes,ptr.size);
415
+ return;
416
+ }
417
+ else
418
+ {
419
+ unsigned i = 0;
420
+ unsigned int l = nBits;
421
+ length = l+3+1;
422
+ value = malloc(length); // !!! memory leak?
423
+ value[0] = 'B';
424
+ value[1] = '\'';
425
+ for (i = 0; i < nBits; i++)
426
+ {
427
+ int bit = 0;
428
+ if (i/8 < ptr.size) bit = ptr.bytes[i/8] & (1<<(7-(i%8)));
429
+ value[i*2+2] = bit?'1':'0';
430
+ }
431
+ value[i*2+2] = '\'';
432
+ value[i*2+3] = 0;
433
+ }
434
+ break;
435
+ }
436
+ case FB_BLOB:
437
+ case FB_CLOB:
438
+ {
439
+ unsigned char* bytes = (unsigned char*) result->row[column_index];
440
+ FBSQL_LOB *lob = malloc(sizeof(FBSQL_LOB));
441
+
442
+ lob->type = dtc;
443
+ lob->fbdc = result->fbdc;
444
+ lob->bhandle = strdup((char *)&bytes[1]);
445
+ lob->handle = fbcbhInitWithHandle(lob->bhandle);
446
+ lob->size = fbcbhBlobSize(lob->handle);
447
+
448
+ *r = Data_Wrap_Struct(rb_cFBLOB, 0, free_fblob, lob);
449
+ return;
450
+ }
451
+ case FB_Date:
452
+ case FB_Time:
453
+ case FB_TimeTZ:
454
+ case FB_Timestamp:
455
+ case FB_TimestampTZ:
456
+ {
457
+ value = strdup((char*) result->row[column_index]);
458
+ break;
459
+ }
460
+ case FB_YearMonth:
461
+ {
462
+ value = "YearMonth";
463
+ break;
464
+ }
465
+ case FB_DayTime:
466
+ {
467
+ value = "DayTime";
468
+ break;
469
+ }
470
+ default:
471
+ rb_raise(rb_cFBError, "Undefined column type.");
472
+ }
473
+ }
474
+
475
+ *r = rb_tainted_str_new2(value);
476
+
477
+ return;
478
+ }
479
+
480
+ #pragma mark --- Ruby method definitions ---
481
+
482
+ #pragma mark --- FBSQL_Connect methods ---
483
+
484
+ //
485
+ // FBSQL_Connect.new
486
+ // FBSQL_Connect.connect
487
+ // FBSQL_Connect.setdb
488
+ // FBSQL_Connect.setdblogin
489
+ // !!! Why 4 methods?
490
+
491
+ static VALUE fbconn_connect(argc, argv, fbconn) int argc; VALUE *argv; VALUE fbconn;
492
+ {
493
+ VALUE arg[7];
494
+ FBSQL_Connect *conn = malloc(sizeof(FBSQL_Connect)); // !!! Use ruby memory functions
495
+ char *session_name = NULL;
496
+
497
+ conn->port = -1;
498
+ conn->fbeh = NULL;
499
+ rb_scan_args(argc, argv, "07", &arg[0], &arg[1], &arg[2], &arg[3], &arg[4], &arg[5], &arg[6]);
500
+
501
+ if (!NIL_P(arg[0]))
502
+ {
503
+ Check_Type(arg[0], T_STRING);
504
+ conn->host = STR2CSTR(arg[0]);
505
+ }
506
+ else
507
+ {
508
+ conn->host = "localhost";
509
+ }
510
+ if (!NIL_P(arg[1]))
511
+ {
512
+ conn->port = NUM2INT(arg[1]);
513
+ }
514
+ if (!NIL_P(arg[2]))
515
+ {
516
+ Check_Type(arg[2], T_STRING);
517
+ conn->database = STR2CSTR(arg[2]);
518
+ }
519
+ if (!NIL_P(arg[3]))
520
+ {
521
+ Check_Type(arg[3], T_STRING);
522
+ conn->user = STR2CSTR(arg[3]);
523
+
524
+ }
525
+ if (!NIL_P(arg[4]))
526
+ {
527
+ Check_Type(arg[4], T_STRING);
528
+ conn->password = STR2CSTR(arg[4]);
529
+ }
530
+ if (!NIL_P(arg[5]))
531
+ {
532
+ Check_Type(arg[5], T_STRING);
533
+ conn->databasePassword = STR2CSTR(arg[5]);
534
+ }
535
+
536
+ if (!NIL_P(arg[6]))
537
+ {
538
+ Check_Type(arg[6], T_STRING);
539
+ session_name = STR2CSTR(arg[6]);
540
+ }
541
+ else
542
+ {
543
+ session_name = "ruby";
544
+ }
545
+
546
+ fbcInitialize();
547
+
548
+ if (conn->port!=-1)
549
+ {
550
+ conn->fbdc = fbcdcConnectToDatabaseUsingPort(conn->host, conn->port, conn->databasePassword);
551
+ }
552
+ else
553
+ {
554
+ conn->fbdc = fbcdcConnectToDatabase(conn->database, conn->host, conn->databasePassword);
555
+ }
556
+
557
+ if (conn->fbdc == NULL)
558
+ {
559
+ rb_raise(rb_cFBError, fbcdcClassErrorMessage());
560
+ }
561
+
562
+ conn->meta = fbcdcCreateSession(conn->fbdc, session_name, conn->user, conn->password, "system_user");
563
+
564
+ if (fbcmdErrorsFound(conn->meta) == T_TRUE)
565
+ {
566
+ FBCErrorMetaData* emd = fbcdcErrorMetaData(conn->fbdc, conn->meta);
567
+ char* msgs = fbcemdAllErrorMessages(emd);
568
+
569
+ rb_raise(rb_cFBError, msgs);
570
+ fbcemdRelease(emd);
571
+ free(msgs);
572
+
573
+ fbcmdRelease(conn->meta);
574
+ conn->meta = NULL;
575
+
576
+ fbcdcClose(conn->fbdc);
577
+ fbcdcRelease(conn->fbdc);
578
+ conn->fbdc = NULL;
579
+
580
+ return 0;
581
+ }
582
+ fbcmdRelease(conn->meta);
583
+ conn->meta = NULL;
584
+
585
+ return Data_Wrap_Struct(fbconn, 0, free_fbconn, conn);
586
+ }
587
+
588
+ //
589
+ // FBSQL_Connect#close
590
+ //
591
+
592
+ static VALUE fbconn_close(obj) VALUE obj;
593
+ {
594
+ FBSQL_Connect *conn = get_fbconn(obj);
595
+
596
+ if (!fbcdcConnected(conn->fbdc))
597
+ {
598
+ rb_raise(rb_cFBError, "connection already closed.");
599
+ }
600
+
601
+ if (conn->meta)
602
+ {
603
+ fbcmdRelease(conn->meta);
604
+ }
605
+ conn->meta = NULL;
606
+
607
+ if (conn->fbdc)
608
+ {
609
+ fbcdcClose(conn->fbdc);
610
+ fbcdcRelease(conn->fbdc);
611
+ }
612
+ conn->fbdc = NULL;
613
+
614
+ if (conn->fbeh)
615
+ {
616
+ fbcehRelease(conn->fbeh);
617
+ }
618
+ conn->fbeh = NULL;
619
+
620
+ if (conn->host)
621
+ {
622
+ conn->host = NULL;
623
+ }
624
+ if (conn->database)
625
+ {
626
+ conn->database = NULL;
627
+ }
628
+ if (conn->user)
629
+ {
630
+ conn->user = NULL;
631
+ }
632
+ if (conn->password)
633
+ {
634
+ conn->password = NULL;
635
+ }
636
+ if (conn->databasePassword)
637
+ {
638
+ conn->databasePassword = NULL;
639
+ }
640
+
641
+ DATA_PTR(obj) = 0;
642
+
643
+ return Qnil;
644
+ }
645
+
646
+ //
647
+ // FBSQL_Connect#
648
+ //
649
+
650
+ static VALUE fbconn_autocommit(obj, commit) VALUE obj; int commit;
651
+ {
652
+ FBSQL_Connect *conn = get_fbconn(obj);
653
+ FBCMetaData* md;
654
+ int i = NUM2INT(commit);
655
+
656
+ if (conn->fbdc) {
657
+ if (i)
658
+ md = fbcdcExecuteDirectSQL(conn->fbdc,"SET COMMIT TRUE;");
659
+ else
660
+ md = fbcdcExecuteDirectSQL(conn->fbdc,"SET COMMIT FALSE;");
661
+
662
+ checkMetaData(conn->fbdc, md);
663
+ if (md)
664
+ fbcmdRelease(md);
665
+ }
666
+ else
667
+ rb_raise(rb_cFBError, "No connection available");
668
+
669
+ return Qnil;
670
+ }
671
+
672
+ //
673
+ // FBSQL_Connect#
674
+ //
675
+
676
+ static VALUE fbconn_database_server_info(obj) VALUE obj;
677
+ {
678
+ VALUE ret;
679
+ VALUE result = fbconn_query(obj, rb_tainted_str_new2("VALUES(SERVER_NAME);"));
680
+ fetch_fbresult(get_fbresult(result), 0, 0, &ret);
681
+ fbresult_clear(result);
682
+
683
+ return ret;
684
+ }
685
+
686
+ //
687
+ // FBSQL_Connect#
688
+ //
689
+
690
+ static VALUE fbconn_commit(obj) VALUE obj;
691
+ {
692
+ FBSQL_Connect *conn = get_fbconn(obj);
693
+ FBCMetaData* md;
694
+
695
+ md = fbcdcCommit(conn->fbdc);
696
+ checkMetaData(conn->fbdc, md);
697
+ return Qnil;
698
+ }
699
+
700
+ //
701
+ // FBSQL_Connect#
702
+ //
703
+
704
+ static VALUE fbconn_rollback(obj) VALUE obj;
705
+ {
706
+ FBSQL_Connect *conn = get_fbconn(obj);
707
+ FBCMetaData* md;
708
+
709
+ md = fbcdcRollback(conn->fbdc);
710
+ checkMetaData(conn->fbdc, md);
711
+ return Qnil;
712
+ }
713
+
714
+ //
715
+ // FBSQL_Connect#
716
+ //
717
+
718
+ static VALUE fbconn_query(obj, str) VALUE obj, str;
719
+ {
720
+ FBSQL_Connect *conn = get_fbconn(obj);
721
+ FBSQL_Result *result = malloc(sizeof(FBSQL_Result));
722
+ FBCMetaData *meta = NULL;
723
+
724
+ result->fbdc = conn->fbdc;
725
+
726
+ int status = FRONTBASE_COMMAND_OK;
727
+ const char *msg = NULL, *type = NULL;
728
+ char *sql = NULL, *sqlCmd = NULL;
729
+ unsigned len = 0;
730
+
731
+ Check_Type(str, T_STRING);
732
+
733
+ sql = STR2CSTR(str);
734
+ len = strlen(sql);
735
+
736
+ sqlCmd = malloc(len + 1 + 1);
737
+
738
+ sprintf(sqlCmd, "%s", sql);
739
+ if (sql[len-1] != ';')
740
+ strcat(sqlCmd, ";");
741
+
742
+ meta = fbcdcExecuteDirectSQL(conn->fbdc, sqlCmd);
743
+
744
+ checkMetaData(conn->fbdc, meta);
745
+
746
+ result->currentResult = 0;
747
+ result->resultCount = 1;
748
+
749
+ if (fbcmdHasMetaDataArray(meta))
750
+ {
751
+ result->resultCount = fbcmdMetaDataArrayCount(meta);
752
+ result->md = (FBCMetaData*) fbcmdMetaDataAtIndex(meta, 0);
753
+ result->meta = meta;
754
+ }
755
+ else
756
+ {
757
+ result->md = meta;
758
+ result->meta = meta;
759
+ }
760
+
761
+ type = fbcmdStatementType(result->md);
762
+
763
+ if (type != NULL && strcmp("SELECT", type) == 0)
764
+ {
765
+ status = FRONTBASE_ROWS_OK;
766
+ }
767
+ else if(type != NULL && strcmp("UNIQUE", type) == 0)
768
+ {
769
+ status = FRONTBASE_UNIQUE_OK;
770
+ }
771
+
772
+ switch (status)
773
+ {
774
+ case FRONTBASE_COMMAND_OK:
775
+ case FRONTBASE_ROWS_OK:
776
+ case FRONTBASE_UNIQUE_OK:
777
+ result->row = NULL;
778
+ result->rawData = NULL;
779
+ result->rowHandler = NULL;
780
+ result->fetchHandle = fbcmdFetchHandle(result->meta);
781
+ result->rows = fbcmdRowCount(result->meta);
782
+ result->cols = fbcmdColumnCount(result->meta);
783
+ result->rowIndex = -1;
784
+ return Data_Wrap_Struct(rb_cFBResult, 0, free_fbresult, result);
785
+
786
+ default:
787
+ msg = fbcdcErrorMessage(conn->fbdc);
788
+ break;
789
+ }
790
+
791
+ fbcmdRelease(result->meta);
792
+ rb_raise(rb_cFBError, msg);
793
+ }
794
+
795
+ //
796
+ // FBSQL_Connect#
797
+ //
798
+
799
+ static VALUE fbconn_exec(obj, str) VALUE obj, str;
800
+ {
801
+ VALUE result = fbconn_query(obj, str);
802
+ fbresult_clear(result);
803
+ return result;
804
+ }
805
+
806
+ //
807
+ // FBSQL_Connect#
808
+ //
809
+
810
+ static VALUE fbconn_host(obj) VALUE obj;
811
+ {
812
+ const char *host = fbcdcHostName(get_fbconn(obj)->fbdc);
813
+ if (!host) return Qnil;
814
+ return rb_tainted_str_new2(host);
815
+ }
816
+
817
+ //
818
+ // FBSQL_Connect#
819
+ //
820
+
821
+ static VALUE fbconn_db(obj) VALUE obj;
822
+ {
823
+ const char *db = fbcdcDatabaseName(get_fbconn(obj)->fbdc);
824
+ if (!db) return Qnil;
825
+ return rb_tainted_str_new2(db);
826
+ }
827
+
828
+ //
829
+ // FBSQL_Connect#
830
+ //
831
+
832
+ static VALUE fbconn_user(obj) VALUE obj;
833
+ {
834
+ return rb_tainted_str_new2(get_fbconn(obj)->user);
835
+ }
836
+
837
+ //
838
+ // FBSQL_Connect#
839
+ //
840
+
841
+ static VALUE fbconn_status(obj) VALUE obj;
842
+ {
843
+ Bool status = fbcdcConnected(get_fbconn(obj)->fbdc);
844
+
845
+ return INT2NUM(status ? 1 : 0);
846
+ }
847
+
848
+ //
849
+ // FBSQL_Connect#
850
+ //
851
+
852
+ static VALUE fbconn_error(obj) VALUE obj;
853
+ {
854
+ const char *error = fbcdcErrorMessage(get_fbconn(obj)->fbdc);
855
+ if (!error) return Qnil;
856
+ return rb_tainted_str_new2(error);
857
+ }
858
+
859
+ //
860
+ // FBSQL_Connect#
861
+ //
862
+
863
+ static VALUE fbconn_create_blob(VALUE obj, VALUE data)
864
+ {
865
+ int size;
866
+
867
+ FBSQL_Connect *conn = get_fbconn(obj);
868
+ FBSQL_LOB *lob = malloc(sizeof(FBSQL_LOB));
869
+ size = RSTRING(data)->len;
870
+
871
+ lob->type = FB_BLOB;
872
+ lob->fbdc = conn->fbdc;
873
+ lob->bhandle = NULL;
874
+ lob->handle = fbcdcWriteBLOB(conn->fbdc, RSTRING(data)->ptr, size);
875
+ lob->size = size;
876
+
877
+ return Data_Wrap_Struct(rb_cFBLOB, 0, free_fblob, lob);
878
+ }
879
+
880
+ //
881
+ // FBSQL_Connect#
882
+ //
883
+
884
+ static VALUE fbconn_create_clob(VALUE obj, VALUE data)
885
+ {
886
+ FBSQL_Connect *conn = get_fbconn(obj);
887
+ FBSQL_LOB *lob = malloc(sizeof(FBSQL_LOB));
888
+
889
+ lob->type = FB_CLOB;
890
+ lob->fbdc = conn->fbdc;
891
+ lob->bhandle = NULL;
892
+ lob->handle = fbcdcWriteCLOB(conn->fbdc, RSTRING(data)->ptr);
893
+ lob->size = RSTRING(data)->len;
894
+
895
+ return Data_Wrap_Struct(rb_cFBLOB, 0, free_fblob, lob);
896
+ }
897
+
898
+
899
+ #pragma mark --- FBResult methods ---
900
+
901
+ //
902
+ // FBResult#status
903
+ //
904
+
905
+ static VALUE fbresult_status(obj) VALUE obj;
906
+ {
907
+ FBSQL_Result *result;
908
+ int status = FRONTBASE_COMMAND_OK;
909
+ char *type;
910
+
911
+ result = get_fbresult(obj);
912
+
913
+ if (fbcmdErrorsFound(result->meta) == T_TRUE)
914
+ {
915
+ return -1;
916
+ }
917
+
918
+ type = fbcmdStatementType(result->meta);
919
+
920
+ if (type != NULL && strcmp("SELECT", type) == 0)
921
+ {
922
+ status = FRONTBASE_ROWS_OK;
923
+ }
924
+ else if (type != NULL && strcmp("UNIQUE", type) == 0)
925
+ {
926
+ status = FRONTBASE_UNIQUE_OK;
927
+ }
928
+
929
+ return INT2NUM(status);
930
+ }
931
+
932
+ //
933
+ // FBResult#result
934
+ //
935
+
936
+ static VALUE fbresult_result(obj) VALUE obj;
937
+ {
938
+ FBSQL_Result *result;
939
+ VALUE ary, row;
940
+ int i;
941
+
942
+ result = get_fbresult(obj);
943
+ ary = rb_ary_new2(result->rows);
944
+
945
+ if (fbcmdFetchHandle(result->meta) == NULL)
946
+ {
947
+ return ary;
948
+ }
949
+
950
+ while (1)
951
+ {
952
+ VALUE row = rb_ary_new2(result->cols);
953
+ i = fetch_next_row(result, &row);
954
+ if (i != -1)
955
+ {
956
+ rb_ary_push(ary, row);
957
+ }
958
+ else
959
+ {
960
+ return ary;
961
+ }
962
+ }
963
+
964
+ return ary;
965
+ }
966
+
967
+ //
968
+ // FBResult#each
969
+ //
970
+
971
+ static VALUE fbresult_each(obj) VALUE obj;
972
+ {
973
+ FBSQL_Result *result;
974
+ int i, j;
975
+ VALUE row;
976
+
977
+ result = get_fbresult(obj);
978
+
979
+ if (fbcmdFetchHandle(result->meta) == NULL)
980
+ {
981
+ return Qnil;
982
+ }
983
+
984
+ while (1)
985
+ {
986
+ VALUE row = rb_ary_new2(result->cols);
987
+ i = fetch_next_row(result, &row);
988
+ if (i != -1)
989
+ {
990
+ rb_yield(row);
991
+ }
992
+ else
993
+ {
994
+ return Qnil;
995
+ }
996
+ }
997
+
998
+ return Qnil;
999
+ }
1000
+
1001
+ //
1002
+ // FBResult#[]
1003
+ //
1004
+
1005
+ static VALUE fbresult_aref(argc, argv, obj) int argc; VALUE *argv; VALUE obj;
1006
+ {
1007
+ FBSQL_Result *result;
1008
+ VALUE a1, a2, val, value;
1009
+ int i, j;
1010
+
1011
+ result = get_fbresult(obj);
1012
+
1013
+ switch (rb_scan_args(argc, argv, "11", &a1, &a2))
1014
+ {
1015
+ case 1:
1016
+ i = NUM2INT(a1);
1017
+ if( i >= result->rows ) return Qnil;
1018
+
1019
+ val = rb_ary_new();
1020
+ for (j=0; j<result->cols; j++)
1021
+ {
1022
+ fetch_fbresult(result, i, j, &value);
1023
+ rb_ary_push(val, value);
1024
+ }
1025
+ return val;
1026
+
1027
+ case 2:
1028
+ i = NUM2INT(a1);
1029
+ if( i >= result->rows ) return Qnil;
1030
+ j = NUM2INT(a2);
1031
+ if( j >= result->cols ) return Qnil;
1032
+
1033
+ fetch_fbresult(result, i, j, &value);
1034
+ return value;
1035
+
1036
+ default:
1037
+ return Qnil; /* not reached */
1038
+ }
1039
+ }
1040
+
1041
+ //
1042
+ // FBResult#columns
1043
+ //
1044
+
1045
+ static VALUE fbresult_columns(obj) VALUE obj;
1046
+ {
1047
+ FBSQL_Result *result;
1048
+ const FBCColumnMetaData *column_meta;
1049
+ VALUE ary;
1050
+ int i;
1051
+
1052
+ result = get_fbresult(obj);
1053
+ ary = rb_ary_new2(result->cols);
1054
+
1055
+ for (i=0;i<result->cols;i++)
1056
+ {
1057
+ column_meta = fbcmdColumnMetaDataAtIndex(result->meta, i);
1058
+ rb_ary_push(ary, rb_tainted_str_new2(fbccmdLabelName(column_meta)));
1059
+ }
1060
+
1061
+ return ary;
1062
+ }
1063
+
1064
+ //
1065
+ // FBResult#num_rows
1066
+ //
1067
+
1068
+ static VALUE fbresult_num_rows(obj) VALUE obj;
1069
+ {
1070
+ return INT2NUM(get_fbresult(obj)->rows);
1071
+ }
1072
+
1073
+ //
1074
+ // FBResult#row_index
1075
+ //
1076
+ // added by Eric Ocean
1077
+ //
1078
+
1079
+ static VALUE fbresult_row_index(obj) VALUE obj;
1080
+ {
1081
+ long retValue = 0;
1082
+ FBSQL_Result *res = get_fbresult(obj);
1083
+ FBCMetaData *md = res->meta;
1084
+ // int fbcmdRowCount(const FBCMetaData* self);
1085
+ retValue = fbcmdRowIndex(md);
1086
+
1087
+ return INT2NUM( retValue );
1088
+ }
1089
+
1090
+ //
1091
+ // FBResult#table_name
1092
+ //
1093
+ // added by Eric Ocean
1094
+ //
1095
+
1096
+ static VALUE fbresult_table_name(obj) VALUE obj;
1097
+ {
1098
+ FBSQL_Result *result;
1099
+ const FBCColumnMetaData *column_meta;
1100
+
1101
+ result = get_fbresult(obj);
1102
+ column_meta = fbcmdColumnMetaDataAtIndex(result->meta, 0);
1103
+
1104
+ return rb_tainted_str_new2(fbccmdTableName(column_meta));
1105
+ }
1106
+
1107
+ //
1108
+ // FBResult#num_cols
1109
+ //
1110
+
1111
+ static VALUE fbresult_num_cols(obj) VALUE obj;
1112
+ {
1113
+ return INT2NUM(get_fbresult(obj)->cols);
1114
+ }
1115
+
1116
+ //
1117
+ // FBResult#column_name
1118
+ //
1119
+
1120
+ static VALUE fbresult_column_name(obj, index) VALUE obj, index;
1121
+ {
1122
+ FBSQL_Result *result;
1123
+ const FBCColumnMetaData *column_meta;
1124
+ int i = NUM2INT(index);
1125
+
1126
+ result = get_fbresult(obj);
1127
+
1128
+ if (i < 0 || i >= result->cols)
1129
+ {
1130
+ rb_raise(rb_eArgError,"invalid column number %d", i);
1131
+ }
1132
+
1133
+ column_meta = fbcmdColumnMetaDataAtIndex(result->meta, i);
1134
+
1135
+ return rb_tainted_str_new2(fbccmdLabelName(column_meta));
1136
+ }
1137
+
1138
+ //
1139
+ // FBResult#column_type
1140
+ //
1141
+
1142
+ static VALUE fbresult_column_type(obj, index) VALUE obj, index;
1143
+ {
1144
+ FBSQL_Result *result;
1145
+ const FBCDatatypeMetaData *datatype_meta;
1146
+
1147
+ int i = NUM2INT(index);
1148
+ int type;
1149
+
1150
+ result = get_fbresult(obj);
1151
+ datatype_meta = fbcmdDatatypeMetaDataAtIndex(result->meta, i);
1152
+
1153
+ if (i < 0 || i >= result->cols)
1154
+ {
1155
+ rb_raise(rb_eArgError,"invalid column number %d", i);
1156
+ }
1157
+
1158
+ if (datatype_meta)
1159
+ {
1160
+ type = fbcdmdDatatypeCode(datatype_meta);
1161
+ }
1162
+
1163
+ return INT2NUM(type);
1164
+ }
1165
+
1166
+ //
1167
+ // FBResult#column_length
1168
+ //
1169
+
1170
+ static VALUE fbresult_column_length(obj, index) VALUE obj, index;
1171
+ {
1172
+ FBSQL_Result *result;
1173
+ const FBCDatatypeMetaData *datatype_meta;
1174
+
1175
+ int i = NUM2INT(index);
1176
+ int size;
1177
+
1178
+ result = get_fbresult(obj);
1179
+ datatype_meta = fbcmdDatatypeMetaDataAtIndex(result->meta, i);
1180
+
1181
+ if (i < 0 || i >= result->cols)
1182
+ {
1183
+ rb_raise(rb_eArgError,"invalid column number %d", i);
1184
+ }
1185
+
1186
+ if (datatype_meta)
1187
+ {
1188
+ size = fbcdmdLength(datatype_meta);
1189
+ }
1190
+
1191
+ return INT2NUM(size);
1192
+ }
1193
+
1194
+ //
1195
+ // FBResult#column_precision
1196
+ //
1197
+
1198
+ static VALUE fbresult_column_precision(obj, index) VALUE obj, index;
1199
+ {
1200
+ FBSQL_Result *result;
1201
+ const FBCDatatypeMetaData *datatype_meta;
1202
+
1203
+ int i = NUM2INT(index);
1204
+ int size;
1205
+
1206
+ result = get_fbresult(obj);
1207
+ datatype_meta = fbcmdDatatypeMetaDataAtIndex(result->meta, i);
1208
+
1209
+ if (i < 0 || i >= result->cols)
1210
+ {
1211
+ rb_raise(rb_eArgError,"invalid column number %d", i);
1212
+ }
1213
+
1214
+ if (datatype_meta)
1215
+ {
1216
+ size = fbcdmdPrecision(datatype_meta);
1217
+ }
1218
+
1219
+ return INT2NUM(size);
1220
+ }
1221
+
1222
+ //
1223
+ // FBResult#column_scale
1224
+ //
1225
+
1226
+ static VALUE fbresult_column_scale(obj, index) VALUE obj, index;
1227
+ {
1228
+ FBSQL_Result *result;
1229
+ const FBCDatatypeMetaData *datatype_meta;
1230
+
1231
+ int i = NUM2INT(index);
1232
+ int size;
1233
+
1234
+ result = get_fbresult(obj);
1235
+ datatype_meta = fbcmdDatatypeMetaDataAtIndex(result->meta, i);
1236
+
1237
+ if (i < 0 || i >= result->cols)
1238
+ {
1239
+ rb_raise(rb_eArgError,"invalid column number %d", i);
1240
+ }
1241
+
1242
+ if (datatype_meta)
1243
+ {
1244
+ size = fbcdmdScale(datatype_meta);
1245
+ }
1246
+
1247
+ return INT2NUM(size);
1248
+ }
1249
+
1250
+ //
1251
+ // FBResult#column_isnullable
1252
+ //
1253
+
1254
+ static VALUE fbresult_column_isnullable(obj, index) VALUE obj, index;
1255
+ {
1256
+ FBSQL_Result *result;
1257
+ const FBCColumnMetaData *column_meta;
1258
+ int i = NUM2INT(index);
1259
+
1260
+ result = get_fbresult(obj);
1261
+
1262
+ if (i < 0 || i >= result->cols)
1263
+ {
1264
+ rb_raise(rb_eArgError,"invalid column number %d", i);
1265
+ }
1266
+
1267
+ column_meta = fbcmdColumnMetaDataAtIndex(result->meta, i);
1268
+
1269
+ return fbccmdIsNullable(column_meta)? Qtrue : Qfalse;
1270
+ }
1271
+
1272
+ //
1273
+ // FBResult#clear
1274
+ // FBResult#close
1275
+ //
1276
+
1277
+ static VALUE fbresult_clear(obj) VALUE obj;
1278
+ {
1279
+ FBSQL_Result *result = get_fbresult(obj);
1280
+
1281
+ if (result->meta)
1282
+ {
1283
+ fbcmdRelease(result->meta);
1284
+ }
1285
+ result->meta = NULL;
1286
+ result->md = NULL;
1287
+
1288
+ if (result->fbdc)
1289
+ {
1290
+ result->fbdc = NULL;
1291
+ }
1292
+
1293
+ if (result->rowHandler != NULL)
1294
+ {
1295
+ fbcrhRelease(result->rowHandler);
1296
+ }
1297
+
1298
+ result->row = NULL;
1299
+ result->rawData = NULL;
1300
+ result->fetchHandle = NULL;
1301
+
1302
+ DATA_PTR(obj) = 0;
1303
+
1304
+ return Qnil;
1305
+ }
1306
+
1307
+ #pragma mark --- FBSQL_LOB methods ---
1308
+
1309
+ //
1310
+ // FBBlob#
1311
+ //
1312
+
1313
+ static VALUE fblob_read(obj) VALUE obj;
1314
+ {
1315
+ FBSQL_LOB *lob = get_fblob(obj);
1316
+
1317
+ if (lob->type == FB_BLOB)
1318
+ {
1319
+ return rb_tainted_str_new((char*) fbcdcReadBLOB(lob->fbdc, lob->handle), lob->size);
1320
+ }
1321
+ else
1322
+ {
1323
+ return rb_tainted_str_new((char*) fbcdcReadCLOB(lob->fbdc, lob->handle), lob->size);
1324
+ }
1325
+ }
1326
+
1327
+ //
1328
+ // FBBlob#
1329
+ //
1330
+
1331
+ static VALUE fblob_handle(obj) VALUE obj;
1332
+ {
1333
+ FBSQL_LOB *lob = get_fblob(obj);
1334
+
1335
+ return rb_tainted_str_new2(fbcbhDescription(lob->handle));
1336
+ }
1337
+
1338
+ //
1339
+ // FBBlob#
1340
+ //
1341
+
1342
+ static VALUE fblob_size(obj) VALUE obj;
1343
+ {
1344
+ FBSQL_LOB *lob = get_fblob(obj);
1345
+
1346
+ return INT2NUM(lob->size);
1347
+ }
1348
+
1349
+ //
1350
+ // FBBlob#
1351
+ //
1352
+
1353
+ static FBSQL_LOB* get_fblob(obj) VALUE obj;
1354
+ {
1355
+ FBSQL_LOB *lob;
1356
+
1357
+ Data_Get_Struct(obj, FBSQL_LOB, lob);
1358
+ if (lob == 0)
1359
+ {
1360
+ rb_raise(rb_cFBError, "no blob available");
1361
+ }
1362
+
1363
+ return lob;
1364
+ }
1365
+
1366
+ #pragma mark --- Ruby initialization ---
1367
+
1368
+ void Init_frontbase()
1369
+ {
1370
+ rb_cFBConn = rb_define_class("FBSQL_Connect", rb_cObject);
1371
+ rb_cFBResult = rb_define_class("FBSQL_Result", rb_cObject);
1372
+ rb_cFBLOB = rb_define_class("FBSQL_LOB", rb_cObject);
1373
+ rb_cFBError = rb_define_class("FBError", rb_eStandardError);
1374
+
1375
+ //
1376
+ // FBSQL_LOB
1377
+ //
1378
+ rb_define_method(rb_cFBLOB, "read", fblob_read, 0);
1379
+ rb_define_method(rb_cFBLOB, "handle", fblob_handle, 0);
1380
+ rb_define_method(rb_cFBLOB, "size", fblob_size, 0);
1381
+
1382
+ //
1383
+ // FBSQL_Connect
1384
+ //
1385
+
1386
+ // Class methods
1387
+ rb_define_singleton_method(rb_cFBConn, "new", fbconn_connect, -1);
1388
+ rb_define_singleton_method(rb_cFBConn, "connect", fbconn_connect, -1);
1389
+ rb_define_singleton_method(rb_cFBConn, "setdb", fbconn_connect, -1);
1390
+ rb_define_singleton_method(rb_cFBConn, "setdblogin", fbconn_connect, -1);
1391
+
1392
+ // Constants
1393
+ rb_define_const(rb_cFBConn, "NO_CONNECTION", INT2FIX(FB_ERR_NO_CONNECTION));
1394
+ rb_define_const(rb_cFBConn, "FB_BINDINGS_VERSION", rb_str_new2(RUBY_BINDINGS_VERSION));
1395
+
1396
+ // Instance methods
1397
+ rb_define_method(rb_cFBConn, "create_blob", fbconn_create_blob, 1);
1398
+ rb_define_method(rb_cFBConn, "create_clob", fbconn_create_clob, 1);
1399
+
1400
+ rb_define_method(rb_cFBConn, "database_server_info", fbconn_database_server_info, 0);
1401
+ rb_define_method(rb_cFBConn, "autocommit", fbconn_autocommit, 1);
1402
+ rb_define_method(rb_cFBConn, "commit", fbconn_commit, 0);
1403
+ rb_define_method(rb_cFBConn, "rollback", fbconn_rollback, 0);
1404
+ rb_define_method(rb_cFBConn, "db", fbconn_db, 0);
1405
+ rb_define_method(rb_cFBConn, "host", fbconn_host, 0);
1406
+ rb_define_method(rb_cFBConn, "status", fbconn_status, 0);
1407
+ rb_define_method(rb_cFBConn, "error", fbconn_error, 0);
1408
+ rb_define_method(rb_cFBConn, "close", fbconn_close, 0);
1409
+ rb_define_alias(rb_cFBConn, "finish", "close");
1410
+ rb_define_method(rb_cFBConn, "user", fbconn_user, 0);
1411
+
1412
+ rb_define_method(rb_cFBConn, "exec", fbconn_exec, 1);
1413
+ rb_define_method(rb_cFBConn, "query", fbconn_query, 1);
1414
+
1415
+ rb_define_const(rb_cFBConn, "COMMAND_OK", INT2FIX(FRONTBASE_COMMAND_OK));
1416
+ rb_define_const(rb_cFBConn, "ROWS_OK", INT2FIX(FRONTBASE_ROWS_OK));
1417
+ rb_define_const(rb_cFBConn, "UNIQUE_OK", INT2FIX(FRONTBASE_UNIQUE_OK));
1418
+
1419
+ rb_define_const(rb_cFBConn, "FB_Undecided", INT2FIX(FB_Undecided));
1420
+ rb_define_const(rb_cFBConn, "FB_PrimaryKey", INT2FIX(FB_PrimaryKey));
1421
+ rb_define_const(rb_cFBConn, "FB_Boolean", INT2FIX(FB_Boolean));
1422
+ rb_define_const(rb_cFBConn, "FB_Integer", INT2FIX(FB_Integer));
1423
+ rb_define_const(rb_cFBConn, "FB_SmallInteger", INT2FIX(FB_SmallInteger));
1424
+ rb_define_const(rb_cFBConn, "FB_Float", INT2FIX(FB_Float));
1425
+ rb_define_const(rb_cFBConn, "FB_Real", INT2FIX(FB_Real));
1426
+ rb_define_const(rb_cFBConn, "FB_Double", INT2FIX(FB_Double));
1427
+ rb_define_const(rb_cFBConn, "FB_Numeric", INT2FIX(FB_Numeric));
1428
+ rb_define_const(rb_cFBConn, "FB_Decimal", INT2FIX(FB_Decimal));
1429
+ rb_define_const(rb_cFBConn, "FB_Character", INT2FIX(FB_Character));
1430
+ rb_define_const(rb_cFBConn, "FB_VCharacter", INT2FIX(FB_VCharacter));
1431
+ rb_define_const(rb_cFBConn, "FB_Bit", INT2FIX(FB_Bit));
1432
+ rb_define_const(rb_cFBConn, "FB_VBit", INT2FIX(FB_VBit));
1433
+ rb_define_const(rb_cFBConn, "FB_Date", INT2FIX(FB_Date));
1434
+ rb_define_const(rb_cFBConn, "FB_Time", INT2FIX(FB_Time));
1435
+ rb_define_const(rb_cFBConn, "FB_TimeTZ", INT2FIX(FB_TimeTZ));
1436
+ rb_define_const(rb_cFBConn, "FB_Timestamp", INT2FIX(FB_Timestamp));
1437
+ rb_define_const(rb_cFBConn, "FB_TimestampTZ", INT2FIX(FB_TimestampTZ));
1438
+ rb_define_const(rb_cFBConn, "FB_YearMonth", INT2FIX(FB_YearMonth));
1439
+ rb_define_const(rb_cFBConn, "FB_DayTime", INT2FIX(FB_DayTime));
1440
+ rb_define_const(rb_cFBConn, "FB_CLOB", INT2FIX(FB_CLOB));
1441
+ rb_define_const(rb_cFBConn, "FB_BLOB", INT2FIX(FB_BLOB));
1442
+ rb_define_const(rb_cFBConn, "FB_TinyInteger", INT2FIX(FB_TinyInteger));
1443
+ rb_define_const(rb_cFBConn, "FB_LongInteger", INT2FIX(FB_LongInteger));
1444
+
1445
+ rb_include_module(rb_cFBResult, rb_mEnumerable);
1446
+
1447
+ rb_define_const(rb_cFBResult, "COMMAND_OK", INT2FIX(FRONTBASE_COMMAND_OK));
1448
+ rb_define_const(rb_cFBResult, "ROWS_OK", INT2FIX(FRONTBASE_ROWS_OK));
1449
+ rb_define_const(rb_cFBResult, "UNIQUE_OK", INT2FIX(FRONTBASE_UNIQUE_OK));
1450
+
1451
+ rb_define_method(rb_cFBResult, "status", fbresult_status, 0);
1452
+ rb_define_method(rb_cFBResult, "result", fbresult_result, 0);
1453
+ rb_define_method(rb_cFBResult, "each", fbresult_each, 0);
1454
+ rb_define_method(rb_cFBResult, "[]", fbresult_aref, -1);
1455
+ rb_define_method(rb_cFBResult, "columns", fbresult_columns, 0);
1456
+ rb_define_method(rb_cFBResult, "num_rows", fbresult_num_rows, 0);
1457
+
1458
+ // added by Eric Ocean
1459
+ rb_define_method(rb_cFBResult, "row_index", fbresult_row_index, 0);
1460
+ rb_define_method(rb_cFBResult, "table_name", fbresult_table_name, 0); // not sure if the '0' is right
1461
+
1462
+ rb_define_method(rb_cFBResult, "num_cols", fbresult_num_cols, 0);
1463
+ rb_define_method(rb_cFBResult, "column_name", fbresult_column_name, 1);
1464
+ rb_define_method(rb_cFBResult, "column_type", fbresult_column_type, 1);
1465
+ rb_define_method(rb_cFBResult, "column_length", fbresult_column_length, 1);
1466
+ rb_define_method(rb_cFBResult, "column_precision", fbresult_column_precision, 1);
1467
+ rb_define_method(rb_cFBResult, "column_scale", fbresult_column_scale, 1);
1468
+ rb_define_method(rb_cFBResult, "column_isnullable", fbresult_column_isnullable, 1);
1469
+ rb_define_method(rb_cFBResult, "clear", fbresult_clear, 0);
1470
+ rb_define_method(rb_cFBResult, "close", fbresult_clear, 0);
1471
+ }