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.
- data/README +88 -0
- data/extconf.rb +9 -0
- data/frontbase.c +1471 -0
- 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
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
|
+
}
|