rubyfb 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/CHANGELOG +6 -0
  2. data/LICENSE +411 -0
  3. data/Manifest +73 -0
  4. data/README +460 -0
  5. data/Rakefile +20 -0
  6. data/examples/example01.rb +65 -0
  7. data/ext/AddUser.c +464 -0
  8. data/ext/AddUser.h +37 -0
  9. data/ext/Backup.c +783 -0
  10. data/ext/Backup.h +37 -0
  11. data/ext/Blob.c +421 -0
  12. data/ext/Blob.h +65 -0
  13. data/ext/Common.c +54 -0
  14. data/ext/Common.h +37 -0
  15. data/ext/Connection.c +863 -0
  16. data/ext/Connection.h +50 -0
  17. data/ext/DataArea.c +274 -0
  18. data/ext/DataArea.h +38 -0
  19. data/ext/Database.c +449 -0
  20. data/ext/Database.h +48 -0
  21. data/ext/FireRuby.c +240 -0
  22. data/ext/FireRuby.h +50 -0
  23. data/ext/FireRubyException.c +268 -0
  24. data/ext/FireRubyException.h +51 -0
  25. data/ext/Generator.c +689 -0
  26. data/ext/Generator.h +53 -0
  27. data/ext/RemoveUser.c +212 -0
  28. data/ext/RemoveUser.h +37 -0
  29. data/ext/Restore.c +855 -0
  30. data/ext/Restore.h +37 -0
  31. data/ext/ResultSet.c +809 -0
  32. data/ext/ResultSet.h +60 -0
  33. data/ext/Row.c +965 -0
  34. data/ext/Row.h +55 -0
  35. data/ext/ServiceManager.c +316 -0
  36. data/ext/ServiceManager.h +48 -0
  37. data/ext/Services.c +124 -0
  38. data/ext/Services.h +42 -0
  39. data/ext/Statement.c +785 -0
  40. data/ext/Statement.h +62 -0
  41. data/ext/Transaction.c +684 -0
  42. data/ext/Transaction.h +50 -0
  43. data/ext/TypeMap.c +1182 -0
  44. data/ext/TypeMap.h +51 -0
  45. data/ext/extconf.rb +28 -0
  46. data/ext/mkmf.bat +1 -0
  47. data/lib/SQLType.rb +224 -0
  48. data/lib/active_record/connection_adapters/rubyfb_adapter.rb +805 -0
  49. data/lib/mkdoc +1 -0
  50. data/lib/rubyfb.rb +2 -0
  51. data/lib/rubyfb_lib.so +0 -0
  52. data/lib/src.rb +1800 -0
  53. data/rubyfb.gemspec +31 -0
  54. data/test/AddRemoveUserTest.rb +56 -0
  55. data/test/BackupRestoreTest.rb +99 -0
  56. data/test/BlobTest.rb +57 -0
  57. data/test/CharacterSetTest.rb +63 -0
  58. data/test/ConnectionTest.rb +111 -0
  59. data/test/DDLTest.rb +54 -0
  60. data/test/DatabaseTest.rb +83 -0
  61. data/test/GeneratorTest.rb +50 -0
  62. data/test/KeyTest.rb +140 -0
  63. data/test/ResultSetTest.rb +162 -0
  64. data/test/RoleTest.rb +73 -0
  65. data/test/RowCountTest.rb +65 -0
  66. data/test/RowTest.rb +203 -0
  67. data/test/SQLTest.rb +182 -0
  68. data/test/SQLTypeTest.rb +101 -0
  69. data/test/ServiceManagerTest.rb +29 -0
  70. data/test/StatementTest.rb +135 -0
  71. data/test/TestSetup.rb +11 -0
  72. data/test/TransactionTest.rb +112 -0
  73. data/test/TypeTest.rb +92 -0
  74. data/test/UnitTest.rb +65 -0
  75. 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
+ }