rubyfb 0.6.3 → 0.6.4
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/CHANGELOG +3 -0
- data/Rakefile +1 -1
- data/ext/ResultSet.c +62 -11
- data/ext/ResultSet.h +1 -0
- data/ext/Row.c +139 -380
- data/ext/Row.h +1 -16
- data/ext/TypeMap.c +66 -66
- data/ext/TypeMap.h +1 -0
- data/lib/rubyfb_lib.so +0 -0
- data/rubyfb.gemspec +3 -3
- data/test/KeyTest.rb +4 -4
- data/test/RowTest.rb +20 -27
- data/test/StatementTest.rb +2 -2
- metadata +3 -3
data/CHANGELOG
CHANGED
data/Rakefile
CHANGED
data/ext/ResultSet.c
CHANGED
@@ -31,8 +31,8 @@
|
|
31
31
|
#include "Transaction.h"
|
32
32
|
#include "DataArea.h"
|
33
33
|
#include "Row.h"
|
34
|
-
#include "TypeMap.h"
|
35
34
|
#include "ruby.h"
|
35
|
+
#include "FireRuby.h"
|
36
36
|
|
37
37
|
/* Function prototypes. */
|
38
38
|
static VALUE allocateResultSet(VALUE);
|
@@ -58,7 +58,10 @@ static VALUE isResultSetExhausted(VALUE);
|
|
58
58
|
/* Globals. */
|
59
59
|
VALUE cResultSet;
|
60
60
|
|
61
|
-
|
61
|
+
ID NEW_ID, SIZE_ID, AT_NAME_ID, AT_ALIAS_ID, AT_KEY_ID, AT_SCALE_ID, AT_COLUMNS_ID, AT_TYPE_ID,
|
62
|
+
AT_RELATION_ID, AT_STATEMENT_ID, AT_TRANSACTION_ID, AT_COLUMNS_ID;
|
63
|
+
|
64
|
+
static StatementHandle* getStatementHandle(VALUE self) {
|
62
65
|
StatementHandle *hStatement;
|
63
66
|
Data_Get_Struct(getResultSetStatement(self), StatementHandle, hStatement);
|
64
67
|
|
@@ -87,6 +90,15 @@ void resultSetManageStatement(VALUE self) {
|
|
87
90
|
hResults->manage_statement = 1;
|
88
91
|
}
|
89
92
|
|
93
|
+
/**
|
94
|
+
* @self - the result set object
|
95
|
+
* @return - columns metadata array
|
96
|
+
*/
|
97
|
+
|
98
|
+
VALUE getResultsColumns(VALUE self) {
|
99
|
+
return rb_ivar_get(self, AT_COLUMNS_ID);
|
100
|
+
}
|
101
|
+
|
90
102
|
/**
|
91
103
|
* This method allocates a new ResultSet object.
|
92
104
|
*
|
@@ -123,13 +135,40 @@ VALUE allocateResultSet(VALUE klass) {
|
|
123
135
|
*
|
124
136
|
*/
|
125
137
|
VALUE initializeResultSet(VALUE self, VALUE statement, VALUE transaction) {
|
138
|
+
int index;
|
126
139
|
ResultsHandle *hResults = NULL;
|
127
|
-
|
140
|
+
StatementHandle *hStatement;
|
141
|
+
XSQLVAR *var;
|
142
|
+
VALUE columns, column, name, alias, key_flag;
|
128
143
|
|
129
|
-
|
130
|
-
|
131
|
-
|
144
|
+
Data_Get_Struct(self, ResultsHandle, hResults);
|
145
|
+
rb_ivar_set(self, AT_STATEMENT_ID, statement);
|
146
|
+
rb_ivar_set(self, AT_TRANSACTION_ID, transaction);
|
132
147
|
|
148
|
+
hStatement = getStatementHandle(self);
|
149
|
+
var = hStatement->output->sqlvar;
|
150
|
+
columns = rb_ary_new2(hStatement->output->sqld);
|
151
|
+
rb_ivar_set(self, AT_COLUMNS_ID, columns);
|
152
|
+
|
153
|
+
key_flag = getFireRubySetting("ALIAS_KEYS");
|
154
|
+
for(index = 0; index < hStatement->output->sqld; index++, var++) {
|
155
|
+
column = rb_funcall(rb_cObject, NEW_ID, 0);
|
156
|
+
rb_ary_store(columns, index, column);
|
157
|
+
name = rb_str_new(var->sqlname, var->sqlname_length);
|
158
|
+
alias = rb_str_new(var->aliasname, var->aliasname_length);
|
159
|
+
rb_ivar_set(column, AT_NAME_ID, name);
|
160
|
+
rb_ivar_set(column, AT_ALIAS_ID, alias);
|
161
|
+
if(key_flag == Qtrue) {
|
162
|
+
rb_ivar_set(column, AT_KEY_ID, alias);
|
163
|
+
} else {
|
164
|
+
rb_ivar_set(column, AT_KEY_ID, name);
|
165
|
+
}
|
166
|
+
rb_ivar_set(column, AT_TYPE_ID, getColumnType(var));
|
167
|
+
rb_ivar_set(column, AT_SCALE_ID, INT2FIX(var->sqlscale));
|
168
|
+
rb_ivar_set(column, AT_RELATION_ID, rb_str_new(var->relname, var->relname_length));
|
169
|
+
}
|
170
|
+
|
171
|
+
hResults->active = 1;
|
133
172
|
return(self);
|
134
173
|
}
|
135
174
|
|
@@ -147,8 +186,7 @@ VALUE getResultSetRow(VALUE self) {
|
|
147
186
|
|
148
187
|
Data_Get_Struct(self, ResultsHandle, hResults);
|
149
188
|
if(hResults->fetched) {
|
150
|
-
|
151
|
-
row = rb_row_new(self, array, INT2FIX(hResults->fetched));
|
189
|
+
row = rb_row_new(self, INT2FIX(hResults->fetched));
|
152
190
|
}
|
153
191
|
return (row);
|
154
192
|
}
|
@@ -277,7 +315,7 @@ VALUE getResultSetConnection(VALUE self) {
|
|
277
315
|
*
|
278
316
|
*/
|
279
317
|
VALUE getResultSetTransaction(VALUE self) {
|
280
|
-
return
|
318
|
+
return rb_ivar_get(self, AT_TRANSACTION_ID);
|
281
319
|
}
|
282
320
|
|
283
321
|
/**
|
@@ -291,7 +329,7 @@ VALUE getResultSetTransaction(VALUE self) {
|
|
291
329
|
*
|
292
330
|
*/
|
293
331
|
VALUE getResultSetStatement(VALUE self) {
|
294
|
-
return
|
332
|
+
return rb_ivar_get(self, AT_STATEMENT_ID);
|
295
333
|
}
|
296
334
|
|
297
335
|
|
@@ -333,7 +371,7 @@ VALUE getResultSetDialect(VALUE self) {
|
|
333
371
|
*
|
334
372
|
*/
|
335
373
|
VALUE getResultSetColumnCount(VALUE self) {
|
336
|
-
return(
|
374
|
+
return rb_funcall(getResultsColumns(self), SIZE_ID, 0);
|
337
375
|
}
|
338
376
|
|
339
377
|
|
@@ -573,6 +611,19 @@ void resultSetFree(void *handle) {
|
|
573
611
|
*
|
574
612
|
*/
|
575
613
|
void Init_ResultSet(VALUE module) {
|
614
|
+
NEW_ID = rb_intern("new");
|
615
|
+
SIZE_ID = rb_intern("size");
|
616
|
+
AT_NAME_ID = rb_intern("@name");
|
617
|
+
AT_ALIAS_ID = rb_intern("@alias");
|
618
|
+
AT_KEY_ID = rb_intern("@key");
|
619
|
+
AT_SCALE_ID = rb_intern("@scale");
|
620
|
+
AT_COLUMNS_ID = rb_intern("@columns");
|
621
|
+
AT_TYPE_ID = rb_intern("@type");
|
622
|
+
AT_RELATION_ID = rb_intern("@relation");
|
623
|
+
AT_STATEMENT_ID = rb_intern("@statement");
|
624
|
+
AT_TRANSACTION_ID = rb_intern("@transaction");
|
625
|
+
AT_COLUMNS_ID = rb_intern("@columns");
|
626
|
+
|
576
627
|
cResultSet = rb_define_class_under(module, "ResultSet", rb_cObject);
|
577
628
|
rb_define_alloc_func(cResultSet, allocateResultSet);
|
578
629
|
rb_include_module(cResultSet, rb_mEnumerable);
|
data/ext/ResultSet.h
CHANGED
data/ext/Row.c
CHANGED
@@ -25,13 +25,13 @@
|
|
25
25
|
|
26
26
|
/* Includes. */
|
27
27
|
#include "Row.h"
|
28
|
+
#include "TypeMap.h"
|
28
29
|
#include "FireRuby.h"
|
29
30
|
#include "ibase.h"
|
30
31
|
#include "ruby.h"
|
31
32
|
|
32
33
|
/* Function prototypes. */
|
33
|
-
static VALUE
|
34
|
-
static VALUE initializeRow(VALUE, VALUE, VALUE, VALUE);
|
34
|
+
static VALUE initializeRow(VALUE, VALUE, VALUE);
|
35
35
|
static VALUE columnsInRow(VALUE);
|
36
36
|
static VALUE getRowNumber(VALUE);
|
37
37
|
static VALUE getColumnName(VALUE, VALUE);
|
@@ -57,72 +57,71 @@ static VALUE rowValuesAt(int, VALUE *, VALUE);
|
|
57
57
|
|
58
58
|
/* Globals. */
|
59
59
|
VALUE cRow;
|
60
|
+
ID EQL_ID, FETCH_ID, NEW_ID,
|
61
|
+
AT_COLUMNS_ID, AT_NUMBER_ID,
|
62
|
+
AT_NAME_ID, AT_ALIAS_ID, AT_KEY_ID, AT_SCALE_ID,
|
63
|
+
AT_VALUE_ID, AT_TYPE_ID, AT_COLUMN_ID;
|
60
64
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
if(
|
70
|
-
|
71
|
-
int i;
|
72
|
-
for(i = 0; i < row->size; i++) {
|
73
|
-
rb_gc_mark(row->columns[i].value);
|
74
|
-
rb_gc_mark(row->columns[i].type);
|
75
|
-
rb_gc_mark(row->columns[i].scale);
|
76
|
-
}
|
65
|
+
static VALUE getColumns(VALUE self) {
|
66
|
+
return rb_ivar_get(self, AT_COLUMNS_ID);
|
67
|
+
}
|
68
|
+
|
69
|
+
static VALUE checkRowOffset(VALUE columns, VALUE index) {
|
70
|
+
int offset = FIX2INT(index);
|
71
|
+
|
72
|
+
/* Correct negative index values. */
|
73
|
+
if(offset < 0) {
|
74
|
+
return INT2NUM(RARRAY_LEN(columns) + offset);
|
77
75
|
}
|
76
|
+
return index;
|
78
77
|
}
|
79
78
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
* object is collected.
|
84
|
-
*
|
85
|
-
* @param row A pointer to the RowHandle object for the Row object.
|
86
|
-
*
|
87
|
-
*/
|
88
|
-
void freeRow(void *row) {
|
89
|
-
if(row != NULL) {
|
90
|
-
RowHandle *handle = (RowHandle *)row;
|
79
|
+
static VALUE metadataScan(VALUE self, VALUE key, ID slot) {
|
80
|
+
long idx;
|
81
|
+
VALUE columns = getColumns(self);
|
91
82
|
|
92
|
-
|
93
|
-
|
83
|
+
for(idx=0; idx < RARRAY_LEN(columns); idx++) {
|
84
|
+
VALUE column = rb_ary_entry(columns, idx),
|
85
|
+
meta_data = rb_ivar_get(column, AT_COLUMN_ID);
|
86
|
+
if(Qtrue == rb_funcall(rb_ivar_get(meta_data, slot), EQL_ID, 1, key)) {
|
87
|
+
return(column);
|
94
88
|
}
|
95
|
-
free(handle);
|
96
89
|
}
|
90
|
+
return(Qnil);
|
97
91
|
}
|
98
92
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
VALUE row;
|
110
|
-
RowHandle *handle = ALLOC(RowHandle);
|
111
|
-
|
112
|
-
if(handle != NULL) {
|
113
|
-
/* Initialise the row fields. */
|
114
|
-
handle->size = 0;
|
115
|
-
handle->number = 0;
|
116
|
-
handle->columns = NULL;
|
117
|
-
row = Data_Wrap_Struct(klass, rowGCMark, freeRow, handle);
|
118
|
-
} else {
|
119
|
-
/* Generate an exception. */
|
120
|
-
rb_raise(rb_eNoMemError, "Memory allocation failure allocating a row.");
|
93
|
+
static VALUE rowCollect(VALUE self, ID slot, short metadata_flag) {
|
94
|
+
VALUE columns = getColumns(self);
|
95
|
+
long idx, size = RARRAY_LEN(columns);
|
96
|
+
VALUE result = rb_ary_new2(size);
|
97
|
+
for(idx=0; idx < size; idx++) {
|
98
|
+
VALUE target = rb_ary_entry(columns, idx);
|
99
|
+
if(metadata_flag) {
|
100
|
+
target = rb_ivar_get(target, AT_COLUMN_ID);
|
101
|
+
}
|
102
|
+
rb_ary_store(result, idx, rb_ivar_get(target, slot));
|
121
103
|
}
|
104
|
+
return(result);
|
105
|
+
}
|
122
106
|
|
123
|
-
|
107
|
+
static VALUE getColumn(VALUE columns, VALUE index) {
|
108
|
+
return rb_funcall(columns, FETCH_ID, 1, index);
|
124
109
|
}
|
125
110
|
|
111
|
+
static VALUE getMetadata(VALUE columns, VALUE index) {
|
112
|
+
return rb_ivar_get(getColumn(columns, index), AT_COLUMN_ID);
|
113
|
+
}
|
114
|
+
|
115
|
+
static VALUE columnKey(VALUE column) {
|
116
|
+
return rb_ivar_get(rb_ivar_get(column, AT_COLUMN_ID), AT_KEY_ID);
|
117
|
+
}
|
118
|
+
|
119
|
+
static VALUE keyValuePair(VALUE column) {
|
120
|
+
VALUE result = rb_ary_new2(2);
|
121
|
+
rb_ary_store(result, 0, columnKey(column));
|
122
|
+
rb_ary_store(result, 1, rb_ivar_get(column, AT_VALUE_ID));
|
123
|
+
return(result);
|
124
|
+
}
|
126
125
|
|
127
126
|
/**
|
128
127
|
* This function provides the initialize method for the Row class.
|
@@ -140,46 +139,9 @@ static VALUE allocateRow(VALUE klass) {
|
|
140
139
|
* @return A reference to the initialize Row object.
|
141
140
|
*
|
142
141
|
*/
|
143
|
-
static VALUE initializeRow(VALUE self, VALUE results, VALUE
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
Data_Get_Struct(self, RowHandle, row);
|
148
|
-
rb_iv_set(self, "@number", number);
|
149
|
-
row->size = TYPE(value) == T_FIXNUM ? FIX2INT(value) : NUM2INT(value);
|
150
|
-
if(row->size > 0) {
|
151
|
-
row->columns = ALLOC_N(ColumnHandle, row->size);
|
152
|
-
|
153
|
-
if(row->columns != NULL) {
|
154
|
-
int i;
|
155
|
-
|
156
|
-
memset(row->columns, 0, sizeof(ColumnHandle) * row->size);
|
157
|
-
for(i = 0; i < row->size; i++) {
|
158
|
-
VALUE index,
|
159
|
-
name,
|
160
|
-
alias,
|
161
|
-
scale,
|
162
|
-
items;
|
163
|
-
|
164
|
-
index = INT2NUM(i);
|
165
|
-
name = rb_funcall(results, rb_intern("column_name"), 1, index);
|
166
|
-
alias = rb_funcall(results, rb_intern("column_alias"), 1, index);
|
167
|
-
strcpy(row->columns[i].name, StringValuePtr(name));
|
168
|
-
strcpy(row->columns[i].alias, StringValuePtr(alias));
|
169
|
-
items = rb_ary_entry(data, i);
|
170
|
-
row->columns[i].value = rb_ary_entry(items, 0);
|
171
|
-
row->columns[i].type = rb_ary_entry(items, 1);
|
172
|
-
row->columns[i].scale = rb_funcall(results, rb_intern("column_scale"), 1, index);
|
173
|
-
|
174
|
-
if(TYPE(rb_ary_entry(items, 1)) == T_NIL) {
|
175
|
-
fprintf(stderr, "Nil column type encountered.\n");
|
176
|
-
}
|
177
|
-
}
|
178
|
-
} else {
|
179
|
-
rb_raise(rb_eNoMemError, "Memory allocation failure populating row.");
|
180
|
-
}
|
181
|
-
}
|
182
|
-
|
142
|
+
static VALUE initializeRow(VALUE self, VALUE results, VALUE number) {
|
143
|
+
rb_ivar_set(self, AT_NUMBER_ID, number);
|
144
|
+
rb_ivar_set(self, AT_COLUMNS_ID, toRowColumns(results));
|
183
145
|
return(self);
|
184
146
|
}
|
185
147
|
|
@@ -193,11 +155,7 @@ static VALUE initializeRow(VALUE self, VALUE results, VALUE data, VALUE number)
|
|
193
155
|
*
|
194
156
|
*/
|
195
157
|
static VALUE columnsInRow(VALUE self) {
|
196
|
-
|
197
|
-
|
198
|
-
Data_Get_Struct(self, RowHandle, row);
|
199
|
-
|
200
|
-
return(INT2NUM(row->size));
|
158
|
+
return LONG2NUM(RARRAY_LEN(getColumns(self)));
|
201
159
|
}
|
202
160
|
|
203
161
|
|
@@ -210,7 +168,7 @@ static VALUE columnsInRow(VALUE self) {
|
|
210
168
|
*
|
211
169
|
*/
|
212
170
|
static VALUE getRowNumber(VALUE self) {
|
213
|
-
return(
|
171
|
+
return(rb_ivar_get(self, AT_NUMBER_ID));
|
214
172
|
}
|
215
173
|
|
216
174
|
|
@@ -225,17 +183,7 @@ static VALUE getRowNumber(VALUE self) {
|
|
225
183
|
*
|
226
184
|
*/
|
227
185
|
static VALUE getColumnName(VALUE self, VALUE index) {
|
228
|
-
|
229
|
-
RowHandle *row = NULL;
|
230
|
-
int number = 0;
|
231
|
-
|
232
|
-
Data_Get_Struct(self, RowHandle, row);
|
233
|
-
number = TYPE(index) == T_FIXNUM ? FIX2INT(index) : NUM2INT(index);
|
234
|
-
if(number >= 0 && number < row->size) {
|
235
|
-
name = rb_str_new2(row->columns[number].name);
|
236
|
-
}
|
237
|
-
|
238
|
-
return(name);
|
186
|
+
return rb_ivar_get(getMetadata(getColumns(self), index), AT_NAME_ID);
|
239
187
|
}
|
240
188
|
|
241
189
|
|
@@ -250,17 +198,7 @@ static VALUE getColumnName(VALUE self, VALUE index) {
|
|
250
198
|
*
|
251
199
|
*/
|
252
200
|
static VALUE getColumnAlias(VALUE self, VALUE index) {
|
253
|
-
|
254
|
-
RowHandle *row = NULL;
|
255
|
-
int number = 0;
|
256
|
-
|
257
|
-
Data_Get_Struct(self, RowHandle, row);
|
258
|
-
number = TYPE(index) == T_FIXNUM ? FIX2INT(index) : NUM2INT(index);
|
259
|
-
if(number >= 0 && number < row->size) {
|
260
|
-
alias = rb_str_new2(row->columns[number].alias);
|
261
|
-
}
|
262
|
-
|
263
|
-
return(alias);
|
201
|
+
return rb_ivar_get(getMetadata(getColumns(self), index), AT_ALIAS_ID);
|
264
202
|
}
|
265
203
|
|
266
204
|
|
@@ -276,41 +214,17 @@ static VALUE getColumnAlias(VALUE self, VALUE index) {
|
|
276
214
|
*
|
277
215
|
*/
|
278
216
|
static VALUE getColumnValue(VALUE self, VALUE index) {
|
279
|
-
VALUE
|
280
|
-
RowHandle *row = NULL;
|
217
|
+
VALUE fld;
|
281
218
|
|
282
|
-
Data_Get_Struct(self, RowHandle, row);
|
283
219
|
if(TYPE(index) == T_STRING) {
|
284
|
-
|
285
|
-
int i,
|
286
|
-
done = 0;
|
287
|
-
VALUE flag = getFireRubySetting("ALIAS_KEYS");
|
288
|
-
|
289
|
-
strcpy(name, StringValuePtr(index));
|
290
|
-
for(i = 0; i < row->size && done == 0; i++) {
|
291
|
-
int match;
|
292
|
-
|
293
|
-
/* Check whether its column name or column alias to compare on. */
|
294
|
-
if(flag == Qtrue) {
|
295
|
-
match = strcmp(name, row->columns[i].alias);
|
296
|
-
} else {
|
297
|
-
match = strcmp(name, row->columns[i].name);
|
298
|
-
}
|
299
|
-
|
300
|
-
if(match == 0) {
|
301
|
-
value = row->columns[i].value;
|
302
|
-
done = 1;
|
303
|
-
}
|
304
|
-
}
|
220
|
+
fld = metadataScan(self, index, AT_KEY_ID);
|
305
221
|
} else {
|
306
|
-
|
307
|
-
|
308
|
-
if(number >= 0 && number < row->size) {
|
309
|
-
value = row->columns[number].value;
|
310
|
-
}
|
222
|
+
fld = getColumn(getColumns(self), index);
|
311
223
|
}
|
312
|
-
|
313
|
-
|
224
|
+
if(Qnil == fld) {
|
225
|
+
return(Qnil);
|
226
|
+
}
|
227
|
+
return rb_ivar_get(fld, AT_VALUE_ID);
|
314
228
|
}
|
315
229
|
|
316
230
|
|
@@ -328,22 +242,10 @@ VALUE eachColumn(VALUE self) {
|
|
328
242
|
VALUE result = Qnil;
|
329
243
|
|
330
244
|
if(rb_block_given_p()) {
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
Data_Get_Struct(self, RowHandle, row);
|
336
|
-
for(i = 0; i < row->size; i++) {
|
337
|
-
VALUE parameters = rb_ary_new();
|
338
|
-
|
339
|
-
/* Decide whether we're keying on column name or alias. */
|
340
|
-
if(flag == Qtrue) {
|
341
|
-
rb_ary_push(parameters, rb_str_new2(row->columns[i].alias));
|
342
|
-
} else {
|
343
|
-
rb_ary_push(parameters, rb_str_new2(row->columns[i].name));
|
344
|
-
}
|
345
|
-
rb_ary_push(parameters, row->columns[i].value);
|
346
|
-
result = rb_yield(parameters);
|
245
|
+
long i;
|
246
|
+
VALUE columns = getColumns(self);
|
247
|
+
for(i = 0; i < RARRAY_LEN(columns); i++) {
|
248
|
+
result = rb_yield(keyValuePair(rb_ary_entry(columns, i)));
|
347
249
|
}
|
348
250
|
}
|
349
251
|
|
@@ -366,17 +268,10 @@ VALUE eachColumnKey(VALUE self) {
|
|
366
268
|
VALUE result = Qnil;
|
367
269
|
|
368
270
|
if(rb_block_given_p()) {
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
Data_Get_Struct(self, RowHandle, row);
|
374
|
-
for(i = 0; i < row->size; i++) {
|
375
|
-
if(flag == Qtrue) {
|
376
|
-
result = rb_yield(rb_str_new2(row->columns[i].alias));
|
377
|
-
} else {
|
378
|
-
result = rb_yield(rb_str_new2(row->columns[i].name));
|
379
|
-
}
|
271
|
+
long i;
|
272
|
+
VALUE columns = getColumns(self);
|
273
|
+
for(i = 0; i < RARRAY_LEN(columns); i++) {
|
274
|
+
result = rb_yield(columnKey(rb_ary_entry(columns, i)));
|
380
275
|
}
|
381
276
|
}
|
382
277
|
|
@@ -398,12 +293,10 @@ VALUE eachColumnValue(VALUE self) {
|
|
398
293
|
VALUE result = Qnil;
|
399
294
|
|
400
295
|
if(rb_block_given_p()) {
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
for(i = 0; i < row->size; i++) {
|
406
|
-
result = rb_yield(row->columns[i].value);
|
296
|
+
long i;
|
297
|
+
VALUE columns = getColumns(self);
|
298
|
+
for(i = 0; i < RARRAY_LEN(columns); i++) {
|
299
|
+
result = rb_yield(rb_ivar_get(rb_ary_entry(columns, i), AT_VALUE_ID));
|
407
300
|
}
|
408
301
|
}
|
409
302
|
|
@@ -460,30 +353,10 @@ VALUE fetchRowValue(int size, VALUE *parameters, VALUE self) {
|
|
460
353
|
*
|
461
354
|
*/
|
462
355
|
VALUE hasColumnKey(VALUE self, VALUE name) {
|
463
|
-
|
464
|
-
|
465
|
-
char text[32];
|
466
|
-
int i;
|
467
|
-
VALUE flag = getFireRubySetting("ALIAS_KEYS");
|
468
|
-
|
469
|
-
Data_Get_Struct(self, RowHandle, row);
|
470
|
-
strcpy(text, StringValuePtr(name));
|
471
|
-
for(i = 0; i < row->size && result == Qfalse; i++) {
|
472
|
-
int match;
|
473
|
-
|
474
|
-
/* Check whether key is column name or alias. */
|
475
|
-
if(flag == Qtrue) {
|
476
|
-
match = strcmp(text, row->columns[i].alias);
|
477
|
-
} else {
|
478
|
-
match = strcmp(text, row->columns[i].name);
|
479
|
-
}
|
480
|
-
|
481
|
-
if(match == 0) {
|
482
|
-
result = Qtrue;
|
483
|
-
}
|
356
|
+
if(Qnil == metadataScan(self, name, AT_KEY_ID)) {
|
357
|
+
return Qfalse;
|
484
358
|
}
|
485
|
-
|
486
|
-
return(result);
|
359
|
+
return Qtrue;
|
487
360
|
}
|
488
361
|
|
489
362
|
|
@@ -499,20 +372,10 @@ VALUE hasColumnKey(VALUE self, VALUE name) {
|
|
499
372
|
*
|
500
373
|
*/
|
501
374
|
VALUE hasColumnName(VALUE self, VALUE name) {
|
502
|
-
|
503
|
-
|
504
|
-
char text[32];
|
505
|
-
int i;
|
506
|
-
|
507
|
-
Data_Get_Struct(self, RowHandle, row);
|
508
|
-
strcpy(text, StringValuePtr(name));
|
509
|
-
for(i = 0; i < row->size && result == Qfalse; i++) {
|
510
|
-
if(strcmp(text, row->columns[i].name) == 0) {
|
511
|
-
result = Qtrue;
|
512
|
-
}
|
375
|
+
if(Qnil == metadataScan(self, name, AT_NAME_ID)) {
|
376
|
+
return Qfalse;
|
513
377
|
}
|
514
|
-
|
515
|
-
return(result);
|
378
|
+
return Qtrue;
|
516
379
|
}
|
517
380
|
|
518
381
|
|
@@ -528,20 +391,10 @@ VALUE hasColumnName(VALUE self, VALUE name) {
|
|
528
391
|
*
|
529
392
|
*/
|
530
393
|
VALUE hasColumnAlias(VALUE self, VALUE name) {
|
531
|
-
|
532
|
-
|
533
|
-
char text[32];
|
534
|
-
int i;
|
535
|
-
|
536
|
-
Data_Get_Struct(self, RowHandle, row);
|
537
|
-
strcpy(text, StringValuePtr(name));
|
538
|
-
for(i = 0; i < row->size && result == Qfalse; i++) {
|
539
|
-
if(strcmp(text, row->columns[i].alias) == 0) {
|
540
|
-
result = Qtrue;
|
541
|
-
}
|
394
|
+
if(Qnil == metadataScan(self, name, AT_ALIAS_ID)) {
|
395
|
+
return Qfalse;
|
542
396
|
}
|
543
|
-
|
544
|
-
return(result);
|
397
|
+
return Qtrue;
|
545
398
|
}
|
546
399
|
|
547
400
|
|
@@ -555,19 +408,16 @@ VALUE hasColumnAlias(VALUE self, VALUE name) {
|
|
555
408
|
*
|
556
409
|
*/
|
557
410
|
VALUE hasColumnValue(VALUE self, VALUE value) {
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
result = rb_funcall(row->columns[i].value, rb_intern("eql?"), 1, value);
|
411
|
+
long i;
|
412
|
+
VALUE columns = getColumns(self);
|
413
|
+
for(i = 0; i < RARRAY_LEN(columns); i++) {
|
414
|
+
if(Qtrue == rb_funcall(rb_ivar_get(rb_ary_entry(columns, i), AT_VALUE_ID), EQL_ID, 1, value)) {
|
415
|
+
return(Qtrue);
|
416
|
+
}
|
565
417
|
}
|
566
|
-
|
567
|
-
return(result);
|
418
|
+
return(Qfalse);
|
568
419
|
}
|
569
420
|
|
570
|
-
|
571
421
|
/**
|
572
422
|
* This function fetches a list of column index keys for a Row object. What the
|
573
423
|
* keys are depends on the library settings, but they will either be the column
|
@@ -579,16 +429,7 @@ VALUE hasColumnValue(VALUE self, VALUE value) {
|
|
579
429
|
*
|
580
430
|
*/
|
581
431
|
VALUE getColumnKeys(VALUE self) {
|
582
|
-
|
583
|
-
keys = Qnil;
|
584
|
-
|
585
|
-
if(flag == Qtrue) {
|
586
|
-
keys = getColumnAliases(self);
|
587
|
-
} else {
|
588
|
-
keys = getColumnNames(self);
|
589
|
-
}
|
590
|
-
|
591
|
-
return(keys);
|
432
|
+
return rowCollect(self, AT_KEY_ID, 1);
|
592
433
|
}
|
593
434
|
|
594
435
|
|
@@ -601,16 +442,7 @@ VALUE getColumnKeys(VALUE self) {
|
|
601
442
|
*
|
602
443
|
*/
|
603
444
|
VALUE getColumnNames(VALUE self) {
|
604
|
-
|
605
|
-
RowHandle *row = NULL;
|
606
|
-
int i;
|
607
|
-
|
608
|
-
Data_Get_Struct(self, RowHandle, row);
|
609
|
-
for(i = 0; i < row->size; i++) {
|
610
|
-
rb_ary_push(result, rb_str_new2(row->columns[i].name));
|
611
|
-
}
|
612
|
-
|
613
|
-
return(result);
|
445
|
+
return rowCollect(self, AT_NAME_ID, 1);
|
614
446
|
}
|
615
447
|
|
616
448
|
|
@@ -623,16 +455,7 @@ VALUE getColumnNames(VALUE self) {
|
|
623
455
|
*
|
624
456
|
*/
|
625
457
|
VALUE getColumnAliases(VALUE self) {
|
626
|
-
|
627
|
-
RowHandle *row = NULL;
|
628
|
-
int i;
|
629
|
-
|
630
|
-
Data_Get_Struct(self, RowHandle, row);
|
631
|
-
for(i = 0; i < row->size; i++) {
|
632
|
-
rb_ary_push(result, rb_str_new2(row->columns[i].alias));
|
633
|
-
}
|
634
|
-
|
635
|
-
return(result);
|
458
|
+
return rowCollect(self, AT_ALIAS_ID, 1);
|
636
459
|
}
|
637
460
|
|
638
461
|
|
@@ -645,16 +468,7 @@ VALUE getColumnAliases(VALUE self) {
|
|
645
468
|
*
|
646
469
|
*/
|
647
470
|
VALUE getColumnValues(VALUE self) {
|
648
|
-
|
649
|
-
RowHandle *row = NULL;
|
650
|
-
int i;
|
651
|
-
|
652
|
-
Data_Get_Struct(self, RowHandle, row);
|
653
|
-
for(i = 0; i < row->size; i++) {
|
654
|
-
rb_ary_push(result, row->columns[i].value);
|
655
|
-
}
|
656
|
-
|
657
|
-
return(result);
|
471
|
+
return rowCollect(self, AT_VALUE_ID, 0);
|
658
472
|
}
|
659
473
|
|
660
474
|
|
@@ -668,27 +482,8 @@ VALUE getColumnValues(VALUE self) {
|
|
668
482
|
*
|
669
483
|
*/
|
670
484
|
VALUE getColumnBaseType(VALUE self, VALUE index) {
|
671
|
-
VALUE
|
672
|
-
|
673
|
-
if(TYPE(index) == T_FIXNUM) {
|
674
|
-
RowHandle *row = NULL;
|
675
|
-
|
676
|
-
Data_Get_Struct(self, RowHandle, row);
|
677
|
-
if(row != NULL) {
|
678
|
-
int offset = FIX2INT(index);
|
679
|
-
|
680
|
-
/* Correct negative index values. */
|
681
|
-
if(offset < 0) {
|
682
|
-
offset = row->size + offset;
|
683
|
-
}
|
684
|
-
|
685
|
-
if(offset >= 0 && offset < row->size) {
|
686
|
-
result = row->columns[offset].type;
|
687
|
-
}
|
688
|
-
}
|
689
|
-
}
|
690
|
-
|
691
|
-
return(result);
|
485
|
+
VALUE columns = getColumns(self);
|
486
|
+
return rb_ivar_get(getMetadata(columns, checkRowOffset(columns, index)), AT_TYPE_ID);
|
692
487
|
}
|
693
488
|
|
694
489
|
/**
|
@@ -703,27 +498,8 @@ VALUE getColumnBaseType(VALUE self, VALUE index) {
|
|
703
498
|
*
|
704
499
|
*/
|
705
500
|
static VALUE getColumnScale(VALUE self, VALUE index) {
|
706
|
-
VALUE
|
707
|
-
|
708
|
-
if(TYPE(index) == T_FIXNUM) {
|
709
|
-
RowHandle *row = NULL;
|
710
|
-
|
711
|
-
Data_Get_Struct(self, RowHandle, row);
|
712
|
-
if(row != NULL) {
|
713
|
-
int offset = FIX2INT(index);
|
714
|
-
|
715
|
-
/* Correct negative index values. */
|
716
|
-
if(offset < 0) {
|
717
|
-
offset = row->size + offset;
|
718
|
-
}
|
719
|
-
|
720
|
-
if(offset >= 0 && offset < row->size) {
|
721
|
-
result = row->columns[offset].scale;
|
722
|
-
}
|
723
|
-
}
|
724
|
-
}
|
725
|
-
|
726
|
-
return(result);
|
501
|
+
VALUE columns = getColumns(self);
|
502
|
+
return rb_ivar_get(getMetadata(columns, checkRowOffset(columns, index)), AT_SCALE_ID);
|
727
503
|
}
|
728
504
|
|
729
505
|
|
@@ -737,33 +513,21 @@ static VALUE getColumnScale(VALUE self, VALUE index) {
|
|
737
513
|
*
|
738
514
|
*/
|
739
515
|
VALUE selectRowEntries(VALUE self) {
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
int i;
|
516
|
+
long i;
|
517
|
+
VALUE result = rb_ary_new(),
|
518
|
+
columns = getColumns(self);
|
744
519
|
|
745
520
|
if(!rb_block_given_p()) {
|
746
521
|
rb_raise(rb_eStandardError, "No block specified in call to Row#select.");
|
747
522
|
}
|
748
523
|
|
749
|
-
|
750
|
-
|
751
|
-
for(i = 0; i < row->size; i++) {
|
752
|
-
VALUE parameters = rb_ary_new();
|
753
|
-
|
754
|
-
/* Check whether we're keying on column name or alias. */
|
755
|
-
if(flag == Qtrue) {
|
756
|
-
rb_ary_push(parameters, rb_str_new2(row->columns[i].alias));
|
757
|
-
} else {
|
758
|
-
rb_ary_push(parameters, rb_str_new2(row->columns[i].name));
|
759
|
-
}
|
760
|
-
rb_ary_push(parameters, row->columns[i].value);
|
524
|
+
for(i = 0; i < RARRAY_LEN(columns); i++) {
|
525
|
+
VALUE parameters = keyValuePair(rb_ary_entry(columns, i));
|
761
526
|
if(rb_yield(parameters) == Qtrue) {
|
762
527
|
rb_ary_push(result, parameters);
|
763
528
|
}
|
764
529
|
}
|
765
530
|
|
766
|
-
|
767
531
|
return(result);
|
768
532
|
}
|
769
533
|
|
@@ -777,23 +541,12 @@ VALUE selectRowEntries(VALUE self) {
|
|
777
541
|
*
|
778
542
|
*/
|
779
543
|
VALUE rowToArray(VALUE self) {
|
544
|
+
long i;
|
780
545
|
VALUE result = rb_ary_new(),
|
781
|
-
|
782
|
-
RowHandle *row = NULL;
|
783
|
-
int i;
|
546
|
+
columns = getColumns(self);
|
784
547
|
|
785
|
-
|
786
|
-
|
787
|
-
VALUE parameters = rb_ary_new();
|
788
|
-
|
789
|
-
/* Check whether we're keying on column name or alias. */
|
790
|
-
if(flag == Qtrue) {
|
791
|
-
rb_ary_push(parameters, rb_str_new2(row->columns[i].alias));
|
792
|
-
} else {
|
793
|
-
rb_ary_push(parameters, rb_str_new2(row->columns[i].name));
|
794
|
-
}
|
795
|
-
rb_ary_push(parameters, row->columns[i].value);
|
796
|
-
rb_ary_push(result, parameters);
|
548
|
+
for(i = 0; i < RARRAY_LEN(columns); i++) {
|
549
|
+
rb_ary_push(result, keyValuePair(rb_ary_entry(columns, i)));
|
797
550
|
}
|
798
551
|
|
799
552
|
return(result);
|
@@ -809,22 +562,13 @@ VALUE rowToArray(VALUE self) {
|
|
809
562
|
*
|
810
563
|
*/
|
811
564
|
VALUE rowToHash(VALUE self) {
|
565
|
+
long i;
|
812
566
|
VALUE result = rb_hash_new(),
|
813
|
-
|
814
|
-
RowHandle *row = NULL;
|
815
|
-
int i;
|
567
|
+
columns = getColumns(self);
|
816
568
|
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
/* Check if we're keying on column name or alias. */
|
822
|
-
if(flag == Qtrue) {
|
823
|
-
key = rb_str_new2(row->columns[i].alias);
|
824
|
-
} else {
|
825
|
-
key = rb_str_new2(row->columns[i].name);
|
826
|
-
}
|
827
|
-
rb_hash_aset(result, key, row->columns[i].value);
|
569
|
+
for(i = 0; i < RARRAY_LEN(columns); i++) {
|
570
|
+
VALUE fld = rb_ary_entry(columns, i);
|
571
|
+
rb_hash_aset(result, columnKey(fld), rb_ivar_get(fld, AT_VALUE_ID));
|
828
572
|
}
|
829
573
|
|
830
574
|
return(result);
|
@@ -842,8 +586,8 @@ VALUE rowToHash(VALUE self) {
|
|
842
586
|
*
|
843
587
|
*/
|
844
588
|
VALUE rowValuesAt(int size, VALUE *keys, VALUE self) {
|
845
|
-
VALUE result = rb_ary_new();
|
846
589
|
int i;
|
590
|
+
VALUE result = rb_ary_new();
|
847
591
|
|
848
592
|
for(i = 0; i < size; i++) {
|
849
593
|
rb_ary_push(result, getColumnValue(self, keys[i]));
|
@@ -863,10 +607,12 @@ VALUE rowValuesAt(int size, VALUE *keys, VALUE self) {
|
|
863
607
|
* @return A reference to the Row object created.
|
864
608
|
*
|
865
609
|
*/
|
866
|
-
VALUE rb_row_new(VALUE results, VALUE
|
867
|
-
VALUE row =
|
610
|
+
VALUE rb_row_new(VALUE results, VALUE number) {
|
611
|
+
VALUE row = rb_funcall(cRow, NEW_ID, 2, results, number);
|
612
|
+
|
613
|
+
RB_GC_GUARD(row);
|
868
614
|
|
869
|
-
initializeRow(row, results,
|
615
|
+
initializeRow(row, results, number);
|
870
616
|
|
871
617
|
return(row);
|
872
618
|
}
|
@@ -881,10 +627,23 @@ VALUE rb_row_new(VALUE results, VALUE data, VALUE number) {
|
|
881
627
|
*
|
882
628
|
*/
|
883
629
|
void Init_Row(VALUE module) {
|
630
|
+
Init_TypeMap();
|
631
|
+
EQL_ID = rb_intern("eql?");
|
632
|
+
FETCH_ID = rb_intern("fetch");
|
633
|
+
AT_NAME_ID = rb_intern("@name");
|
634
|
+
AT_ALIAS_ID = rb_intern("@alias");
|
635
|
+
AT_KEY_ID = rb_intern("@key");
|
636
|
+
AT_SCALE_ID = rb_intern("@scale");
|
637
|
+
AT_COLUMNS_ID = rb_intern("@columns");
|
638
|
+
AT_NUMBER_ID = rb_intern("@number");
|
639
|
+
AT_VALUE_ID = rb_intern("@value");
|
640
|
+
AT_TYPE_ID = rb_intern("@type");
|
641
|
+
NEW_ID = rb_intern("new");
|
642
|
+
AT_COLUMN_ID = rb_intern("@column");
|
643
|
+
|
884
644
|
cRow = rb_define_class_under(module, "Row", rb_cObject);
|
885
|
-
rb_define_alloc_func(cRow, allocateRow);
|
886
645
|
rb_include_module(cRow, rb_mEnumerable);
|
887
|
-
rb_define_method(cRow, "initialize", initializeRow,
|
646
|
+
rb_define_method(cRow, "initialize", initializeRow, 2);
|
888
647
|
rb_define_method(cRow, "number", getRowNumber, 0);
|
889
648
|
rb_define_method(cRow, "column_count", columnsInRow, 0);
|
890
649
|
rb_define_method(cRow, "column_name", getColumnName, 1);
|