rubyfb 0.6.4 → 0.6.7
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 +14 -0
- data/Manifest +6 -7
- data/Rakefile +1 -1
- data/ext/Common.c +74 -0
- data/ext/Common.h +2 -0
- data/ext/Connection.c +0 -1
- data/ext/FireRuby.c +1 -4
- data/ext/Generator.c +0 -1
- data/ext/Statement.c +186 -26
- data/ext/Statement.h +1 -0
- data/ext/Transaction.c +0 -1
- data/ext/TypeMap.c +60 -285
- data/ext/TypeMap.h +2 -10
- data/lib/active_record/connection_adapters/rubyfb_adapter.rb +17 -16
- data/lib/{Connection.rb → connection.rb} +0 -0
- data/lib/{ProcedureCall.rb → procedure_call.rb} +0 -0
- data/lib/result_set.rb +109 -0
- data/lib/row.rb +149 -0
- data/lib/rubyfb.rb +7 -3
- data/lib/rubyfb_lib.so +0 -0
- data/lib/{SQLType.rb → sql_type.rb} +0 -0
- data/lib/statement.rb +17 -0
- data/rubyfb.gemspec +4 -4
- data/test/ResultSetTest.rb +7 -4
- data/test/RowTest.rb +4 -1
- data/test/TypeTest.rb +1 -1
- metadata +14 -12
- data/ext/ResultSet.c +0 -648
- data/ext/ResultSet.h +0 -59
- data/ext/Row.c +0 -678
- data/ext/Row.h +0 -38
data/ext/ResultSet.c
DELETED
@@ -1,648 +0,0 @@
|
|
1
|
-
/*------------------------------------------------------------------------------
|
2
|
-
* ResultSet.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 "ResultSet.h"
|
28
|
-
#include "Common.h"
|
29
|
-
#include "Statement.h"
|
30
|
-
#include "Connection.h"
|
31
|
-
#include "Transaction.h"
|
32
|
-
#include "DataArea.h"
|
33
|
-
#include "Row.h"
|
34
|
-
#include "ruby.h"
|
35
|
-
#include "FireRuby.h"
|
36
|
-
|
37
|
-
/* Function prototypes. */
|
38
|
-
static VALUE allocateResultSet(VALUE);
|
39
|
-
static VALUE initializeResultSet(VALUE, VALUE, VALUE);
|
40
|
-
static VALUE getResultSetRow(VALUE);
|
41
|
-
static VALUE fetchResultSetEntry(VALUE);
|
42
|
-
static VALUE closeResultSet(VALUE);
|
43
|
-
static VALUE getResultSetCount(VALUE);
|
44
|
-
static VALUE getResultSetConnection(VALUE);
|
45
|
-
static VALUE getResultSetTransaction(VALUE);
|
46
|
-
static VALUE getResultSetStatement(VALUE);
|
47
|
-
static VALUE getResultSetSQL(VALUE);
|
48
|
-
static VALUE getResultSetDialect(VALUE);
|
49
|
-
static VALUE getResultSetColumnCount(VALUE);
|
50
|
-
static VALUE getResultSetColumnName(VALUE, VALUE);
|
51
|
-
static VALUE getResultSetColumnAlias(VALUE, VALUE);
|
52
|
-
static VALUE getResultSetColumnScale(VALUE, VALUE);
|
53
|
-
static VALUE getResultSetColumnTable(VALUE, VALUE);
|
54
|
-
static VALUE getResultSetColumnType(VALUE, VALUE);
|
55
|
-
static VALUE eachResultSetRow(VALUE);
|
56
|
-
static VALUE isResultSetExhausted(VALUE);
|
57
|
-
|
58
|
-
/* Globals. */
|
59
|
-
VALUE cResultSet;
|
60
|
-
|
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) {
|
65
|
-
StatementHandle *hStatement;
|
66
|
-
Data_Get_Struct(getResultSetStatement(self), StatementHandle, hStatement);
|
67
|
-
|
68
|
-
return (hStatement);
|
69
|
-
}
|
70
|
-
|
71
|
-
short isActiveResultSet(VALUE self) {
|
72
|
-
short result = 0;
|
73
|
-
if ((Qtrue == rb_obj_is_kind_of(self, cResultSet))) {
|
74
|
-
ResultsHandle *hResults = NULL;
|
75
|
-
Data_Get_Struct(self, ResultsHandle, hResults);
|
76
|
-
result = hResults->active;
|
77
|
-
}
|
78
|
-
return (result);
|
79
|
-
}
|
80
|
-
|
81
|
-
void resultSetManageTransaction(VALUE self) {
|
82
|
-
ResultsHandle *hResults = NULL;
|
83
|
-
Data_Get_Struct(self, ResultsHandle, hResults);
|
84
|
-
hResults->manage_transaction = 1;
|
85
|
-
}
|
86
|
-
|
87
|
-
void resultSetManageStatement(VALUE self) {
|
88
|
-
ResultsHandle *hResults = NULL;
|
89
|
-
Data_Get_Struct(self, ResultsHandle, hResults);
|
90
|
-
hResults->manage_statement = 1;
|
91
|
-
}
|
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
|
-
|
102
|
-
/**
|
103
|
-
* This method allocates a new ResultSet object.
|
104
|
-
*
|
105
|
-
* @param klass A reference to the ResultSet Class object.
|
106
|
-
*
|
107
|
-
* @return A reference to the newly allocated ResultSet object.
|
108
|
-
*
|
109
|
-
*/
|
110
|
-
VALUE allocateResultSet(VALUE klass) {
|
111
|
-
ResultsHandle *results = ALLOC(ResultsHandle);
|
112
|
-
|
113
|
-
if(results == NULL) {
|
114
|
-
rb_raise(rb_eNoMemError,
|
115
|
-
"Memory allocation failure allocating a result set.");
|
116
|
-
}
|
117
|
-
results->fetched = 0;
|
118
|
-
results->active = 0;
|
119
|
-
results->manage_transaction = 0;
|
120
|
-
results->manage_statement = 0;
|
121
|
-
|
122
|
-
return(Data_Wrap_Struct(klass, NULL, resultSetFree, results));
|
123
|
-
}
|
124
|
-
|
125
|
-
|
126
|
-
/**
|
127
|
-
* This function provides the initialize method for the ResultSet class.
|
128
|
-
*
|
129
|
-
* @param self A reference to the ResultSet object to be initialized.
|
130
|
-
* @param statement A statement to iterate over
|
131
|
-
* @param transaction A reference to a privater transaction object
|
132
|
-
* taht should be managed by this ResultSet.
|
133
|
-
*
|
134
|
-
* @return A reference to the newly initialize ResultSet object.
|
135
|
-
*
|
136
|
-
*/
|
137
|
-
VALUE initializeResultSet(VALUE self, VALUE statement, VALUE transaction) {
|
138
|
-
int index;
|
139
|
-
ResultsHandle *hResults = NULL;
|
140
|
-
StatementHandle *hStatement;
|
141
|
-
XSQLVAR *var;
|
142
|
-
VALUE columns, column, name, alias, key_flag;
|
143
|
-
|
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);
|
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;
|
172
|
-
return(self);
|
173
|
-
}
|
174
|
-
|
175
|
-
/**
|
176
|
-
* This function provides the row method for the ResultSet class.
|
177
|
-
*
|
178
|
-
* @param self A reference to the ResultSet object to make the call on.
|
179
|
-
*
|
180
|
-
* @return Either a reference to a Row object or nil.
|
181
|
-
*
|
182
|
-
*/
|
183
|
-
VALUE getResultSetRow(VALUE self) {
|
184
|
-
VALUE row = Qnil;
|
185
|
-
ResultsHandle *hResults = NULL;
|
186
|
-
|
187
|
-
Data_Get_Struct(self, ResultsHandle, hResults);
|
188
|
-
if(hResults->fetched) {
|
189
|
-
row = rb_row_new(self, INT2FIX(hResults->fetched));
|
190
|
-
}
|
191
|
-
return (row);
|
192
|
-
}
|
193
|
-
|
194
|
-
|
195
|
-
/**
|
196
|
-
* This function provides the fetch method for the ResultSet class.
|
197
|
-
*
|
198
|
-
* @param self A reference to the ResultSet object to make the call on.
|
199
|
-
*
|
200
|
-
* @return Either a reference to a Row object or nil.
|
201
|
-
*
|
202
|
-
*/
|
203
|
-
VALUE fetchResultSetEntry(VALUE self) {
|
204
|
-
VALUE row = Qnil;
|
205
|
-
StatementHandle *hStatement = getStatementHandle(self);
|
206
|
-
ResultsHandle *hResults = NULL;
|
207
|
-
ISC_STATUS status[ISC_STATUS_LENGTH],
|
208
|
-
fetch_result;
|
209
|
-
|
210
|
-
Data_Get_Struct(self, ResultsHandle, hResults);
|
211
|
-
if(hResults->active) {
|
212
|
-
if (isCursorStatement(hStatement)) {
|
213
|
-
fetch_result = isc_dsql_fetch(status, &hStatement->handle, hStatement->dialect,
|
214
|
-
hStatement->output);
|
215
|
-
switch(fetch_result) {
|
216
|
-
case 0:
|
217
|
-
hResults->fetched += 1;
|
218
|
-
row = getResultSetRow(self);
|
219
|
-
break;
|
220
|
-
case 100:
|
221
|
-
hResults->active = 0;
|
222
|
-
break;
|
223
|
-
default:
|
224
|
-
rb_fireruby_raise(status, "Error fetching query row.");
|
225
|
-
}
|
226
|
-
} else {
|
227
|
-
hResults->active = 0;
|
228
|
-
hResults->fetched = 1;
|
229
|
-
row = getResultSetRow(self);
|
230
|
-
}
|
231
|
-
}
|
232
|
-
return (row);
|
233
|
-
}
|
234
|
-
|
235
|
-
/**
|
236
|
-
* This function provides the close method for the ResultSet class, releasing
|
237
|
-
* resources associated with the ResultSet.
|
238
|
-
*
|
239
|
-
* @param self A reference to the ResultSet object to be closed.
|
240
|
-
*
|
241
|
-
* @return A reference to the closed ResultSet object.
|
242
|
-
*
|
243
|
-
*/
|
244
|
-
VALUE closeResultSet(VALUE self) {
|
245
|
-
StatementHandle *hStatement = getStatementHandle(self);
|
246
|
-
ResultsHandle *hResults = NULL;
|
247
|
-
Data_Get_Struct(self, ResultsHandle, hResults);
|
248
|
-
ISC_STATUS status[ISC_STATUS_LENGTH];
|
249
|
-
|
250
|
-
hResults->active = 0;
|
251
|
-
if(isc_dsql_free_statement(status, &hStatement->handle, DSQL_close)) {
|
252
|
-
rb_fireruby_raise(status, "Error closing cursor.");
|
253
|
-
}
|
254
|
-
if(hResults->manage_statement) {
|
255
|
-
VALUE statement = getResultSetStatement(self),
|
256
|
-
menagement_required = rb_funcall(statement, rb_intern("prepared?"), 0);
|
257
|
-
if(Qtrue == menagement_required) {
|
258
|
-
rb_funcall(statement, rb_intern("close"), 0);
|
259
|
-
}
|
260
|
-
}
|
261
|
-
if(hResults->manage_transaction) {
|
262
|
-
VALUE transaction = getResultSetTransaction(self),
|
263
|
-
menagement_required = rb_funcall(transaction, rb_intern("active?"), 0);
|
264
|
-
if(Qtrue == menagement_required) {
|
265
|
-
rb_funcall(transaction, rb_intern("commit"), 0);
|
266
|
-
}
|
267
|
-
}
|
268
|
-
|
269
|
-
return(self);
|
270
|
-
}
|
271
|
-
|
272
|
-
|
273
|
-
/**
|
274
|
-
* This function provides the count method for the ResultSet class.
|
275
|
-
*
|
276
|
-
* @param self A reference to the ResultSet object to fetch the current row
|
277
|
-
* count for.
|
278
|
-
*
|
279
|
-
* @return A reference to an integer containing a count of the number of rows
|
280
|
-
* fetched from the ResultSet so far.
|
281
|
-
*
|
282
|
-
*/
|
283
|
-
VALUE getResultSetCount(VALUE self) {
|
284
|
-
ResultsHandle *results = NULL;
|
285
|
-
|
286
|
-
Data_Get_Struct(self, ResultsHandle, results);
|
287
|
-
|
288
|
-
return(INT2NUM(results->fetched));
|
289
|
-
}
|
290
|
-
|
291
|
-
|
292
|
-
/**
|
293
|
-
* This method provides the accessor method for the connection ResultSet
|
294
|
-
* attribute.
|
295
|
-
*
|
296
|
-
* @param self A reference to the ResultSet object to fetch the attribute
|
297
|
-
* from.
|
298
|
-
*
|
299
|
-
* @return A reference to the requested attribute object.
|
300
|
-
*
|
301
|
-
*/
|
302
|
-
VALUE getResultSetConnection(VALUE self) {
|
303
|
-
return(rb_funcall(getResultSetStatement(self), rb_intern("connection"), 0));
|
304
|
-
}
|
305
|
-
|
306
|
-
|
307
|
-
/**
|
308
|
-
* This method provides the accessor method for the transaction ResultSet
|
309
|
-
* attribute.
|
310
|
-
*
|
311
|
-
* @param self A reference to the ResultSet object to fetch the attribute
|
312
|
-
* from.
|
313
|
-
*
|
314
|
-
* @return A reference to the requested attribute object.
|
315
|
-
*
|
316
|
-
*/
|
317
|
-
VALUE getResultSetTransaction(VALUE self) {
|
318
|
-
return rb_ivar_get(self, AT_TRANSACTION_ID);
|
319
|
-
}
|
320
|
-
|
321
|
-
/**
|
322
|
-
* This method provides the accessor method for the transaction ResultSet
|
323
|
-
* statement.
|
324
|
-
*
|
325
|
-
* @param self A reference to the ResultSet object to fetch the attribute
|
326
|
-
* from.
|
327
|
-
*
|
328
|
-
* @return A reference to the requested attribute object.
|
329
|
-
*
|
330
|
-
*/
|
331
|
-
VALUE getResultSetStatement(VALUE self) {
|
332
|
-
return rb_ivar_get(self, AT_STATEMENT_ID);
|
333
|
-
}
|
334
|
-
|
335
|
-
|
336
|
-
/**
|
337
|
-
* This method provides the accessor method for the SQL ResultSet attribute.
|
338
|
-
*
|
339
|
-
* @param self A reference to the ResultSet object to fetch the attribute
|
340
|
-
* from.
|
341
|
-
*
|
342
|
-
* @return A reference to the requested attribute object.
|
343
|
-
*
|
344
|
-
*/
|
345
|
-
VALUE getResultSetSQL(VALUE self) {
|
346
|
-
return(rb_funcall(getResultSetStatement(self), rb_intern("sql"), 0));
|
347
|
-
}
|
348
|
-
|
349
|
-
|
350
|
-
/**
|
351
|
-
* This method provides the accessor method for the dialect ResultSet attribute.
|
352
|
-
*
|
353
|
-
* @param self A reference to the ResultSet object to fetch the attribute
|
354
|
-
* from.
|
355
|
-
*
|
356
|
-
* @return A reference to the requested attribute object.
|
357
|
-
*
|
358
|
-
*/
|
359
|
-
VALUE getResultSetDialect(VALUE self) {
|
360
|
-
return(rb_funcall(getResultSetStatement(self), rb_intern("dialect"), 0));
|
361
|
-
}
|
362
|
-
|
363
|
-
|
364
|
-
/**
|
365
|
-
* This function provides the column_count attribute accessor for the ResultSet
|
366
|
-
* class.
|
367
|
-
*
|
368
|
-
* @param self A reference to the ResultSet object to fetch the attribute for.
|
369
|
-
*
|
370
|
-
* @return A reference to an integer containing the column count.
|
371
|
-
*
|
372
|
-
*/
|
373
|
-
VALUE getResultSetColumnCount(VALUE self) {
|
374
|
-
return rb_funcall(getResultsColumns(self), SIZE_ID, 0);
|
375
|
-
}
|
376
|
-
|
377
|
-
|
378
|
-
/**
|
379
|
-
* This function provides the column_name method for the ResultSet class.
|
380
|
-
*
|
381
|
-
* @param self A reference to the ResultSet object to retrieve the column
|
382
|
-
* name from.
|
383
|
-
* @param column An offset to the column to retrieve the name for.
|
384
|
-
*
|
385
|
-
* @return A String containing the column name or nil if an invalid column
|
386
|
-
* was specified.
|
387
|
-
*
|
388
|
-
*/
|
389
|
-
static VALUE getResultSetColumnName(VALUE self, VALUE column) {
|
390
|
-
int offset = 0;
|
391
|
-
VALUE name = Qnil;
|
392
|
-
StatementHandle *hStatement = getStatementHandle(self);
|
393
|
-
|
394
|
-
offset = (TYPE(column) == T_FIXNUM ? FIX2INT(column) : NUM2INT(column));
|
395
|
-
if(offset >= 0 && offset < hStatement->output->sqld) {
|
396
|
-
XSQLVAR *var = hStatement->output->sqlvar;
|
397
|
-
int index;
|
398
|
-
|
399
|
-
for(index = 0; index < offset; index++, var++) ;
|
400
|
-
name = rb_str_new(var->sqlname, var->sqlname_length);
|
401
|
-
}
|
402
|
-
|
403
|
-
return(name);
|
404
|
-
}
|
405
|
-
|
406
|
-
|
407
|
-
/**
|
408
|
-
* This function provides the column_alias method for the ResultSet class.
|
409
|
-
*
|
410
|
-
* @param self A reference to the ResultSet object to retrieve the column
|
411
|
-
* alias from.
|
412
|
-
* @param column An offset to the column to retrieve the alias for.
|
413
|
-
*
|
414
|
-
* @return A String containing the column alias or nil if an invalid column
|
415
|
-
* was specified.
|
416
|
-
*
|
417
|
-
*/
|
418
|
-
static VALUE getResultSetColumnAlias(VALUE self, VALUE column) {
|
419
|
-
int offset = 0;
|
420
|
-
VALUE alias = Qnil;
|
421
|
-
StatementHandle *hStatement = getStatementHandle(self);
|
422
|
-
|
423
|
-
offset = (TYPE(column) == T_FIXNUM ? FIX2INT(column) : NUM2INT(column));
|
424
|
-
if(offset >= 0 && offset < hStatement->output->sqld) {
|
425
|
-
XSQLVAR *var = hStatement->output->sqlvar;
|
426
|
-
int index;
|
427
|
-
|
428
|
-
for(index = 0; index < offset; index++, var++) ;
|
429
|
-
alias = rb_str_new(var->aliasname, var->aliasname_length);
|
430
|
-
}
|
431
|
-
|
432
|
-
return(alias);
|
433
|
-
}
|
434
|
-
|
435
|
-
/**
|
436
|
-
* This function provides the column_scale method for the ResultSet class.
|
437
|
-
*
|
438
|
-
* @param self A reference to the ResultSet object to retrieve the column
|
439
|
-
* alias from.
|
440
|
-
* @param column An offset to the column to retrieve the scale of.
|
441
|
-
*
|
442
|
-
* @return An Integer representing the sqlscale of the column, or nil if an
|
443
|
-
* invalid column was specified.
|
444
|
-
*
|
445
|
-
*/
|
446
|
-
static VALUE getResultSetColumnScale(VALUE self, VALUE column) {
|
447
|
-
int offset = 0;
|
448
|
-
VALUE scale = Qnil;
|
449
|
-
StatementHandle *hStatement = getStatementHandle(self);
|
450
|
-
|
451
|
-
offset = (TYPE(column) == T_FIXNUM ? FIX2INT(column) : NUM2INT(column));
|
452
|
-
if(offset >= 0 && offset < hStatement->output->sqld) {
|
453
|
-
XSQLVAR *var = hStatement->output->sqlvar;
|
454
|
-
int index;
|
455
|
-
|
456
|
-
for(index = 0; index < offset; index++, var++) ;
|
457
|
-
scale = INT2FIX(var->sqlscale);
|
458
|
-
}
|
459
|
-
|
460
|
-
return(scale);
|
461
|
-
}
|
462
|
-
|
463
|
-
|
464
|
-
/**
|
465
|
-
* This function provides the column_table method for the ResultSet class.
|
466
|
-
*
|
467
|
-
* @param self A reference to the ResultSet object to retrieve the column
|
468
|
-
* table name from.
|
469
|
-
* @param column An offset to the column to retrieve the table name for.
|
470
|
-
*
|
471
|
-
* @return A String containing the column table name or nil if an invalid
|
472
|
-
* column was specified.
|
473
|
-
*
|
474
|
-
*/
|
475
|
-
static VALUE getResultSetColumnTable(VALUE self, VALUE column) {
|
476
|
-
int offset = 0;
|
477
|
-
VALUE name = Qnil;
|
478
|
-
StatementHandle *hStatement = getStatementHandle(self);
|
479
|
-
|
480
|
-
offset = (TYPE(column) == T_FIXNUM ? FIX2INT(column) : NUM2INT(column));
|
481
|
-
if(offset >= 0 && offset < hStatement->output->sqld) {
|
482
|
-
XSQLVAR *var = hStatement->output->sqlvar;
|
483
|
-
int index;
|
484
|
-
|
485
|
-
for(index = 0; index < offset; index++, var++) ;
|
486
|
-
name = rb_str_new(var->relname, var->relname_length);
|
487
|
-
}
|
488
|
-
|
489
|
-
return(name);
|
490
|
-
}
|
491
|
-
|
492
|
-
|
493
|
-
/**
|
494
|
-
* This function attempts to extract basic type information for a column within
|
495
|
-
* a ResultSet object.
|
496
|
-
*
|
497
|
-
* @param self A reference to the ResultSet to execute on.
|
498
|
-
* @param column A integer offset for the column to extract the type of.
|
499
|
-
*
|
500
|
-
* @return A Symbol representing the basic data type.
|
501
|
-
*
|
502
|
-
*/
|
503
|
-
static VALUE getResultSetColumnType(VALUE self, VALUE column) {
|
504
|
-
VALUE type = toSymbol("UNKNOWN");
|
505
|
-
|
506
|
-
if(TYPE(column) == T_FIXNUM) {
|
507
|
-
StatementHandle *hStatement = getStatementHandle(self);
|
508
|
-
int index = FIX2INT(column);
|
509
|
-
|
510
|
-
/* Fix negative index values. */
|
511
|
-
if(index < 0) {
|
512
|
-
index = hStatement->output->sqln + index;
|
513
|
-
}
|
514
|
-
|
515
|
-
if(index >= 0 && index < hStatement->output->sqln) {
|
516
|
-
type = getColumnType(&hStatement->output->sqlvar[index]);
|
517
|
-
}
|
518
|
-
}
|
519
|
-
|
520
|
-
return(type);
|
521
|
-
}
|
522
|
-
|
523
|
-
VALUE yieldRows(VALUE self) {
|
524
|
-
VALUE result = Qnil;
|
525
|
-
|
526
|
-
/* Check if a block was provided. */
|
527
|
-
if(rb_block_given_p()) {
|
528
|
-
VALUE row;
|
529
|
-
while((row = fetchResultSetEntry(self)) != Qnil) {
|
530
|
-
result = rb_yield(row);
|
531
|
-
}
|
532
|
-
}
|
533
|
-
|
534
|
-
return(result);
|
535
|
-
}
|
536
|
-
|
537
|
-
VALUE yieldResultsRows(VALUE self) {
|
538
|
-
return rb_ensure(yieldRows, self, closeResultSet, self);
|
539
|
-
}
|
540
|
-
|
541
|
-
/**
|
542
|
-
* This function provides the each method for the ResultSet class.
|
543
|
-
*
|
544
|
-
* @param self A reference to the ResultSet object to execute the method for.
|
545
|
-
*
|
546
|
-
* @return A reference to the last value returned by the associated block or
|
547
|
-
* nil.
|
548
|
-
*
|
549
|
-
*/
|
550
|
-
VALUE eachResultSetRow(VALUE self) {
|
551
|
-
return yieldRows(self);
|
552
|
-
}
|
553
|
-
|
554
|
-
/**
|
555
|
-
* This function provides the exhausted? method of the ResultSet class.
|
556
|
-
*
|
557
|
-
* @param self A reference to the ResultSet object to make the call for.
|
558
|
-
*
|
559
|
-
* @return True if all rows have been fetched from the result set, false
|
560
|
-
* if they haven't.
|
561
|
-
*
|
562
|
-
*/
|
563
|
-
VALUE isResultSetExhausted(VALUE self) {
|
564
|
-
VALUE exhausted = Qtrue;
|
565
|
-
ResultsHandle *hResults = NULL;
|
566
|
-
|
567
|
-
Data_Get_Struct(self, ResultsHandle, hResults);
|
568
|
-
if(hResults->active) {
|
569
|
-
exhausted = Qfalse;
|
570
|
-
}
|
571
|
-
|
572
|
-
return(exhausted);
|
573
|
-
}
|
574
|
-
|
575
|
-
|
576
|
-
/**
|
577
|
-
* This function provides a programmatic means of creating a ResultSet object.
|
578
|
-
*
|
579
|
-
* @param statement A statement to iterate over
|
580
|
-
* @param transaction A reference to a privater transaction object
|
581
|
-
* taht should be managed by this ResultSet.
|
582
|
-
* @param owns_transaction true if the result set should manage the transaction
|
583
|
-
*
|
584
|
-
* @return A reference to the newly created ResultSet object.
|
585
|
-
*
|
586
|
-
*/
|
587
|
-
VALUE rb_result_set_new(VALUE statement, VALUE transaction) {
|
588
|
-
VALUE instance = allocateResultSet(cResultSet);
|
589
|
-
return (initializeResultSet(instance, statement, transaction));
|
590
|
-
}
|
591
|
-
|
592
|
-
/**
|
593
|
-
* This function integrates with the Ruby garbage collector to free all of the
|
594
|
-
* resources for a ResultSet object that is being collected.
|
595
|
-
*
|
596
|
-
* @param handle A pointer to the ResultsHandle structure associated with the
|
597
|
-
* object being collected.
|
598
|
-
*
|
599
|
-
*/
|
600
|
-
void resultSetFree(void *handle) {
|
601
|
-
if(handle) {
|
602
|
-
free(handle);
|
603
|
-
}
|
604
|
-
}
|
605
|
-
|
606
|
-
/**
|
607
|
-
* This function initializes the ResultSet class within the Ruby environment.
|
608
|
-
* The class is established under the module specified to the function.
|
609
|
-
*
|
610
|
-
* @param module A reference to the module to create the class within.
|
611
|
-
*
|
612
|
-
*/
|
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
|
-
|
627
|
-
cResultSet = rb_define_class_under(module, "ResultSet", rb_cObject);
|
628
|
-
rb_define_alloc_func(cResultSet, allocateResultSet);
|
629
|
-
rb_include_module(cResultSet, rb_mEnumerable);
|
630
|
-
rb_define_method(cResultSet, "initialize", initializeResultSet, 2);
|
631
|
-
rb_define_method(cResultSet, "initialize_copy", forbidObjectCopy, 1);
|
632
|
-
rb_define_method(cResultSet, "row_count", getResultSetCount, 0);
|
633
|
-
rb_define_method(cResultSet, "fetch", fetchResultSetEntry, 0);
|
634
|
-
rb_define_method(cResultSet, "close", closeResultSet, 0);
|
635
|
-
rb_define_method(cResultSet, "connection", getResultSetConnection, 0);
|
636
|
-
rb_define_method(cResultSet, "transaction", getResultSetTransaction, 0);
|
637
|
-
rb_define_method(cResultSet, "statement", getResultSetStatement, 0);
|
638
|
-
rb_define_method(cResultSet, "sql", getResultSetSQL, 0);
|
639
|
-
rb_define_method(cResultSet, "dialect", getResultSetDialect, 0);
|
640
|
-
rb_define_method(cResultSet, "each", eachResultSetRow, 0);
|
641
|
-
rb_define_method(cResultSet, "column_name", getResultSetColumnName, 1);
|
642
|
-
rb_define_method(cResultSet, "column_alias", getResultSetColumnAlias, 1);
|
643
|
-
rb_define_method(cResultSet, "column_scale", getResultSetColumnScale, 1);
|
644
|
-
rb_define_method(cResultSet, "column_table", getResultSetColumnTable, 1);
|
645
|
-
rb_define_method(cResultSet, "column_count", getResultSetColumnCount, 0);
|
646
|
-
rb_define_method(cResultSet, "exhausted?", isResultSetExhausted, 0);
|
647
|
-
rb_define_method(cResultSet, "get_base_type", getResultSetColumnType, 1);
|
648
|
-
}
|