rubyfb 0.6.3 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- 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);
|