rubyfb 0.5.5 → 0.5.6
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/Manifest +0 -1
- data/Rakefile +1 -1
- data/ext/AddUser.c +217 -248
- data/ext/AddUser.h +3 -3
- data/ext/Backup.c +337 -404
- data/ext/Backup.h +3 -3
- data/ext/Blob.c +197 -248
- data/ext/Blob.h +30 -31
- data/ext/Common.c +17 -18
- data/ext/Common.h +10 -10
- data/ext/Connection.c +413 -487
- data/ext/Connection.h +18 -19
- data/ext/DataArea.c +172 -189
- data/ext/DataArea.h +11 -11
- data/ext/Database.c +198 -238
- data/ext/Database.h +16 -17
- data/ext/FireRuby.c +118 -142
- data/ext/FireRuby.h +17 -17
- data/ext/FireRubyException.c +68 -138
- data/ext/FireRubyException.h +14 -21
- data/ext/Generator.c +296 -377
- data/ext/Generator.h +17 -18
- data/ext/RemoveUser.c +91 -102
- data/ext/RemoveUser.h +3 -3
- data/ext/Restore.c +353 -423
- data/ext/Restore.h +3 -3
- data/ext/ResultSet.c +423 -456
- data/ext/ResultSet.h +26 -27
- data/ext/Row.c +505 -568
- data/ext/Row.h +27 -28
- data/ext/ServiceManager.c +143 -164
- data/ext/ServiceManager.h +17 -18
- data/ext/Services.c +58 -67
- data/ext/Services.h +3 -3
- data/ext/Statement.c +388 -449
- data/ext/Statement.h +30 -31
- data/ext/Transaction.c +374 -448
- data/ext/Transaction.h +17 -18
- data/ext/TypeMap.c +654 -774
- data/ext/TypeMap.h +17 -17
- data/ext/rfbint.h +3 -3
- data/lib/active_record/connection_adapters/rubyfb_adapter.rb +1 -1
- data/lib/rubyfb_lib.so +0 -0
- data/lib/src.rb +33 -0
- data/rubyfb.gemspec +3 -3
- data/test/ResultSetTest.rb +13 -0
- data/test/RowTest.rb +16 -0
- metadata +4 -5
- data/test/UnitTest.rb +0 -65
data/ext/ResultSet.c
CHANGED
@@ -3,20 +3,20 @@
|
|
3
3
|
*----------------------------------------------------------------------------*/
|
4
4
|
/**
|
5
5
|
* Copyright � Peter Wood, 2005
|
6
|
-
*
|
6
|
+
*
|
7
7
|
* The contents of this file are subject to the Mozilla Public License Version
|
8
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
|
9
|
+
* License. You may obtain a copy of the License at
|
10
10
|
*
|
11
11
|
* http://www.mozilla.org/MPL/
|
12
|
-
*
|
12
|
+
*
|
13
13
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
14
14
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
15
15
|
* the specificlanguage governing rights and limitations under the License.
|
16
|
-
*
|
16
|
+
*
|
17
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
|
18
|
+
*
|
19
|
+
* The Initial Developer of the Original Code is Peter Wood. All Rights
|
20
20
|
* Reserved.
|
21
21
|
*
|
22
22
|
* @author Peter Wood
|
@@ -47,6 +47,7 @@ static VALUE getResultSetDialect(VALUE);
|
|
47
47
|
static VALUE getResultSetColumnCount(VALUE);
|
48
48
|
static VALUE getResultSetColumnName(VALUE, VALUE);
|
49
49
|
static VALUE getResultSetColumnAlias(VALUE, VALUE);
|
50
|
+
static VALUE getResultSetColumnScale(VALUE, VALUE);
|
50
51
|
static VALUE getResultSetColumnTable(VALUE, VALUE);
|
51
52
|
static VALUE getResultSetColumnType(VALUE, VALUE);
|
52
53
|
static VALUE eachResultSetRow(VALUE);
|
@@ -67,24 +68,22 @@ VALUE cResultSet;
|
|
67
68
|
* @return A reference to the newly allocated ResultSet object.
|
68
69
|
*
|
69
70
|
*/
|
70
|
-
VALUE allocateResultSet(VALUE klass)
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
return(Data_Wrap_Struct(klass, resultSetMark, resultSetFree, results));
|
71
|
+
VALUE allocateResultSet(VALUE klass) {
|
72
|
+
ResultsHandle *results = ALLOC(ResultsHandle);
|
73
|
+
|
74
|
+
if(results == NULL) {
|
75
|
+
rb_raise(rb_eNoMemError,
|
76
|
+
"Memory allocation failure allocating a result set.");
|
77
|
+
}
|
78
|
+
results->handle = 0;
|
79
|
+
results->output = NULL;
|
80
|
+
results->exhausted = 0;
|
81
|
+
results->fetched = 0;
|
82
|
+
results->dialect = 0;
|
83
|
+
results->procedure_output_fetch_state = -1;
|
84
|
+
results->transaction = Qnil;
|
85
|
+
|
86
|
+
return(Data_Wrap_Struct(klass, resultSetMark, resultSetFree, results));
|
88
87
|
}
|
89
88
|
|
90
89
|
|
@@ -107,140 +106,122 @@ VALUE allocateResultSet(VALUE klass)
|
|
107
106
|
*
|
108
107
|
*/
|
109
108
|
VALUE initializeResultSet(VALUE self, VALUE connection, VALUE transaction,
|
110
|
-
VALUE sql, VALUE dialect, VALUE parameters)
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
else
|
146
|
-
{
|
147
|
-
rb_fireruby_raise(NULL, "Invalid transaction specified for result set.");
|
148
|
-
}
|
149
|
-
|
150
|
-
value = rb_funcall(dialect, rb_intern("to_i"), 0);
|
151
|
-
if(TYPE(value) == T_FIXNUM)
|
152
|
-
{
|
153
|
-
setting = FIX2INT(value);
|
154
|
-
if(setting < 1 || setting > 3)
|
155
|
-
{
|
156
|
-
rb_fireruby_raise(NULL,
|
157
|
-
"Invalid dialect value specified for result set. "\
|
158
|
-
"The dialect value must be between 1 and 3.");
|
159
|
-
}
|
160
|
-
}
|
161
|
-
else
|
162
|
-
{
|
109
|
+
VALUE sql, VALUE dialect, VALUE parameters) {
|
110
|
+
short setting = 0;
|
111
|
+
int type = 0,
|
112
|
+
inputs = 0,
|
113
|
+
outputs = 0;
|
114
|
+
long affected = 0;
|
115
|
+
ResultsHandle *results = NULL;
|
116
|
+
VALUE value = Qnil;
|
117
|
+
ConnectionHandle *cHandle = NULL;
|
118
|
+
TransactionHandle *tHandle = NULL;
|
119
|
+
XSQLDA *params = NULL;
|
120
|
+
|
121
|
+
/* Validate the inputs. */
|
122
|
+
if(TYPE(connection) == T_DATA &&
|
123
|
+
RDATA(connection)->dfree == (RUBY_DATA_FUNC)connectionFree) {
|
124
|
+
if(rb_funcall(connection, rb_intern("open?"), 0) == Qfalse) {
|
125
|
+
rb_fireruby_raise(NULL, "Closed connection specified for result set.");
|
126
|
+
}
|
127
|
+
} else {
|
128
|
+
rb_fireruby_raise(NULL, "Invalid connection specified for result set.");
|
129
|
+
}
|
130
|
+
|
131
|
+
if(TYPE(transaction) == T_DATA &&
|
132
|
+
RDATA(transaction)->dfree == (RUBY_DATA_FUNC)transactionFree) {
|
133
|
+
if(rb_funcall(transaction, rb_intern("active?"), 0) == Qfalse) {
|
134
|
+
rb_fireruby_raise(NULL, "Inactive transaction specified for result set.");
|
135
|
+
}
|
136
|
+
} else {
|
137
|
+
rb_fireruby_raise(NULL, "Invalid transaction specified for result set.");
|
138
|
+
}
|
139
|
+
|
140
|
+
value = rb_funcall(dialect, rb_intern("to_i"), 0);
|
141
|
+
if(TYPE(value) == T_FIXNUM) {
|
142
|
+
setting = FIX2INT(value);
|
143
|
+
if(setting < 1 || setting > 3) {
|
163
144
|
rb_fireruby_raise(NULL,
|
164
|
-
"Invalid dialect value specified for result set.
|
165
|
-
"dialect value must be between 1 and 3.");
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
145
|
+
"Invalid dialect value specified for result set. " \
|
146
|
+
"The dialect value must be between 1 and 3.");
|
147
|
+
}
|
148
|
+
} else {
|
149
|
+
rb_fireruby_raise(NULL,
|
150
|
+
"Invalid dialect value specified for result set. The " \
|
151
|
+
"dialect value must be between 1 and 3.");
|
152
|
+
}
|
153
|
+
|
154
|
+
/* Prepare the result set. */
|
155
|
+
Data_Get_Struct(connection, ConnectionHandle, cHandle);
|
156
|
+
Data_Get_Struct(transaction, TransactionHandle, tHandle);
|
157
|
+
Data_Get_Struct(self, ResultsHandle, results);
|
158
|
+
prepare(&cHandle->handle, &tHandle->handle, StringValuePtr(sql), &results->handle,
|
159
|
+
setting, &type, &inputs, &outputs);
|
160
|
+
|
161
|
+
if(type != isc_info_sql_stmt_select &&
|
162
|
+
type != isc_info_sql_stmt_select_for_upd &&
|
163
|
+
type != isc_info_sql_stmt_exec_procedure) {
|
164
|
+
cleanupHandle(&results->handle);
|
165
|
+
rb_fireruby_raise(NULL,
|
166
|
+
"Non-query SQL statement specified for result set.");
|
167
|
+
}
|
168
|
+
|
169
|
+
rb_iv_set(self, "@connection", connection);
|
170
|
+
rb_iv_set(self, "@transaction", transaction);
|
171
|
+
rb_iv_set(self, "@sql", rb_funcall(sql, rb_intern("to_s"), 0));
|
172
|
+
rb_iv_set(self, "@dialect", value);
|
173
|
+
results->dialect = setting;
|
174
|
+
|
175
|
+
/* UNCOMMENT FOR DEBUGGING PURPOSES! */
|
176
|
+
/*strcpy(results->sql, StringValuePtr(sql));*/
|
177
|
+
|
178
|
+
/* Check if input parameters are needed. */
|
179
|
+
if(inputs > 0) {
|
180
|
+
VALUE value = Qnil;
|
181
|
+
int size = 0;
|
182
|
+
|
183
|
+
if(parameters == Qnil) {
|
179
184
|
cleanupHandle(&results->handle);
|
180
185
|
rb_fireruby_raise(NULL,
|
181
|
-
"
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
/* Allocate output storage. */
|
222
|
-
results->output = allocateOutXSQLDA(outputs, &results->handle, setting);
|
223
|
-
prepareDataArea(results->output);
|
224
|
-
|
225
|
-
/* Execute the statement and clean up. */
|
226
|
-
if(type == isc_info_sql_stmt_exec_procedure) {
|
227
|
-
/* Execute with output params */
|
228
|
-
execute_2(&tHandle->handle, &results->handle, setting, params, type,
|
229
|
-
&affected, results->output);
|
230
|
-
/* Initialize procedure output fetch */
|
231
|
-
results->procedure_output_fetch_state = 0;
|
232
|
-
/* Early resolve transaction */
|
233
|
-
resolveResultsTransaction (results, "commit");
|
234
|
-
} else {
|
235
|
-
execute(&tHandle->handle, &results->handle, setting, params, type,
|
236
|
-
&affected);
|
237
|
-
}
|
238
|
-
if(params != NULL)
|
239
|
-
{
|
240
|
-
releaseDataArea(params);
|
241
|
-
}
|
242
|
-
|
243
|
-
return(self);
|
186
|
+
"Empty parameter list specified for result set.");
|
187
|
+
}
|
188
|
+
|
189
|
+
value = rb_funcall(parameters, rb_intern("size"), 0);
|
190
|
+
size = TYPE(value) == T_FIXNUM ? FIX2INT(value) : NUM2INT(value);
|
191
|
+
if(size < inputs) {
|
192
|
+
cleanupHandle(&results->handle);
|
193
|
+
rb_fireruby_raise(NULL,
|
194
|
+
"Insufficient parameters specified for result set.");
|
195
|
+
}
|
196
|
+
|
197
|
+
/* Allocate the XSQLDA and populate it. */
|
198
|
+
params = allocateInXSQLDA(inputs, &results->handle, setting);
|
199
|
+
prepareDataArea(params);
|
200
|
+
setParameters(params, parameters, self);
|
201
|
+
}
|
202
|
+
|
203
|
+
/* Allocate output storage. */
|
204
|
+
results->output = allocateOutXSQLDA(outputs, &results->handle, setting);
|
205
|
+
prepareDataArea(results->output);
|
206
|
+
|
207
|
+
/* Execute the statement and clean up. */
|
208
|
+
if(type == isc_info_sql_stmt_exec_procedure) {
|
209
|
+
/* Execute with output params */
|
210
|
+
execute_2(&tHandle->handle, &results->handle, setting, params, type,
|
211
|
+
&affected, results->output);
|
212
|
+
/* Initialize procedure output fetch */
|
213
|
+
results->procedure_output_fetch_state = 0;
|
214
|
+
/* Early resolve transaction */
|
215
|
+
resolveResultsTransaction (results, "commit");
|
216
|
+
} else {
|
217
|
+
execute(&tHandle->handle, &results->handle, setting, params, type,
|
218
|
+
&affected);
|
219
|
+
}
|
220
|
+
if(params != NULL) {
|
221
|
+
releaseDataArea(params);
|
222
|
+
}
|
223
|
+
|
224
|
+
return(self);
|
244
225
|
}
|
245
226
|
|
246
227
|
|
@@ -252,44 +233,41 @@ VALUE initializeResultSet(VALUE self, VALUE connection, VALUE transaction,
|
|
252
233
|
* @return Either a reference to a Row object or nil.
|
253
234
|
*
|
254
235
|
*/
|
255
|
-
VALUE fetchResultSetEntry(VALUE self)
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
}
|
291
|
-
|
292
|
-
return(row);
|
236
|
+
VALUE fetchResultSetEntry(VALUE self) {
|
237
|
+
VALUE row = Qnil;
|
238
|
+
ResultsHandle *results = NULL;
|
239
|
+
ISC_STATUS status[ISC_STATUS_LENGTH],
|
240
|
+
value;
|
241
|
+
|
242
|
+
Data_Get_Struct(self, ResultsHandle, results);
|
243
|
+
if(results->handle != 0) {
|
244
|
+
VALUE array,number;
|
245
|
+
value = results->procedure_output_fetch_state;
|
246
|
+
if(value < 0) {
|
247
|
+
value = isc_dsql_fetch(status, &results->handle, results->dialect,
|
248
|
+
results->output);
|
249
|
+
} else {
|
250
|
+
/* move procedure_output_fetch_state ahead - fetch only one row */
|
251
|
+
results->procedure_output_fetch_state = 100;
|
252
|
+
}
|
253
|
+
array = Qnil;
|
254
|
+
number = Qnil;
|
255
|
+
switch(value) {
|
256
|
+
case 0:
|
257
|
+
array = toArray(self);
|
258
|
+
number = INT2NUM(++(results->fetched));
|
259
|
+
row = rb_row_new(self, array, number);
|
260
|
+
break;
|
261
|
+
case 100:
|
262
|
+
results->exhausted = 1;
|
263
|
+
resolveResultsTransaction(results, "commit");
|
264
|
+
break;
|
265
|
+
default:
|
266
|
+
rb_fireruby_raise(status, "Error fetching query row.");
|
267
|
+
}
|
268
|
+
}
|
269
|
+
|
270
|
+
return(row);
|
293
271
|
}
|
294
272
|
|
295
273
|
|
@@ -302,31 +280,27 @@ VALUE fetchResultSetEntry(VALUE self)
|
|
302
280
|
* @return A reference to the closed ResultSet object.
|
303
281
|
*
|
304
282
|
*/
|
305
|
-
VALUE closeResultSet(VALUE self)
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
resolveResultsTransaction(results, "commit");
|
328
|
-
|
329
|
-
return(self);
|
283
|
+
VALUE closeResultSet(VALUE self) {
|
284
|
+
ResultsHandle *results = NULL;
|
285
|
+
|
286
|
+
Data_Get_Struct(self, ResultsHandle, results);
|
287
|
+
if(results->handle != 0) {
|
288
|
+
ISC_STATUS status[ISC_STATUS_LENGTH];
|
289
|
+
|
290
|
+
if(isc_dsql_free_statement(status, &results->handle, DSQL_drop)) {
|
291
|
+
rb_fireruby_raise(status, "Error closing result set.");
|
292
|
+
}
|
293
|
+
results->handle = 0;
|
294
|
+
}
|
295
|
+
|
296
|
+
if(results->output != NULL) {
|
297
|
+
releaseDataArea(results->output);
|
298
|
+
results->output = NULL;
|
299
|
+
}
|
300
|
+
|
301
|
+
resolveResultsTransaction(results, "commit");
|
302
|
+
|
303
|
+
return(self);
|
330
304
|
}
|
331
305
|
|
332
306
|
|
@@ -340,13 +314,12 @@ VALUE closeResultSet(VALUE self)
|
|
340
314
|
* fetched from the ResultSet so far.
|
341
315
|
*
|
342
316
|
*/
|
343
|
-
VALUE getResultSetCount(VALUE self)
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
return(INT2NUM(results->fetched));
|
317
|
+
VALUE getResultSetCount(VALUE self) {
|
318
|
+
ResultsHandle *results = NULL;
|
319
|
+
|
320
|
+
Data_Get_Struct(self, ResultsHandle, results);
|
321
|
+
|
322
|
+
return(INT2NUM(results->fetched));
|
350
323
|
}
|
351
324
|
|
352
325
|
|
@@ -360,9 +333,8 @@ VALUE getResultSetCount(VALUE self)
|
|
360
333
|
* @return A reference to the requested attribute object.
|
361
334
|
*
|
362
335
|
*/
|
363
|
-
VALUE getResultSetConnection(VALUE self)
|
364
|
-
|
365
|
-
return(rb_iv_get(self, "@connection"));
|
336
|
+
VALUE getResultSetConnection(VALUE self) {
|
337
|
+
return(rb_iv_get(self, "@connection"));
|
366
338
|
}
|
367
339
|
|
368
340
|
|
@@ -376,9 +348,8 @@ VALUE getResultSetConnection(VALUE self)
|
|
376
348
|
* @return A reference to the requested attribute object.
|
377
349
|
*
|
378
350
|
*/
|
379
|
-
VALUE getResultSetTransaction(VALUE self)
|
380
|
-
|
381
|
-
return(rb_iv_get(self, "@transaction"));
|
351
|
+
VALUE getResultSetTransaction(VALUE self) {
|
352
|
+
return(rb_iv_get(self, "@transaction"));
|
382
353
|
}
|
383
354
|
|
384
355
|
|
@@ -391,9 +362,8 @@ VALUE getResultSetTransaction(VALUE self)
|
|
391
362
|
* @return A reference to the requested attribute object.
|
392
363
|
*
|
393
364
|
*/
|
394
|
-
VALUE getResultSetSQL(VALUE self)
|
395
|
-
|
396
|
-
return(rb_iv_get(self, "@sql"));
|
365
|
+
VALUE getResultSetSQL(VALUE self) {
|
366
|
+
return(rb_iv_get(self, "@sql"));
|
397
367
|
}
|
398
368
|
|
399
369
|
|
@@ -406,9 +376,8 @@ VALUE getResultSetSQL(VALUE self)
|
|
406
376
|
* @return A reference to the requested attribute object.
|
407
377
|
*
|
408
378
|
*/
|
409
|
-
VALUE getResultSetDialect(VALUE self)
|
410
|
-
|
411
|
-
return(rb_iv_get(self, "@dialect"));
|
379
|
+
VALUE getResultSetDialect(VALUE self) {
|
380
|
+
return(rb_iv_get(self, "@dialect"));
|
412
381
|
}
|
413
382
|
|
414
383
|
|
@@ -421,18 +390,16 @@ VALUE getResultSetDialect(VALUE self)
|
|
421
390
|
* @return A reference to an integer containing the column count.
|
422
391
|
*
|
423
392
|
*/
|
424
|
-
VALUE getResultSetColumnCount(VALUE self)
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
return(count);
|
393
|
+
VALUE getResultSetColumnCount(VALUE self) {
|
394
|
+
VALUE count = Qnil;
|
395
|
+
ResultsHandle *results = NULL;
|
396
|
+
|
397
|
+
Data_Get_Struct(self, ResultsHandle, results);
|
398
|
+
if(results != NULL) {
|
399
|
+
count = INT2NUM(results->output->sqld);
|
400
|
+
}
|
401
|
+
|
402
|
+
return(count);
|
436
403
|
}
|
437
404
|
|
438
405
|
|
@@ -447,28 +414,25 @@ VALUE getResultSetColumnCount(VALUE self)
|
|
447
414
|
* was specified.
|
448
415
|
*
|
449
416
|
*/
|
450
|
-
static VALUE getResultSetColumnName(VALUE self, VALUE column)
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
}
|
470
|
-
|
471
|
-
return(name);
|
417
|
+
static VALUE getResultSetColumnName(VALUE self, VALUE column) {
|
418
|
+
VALUE name = Qnil;
|
419
|
+
ResultsHandle *results = NULL;
|
420
|
+
|
421
|
+
Data_Get_Struct(self, ResultsHandle, results);
|
422
|
+
if(results != NULL) {
|
423
|
+
int offset = 0;
|
424
|
+
|
425
|
+
offset = (TYPE(column) == T_FIXNUM ? FIX2INT(column) : NUM2INT(column));
|
426
|
+
if(offset >= 0 && offset < results->output->sqld) {
|
427
|
+
XSQLVAR *var = results->output->sqlvar;
|
428
|
+
int index;
|
429
|
+
|
430
|
+
for(index = 0; index < offset; index++, var++) ;
|
431
|
+
name = rb_str_new(var->sqlname, var->sqlname_length);
|
432
|
+
}
|
433
|
+
}
|
434
|
+
|
435
|
+
return(name);
|
472
436
|
}
|
473
437
|
|
474
438
|
|
@@ -483,28 +447,57 @@ static VALUE getResultSetColumnName(VALUE self, VALUE column)
|
|
483
447
|
* was specified.
|
484
448
|
*
|
485
449
|
*/
|
486
|
-
static VALUE getResultSetColumnAlias(VALUE self, VALUE column)
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
450
|
+
static VALUE getResultSetColumnAlias(VALUE self, VALUE column) {
|
451
|
+
VALUE alias = Qnil;
|
452
|
+
ResultsHandle *results = NULL;
|
453
|
+
|
454
|
+
Data_Get_Struct(self, ResultsHandle, results);
|
455
|
+
if(results != NULL) {
|
456
|
+
int offset = 0;
|
457
|
+
|
458
|
+
offset = (TYPE(column) == T_FIXNUM ? FIX2INT(column) : NUM2INT(column));
|
459
|
+
if(offset >= 0 && offset < results->output->sqld) {
|
460
|
+
XSQLVAR *var = results->output->sqlvar;
|
461
|
+
int index;
|
462
|
+
|
463
|
+
for(index = 0; index < offset; index++, var++) ;
|
464
|
+
alias = rb_str_new(var->aliasname, var->aliasname_length);
|
465
|
+
}
|
466
|
+
}
|
467
|
+
|
468
|
+
return(alias);
|
469
|
+
}
|
470
|
+
|
471
|
+
/**
|
472
|
+
* This function provides the column_scale method for the ResultSet class.
|
473
|
+
*
|
474
|
+
* @param self A reference to the ResultSet object to retrieve the column
|
475
|
+
* alias from.
|
476
|
+
* @param column An offset to the column to retrieve the scale of.
|
477
|
+
*
|
478
|
+
* @return An Integer representing the sqlscale of the column, or nil if an
|
479
|
+
* invalid column was specified.
|
480
|
+
*
|
481
|
+
*/
|
482
|
+
static VALUE getResultSetColumnScale(VALUE self, VALUE column) {
|
483
|
+
VALUE scale = Qnil;
|
484
|
+
ResultsHandle *results = NULL;
|
485
|
+
|
486
|
+
Data_Get_Struct(self, ResultsHandle, results);
|
487
|
+
if(results != NULL) {
|
488
|
+
int offset = 0;
|
489
|
+
|
490
|
+
offset = (TYPE(column) == T_FIXNUM ? FIX2INT(column) : NUM2INT(column));
|
491
|
+
if(offset >= 0 && offset < results->output->sqld) {
|
492
|
+
XSQLVAR *var = results->output->sqlvar;
|
493
|
+
int index;
|
494
|
+
|
495
|
+
for(index = 0; index < offset; index++, var++) ;
|
496
|
+
scale = INT2FIX(var->sqlscale);
|
497
|
+
}
|
498
|
+
}
|
499
|
+
|
500
|
+
return(scale);
|
508
501
|
}
|
509
502
|
|
510
503
|
|
@@ -519,28 +512,25 @@ static VALUE getResultSetColumnAlias(VALUE self, VALUE column)
|
|
519
512
|
* column was specified.
|
520
513
|
*
|
521
514
|
*/
|
522
|
-
static VALUE getResultSetColumnTable(VALUE self, VALUE column)
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
}
|
542
|
-
|
543
|
-
return(name);
|
515
|
+
static VALUE getResultSetColumnTable(VALUE self, VALUE column) {
|
516
|
+
VALUE name = Qnil;
|
517
|
+
ResultsHandle *results = NULL;
|
518
|
+
|
519
|
+
Data_Get_Struct(self, ResultsHandle, results);
|
520
|
+
if(results != NULL) {
|
521
|
+
int offset = 0;
|
522
|
+
|
523
|
+
offset = (TYPE(column) == T_FIXNUM ? FIX2INT(column) : NUM2INT(column));
|
524
|
+
if(offset >= 0 && offset < results->output->sqld) {
|
525
|
+
XSQLVAR *var = results->output->sqlvar;
|
526
|
+
int index;
|
527
|
+
|
528
|
+
for(index = 0; index < offset; index++, var++) ;
|
529
|
+
name = rb_str_new(var->relname, var->relname_length);
|
530
|
+
}
|
531
|
+
}
|
532
|
+
|
533
|
+
return(name);
|
544
534
|
}
|
545
535
|
|
546
536
|
|
@@ -554,34 +544,29 @@ static VALUE getResultSetColumnTable(VALUE self, VALUE column)
|
|
554
544
|
* @return A Symbol representing the basic data type.
|
555
545
|
*
|
556
546
|
*/
|
557
|
-
static VALUE getResultSetColumnType(VALUE self, VALUE column)
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
/* Fix negative index values. */
|
571
|
-
if(index < 0)
|
572
|
-
{
|
573
|
-
index = handle->output->sqln + index;
|
574
|
-
}
|
575
|
-
|
576
|
-
if(index >= 0 && index < handle->output->sqln)
|
577
|
-
{
|
578
|
-
type = getColumnType(&handle->output->sqlvar[index]);
|
579
|
-
}
|
547
|
+
static VALUE getResultSetColumnType(VALUE self, VALUE column) {
|
548
|
+
VALUE type = toSymbol("UNKNOWN");
|
549
|
+
|
550
|
+
if(TYPE(column) == T_FIXNUM) {
|
551
|
+
ResultsHandle *handle = NULL;
|
552
|
+
|
553
|
+
Data_Get_Struct(self, ResultsHandle, handle);
|
554
|
+
if(handle != NULL) {
|
555
|
+
int index = FIX2INT(column);
|
556
|
+
|
557
|
+
/* Fix negative index values. */
|
558
|
+
if(index < 0) {
|
559
|
+
index = handle->output->sqln + index;
|
580
560
|
}
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
561
|
+
|
562
|
+
if(index >= 0 && index < handle->output->sqln) {
|
563
|
+
type = getColumnType(&handle->output->sqlvar[index]);
|
564
|
+
}
|
565
|
+
}
|
566
|
+
}
|
567
|
+
|
568
|
+
|
569
|
+
return(type);
|
585
570
|
}
|
586
571
|
|
587
572
|
|
@@ -594,22 +579,19 @@ static VALUE getResultSetColumnType(VALUE self, VALUE column)
|
|
594
579
|
* nil.
|
595
580
|
*
|
596
581
|
*/
|
597
|
-
VALUE eachResultSetRow(VALUE self)
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
}
|
611
|
-
|
612
|
-
return(result);
|
582
|
+
VALUE eachResultSetRow(VALUE self) {
|
583
|
+
VALUE result = Qnil;
|
584
|
+
|
585
|
+
/* Check if a block was provided. */
|
586
|
+
if(rb_block_given_p()) {
|
587
|
+
VALUE row;
|
588
|
+
|
589
|
+
while((row = fetchResultSetEntry(self)) != Qnil) {
|
590
|
+
result = rb_yield(row);
|
591
|
+
}
|
592
|
+
}
|
593
|
+
|
594
|
+
return(result);
|
613
595
|
}
|
614
596
|
|
615
597
|
|
@@ -622,18 +604,16 @@ VALUE eachResultSetRow(VALUE self)
|
|
622
604
|
* if they haven't.
|
623
605
|
*
|
624
606
|
*/
|
625
|
-
VALUE isResultSetExhausted(VALUE self)
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
return(exhausted);
|
607
|
+
VALUE isResultSetExhausted(VALUE self) {
|
608
|
+
VALUE exhausted = Qfalse;
|
609
|
+
ResultsHandle *results = NULL;
|
610
|
+
|
611
|
+
Data_Get_Struct(self, ResultsHandle, results);
|
612
|
+
if(results->exhausted) {
|
613
|
+
exhausted = Qtrue;
|
614
|
+
}
|
615
|
+
|
616
|
+
return(exhausted);
|
637
617
|
}
|
638
618
|
|
639
619
|
|
@@ -646,17 +626,14 @@ VALUE isResultSetExhausted(VALUE self)
|
|
646
626
|
* being scanned by the garbage collector.
|
647
627
|
*
|
648
628
|
*/
|
649
|
-
void resultSetMark(void *handle)
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
rb_gc_mark(results->transaction);
|
658
|
-
}
|
659
|
-
}
|
629
|
+
void resultSetMark(void *handle) {
|
630
|
+
ResultsHandle *results = (ResultsHandle *)handle;
|
631
|
+
|
632
|
+
if(results != NULL) {
|
633
|
+
if(results->transaction != Qnil) {
|
634
|
+
rb_gc_mark(results->transaction);
|
635
|
+
}
|
636
|
+
}
|
660
637
|
}
|
661
638
|
|
662
639
|
|
@@ -678,14 +655,13 @@ void resultSetMark(void *handle)
|
|
678
655
|
*
|
679
656
|
*/
|
680
657
|
VALUE rb_result_set_new(VALUE connection, VALUE transaction, VALUE sql,
|
681
|
-
VALUE dialect, VALUE parameters)
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
return(instance);
|
658
|
+
VALUE dialect, VALUE parameters) {
|
659
|
+
VALUE instance = allocateResultSet(cResultSet);
|
660
|
+
|
661
|
+
initializeResultSet(instance, connection, transaction, sql, dialect,
|
662
|
+
parameters);
|
663
|
+
|
664
|
+
return(instance);
|
689
665
|
}
|
690
666
|
|
691
667
|
|
@@ -699,12 +675,11 @@ VALUE rb_result_set_new(VALUE connection, VALUE transaction, VALUE sql,
|
|
699
675
|
* is assuming responsibility for.
|
700
676
|
*
|
701
677
|
*/
|
702
|
-
void rb_assign_transaction(VALUE set, VALUE transaction)
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
results->transaction = transaction;
|
678
|
+
void rb_assign_transaction(VALUE set, VALUE transaction) {
|
679
|
+
ResultsHandle *results = NULL;
|
680
|
+
|
681
|
+
Data_Get_Struct(set, ResultsHandle, results);
|
682
|
+
results->transaction = transaction;
|
708
683
|
}
|
709
684
|
|
710
685
|
|
@@ -716,29 +691,25 @@ void rb_assign_transaction(VALUE set, VALUE transaction)
|
|
716
691
|
* object being collected.
|
717
692
|
*
|
718
693
|
*/
|
719
|
-
void resultSetFree(void *handle)
|
720
|
-
{
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
resolveResultsTransaction(results, "rollback");
|
740
|
-
free(results);
|
741
|
-
}
|
694
|
+
void resultSetFree(void *handle) {
|
695
|
+
if(handle != NULL) {
|
696
|
+
ResultsHandle *results = (ResultsHandle *)handle;
|
697
|
+
|
698
|
+
if(results->handle != 0) {
|
699
|
+
ISC_STATUS status[ISC_STATUS_LENGTH];
|
700
|
+
|
701
|
+
/* UNCOMMENT FOR DEBUG PURPOSES! */
|
702
|
+
/*fprintf(stderr, "Releasing statement handle for...\n%s\n", results->sql);*/
|
703
|
+
isc_dsql_free_statement(status, &results->handle, DSQL_drop);
|
704
|
+
}
|
705
|
+
|
706
|
+
if(results->output != NULL) {
|
707
|
+
releaseDataArea(results->output);
|
708
|
+
}
|
709
|
+
|
710
|
+
resolveResultsTransaction(results, "rollback");
|
711
|
+
free(results);
|
712
|
+
}
|
742
713
|
}
|
743
714
|
|
744
715
|
|
@@ -748,16 +719,14 @@ void resultSetFree(void *handle)
|
|
748
719
|
* @param handle A pointer to the statement handle to be cleaned up.
|
749
720
|
*
|
750
721
|
*/
|
751
|
-
void cleanupHandle(isc_stmt_handle *handle)
|
752
|
-
{
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
isc_dsql_free_statement(status, handle, DSQL_drop);
|
760
|
-
}
|
722
|
+
void cleanupHandle(isc_stmt_handle *handle) {
|
723
|
+
if(*handle != 0) {
|
724
|
+
ISC_STATUS status[ISC_STATUS_LENGTH];
|
725
|
+
|
726
|
+
/* UNCOMMENT FOR DEBUG PURPOSES! */
|
727
|
+
/*fprintf(stderr, "Cleaning up a statement handle.\n");*/
|
728
|
+
isc_dsql_free_statement(status, handle, DSQL_drop);
|
729
|
+
}
|
761
730
|
}
|
762
731
|
|
763
732
|
|
@@ -769,13 +738,11 @@ void cleanupHandle(isc_stmt_handle *handle)
|
|
769
738
|
* @param resolveMethod - transaction resolving method - eg. commit, rollback
|
770
739
|
*
|
771
740
|
*/
|
772
|
-
void resolveResultsTransaction(ResultsHandle *results, char *resolveMethod)
|
773
|
-
{
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
results->transaction = Qnil;
|
778
|
-
}
|
741
|
+
void resolveResultsTransaction(ResultsHandle *results, char *resolveMethod) {
|
742
|
+
if(results->transaction != Qnil) {
|
743
|
+
rb_funcall(results->transaction, rb_intern(resolveMethod), 0);
|
744
|
+
results->transaction = Qnil;
|
745
|
+
}
|
779
746
|
}
|
780
747
|
|
781
748
|
|
@@ -786,25 +753,25 @@ void resolveResultsTransaction(ResultsHandle *results, char *resolveMethod)
|
|
786
753
|
* @param module A reference to the module to create the class within.
|
787
754
|
*
|
788
755
|
*/
|
789
|
-
void Init_ResultSet(VALUE module)
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
756
|
+
void Init_ResultSet(VALUE module) {
|
757
|
+
cResultSet = rb_define_class_under(module, "ResultSet", rb_cObject);
|
758
|
+
rb_define_alloc_func(cResultSet, allocateResultSet);
|
759
|
+
rb_include_module(cResultSet, rb_mEnumerable);
|
760
|
+
rb_define_method(cResultSet, "initialize", initializeResultSet, 5);
|
761
|
+
rb_define_method(cResultSet, "initialize_copy", forbidObjectCopy, 1);
|
762
|
+
rb_define_method(cResultSet, "row_count", getResultSetCount, 0);
|
763
|
+
rb_define_method(cResultSet, "fetch", fetchResultSetEntry, 0);
|
764
|
+
rb_define_method(cResultSet, "close", closeResultSet, 0);
|
765
|
+
rb_define_method(cResultSet, "connection", getResultSetConnection, 0);
|
766
|
+
rb_define_method(cResultSet, "transaction", getResultSetTransaction, 0);
|
767
|
+
rb_define_method(cResultSet, "sql", getResultSetSQL, 0);
|
768
|
+
rb_define_method(cResultSet, "dialect", getResultSetDialect, 0);
|
769
|
+
rb_define_method(cResultSet, "each", eachResultSetRow, 0);
|
770
|
+
rb_define_method(cResultSet, "column_name", getResultSetColumnName, 1);
|
771
|
+
rb_define_method(cResultSet, "column_alias", getResultSetColumnAlias, 1);
|
772
|
+
rb_define_method(cResultSet, "column_scale", getResultSetColumnScale, 1);
|
773
|
+
rb_define_method(cResultSet, "column_table", getResultSetColumnTable, 1);
|
774
|
+
rb_define_method(cResultSet, "column_count", getResultSetColumnCount, 0);
|
775
|
+
rb_define_method(cResultSet, "exhausted?", isResultSetExhausted, 0);
|
776
|
+
rb_define_method(cResultSet, "get_base_type", getResultSetColumnType, 1);
|
810
777
|
}
|