rubyfb 0.5.2-x86-linux
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 +6 -0
- data/LICENSE +411 -0
- data/Manifest +73 -0
- data/README +460 -0
- data/Rakefile +20 -0
- data/examples/example01.rb +65 -0
- data/ext/AddUser.c +464 -0
- data/ext/AddUser.h +37 -0
- data/ext/Backup.c +783 -0
- data/ext/Backup.h +37 -0
- data/ext/Blob.c +421 -0
- data/ext/Blob.h +65 -0
- data/ext/Common.c +54 -0
- data/ext/Common.h +37 -0
- data/ext/Connection.c +863 -0
- data/ext/Connection.h +50 -0
- data/ext/DataArea.c +274 -0
- data/ext/DataArea.h +38 -0
- data/ext/Database.c +449 -0
- data/ext/Database.h +48 -0
- data/ext/FireRuby.c +240 -0
- data/ext/FireRuby.h +50 -0
- data/ext/FireRubyException.c +268 -0
- data/ext/FireRubyException.h +51 -0
- data/ext/Generator.c +689 -0
- data/ext/Generator.h +53 -0
- data/ext/RemoveUser.c +212 -0
- data/ext/RemoveUser.h +37 -0
- data/ext/Restore.c +855 -0
- data/ext/Restore.h +37 -0
- data/ext/ResultSet.c +809 -0
- data/ext/ResultSet.h +60 -0
- data/ext/Row.c +965 -0
- data/ext/Row.h +55 -0
- data/ext/ServiceManager.c +316 -0
- data/ext/ServiceManager.h +48 -0
- data/ext/Services.c +124 -0
- data/ext/Services.h +42 -0
- data/ext/Statement.c +785 -0
- data/ext/Statement.h +62 -0
- data/ext/Transaction.c +684 -0
- data/ext/Transaction.h +50 -0
- data/ext/TypeMap.c +1182 -0
- data/ext/TypeMap.h +51 -0
- data/ext/extconf.rb +28 -0
- data/ext/mkmf.bat +1 -0
- data/lib/SQLType.rb +224 -0
- data/lib/active_record/connection_adapters/rubyfb_adapter.rb +805 -0
- data/lib/mkdoc +1 -0
- data/lib/rubyfb.rb +2 -0
- data/lib/rubyfb_lib.so +0 -0
- data/lib/src.rb +1800 -0
- data/rubyfb.gemspec +31 -0
- data/test/AddRemoveUserTest.rb +56 -0
- data/test/BackupRestoreTest.rb +99 -0
- data/test/BlobTest.rb +57 -0
- data/test/CharacterSetTest.rb +63 -0
- data/test/ConnectionTest.rb +111 -0
- data/test/DDLTest.rb +54 -0
- data/test/DatabaseTest.rb +83 -0
- data/test/GeneratorTest.rb +50 -0
- data/test/KeyTest.rb +140 -0
- data/test/ResultSetTest.rb +162 -0
- data/test/RoleTest.rb +73 -0
- data/test/RowCountTest.rb +65 -0
- data/test/RowTest.rb +203 -0
- data/test/SQLTest.rb +182 -0
- data/test/SQLTypeTest.rb +101 -0
- data/test/ServiceManagerTest.rb +29 -0
- data/test/StatementTest.rb +135 -0
- data/test/TestSetup.rb +11 -0
- data/test/TransactionTest.rb +112 -0
- data/test/TypeTest.rb +92 -0
- data/test/UnitTest.rb +65 -0
- metadata +149 -0
data/ext/Row.c
ADDED
@@ -0,0 +1,965 @@
|
|
1
|
+
/*------------------------------------------------------------------------------
|
2
|
+
* Row.c
|
3
|
+
*----------------------------------------------------------------------------*/
|
4
|
+
/**
|
5
|
+
* Copyright � Peter Wood, 2005
|
6
|
+
*
|
7
|
+
* The contents of this file are subject to the Mozilla Public License Version
|
8
|
+
* 1.1 (the "License"); you may not use this file except in compliance with the
|
9
|
+
* License. You may obtain a copy of the License at
|
10
|
+
*
|
11
|
+
* http://www.mozilla.org/MPL/
|
12
|
+
*
|
13
|
+
* Software distributed under the License is distributed on an "AS IS" basis,
|
14
|
+
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
15
|
+
* the specificlanguage governing rights and limitations under the License.
|
16
|
+
*
|
17
|
+
* The Original Code is the FireRuby extension for the Ruby language.
|
18
|
+
*
|
19
|
+
* The Initial Developer of the Original Code is Peter Wood. All Rights
|
20
|
+
* Reserved.
|
21
|
+
*
|
22
|
+
* @author Peter Wood
|
23
|
+
* @version 1.0
|
24
|
+
*/
|
25
|
+
|
26
|
+
/* Includes. */
|
27
|
+
#include "Row.h"
|
28
|
+
#include "FireRuby.h"
|
29
|
+
#include "ibase.h"
|
30
|
+
#include "ruby.h"
|
31
|
+
|
32
|
+
/* Function prototypes. */
|
33
|
+
static VALUE allocateRow(VALUE);
|
34
|
+
static VALUE initializeRow(VALUE, VALUE, VALUE, VALUE);
|
35
|
+
static VALUE columnsInRow(VALUE);
|
36
|
+
static VALUE getRowNumber(VALUE);
|
37
|
+
static VALUE getColumnName(VALUE, VALUE);
|
38
|
+
static VALUE getColumnAlias(VALUE, VALUE);
|
39
|
+
static VALUE getColumnValue(VALUE, VALUE);
|
40
|
+
static VALUE eachColumn(VALUE);
|
41
|
+
static VALUE eachColumnKey(VALUE);
|
42
|
+
static VALUE eachColumnValue(VALUE);
|
43
|
+
static VALUE fetchRowValue(int, VALUE *, VALUE);
|
44
|
+
static VALUE hasColumnKey(VALUE, VALUE);
|
45
|
+
static VALUE hasColumnName(VALUE, VALUE);
|
46
|
+
static VALUE hasColumnAlias(VALUE, VALUE);
|
47
|
+
static VALUE hasColumnValue(VALUE, VALUE);
|
48
|
+
static VALUE getColumnNames(VALUE);
|
49
|
+
static VALUE getColumnAliases(VALUE);
|
50
|
+
static VALUE getColumnValues(VALUE);
|
51
|
+
static VALUE getColumnBaseType(VALUE, VALUE);
|
52
|
+
static VALUE selectRowEntries(VALUE);
|
53
|
+
static VALUE rowToArray(VALUE);
|
54
|
+
static VALUE rowToHash(VALUE);
|
55
|
+
static VALUE rowValuesAt(int, VALUE *, VALUE);
|
56
|
+
|
57
|
+
/* Globals. */
|
58
|
+
VALUE cRow;
|
59
|
+
|
60
|
+
|
61
|
+
/**
|
62
|
+
* This function integrates with the Ruby memory allocation system to allocate
|
63
|
+
* space for new Row objects.
|
64
|
+
*
|
65
|
+
* @param klass A reference to the Row class.
|
66
|
+
*
|
67
|
+
* @return A reference to the Row class instance allocated.
|
68
|
+
*
|
69
|
+
*/
|
70
|
+
static VALUE allocateRow(VALUE klass)
|
71
|
+
{
|
72
|
+
VALUE row;
|
73
|
+
RowHandle *handle = ALLOC(RowHandle);
|
74
|
+
|
75
|
+
if(handle != NULL)
|
76
|
+
{
|
77
|
+
/* Initialise the row fields. */
|
78
|
+
handle->size = 0;
|
79
|
+
handle->number = 0;
|
80
|
+
handle->columns = NULL;
|
81
|
+
row = Data_Wrap_Struct(klass, NULL, freeRow, handle);
|
82
|
+
}
|
83
|
+
else
|
84
|
+
{
|
85
|
+
/* Generate an exception. */
|
86
|
+
rb_raise(rb_eNoMemError, "Memory allocation failure allocating a row.");
|
87
|
+
}
|
88
|
+
|
89
|
+
return(row);
|
90
|
+
}
|
91
|
+
|
92
|
+
|
93
|
+
/**
|
94
|
+
* This function provides the initialize method for the Row class.
|
95
|
+
*
|
96
|
+
* @param self A reference to the Row object to be initialized.
|
97
|
+
* @param results A reference to the ResultSet object that generated the row
|
98
|
+
* of data.
|
99
|
+
* @param data A reference to an array object containing the data for the
|
100
|
+
* row. This will be in the form of an array of arrays, with
|
101
|
+
* each contained array containing two elements - the column
|
102
|
+
* value and the column base type.
|
103
|
+
* @param number A reference to the row number to be associated with the
|
104
|
+
* row.
|
105
|
+
*
|
106
|
+
* @return A reference to the initialize Row object.
|
107
|
+
*
|
108
|
+
*/
|
109
|
+
static VALUE initializeRow(VALUE self, VALUE results, VALUE data, VALUE number)
|
110
|
+
{
|
111
|
+
RowHandle *row = NULL;
|
112
|
+
VALUE value = rb_funcall(data, rb_intern("size"), 0);
|
113
|
+
|
114
|
+
Data_Get_Struct(self, RowHandle, row);
|
115
|
+
rb_iv_set(self, "@number", number);
|
116
|
+
row->size = TYPE(value) == T_FIXNUM ? FIX2INT(value) : NUM2INT(value);
|
117
|
+
if(row->size > 0)
|
118
|
+
{
|
119
|
+
row->columns = ALLOC_N(ColumnHandle, row->size);
|
120
|
+
|
121
|
+
if(row->columns != NULL)
|
122
|
+
{
|
123
|
+
int i;
|
124
|
+
|
125
|
+
memset(row->columns, 0, sizeof(ColumnHandle) * row->size);
|
126
|
+
for(i = 0; i < row->size; i++)
|
127
|
+
{
|
128
|
+
VALUE index,
|
129
|
+
name,
|
130
|
+
alias,
|
131
|
+
items;
|
132
|
+
|
133
|
+
index = INT2NUM(i);
|
134
|
+
name = rb_funcall(results, rb_intern("column_name"), 1, index);
|
135
|
+
alias = rb_funcall(results, rb_intern("column_alias"), 1, index);
|
136
|
+
strcpy(row->columns[i].name, STR2CSTR(name));
|
137
|
+
strcpy(row->columns[i].alias, STR2CSTR(alias));
|
138
|
+
items = rb_ary_entry(data, i);
|
139
|
+
row->columns[i].value = rb_ary_entry(items, 0);
|
140
|
+
row->columns[i].type = rb_ary_entry(items, 1);
|
141
|
+
|
142
|
+
if(TYPE(rb_ary_entry(items, 1)) == T_NIL)
|
143
|
+
{
|
144
|
+
fprintf(stderr, "Nil column type encountered.\n");
|
145
|
+
}
|
146
|
+
}
|
147
|
+
}
|
148
|
+
else
|
149
|
+
{
|
150
|
+
rb_raise(rb_eNoMemError, "Memory allocation failure populating row.");
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
return(self);
|
155
|
+
}
|
156
|
+
|
157
|
+
|
158
|
+
/**
|
159
|
+
* This function provides the column_count method for the Row class.
|
160
|
+
*
|
161
|
+
* @param self A reference to the Row object to fetch the column count for.
|
162
|
+
*
|
163
|
+
* @return The number of columns that make up the row.
|
164
|
+
*
|
165
|
+
*/
|
166
|
+
static VALUE columnsInRow(VALUE self)
|
167
|
+
{
|
168
|
+
RowHandle *row = NULL;
|
169
|
+
|
170
|
+
Data_Get_Struct(self, RowHandle, row);
|
171
|
+
|
172
|
+
return(INT2NUM(row->size));
|
173
|
+
}
|
174
|
+
|
175
|
+
|
176
|
+
/**
|
177
|
+
* This function provides the number method for the Row class.
|
178
|
+
*
|
179
|
+
* @param self A reference to the Row object to retrieve the number for.
|
180
|
+
*
|
181
|
+
* @param A reference to the row number.
|
182
|
+
*
|
183
|
+
*/
|
184
|
+
static VALUE getRowNumber(VALUE self)
|
185
|
+
{
|
186
|
+
return(rb_iv_get(self, "@number"));
|
187
|
+
}
|
188
|
+
|
189
|
+
|
190
|
+
/**
|
191
|
+
* This function provides the column_name method for the Row class.
|
192
|
+
*
|
193
|
+
* @param self A reference to the Row object to fetch the column name for.
|
194
|
+
* @param index A reference to the column index to retrieve the name for.
|
195
|
+
*
|
196
|
+
* @return A reference to the column name or nil if an invalid index is
|
197
|
+
* specified.
|
198
|
+
*
|
199
|
+
*/
|
200
|
+
static VALUE getColumnName(VALUE self, VALUE index)
|
201
|
+
{
|
202
|
+
VALUE name = Qnil;
|
203
|
+
RowHandle *row = NULL;
|
204
|
+
int number = 0;
|
205
|
+
|
206
|
+
Data_Get_Struct(self, RowHandle, row);
|
207
|
+
number = TYPE(index) == T_FIXNUM ? FIX2INT(index) : NUM2INT(index);
|
208
|
+
if(number >= 0 && number < row->size)
|
209
|
+
{
|
210
|
+
name = rb_str_new2(row->columns[number].name);
|
211
|
+
}
|
212
|
+
|
213
|
+
return(name);
|
214
|
+
}
|
215
|
+
|
216
|
+
|
217
|
+
/**
|
218
|
+
* This function provides the column_alias method for the Row class.
|
219
|
+
*
|
220
|
+
* @param self A reference to the Row object to fetch the column alias for.
|
221
|
+
* @param index A reference to the column index to retrieve the alias for.
|
222
|
+
*
|
223
|
+
* @return A reference to the column alias or nil if an invalid index is
|
224
|
+
* specified.
|
225
|
+
*
|
226
|
+
*/
|
227
|
+
static VALUE getColumnAlias(VALUE self, VALUE index)
|
228
|
+
{
|
229
|
+
VALUE alias = Qnil;
|
230
|
+
RowHandle *row = NULL;
|
231
|
+
int number = 0;
|
232
|
+
|
233
|
+
Data_Get_Struct(self, RowHandle, row);
|
234
|
+
number = TYPE(index) == T_FIXNUM ? FIX2INT(index) : NUM2INT(index);
|
235
|
+
if(number >= 0 && number < row->size)
|
236
|
+
{
|
237
|
+
alias = rb_str_new2(row->columns[number].alias);
|
238
|
+
}
|
239
|
+
|
240
|
+
return(alias);
|
241
|
+
}
|
242
|
+
|
243
|
+
|
244
|
+
/**
|
245
|
+
* This function provides the [] method for the Row class.
|
246
|
+
*
|
247
|
+
* @param self A reference to the Row object to fetch the column alias for.
|
248
|
+
* @param index Either the column index or the column name of the column to
|
249
|
+
* retrieve the value for.
|
250
|
+
*
|
251
|
+
* @return A reference to the column value or nil if an invalid column index
|
252
|
+
* is specified.
|
253
|
+
*
|
254
|
+
*/
|
255
|
+
static VALUE getColumnValue(VALUE self, VALUE index)
|
256
|
+
{
|
257
|
+
VALUE value = Qnil;
|
258
|
+
RowHandle *row = NULL;
|
259
|
+
|
260
|
+
Data_Get_Struct(self, RowHandle, row);
|
261
|
+
if(TYPE(index) == T_STRING)
|
262
|
+
{
|
263
|
+
char name[32];
|
264
|
+
int i,
|
265
|
+
done = 0;
|
266
|
+
VALUE flag = getFireRubySetting("ALIAS_KEYS");
|
267
|
+
|
268
|
+
strcpy(name, STR2CSTR(index));
|
269
|
+
for(i = 0; i < row->size && done == 0; i++)
|
270
|
+
{
|
271
|
+
int match;
|
272
|
+
|
273
|
+
/* Check whether its column name or column alias to compare on. */
|
274
|
+
if(flag == Qtrue)
|
275
|
+
{
|
276
|
+
match = strcmp(name, row->columns[i].alias);
|
277
|
+
}
|
278
|
+
else
|
279
|
+
{
|
280
|
+
match = strcmp(name, row->columns[i].name);
|
281
|
+
}
|
282
|
+
|
283
|
+
if(match == 0)
|
284
|
+
{
|
285
|
+
value = row->columns[i].value;
|
286
|
+
done = 1;
|
287
|
+
}
|
288
|
+
}
|
289
|
+
}
|
290
|
+
else
|
291
|
+
{
|
292
|
+
int number = TYPE(index) == T_FIXNUM ? FIX2INT(index) : NUM2INT(index);
|
293
|
+
|
294
|
+
if(number >= 0 && number < row->size)
|
295
|
+
{
|
296
|
+
value = row->columns[number].value;
|
297
|
+
}
|
298
|
+
}
|
299
|
+
|
300
|
+
return(value);
|
301
|
+
}
|
302
|
+
|
303
|
+
|
304
|
+
/**
|
305
|
+
* This function provides the each method for the Row class.
|
306
|
+
*
|
307
|
+
* @param self A reference to the Row object that the method is being called
|
308
|
+
* for.
|
309
|
+
*
|
310
|
+
* @return A reference to the last value returned from the block or nil if no
|
311
|
+
* block was provided.
|
312
|
+
*
|
313
|
+
*/
|
314
|
+
VALUE eachColumn(VALUE self)
|
315
|
+
{
|
316
|
+
VALUE result = Qnil;
|
317
|
+
|
318
|
+
if(rb_block_given_p())
|
319
|
+
{
|
320
|
+
RowHandle *row = NULL;
|
321
|
+
int i;
|
322
|
+
VALUE flag = getFireRubySetting("ALIAS_KEYS");
|
323
|
+
|
324
|
+
Data_Get_Struct(self, RowHandle, row);
|
325
|
+
for(i = 0; i < row->size; i++)
|
326
|
+
{
|
327
|
+
VALUE parameters = rb_ary_new();
|
328
|
+
|
329
|
+
/* Decide whether we're keying on column name or alias. */
|
330
|
+
if(flag == Qtrue)
|
331
|
+
{
|
332
|
+
rb_ary_push(parameters, rb_str_new2(row->columns[i].alias));
|
333
|
+
}
|
334
|
+
else
|
335
|
+
{
|
336
|
+
rb_ary_push(parameters, rb_str_new2(row->columns[i].name));
|
337
|
+
}
|
338
|
+
rb_ary_push(parameters, row->columns[i].value);
|
339
|
+
result = rb_yield(parameters);
|
340
|
+
}
|
341
|
+
}
|
342
|
+
|
343
|
+
return(result);
|
344
|
+
}
|
345
|
+
|
346
|
+
|
347
|
+
/**
|
348
|
+
* This function provides iteration across the column identifiers (either name
|
349
|
+
* or alias depending on library settings) of a Row object.
|
350
|
+
*
|
351
|
+
* @param self A reference to the Row object that the method is being called
|
352
|
+
* for.
|
353
|
+
*
|
354
|
+
* @return A reference to the last value returned from the block or nil if no
|
355
|
+
* block was provided.
|
356
|
+
*
|
357
|
+
*/
|
358
|
+
VALUE eachColumnKey(VALUE self)
|
359
|
+
{
|
360
|
+
VALUE result = Qnil;
|
361
|
+
|
362
|
+
if(rb_block_given_p())
|
363
|
+
{
|
364
|
+
RowHandle *row = NULL;
|
365
|
+
int i;
|
366
|
+
VALUE flag = getFireRubySetting("ALIAS_KEYS");
|
367
|
+
|
368
|
+
Data_Get_Struct(self, RowHandle, row);
|
369
|
+
for(i = 0; i < row->size; i++)
|
370
|
+
{
|
371
|
+
if(flag == Qtrue)
|
372
|
+
{
|
373
|
+
result = rb_yield(rb_str_new2(row->columns[i].alias));
|
374
|
+
}
|
375
|
+
else
|
376
|
+
{
|
377
|
+
result = rb_yield(rb_str_new2(row->columns[i].name));
|
378
|
+
}
|
379
|
+
}
|
380
|
+
}
|
381
|
+
|
382
|
+
return(result);
|
383
|
+
}
|
384
|
+
|
385
|
+
|
386
|
+
/**
|
387
|
+
* This function provides the each_value method for the Row class.
|
388
|
+
*
|
389
|
+
* @param self A reference to the Row object that the method is being called
|
390
|
+
* for.
|
391
|
+
*
|
392
|
+
* @return A reference to the last value returned from the block or nil if no
|
393
|
+
* block was provided.
|
394
|
+
*
|
395
|
+
*/
|
396
|
+
VALUE eachColumnValue(VALUE self)
|
397
|
+
{
|
398
|
+
VALUE result = Qnil;
|
399
|
+
|
400
|
+
if(rb_block_given_p())
|
401
|
+
{
|
402
|
+
RowHandle *row = NULL;
|
403
|
+
int i;
|
404
|
+
|
405
|
+
Data_Get_Struct(self, RowHandle, row);
|
406
|
+
for(i = 0; i < row->size; i++)
|
407
|
+
{
|
408
|
+
result = rb_yield(row->columns[i].value);
|
409
|
+
}
|
410
|
+
}
|
411
|
+
|
412
|
+
return(result);
|
413
|
+
}
|
414
|
+
|
415
|
+
|
416
|
+
/**
|
417
|
+
* This function provides the fetch method for the Row class.
|
418
|
+
*
|
419
|
+
* @param self A reference to the Row class that the method is being
|
420
|
+
* called for.
|
421
|
+
* @param parameters A reference to an array containing the parameters for
|
422
|
+
* the method call. Must contain at least a key.
|
423
|
+
*
|
424
|
+
* @return A reference to the column value, the alternative value of the
|
425
|
+
* return value for any block specified.
|
426
|
+
*
|
427
|
+
*/
|
428
|
+
VALUE fetchRowValue(int size, VALUE *parameters, VALUE self)
|
429
|
+
{
|
430
|
+
VALUE value = Qnil;
|
431
|
+
|
432
|
+
if(size < 1)
|
433
|
+
{
|
434
|
+
rb_raise(rb_eArgError, "Wrong number of arguments (%d for %d)", size, 1);
|
435
|
+
}
|
436
|
+
|
437
|
+
/* Extract the parameters. */
|
438
|
+
value = getColumnValue(self, parameters[0]);
|
439
|
+
if(value == Qnil)
|
440
|
+
{
|
441
|
+
if(size == 1 && rb_block_given_p())
|
442
|
+
{
|
443
|
+
value = rb_yield(rb_ary_new());
|
444
|
+
}
|
445
|
+
else
|
446
|
+
{
|
447
|
+
if(size == 1)
|
448
|
+
{
|
449
|
+
rb_raise(rb_eIndexError, "Column identifier '%s' not found in row.",
|
450
|
+
STR2CSTR(parameters[0]));
|
451
|
+
}
|
452
|
+
value = parameters[1];
|
453
|
+
}
|
454
|
+
}
|
455
|
+
|
456
|
+
return(value);
|
457
|
+
}
|
458
|
+
|
459
|
+
|
460
|
+
/**
|
461
|
+
* This function provides the has_key? method for the Row class.
|
462
|
+
*
|
463
|
+
* @param self A reference to the Row object to call the method on.
|
464
|
+
* @param name A reference to a String containing the name of the column to
|
465
|
+
* check for.
|
466
|
+
*
|
467
|
+
* @return True if the row possesses the specified column name, false
|
468
|
+
* otherwise.
|
469
|
+
*
|
470
|
+
*/
|
471
|
+
VALUE hasColumnKey(VALUE self, VALUE name)
|
472
|
+
{
|
473
|
+
VALUE result = Qfalse;
|
474
|
+
RowHandle *row = NULL;
|
475
|
+
char text[32];
|
476
|
+
int i;
|
477
|
+
VALUE flag = getFireRubySetting("ALIAS_KEYS");
|
478
|
+
|
479
|
+
Data_Get_Struct(self, RowHandle, row);
|
480
|
+
strcpy(text, STR2CSTR(name));
|
481
|
+
for(i = 0; i < row->size && result == Qfalse; i++)
|
482
|
+
{
|
483
|
+
int match;
|
484
|
+
|
485
|
+
/* Check whether key is column name or alias. */
|
486
|
+
if(flag == Qtrue)
|
487
|
+
{
|
488
|
+
match = strcmp(text, row->columns[i].alias);
|
489
|
+
}
|
490
|
+
else
|
491
|
+
{
|
492
|
+
match = strcmp(text, row->columns[i].name);
|
493
|
+
}
|
494
|
+
|
495
|
+
if(match == 0)
|
496
|
+
{
|
497
|
+
result = Qtrue;
|
498
|
+
}
|
499
|
+
}
|
500
|
+
|
501
|
+
return(result);
|
502
|
+
}
|
503
|
+
|
504
|
+
|
505
|
+
/**
|
506
|
+
* This function provides the has_column? method for the Row class.
|
507
|
+
*
|
508
|
+
* @param self A reference to the Row object to call the method on.
|
509
|
+
* @param name A reference to a String containing the name of the column to
|
510
|
+
* check for.
|
511
|
+
*
|
512
|
+
* @return True if the row possesses the specified column name, false
|
513
|
+
* otherwise.
|
514
|
+
*
|
515
|
+
*/
|
516
|
+
VALUE hasColumnName(VALUE self, VALUE name)
|
517
|
+
{
|
518
|
+
VALUE result = Qfalse;
|
519
|
+
RowHandle *row = NULL;
|
520
|
+
char text[32];
|
521
|
+
int i;
|
522
|
+
|
523
|
+
Data_Get_Struct(self, RowHandle, row);
|
524
|
+
strcpy(text, STR2CSTR(name));
|
525
|
+
for(i = 0; i < row->size && result == Qfalse; i++)
|
526
|
+
{
|
527
|
+
if(strcmp(text, row->columns[i].name) == 0)
|
528
|
+
{
|
529
|
+
result = Qtrue;
|
530
|
+
}
|
531
|
+
}
|
532
|
+
|
533
|
+
return(result);
|
534
|
+
}
|
535
|
+
|
536
|
+
|
537
|
+
/**
|
538
|
+
* This function provides the has_alias? method for the Row class.
|
539
|
+
*
|
540
|
+
* @param self A reference to the Row object to call the method on.
|
541
|
+
* @param name A reference to a String containing the alias of the column to
|
542
|
+
* check for.
|
543
|
+
*
|
544
|
+
* @return True if the row possesses the specified column alias, false
|
545
|
+
* otherwise.
|
546
|
+
*
|
547
|
+
*/
|
548
|
+
VALUE hasColumnAlias(VALUE self, VALUE name)
|
549
|
+
{
|
550
|
+
VALUE result = Qfalse;
|
551
|
+
RowHandle *row = NULL;
|
552
|
+
char text[32];
|
553
|
+
int i;
|
554
|
+
|
555
|
+
Data_Get_Struct(self, RowHandle, row);
|
556
|
+
strcpy(text, STR2CSTR(name));
|
557
|
+
for(i = 0; i < row->size && result == Qfalse; i++)
|
558
|
+
{
|
559
|
+
if(strcmp(text, row->columns[i].alias) == 0)
|
560
|
+
{
|
561
|
+
result = Qtrue;
|
562
|
+
}
|
563
|
+
}
|
564
|
+
|
565
|
+
return(result);
|
566
|
+
}
|
567
|
+
|
568
|
+
|
569
|
+
/**
|
570
|
+
* This function provides the has_value? method for the Row class.
|
571
|
+
*
|
572
|
+
* @param self A reference to the Row object to call the method on.
|
573
|
+
* @param value A reference to the value to be checked for.
|
574
|
+
*
|
575
|
+
* @return True if the row contains a matching value, false otherwise.
|
576
|
+
*
|
577
|
+
*/
|
578
|
+
VALUE hasColumnValue(VALUE self, VALUE value)
|
579
|
+
{
|
580
|
+
VALUE result = Qfalse;
|
581
|
+
RowHandle *row = NULL;
|
582
|
+
int i;
|
583
|
+
|
584
|
+
Data_Get_Struct(self, RowHandle, row);
|
585
|
+
for(i = 0; i < row->size && result == Qfalse; i++)
|
586
|
+
{
|
587
|
+
result = rb_funcall(row->columns[i].value, rb_intern("eql?"), 1, value);
|
588
|
+
}
|
589
|
+
|
590
|
+
return(result);
|
591
|
+
}
|
592
|
+
|
593
|
+
|
594
|
+
/**
|
595
|
+
* This function fetches a list of column index keys for a Row object. What the
|
596
|
+
* keys are depends on the library settings, but they will either be the column
|
597
|
+
* names or the column aliases.
|
598
|
+
*
|
599
|
+
* @param self A reference to the Row object to make the call on.
|
600
|
+
*
|
601
|
+
* @return A reference to an array containing the row keys.
|
602
|
+
*
|
603
|
+
*/
|
604
|
+
VALUE getColumnKeys(VALUE self)
|
605
|
+
{
|
606
|
+
VALUE flag = getFireRubySetting("ALIAS_KEYS"),
|
607
|
+
keys = Qnil;
|
608
|
+
|
609
|
+
if(flag == Qtrue)
|
610
|
+
{
|
611
|
+
keys = getColumnAliases(self);
|
612
|
+
}
|
613
|
+
else
|
614
|
+
{
|
615
|
+
keys = getColumnNames(self);
|
616
|
+
}
|
617
|
+
|
618
|
+
return(keys);
|
619
|
+
}
|
620
|
+
|
621
|
+
|
622
|
+
/**
|
623
|
+
* This function provides the keys method for the Row class.
|
624
|
+
*
|
625
|
+
* @param self A reference to the Row object to call the method on.
|
626
|
+
*
|
627
|
+
* @return A reference to an array containing the row column names.
|
628
|
+
*
|
629
|
+
*/
|
630
|
+
VALUE getColumnNames(VALUE self)
|
631
|
+
{
|
632
|
+
VALUE result = rb_ary_new();
|
633
|
+
RowHandle *row = NULL;
|
634
|
+
int i;
|
635
|
+
|
636
|
+
Data_Get_Struct(self, RowHandle, row);
|
637
|
+
for(i = 0; i < row->size; i++)
|
638
|
+
{
|
639
|
+
rb_ary_push(result, rb_str_new2(row->columns[i].name));
|
640
|
+
}
|
641
|
+
|
642
|
+
return(result);
|
643
|
+
}
|
644
|
+
|
645
|
+
|
646
|
+
/**
|
647
|
+
* This function provides the aliases method for the Row class.
|
648
|
+
*
|
649
|
+
* @param self A reference to the Row object to call the method on.
|
650
|
+
*
|
651
|
+
* @return A reference to an array containing the row column aliases.
|
652
|
+
*
|
653
|
+
*/
|
654
|
+
VALUE getColumnAliases(VALUE self)
|
655
|
+
{
|
656
|
+
VALUE result = rb_ary_new();
|
657
|
+
RowHandle *row = NULL;
|
658
|
+
int i;
|
659
|
+
|
660
|
+
Data_Get_Struct(self, RowHandle, row);
|
661
|
+
for(i = 0; i < row->size; i++)
|
662
|
+
{
|
663
|
+
rb_ary_push(result, rb_str_new2(row->columns[i].alias));
|
664
|
+
}
|
665
|
+
|
666
|
+
return(result);
|
667
|
+
}
|
668
|
+
|
669
|
+
|
670
|
+
/**
|
671
|
+
* This function provides the values method for the Row class.
|
672
|
+
*
|
673
|
+
* @param self A reference to the Row object to call the method on.
|
674
|
+
*
|
675
|
+
* @return A reference to an array containing the row column names.
|
676
|
+
*
|
677
|
+
*/
|
678
|
+
VALUE getColumnValues(VALUE self)
|
679
|
+
{
|
680
|
+
VALUE result = rb_ary_new();
|
681
|
+
RowHandle *row = NULL;
|
682
|
+
int i;
|
683
|
+
|
684
|
+
Data_Get_Struct(self, RowHandle, row);
|
685
|
+
for(i = 0; i < row->size; i++)
|
686
|
+
{
|
687
|
+
rb_ary_push(result, row->columns[i].value);
|
688
|
+
}
|
689
|
+
|
690
|
+
return(result);
|
691
|
+
}
|
692
|
+
|
693
|
+
|
694
|
+
/**
|
695
|
+
* This function provides the get_base_type method for the Row class.
|
696
|
+
*
|
697
|
+
* @param self A reference to the Row object to call the method on.
|
698
|
+
* @param index The index of the column to retrieve the base type for.
|
699
|
+
*
|
700
|
+
* @return An Symbol containing the base type details.
|
701
|
+
*
|
702
|
+
*/
|
703
|
+
VALUE getColumnBaseType(VALUE self, VALUE index)
|
704
|
+
{
|
705
|
+
VALUE result = Qnil;
|
706
|
+
|
707
|
+
if(TYPE(index) == T_FIXNUM)
|
708
|
+
{
|
709
|
+
RowHandle *row = NULL;
|
710
|
+
|
711
|
+
Data_Get_Struct(self, RowHandle, row);
|
712
|
+
if(row != NULL)
|
713
|
+
{
|
714
|
+
int offset = FIX2INT(index);
|
715
|
+
|
716
|
+
/* Correct negative index values. */
|
717
|
+
if(offset < 0)
|
718
|
+
{
|
719
|
+
offset = row->size + offset;
|
720
|
+
}
|
721
|
+
|
722
|
+
if(offset >= 0 && offset < row->size)
|
723
|
+
{
|
724
|
+
result = row->columns[offset].type;
|
725
|
+
}
|
726
|
+
}
|
727
|
+
}
|
728
|
+
|
729
|
+
return(result);
|
730
|
+
}
|
731
|
+
|
732
|
+
|
733
|
+
/**
|
734
|
+
* This function provides the select method for the Row class.
|
735
|
+
*
|
736
|
+
* @param self A reference to the Row object to make the method call on.
|
737
|
+
*
|
738
|
+
* @return An array containing the entries selected by the block passed to the
|
739
|
+
* function.
|
740
|
+
*
|
741
|
+
*/
|
742
|
+
VALUE selectRowEntries(VALUE self)
|
743
|
+
{
|
744
|
+
VALUE result = Qnil,
|
745
|
+
flag = getFireRubySetting("ALIAS_KEYS");
|
746
|
+
RowHandle *row = NULL;
|
747
|
+
int i;
|
748
|
+
|
749
|
+
if(!rb_block_given_p())
|
750
|
+
{
|
751
|
+
rb_raise(rb_eStandardError, "No block specified in call to Row#select.");
|
752
|
+
}
|
753
|
+
|
754
|
+
result = rb_ary_new();
|
755
|
+
Data_Get_Struct(self, RowHandle, row);
|
756
|
+
for(i = 0; i < row->size; i++)
|
757
|
+
{
|
758
|
+
VALUE parameters = rb_ary_new();
|
759
|
+
|
760
|
+
/* Check whether we're keying on column name or alias. */
|
761
|
+
if(flag == Qtrue)
|
762
|
+
{
|
763
|
+
rb_ary_push(parameters, rb_str_new2(row->columns[i].alias));
|
764
|
+
}
|
765
|
+
else
|
766
|
+
{
|
767
|
+
rb_ary_push(parameters, rb_str_new2(row->columns[i].name));
|
768
|
+
}
|
769
|
+
rb_ary_push(parameters, row->columns[i].value);
|
770
|
+
if(rb_yield(parameters) == Qtrue)
|
771
|
+
{
|
772
|
+
rb_ary_push(result, parameters);
|
773
|
+
}
|
774
|
+
}
|
775
|
+
|
776
|
+
|
777
|
+
return(result);
|
778
|
+
}
|
779
|
+
|
780
|
+
|
781
|
+
/**
|
782
|
+
* This function provides the to_a method for the Row class.
|
783
|
+
*
|
784
|
+
* @param self A reference to the Row object to make the method call on.
|
785
|
+
*
|
786
|
+
* @return An array containing the entries from the Row object.
|
787
|
+
*
|
788
|
+
*/
|
789
|
+
VALUE rowToArray(VALUE self)
|
790
|
+
{
|
791
|
+
VALUE result = rb_ary_new(),
|
792
|
+
flag = getFireRubySetting("ALIAS_KEYS");
|
793
|
+
RowHandle *row = NULL;
|
794
|
+
int i;
|
795
|
+
|
796
|
+
Data_Get_Struct(self, RowHandle, row);
|
797
|
+
for(i = 0; i < row->size; i++)
|
798
|
+
{
|
799
|
+
VALUE parameters = rb_ary_new();
|
800
|
+
|
801
|
+
/* Check whether we're keying on column name or alias. */
|
802
|
+
if(flag == Qtrue)
|
803
|
+
{
|
804
|
+
rb_ary_push(parameters, rb_str_new2(row->columns[i].alias));
|
805
|
+
}
|
806
|
+
else
|
807
|
+
{
|
808
|
+
rb_ary_push(parameters, rb_str_new2(row->columns[i].name));
|
809
|
+
}
|
810
|
+
rb_ary_push(parameters, row->columns[i].value);
|
811
|
+
rb_ary_push(result, parameters);
|
812
|
+
}
|
813
|
+
|
814
|
+
return(result);
|
815
|
+
}
|
816
|
+
|
817
|
+
|
818
|
+
/**
|
819
|
+
* This function provides the to_hash method for the Row class.
|
820
|
+
*
|
821
|
+
* @param self A reference to the Row object to make the method call on.
|
822
|
+
*
|
823
|
+
* @return A hash containing the entries from the Row object.
|
824
|
+
*
|
825
|
+
*/
|
826
|
+
VALUE rowToHash(VALUE self)
|
827
|
+
{
|
828
|
+
VALUE result = rb_hash_new(),
|
829
|
+
flag = getFireRubySetting("ALIAS_KEYS");
|
830
|
+
RowHandle *row = NULL;
|
831
|
+
int i;
|
832
|
+
|
833
|
+
Data_Get_Struct(self, RowHandle, row);
|
834
|
+
for(i = 0; i < row->size; i++)
|
835
|
+
{
|
836
|
+
VALUE key = Qnil;
|
837
|
+
|
838
|
+
/* Check if we're keying on column name or alias. */
|
839
|
+
if(flag == Qtrue)
|
840
|
+
{
|
841
|
+
key = rb_str_new2(row->columns[i].alias);
|
842
|
+
}
|
843
|
+
else
|
844
|
+
{
|
845
|
+
key = rb_str_new2(row->columns[i].name);
|
846
|
+
}
|
847
|
+
rb_hash_aset(result, key, row->columns[i].value);
|
848
|
+
}
|
849
|
+
|
850
|
+
return(result);
|
851
|
+
}
|
852
|
+
|
853
|
+
|
854
|
+
/**
|
855
|
+
* This function provides the values_at method for the Row class.
|
856
|
+
*
|
857
|
+
* @param self A reference to the Row object to call the method on.
|
858
|
+
* @param keys An array containing the name of the columns that should be
|
859
|
+
* included in the output array.
|
860
|
+
*
|
861
|
+
* @return An array of the values that match the column names specified.
|
862
|
+
*
|
863
|
+
*/
|
864
|
+
VALUE rowValuesAt(int size, VALUE *keys, VALUE self)
|
865
|
+
{
|
866
|
+
VALUE result = rb_ary_new();
|
867
|
+
int i;
|
868
|
+
|
869
|
+
for(i = 0; i < size; i++)
|
870
|
+
{
|
871
|
+
rb_ary_push(result, getColumnValue(self, keys[i]));
|
872
|
+
}
|
873
|
+
|
874
|
+
return(result);
|
875
|
+
}
|
876
|
+
|
877
|
+
|
878
|
+
/**
|
879
|
+
* This function integrates with the Ruby garbage collector to insure that
|
880
|
+
* all resources associated with a Row object are released whenever the Row
|
881
|
+
* object is collected.
|
882
|
+
*
|
883
|
+
* @param row A pointer to the RowHandle object for the Row object.
|
884
|
+
*
|
885
|
+
*/
|
886
|
+
void freeRow(void *row)
|
887
|
+
{
|
888
|
+
if(row != NULL)
|
889
|
+
{
|
890
|
+
RowHandle *handle = (RowHandle *)row;
|
891
|
+
|
892
|
+
if(handle->columns != NULL)
|
893
|
+
{
|
894
|
+
free(handle->columns);
|
895
|
+
}
|
896
|
+
free(handle);
|
897
|
+
}
|
898
|
+
}
|
899
|
+
|
900
|
+
|
901
|
+
/**
|
902
|
+
* This function provides a programmatic means of creating a Row object.
|
903
|
+
*
|
904
|
+
* @param results A reference to the ResultSet object that the row relates to.
|
905
|
+
* @param data A reference to an array containing the row data.
|
906
|
+
* @param number A reference to the number to be associated with the row.
|
907
|
+
*
|
908
|
+
* @return A reference to the Row object created.
|
909
|
+
*
|
910
|
+
*/
|
911
|
+
VALUE rb_row_new(VALUE results, VALUE data, VALUE number)
|
912
|
+
{
|
913
|
+
VALUE row = allocateRow(cRow);
|
914
|
+
|
915
|
+
initializeRow(row, results, data, number);
|
916
|
+
|
917
|
+
return(row);
|
918
|
+
}
|
919
|
+
|
920
|
+
|
921
|
+
/**
|
922
|
+
* This function is used to create and initialize the Row class within the
|
923
|
+
* Ruby environment.
|
924
|
+
*
|
925
|
+
* @param module A reference to the module that the Row class will be created
|
926
|
+
* under.
|
927
|
+
*
|
928
|
+
*/
|
929
|
+
void Init_Row(VALUE module)
|
930
|
+
{
|
931
|
+
cRow = rb_define_class_under(module, "Row", rb_cObject);
|
932
|
+
rb_define_alloc_func(cRow, allocateRow);
|
933
|
+
rb_include_module(cRow, rb_mEnumerable);
|
934
|
+
rb_define_method(cRow, "initialize", initializeRow, 3);
|
935
|
+
rb_define_method(cRow, "number", getRowNumber, 0);
|
936
|
+
rb_define_method(cRow, "column_count", columnsInRow, 0);
|
937
|
+
rb_define_method(cRow, "column_name", getColumnName, 1);
|
938
|
+
rb_define_method(cRow, "column_alias", getColumnAlias, 1);
|
939
|
+
rb_define_method(cRow, "each", eachColumn, 0);
|
940
|
+
rb_define_method(cRow, "each_key", eachColumnKey, 0);
|
941
|
+
rb_define_method(cRow, "each_value", eachColumnValue, 0);
|
942
|
+
rb_define_method(cRow, "[]", getColumnValue, 1);
|
943
|
+
rb_define_method(cRow, "fetch", fetchRowValue, -1);
|
944
|
+
rb_define_method(cRow, "has_key?", hasColumnKey, 1);
|
945
|
+
rb_define_method(cRow, "has_column?", hasColumnName, 1);
|
946
|
+
rb_define_method(cRow, "has_alias?", hasColumnAlias, 1);
|
947
|
+
rb_define_method(cRow, "has_value?", hasColumnValue, 1);
|
948
|
+
rb_define_method(cRow, "keys", getColumnKeys, 0);
|
949
|
+
rb_define_method(cRow, "names", getColumnNames, 0);
|
950
|
+
rb_define_method(cRow, "aliases", getColumnAliases, 0);
|
951
|
+
rb_define_method(cRow, "values", getColumnValues, 0);
|
952
|
+
rb_define_method(cRow, "get_base_type", getColumnBaseType, 1);
|
953
|
+
rb_define_method(cRow, "select", selectRowEntries, 0);
|
954
|
+
rb_define_method(cRow, "to_a", rowToArray, 0);
|
955
|
+
rb_define_method(cRow, "to_hash", rowToHash, 0);
|
956
|
+
rb_define_method(cRow, "values_at", rowValuesAt, -1);;
|
957
|
+
|
958
|
+
rb_define_alias(cRow, "each_pair", "each");
|
959
|
+
rb_define_alias(cRow, "include?", "has_key?");
|
960
|
+
rb_define_alias(cRow, "key?", "has_key?");
|
961
|
+
rb_define_alias(cRow, "member?", "has_key?");
|
962
|
+
rb_define_alias(cRow, "value?", "has_value?");
|
963
|
+
rb_define_alias(cRow, "length", "column_count");
|
964
|
+
rb_define_alias(cRow, "size", "column_count");
|
965
|
+
}
|