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/Connection.c
CHANGED
@@ -64,24 +64,20 @@ VALUE cConnection;
|
|
64
64
|
* @return A reference to the newly created instance.
|
65
65
|
*
|
66
66
|
*/
|
67
|
-
static VALUE allocateConnection(VALUE klass)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
"Memory allocation failure creating a connection.");
|
82
|
-
}
|
83
|
-
|
84
|
-
return(instance);
|
67
|
+
static VALUE allocateConnection(VALUE klass) {
|
68
|
+
VALUE instance = Qnil;
|
69
|
+
ConnectionHandle *connection = ALLOC(ConnectionHandle);
|
70
|
+
|
71
|
+
if(connection != NULL) {
|
72
|
+
/* Wrap the structure in a class. */
|
73
|
+
connection->handle = 0;
|
74
|
+
instance = Data_Wrap_Struct(klass, NULL, connectionFree, connection);
|
75
|
+
} else {
|
76
|
+
rb_raise(rb_eNoMemError,
|
77
|
+
"Memory allocation failure creating a connection.");
|
78
|
+
}
|
79
|
+
|
80
|
+
return(instance);
|
85
81
|
}
|
86
82
|
|
87
83
|
|
@@ -97,65 +93,58 @@ static VALUE allocateConnection(VALUE klass)
|
|
97
93
|
* @return A reference to the initialized object.
|
98
94
|
*
|
99
95
|
*/
|
100
|
-
static VALUE initializeConnection(int argc, VALUE *argv, VALUE self)
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
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
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
/* Store connection attributes. */
|
154
|
-
rb_iv_set(self, "@database", argv[0]);
|
155
|
-
rb_iv_set(self, "@user", user);
|
156
|
-
rb_iv_set(self, "@transactions", rb_ary_new());
|
157
|
-
|
158
|
-
return(self);
|
96
|
+
static VALUE initializeConnection(int argc, VALUE *argv, VALUE self) {
|
97
|
+
ConnectionHandle *connection = NULL;
|
98
|
+
ISC_STATUS status[ISC_STATUS_LENGTH], attach_result;
|
99
|
+
short length = 0;
|
100
|
+
char *file = NULL,
|
101
|
+
*dpb = NULL;
|
102
|
+
VALUE user = Qnil,
|
103
|
+
password = Qnil,
|
104
|
+
options = Qnil,
|
105
|
+
tmp_str = Qnil;
|
106
|
+
|
107
|
+
if(argc < 1) {
|
108
|
+
rb_raise(rb_eArgError, "Wrong number of arguments (%d for %d).", argc, 1);
|
109
|
+
}
|
110
|
+
|
111
|
+
if(TYPE(argv[0]) != T_DATA ||
|
112
|
+
RDATA(argv[0])->dfree != (RUBY_DATA_FUNC)databaseFree) {
|
113
|
+
rb_fireruby_raise(NULL, "Invalid database specified for connection.");
|
114
|
+
}
|
115
|
+
|
116
|
+
tmp_str = rb_iv_get(argv[0], "@file");
|
117
|
+
file = StringValuePtr(tmp_str);
|
118
|
+
|
119
|
+
Data_Get_Struct(self, ConnectionHandle, connection);
|
120
|
+
|
121
|
+
/* Extract parameters. */
|
122
|
+
if(argc > 1) {
|
123
|
+
user = argv[1];
|
124
|
+
}
|
125
|
+
if(argc > 2) {
|
126
|
+
password = argv[2];
|
127
|
+
}
|
128
|
+
if(argc > 3) {
|
129
|
+
options = argv[3];
|
130
|
+
}
|
131
|
+
|
132
|
+
/* Open the connection connection. */
|
133
|
+
dpb = createDPB(user, password, options, &length);
|
134
|
+
attach_result = isc_attach_database(status, strlen(file), file, &connection->handle, length, dpb);
|
135
|
+
free(dpb);
|
136
|
+
|
137
|
+
if(attach_result != 0) {
|
138
|
+
/* Generate an error. */
|
139
|
+
rb_fireruby_raise(status, "Error opening database connection.");
|
140
|
+
}
|
141
|
+
|
142
|
+
/* Store connection attributes. */
|
143
|
+
rb_iv_set(self, "@database", argv[0]);
|
144
|
+
rb_iv_set(self, "@user", user);
|
145
|
+
rb_iv_set(self, "@transactions", rb_ary_new());
|
146
|
+
|
147
|
+
return(self);
|
159
148
|
}
|
160
149
|
|
161
150
|
|
@@ -167,18 +156,16 @@ static VALUE initializeConnection(int argc, VALUE *argv, VALUE self)
|
|
167
156
|
* @return Qtrue if the connection is open, Qfalse if it is closed.
|
168
157
|
*
|
169
158
|
*/
|
170
|
-
static VALUE isConnectionOpen(VALUE self)
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
return(result);
|
159
|
+
static VALUE isConnectionOpen(VALUE self) {
|
160
|
+
VALUE result = Qfalse;
|
161
|
+
ConnectionHandle *connection = NULL;
|
162
|
+
|
163
|
+
Data_Get_Struct(self, ConnectionHandle, connection);
|
164
|
+
if(connection->handle != 0) {
|
165
|
+
result = Qtrue;
|
166
|
+
}
|
167
|
+
|
168
|
+
return(result);
|
182
169
|
}
|
183
170
|
|
184
171
|
|
@@ -190,9 +177,8 @@ static VALUE isConnectionOpen(VALUE self)
|
|
190
177
|
* @return Qtrue if the connection is closed, Qfalse if it is open.
|
191
178
|
*
|
192
179
|
*/
|
193
|
-
static VALUE isConnectionClosed(VALUE self)
|
194
|
-
|
195
|
-
return(isConnectionOpen(self) == Qtrue ? Qfalse : Qtrue);
|
180
|
+
static VALUE isConnectionClosed(VALUE self) {
|
181
|
+
return(isConnectionOpen(self) == Qtrue ? Qfalse : Qtrue);
|
196
182
|
}
|
197
183
|
|
198
184
|
|
@@ -205,43 +191,36 @@ static VALUE isConnectionClosed(VALUE self)
|
|
205
191
|
* if the method is called on a closed Connection.
|
206
192
|
*
|
207
193
|
*/
|
208
|
-
static VALUE closeConnection(VALUE self)
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
{
|
223
|
-
|
224
|
-
|
225
|
-
if(active == Qtrue)
|
226
|
-
{
|
227
|
-
rb_funcall(transaction, rb_intern("rollback"), 0);
|
228
|
-
}
|
194
|
+
static VALUE closeConnection(VALUE self) {
|
195
|
+
VALUE result = Qnil;
|
196
|
+
ConnectionHandle *connection = NULL;
|
197
|
+
|
198
|
+
Data_Get_Struct(self, ConnectionHandle, connection);
|
199
|
+
if(connection->handle != 0) {
|
200
|
+
VALUE transactions = rb_iv_get(self, "@transactions"),
|
201
|
+
transaction = Qnil;
|
202
|
+
ISC_STATUS status[ISC_STATUS_LENGTH];
|
203
|
+
|
204
|
+
/* Roll back an outstanding transactions. */
|
205
|
+
while((transaction = rb_ary_pop(transactions)) != Qnil) {
|
206
|
+
VALUE active = rb_funcall(transaction, rb_intern("active?"), 0);
|
207
|
+
|
208
|
+
if(active == Qtrue) {
|
209
|
+
rb_funcall(transaction, rb_intern("rollback"), 0);
|
229
210
|
}
|
211
|
+
}
|
230
212
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
rb_fireruby_raise(status, "Error closing connection.");
|
241
|
-
}
|
242
|
-
}
|
213
|
+
/* Detach from the database. */
|
214
|
+
if(isc_detach_database(status, &connection->handle) == 0) {
|
215
|
+
connection->handle = 0;
|
216
|
+
result = self;
|
217
|
+
} else {
|
218
|
+
/* Generate an error. */
|
219
|
+
rb_fireruby_raise(status, "Error closing connection.");
|
220
|
+
}
|
221
|
+
}
|
243
222
|
|
244
|
-
|
223
|
+
return(result);
|
245
224
|
}
|
246
225
|
|
247
226
|
|
@@ -253,9 +232,8 @@ static VALUE closeConnection(VALUE self)
|
|
253
232
|
* @return A reference to the Connection connection.
|
254
233
|
*
|
255
234
|
*/
|
256
|
-
static VALUE getConnectionDatabase(VALUE self)
|
257
|
-
|
258
|
-
return(rb_iv_get(self, "@database"));
|
235
|
+
static VALUE getConnectionDatabase(VALUE self) {
|
236
|
+
return(rb_iv_get(self, "@database"));
|
259
237
|
}
|
260
238
|
|
261
239
|
|
@@ -268,17 +246,15 @@ static VALUE getConnectionDatabase(VALUE self)
|
|
268
246
|
* @return A reference to a Transaction object or nil if a problem occurs.
|
269
247
|
*
|
270
248
|
*/
|
271
|
-
static VALUE startConnectionTransaction(VALUE self)
|
272
|
-
|
273
|
-
VALUE result = rb_transaction_new(self);
|
249
|
+
static VALUE startConnectionTransaction(VALUE self) {
|
250
|
+
VALUE result = rb_transaction_new(self);
|
274
251
|
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
}
|
252
|
+
if(rb_block_given_p()) {
|
253
|
+
result = rb_rescue(startTransactionBlock, result,
|
254
|
+
startTransactionRescue, result);
|
255
|
+
}
|
280
256
|
|
281
|
-
|
257
|
+
return(result);
|
282
258
|
}
|
283
259
|
|
284
260
|
|
@@ -291,24 +267,22 @@ static VALUE startConnectionTransaction(VALUE self)
|
|
291
267
|
* @return A reference to a String object describing the connection.
|
292
268
|
*
|
293
269
|
*/
|
294
|
-
static VALUE connectionToString(VALUE self)
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
return(result);
|
270
|
+
static VALUE connectionToString(VALUE self) {
|
271
|
+
VALUE result = rb_str_new2("(CLOSED)");
|
272
|
+
ConnectionHandle *connection = NULL;
|
273
|
+
|
274
|
+
Data_Get_Struct(self, ConnectionHandle, connection);
|
275
|
+
if(connection->handle != 0) {
|
276
|
+
VALUE database = rb_iv_get(self, "@database"),
|
277
|
+
user = rb_iv_get(self, "@user"),
|
278
|
+
file = rb_iv_get(database, "@file");
|
279
|
+
char text[256];
|
280
|
+
|
281
|
+
sprintf(text, "%s@%s (OPEN)", StringValuePtr(user), StringValuePtr(file));
|
282
|
+
result = rb_str_new2(text);
|
283
|
+
}
|
284
|
+
|
285
|
+
return(result);
|
312
286
|
}
|
313
287
|
|
314
288
|
|
@@ -325,31 +299,27 @@ static VALUE connectionToString(VALUE self)
|
|
325
299
|
* non-query statement.
|
326
300
|
*
|
327
301
|
*/
|
328
|
-
static VALUE executeOnConnection(VALUE self, VALUE sql, VALUE transaction)
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
while(row != Qnil)
|
342
|
-
{
|
343
|
-
last = rb_yield(row);
|
344
|
-
row = rb_funcall(results, rb_intern("fetch"), 0);
|
345
|
-
}
|
346
|
-
rb_funcall(results, rb_intern("close"), 0);
|
347
|
-
results = last;
|
302
|
+
static VALUE executeOnConnection(VALUE self, VALUE sql, VALUE transaction) {
|
303
|
+
VALUE results = Qnil,
|
304
|
+
statement = rb_statement_new(self, transaction, sql, INT2FIX(3));
|
305
|
+
|
306
|
+
results = rb_execute_statement(statement);
|
307
|
+
if(results != Qnil && rb_obj_is_kind_of(results, rb_cInteger) == Qfalse) {
|
308
|
+
if(rb_block_given_p()) {
|
309
|
+
VALUE row = rb_funcall(results, rb_intern("fetch"), 0),
|
310
|
+
last = Qnil;
|
311
|
+
|
312
|
+
while(row != Qnil) {
|
313
|
+
last = rb_yield(row);
|
314
|
+
row = rb_funcall(results, rb_intern("fetch"), 0);
|
348
315
|
}
|
349
|
-
|
350
|
-
|
316
|
+
rb_funcall(results, rb_intern("close"), 0);
|
317
|
+
results = last;
|
318
|
+
}
|
319
|
+
}
|
320
|
+
rb_statement_close(statement);
|
351
321
|
|
352
|
-
|
322
|
+
return(results);
|
353
323
|
}
|
354
324
|
|
355
325
|
|
@@ -363,49 +333,39 @@ static VALUE executeOnConnection(VALUE self, VALUE sql, VALUE transaction)
|
|
363
333
|
* @return Always returns nil.
|
364
334
|
*
|
365
335
|
*/
|
366
|
-
static VALUE executeOnConnectionImmediate(VALUE self, VALUE sql)
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
results = rb_rescue(executeImmediateBlock, set,
|
390
|
-
executeImmediateRescue, set);
|
391
|
-
}
|
392
|
-
else
|
393
|
-
{
|
394
|
-
results = set;
|
395
|
-
}
|
396
|
-
}
|
397
|
-
else
|
398
|
-
{
|
399
|
-
rb_funcall(transaction, rb_intern("commit"), 0);
|
400
|
-
results = set;
|
336
|
+
static VALUE executeOnConnectionImmediate(VALUE self, VALUE sql) {
|
337
|
+
VALUE transaction = rb_transaction_new(self),
|
338
|
+
set = Qnil,
|
339
|
+
results = Qnil,
|
340
|
+
array = rb_ary_new(),
|
341
|
+
dialect = INT2FIX(3),
|
342
|
+
statement = rb_statement_new(self, transaction, sql, dialect);
|
343
|
+
|
344
|
+
rb_ary_push(array, self);
|
345
|
+
rb_ary_push(array, transaction);
|
346
|
+
rb_ary_push(array, sql);
|
347
|
+
rb_ary_push(array, statement);
|
348
|
+
|
349
|
+
set = rb_rescue(executeBlock, array, executeRescue, array);
|
350
|
+
if(set != Qnil) {
|
351
|
+
if(TYPE(set) == T_DATA &&
|
352
|
+
RDATA(set)->dfree == (RUBY_DATA_FUNC)resultSetFree) {
|
353
|
+
rb_assign_transaction(set, transaction);
|
354
|
+
if(rb_block_given_p()) {
|
355
|
+
results = rb_rescue(executeImmediateBlock, set,
|
356
|
+
executeImmediateRescue, set);
|
357
|
+
} else {
|
358
|
+
results = set;
|
401
359
|
}
|
402
|
-
|
403
|
-
else
|
404
|
-
{
|
360
|
+
} else {
|
405
361
|
rb_funcall(transaction, rb_intern("commit"), 0);
|
406
|
-
|
362
|
+
results = set;
|
363
|
+
}
|
364
|
+
} else {
|
365
|
+
rb_funcall(transaction, rb_intern("commit"), 0);
|
366
|
+
}
|
407
367
|
|
408
|
-
|
368
|
+
return(results);
|
409
369
|
}
|
410
370
|
|
411
371
|
|
@@ -417,9 +377,8 @@ static VALUE executeOnConnectionImmediate(VALUE self, VALUE sql)
|
|
417
377
|
* @return A reference to the user name used to establish the connection.
|
418
378
|
*
|
419
379
|
*/
|
420
|
-
static VALUE getConnectionUser(VALUE self)
|
421
|
-
|
422
|
-
return(rb_iv_get(self, "@user"));
|
380
|
+
static VALUE getConnectionUser(VALUE self) {
|
381
|
+
return(rb_iv_get(self, "@user"));
|
423
382
|
}
|
424
383
|
|
425
384
|
|
@@ -432,13 +391,12 @@ static VALUE getConnectionUser(VALUE self)
|
|
432
391
|
* @return A reference to the return value provided by the block.
|
433
392
|
*
|
434
393
|
*/
|
435
|
-
VALUE startTransactionBlock(VALUE transaction)
|
436
|
-
|
437
|
-
VALUE result = rb_yield(transaction);
|
394
|
+
VALUE startTransactionBlock(VALUE transaction) {
|
395
|
+
VALUE result = rb_yield(transaction);
|
438
396
|
|
439
|
-
|
397
|
+
rb_funcall(transaction, rb_intern("commit"), 0);
|
440
398
|
|
441
|
-
|
399
|
+
return(result);
|
442
400
|
}
|
443
401
|
|
444
402
|
|
@@ -453,11 +411,10 @@ VALUE startTransactionBlock(VALUE transaction)
|
|
453
411
|
* @return Would be nil but always throws an exception.
|
454
412
|
*
|
455
413
|
*/
|
456
|
-
VALUE startTransactionRescue(VALUE transaction, VALUE error)
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
return(Qnil);
|
414
|
+
VALUE startTransactionRescue(VALUE transaction, VALUE error) {
|
415
|
+
rb_funcall(transaction, rb_intern("rollback"), 0);
|
416
|
+
rb_exc_raise(error);
|
417
|
+
return(Qnil);
|
461
418
|
}
|
462
419
|
|
463
420
|
|
@@ -472,18 +429,17 @@ VALUE startTransactionRescue(VALUE transaction, VALUE error)
|
|
472
429
|
* query.
|
473
430
|
*
|
474
431
|
*/
|
475
|
-
VALUE executeBlock(VALUE array)
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
return(result);
|
432
|
+
VALUE executeBlock(VALUE array) {
|
433
|
+
VALUE result = Qnil,
|
434
|
+
connection = rb_ary_entry(array, 0),
|
435
|
+
transaction = rb_ary_entry(array, 1),
|
436
|
+
sql = rb_ary_entry(array, 2),
|
437
|
+
statement = rb_ary_entry(array, 3);
|
438
|
+
|
439
|
+
result = rb_execute_statement(statement);
|
440
|
+
rb_statement_close(statement);
|
441
|
+
|
442
|
+
return(result);
|
487
443
|
}
|
488
444
|
|
489
445
|
|
@@ -497,15 +453,14 @@ VALUE executeBlock(VALUE array)
|
|
497
453
|
* @return Would always returns nil except that it always raises an exception.
|
498
454
|
*
|
499
455
|
*/
|
500
|
-
VALUE executeRescue(VALUE array, VALUE error)
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
return(Qnil);
|
456
|
+
VALUE executeRescue(VALUE array, VALUE error) {
|
457
|
+
VALUE transaction = rb_ary_entry(array, 1),
|
458
|
+
statement = rb_ary_entry(array, 3);
|
459
|
+
|
460
|
+
rb_funcall(transaction, rb_intern("rollback"), 0);
|
461
|
+
rb_statement_close(statement);
|
462
|
+
rb_exc_raise(error);
|
463
|
+
return(Qnil);
|
509
464
|
}
|
510
465
|
|
511
466
|
|
@@ -518,19 +473,17 @@ VALUE executeRescue(VALUE array, VALUE error)
|
|
518
473
|
* @return A reference to the return value generated by the block.
|
519
474
|
*
|
520
475
|
*/
|
521
|
-
VALUE executeImmediateBlock(VALUE set)
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
return(result);
|
476
|
+
VALUE executeImmediateBlock(VALUE set) {
|
477
|
+
VALUE result = Qnil,
|
478
|
+
row = rb_funcall(set, rb_intern("fetch"), 0);
|
479
|
+
|
480
|
+
while(row != Qnil) {
|
481
|
+
result = rb_yield(row);
|
482
|
+
row = rb_funcall(set, rb_intern("fetch"), 0);
|
483
|
+
}
|
484
|
+
rb_funcall(set, rb_intern("close"), 0);
|
485
|
+
|
486
|
+
return(result);
|
534
487
|
}
|
535
488
|
|
536
489
|
|
@@ -544,11 +497,10 @@ VALUE executeImmediateBlock(VALUE set)
|
|
544
497
|
* @return Would always returns nil except that it always raises an exception.
|
545
498
|
*
|
546
499
|
*/
|
547
|
-
VALUE executeImmediateRescue(VALUE set, VALUE error)
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
return(Qnil);
|
500
|
+
VALUE executeImmediateRescue(VALUE set, VALUE error) {
|
501
|
+
rb_funcall(set, rb_intern("close"), 0);
|
502
|
+
rb_exc_raise(error);
|
503
|
+
return(Qnil);
|
552
504
|
}
|
553
505
|
|
554
506
|
|
@@ -569,139 +521,124 @@ VALUE executeImmediateRescue(VALUE set, VALUE error)
|
|
569
521
|
* parameter buffer.
|
570
522
|
*
|
571
523
|
*/
|
572
|
-
char *createDPB(VALUE user, VALUE password, VALUE options, short *length)
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
524
|
+
char *createDPB(VALUE user, VALUE password, VALUE options, short *length) {
|
525
|
+
char *dpb = NULL;
|
526
|
+
VALUE keys;
|
527
|
+
VALUE entry;
|
528
|
+
int i;
|
529
|
+
short type;
|
530
|
+
|
531
|
+
/* Determine the dpb length and allocate it. */
|
532
|
+
*length = 1;
|
533
|
+
if(user != Qnil) {
|
534
|
+
*length += strlen(StringValuePtr(user)) + 2;
|
535
|
+
}
|
536
|
+
if(password != Qnil) {
|
537
|
+
*length += strlen(StringValuePtr(password)) + 2;
|
538
|
+
}
|
539
|
+
if(options != Qnil) {
|
540
|
+
keys = rb_funcall(options, rb_intern("keys"), 0);
|
541
|
+
|
542
|
+
for(i = 0; i < RARRAY_LEN(keys); i++) {
|
543
|
+
type = FIX2INT(rb_ary_entry(keys, i));
|
544
|
+
|
545
|
+
switch (type) {
|
546
|
+
case isc_dpb_sql_role_name:
|
547
|
+
case isc_dpb_lc_messages:
|
548
|
+
case isc_dpb_lc_ctype:
|
549
|
+
case isc_dpb_reserved:
|
595
550
|
{
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
{
|
600
|
-
case isc_dpb_sql_role_name:
|
601
|
-
case isc_dpb_lc_messages:
|
602
|
-
case isc_dpb_lc_ctype:
|
603
|
-
case isc_dpb_reserved:
|
604
|
-
{
|
605
|
-
entry = rb_hash_aref(options, INT2FIX(type));
|
606
|
-
*length += strlen(StringValuePtr(entry)) + 2;
|
607
|
-
break;
|
608
|
-
}
|
609
|
-
default:
|
610
|
-
{
|
611
|
-
*length += 3;
|
612
|
-
}
|
613
|
-
}
|
551
|
+
entry = rb_hash_aref(options, INT2FIX(type));
|
552
|
+
*length += strlen(StringValuePtr(entry)) + 2;
|
553
|
+
break;
|
614
554
|
}
|
615
|
-
|
616
|
-
dpb = ALLOC_N(char, *length);
|
617
|
-
|
618
|
-
/* Populate the buffer. */
|
619
|
-
if(dpb != NULL)
|
620
|
-
{
|
621
|
-
char *ptr = NULL;
|
622
|
-
int size = 0;
|
623
|
-
|
624
|
-
/* Fill out the DPB. */
|
625
|
-
memset(dpb, 0, *length);
|
626
|
-
dpb[0] = isc_dpb_version1;
|
627
|
-
ptr = &dpb[1];
|
628
|
-
|
629
|
-
if(user != Qnil)
|
555
|
+
default:
|
630
556
|
{
|
631
|
-
|
632
|
-
|
633
|
-
size = strlen(username);
|
634
|
-
*ptr++ = isc_dpb_user_name;
|
635
|
-
*ptr++ = (char)size;
|
636
|
-
memcpy(ptr, username, size);
|
637
|
-
ptr = ptr + size;
|
557
|
+
*length += 3;
|
638
558
|
}
|
639
|
-
|
640
|
-
if(password != Qnil)
|
641
|
-
{
|
642
|
-
char *userpwd = StringValuePtr(password);
|
643
|
-
|
644
|
-
size = strlen(userpwd);
|
645
|
-
*ptr++ = isc_dpb_password;
|
646
|
-
*ptr++ = (char)size;
|
647
|
-
memcpy(ptr, userpwd, size);
|
648
|
-
ptr = ptr + size;
|
649
559
|
}
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
560
|
+
}
|
561
|
+
}
|
562
|
+
dpb = ALLOC_N(char, *length);
|
563
|
+
|
564
|
+
/* Populate the buffer. */
|
565
|
+
if(dpb != NULL) {
|
566
|
+
char *ptr = NULL;
|
567
|
+
int size = 0;
|
568
|
+
|
569
|
+
/* Fill out the DPB. */
|
570
|
+
memset(dpb, 0, *length);
|
571
|
+
dpb[0] = isc_dpb_version1;
|
572
|
+
ptr = &dpb[1];
|
573
|
+
|
574
|
+
if(user != Qnil) {
|
575
|
+
char *username = StringValuePtr(user);
|
576
|
+
|
577
|
+
size = strlen(username);
|
578
|
+
*ptr++ = isc_dpb_user_name;
|
579
|
+
*ptr++ = (char)size;
|
580
|
+
memcpy(ptr, username, size);
|
581
|
+
ptr = ptr + size;
|
582
|
+
}
|
583
|
+
|
584
|
+
if(password != Qnil) {
|
585
|
+
char *userpwd = StringValuePtr(password);
|
586
|
+
|
587
|
+
size = strlen(userpwd);
|
588
|
+
*ptr++ = isc_dpb_password;
|
589
|
+
*ptr++ = (char)size;
|
590
|
+
memcpy(ptr, userpwd, size);
|
591
|
+
ptr = ptr + size;
|
592
|
+
}
|
593
|
+
|
594
|
+
if(options != Qnil) {
|
595
|
+
for(i = 0; i < RARRAY_LEN(keys); i++) {
|
596
|
+
type = FIX2INT(rb_ary_entry(keys, i));
|
597
|
+
entry = rb_hash_aref(options, INT2FIX(type));
|
598
|
+
|
599
|
+
switch (type) {
|
600
|
+
case isc_dpb_sql_role_name:
|
601
|
+
case isc_dpb_lc_messages:
|
602
|
+
case isc_dpb_lc_ctype:
|
603
|
+
case isc_dpb_reserved:
|
604
|
+
{
|
605
|
+
char *text = StringValuePtr(entry);
|
606
|
+
|
607
|
+
size = strlen(text);
|
608
|
+
*ptr++ = type;
|
609
|
+
*ptr++ = (char)size;
|
610
|
+
memcpy(ptr, text, size);
|
611
|
+
ptr = ptr + size;
|
612
|
+
break;
|
613
|
+
}
|
614
|
+
default:
|
615
|
+
{
|
616
|
+
short value;
|
617
|
+
switch (TYPE(entry)) {
|
618
|
+
case T_FIXNUM: value = FIX2INT(entry);
|
619
|
+
case T_NIL: value = 0;
|
620
|
+
case T_FALSE: value = 0;
|
621
|
+
case T_TRUE: value = 1;
|
622
|
+
case T_UNDEF: value = 0;
|
623
|
+
case T_FLOAT: value = NUM2INT(entry);
|
624
|
+
case T_BIGNUM: value = NUM2INT(entry);
|
625
|
+
default: value = 0;
|
626
|
+
}
|
627
|
+
|
628
|
+
*ptr++ = type;
|
629
|
+
*ptr++ = (char)1;
|
630
|
+
*ptr++ = value;
|
631
|
+
}
|
632
|
+
}
|
695
633
|
}
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
return(dpb);
|
634
|
+
}
|
635
|
+
} else {
|
636
|
+
/* Generate an error. */
|
637
|
+
rb_raise(rb_eNoMemError,
|
638
|
+
"Memory allocation failure creating database DPB.");
|
639
|
+
}
|
640
|
+
|
641
|
+
return(dpb);
|
705
642
|
}
|
706
643
|
|
707
644
|
|
@@ -713,20 +650,17 @@ char *createDPB(VALUE user, VALUE password, VALUE options, short *length)
|
|
713
650
|
* with a Connection object.
|
714
651
|
*
|
715
652
|
*/
|
716
|
-
void connectionFree(void *connection)
|
717
|
-
{
|
718
|
-
|
719
|
-
{
|
720
|
-
ConnectionHandle *handle = (ConnectionHandle *)connection;
|
653
|
+
void connectionFree(void *connection) {
|
654
|
+
if(connection != NULL) {
|
655
|
+
ConnectionHandle *handle = (ConnectionHandle *)connection;
|
721
656
|
|
722
|
-
|
723
|
-
|
724
|
-
ISC_STATUS status[20];
|
657
|
+
if(handle->handle != 0) {
|
658
|
+
ISC_STATUS status[ISC_STATUS_LENGTH];
|
725
659
|
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
660
|
+
isc_detach_database(status, &handle->handle);
|
661
|
+
}
|
662
|
+
free(handle);
|
663
|
+
}
|
730
664
|
}
|
731
665
|
|
732
666
|
|
@@ -746,19 +680,18 @@ void connectionFree(void *connection)
|
|
746
680
|
* @return A reference to the newly created Connection object.
|
747
681
|
*
|
748
682
|
*/
|
749
|
-
VALUE rb_connection_new(VALUE database, VALUE user, VALUE password, VALUE options)
|
750
|
-
|
751
|
-
|
752
|
-
parameters[4];
|
683
|
+
VALUE rb_connection_new(VALUE database, VALUE user, VALUE password, VALUE options) {
|
684
|
+
VALUE connection = allocateConnection(cConnection),
|
685
|
+
parameters[4];
|
753
686
|
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
687
|
+
parameters[0] = database;
|
688
|
+
parameters[1] = user;
|
689
|
+
parameters[2] = password;
|
690
|
+
parameters[3] = options;
|
758
691
|
|
759
|
-
|
692
|
+
initializeConnection(4, parameters, connection);
|
760
693
|
|
761
|
-
|
694
|
+
return(connection);
|
762
695
|
}
|
763
696
|
|
764
697
|
|
@@ -772,27 +705,24 @@ VALUE rb_connection_new(VALUE database, VALUE user, VALUE password, VALUE option
|
|
772
705
|
* transaction.
|
773
706
|
*
|
774
707
|
*/
|
775
|
-
void rb_tx_started(VALUE transaction, VALUE connection)
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
rb_ary_push(list, transaction);
|
795
|
-
}
|
708
|
+
void rb_tx_started(VALUE transaction, VALUE connection) {
|
709
|
+
VALUE array = TYPE(connection) == T_ARRAY ? connection : rb_ary_new(),
|
710
|
+
number = Qnil;
|
711
|
+
long size = 0,
|
712
|
+
index;
|
713
|
+
|
714
|
+
if(TYPE(connection) != T_ARRAY) {
|
715
|
+
rb_ary_push(array, connection);
|
716
|
+
}
|
717
|
+
number = rb_funcall(array, rb_intern("size"), 0);
|
718
|
+
size = TYPE(number) == T_FIXNUM ? FIX2INT(number) : NUM2INT(number);
|
719
|
+
|
720
|
+
for(index = 0; index < size; index++) {
|
721
|
+
VALUE entry = rb_ary_entry(array, index),
|
722
|
+
list = rb_iv_get(entry, "@transactions");
|
723
|
+
|
724
|
+
rb_ary_push(list, transaction);
|
725
|
+
}
|
796
726
|
}
|
797
727
|
|
798
728
|
|
@@ -808,27 +738,24 @@ void rb_tx_started(VALUE transaction, VALUE connection)
|
|
808
738
|
* released.
|
809
739
|
*
|
810
740
|
*/
|
811
|
-
void rb_tx_released(VALUE connection, VALUE transaction)
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
rb_ary_delete(list, transaction);
|
831
|
-
}
|
741
|
+
void rb_tx_released(VALUE connection, VALUE transaction) {
|
742
|
+
VALUE array = TYPE(connection) == T_ARRAY ? connection : rb_ary_new(),
|
743
|
+
number = Qnil;
|
744
|
+
long size = 0,
|
745
|
+
index;
|
746
|
+
|
747
|
+
if(TYPE(connection) != T_ARRAY) {
|
748
|
+
rb_ary_push(array, connection);
|
749
|
+
}
|
750
|
+
number = rb_funcall(array, rb_intern("size"), 0);
|
751
|
+
size = TYPE(number) == T_FIXNUM ? FIX2INT(number) : NUM2INT(number);
|
752
|
+
|
753
|
+
for(index = 0; index < size; index++) {
|
754
|
+
VALUE entry = rb_ary_entry(array, index),
|
755
|
+
list = rb_iv_get(entry, "@transactions");
|
756
|
+
|
757
|
+
rb_ary_delete(list, transaction);
|
758
|
+
}
|
832
759
|
}
|
833
760
|
|
834
761
|
|
@@ -839,29 +766,28 @@ void rb_tx_released(VALUE connection, VALUE transaction)
|
|
839
766
|
* @param module A reference to the module to create the class within.
|
840
767
|
*
|
841
768
|
*/
|
842
|
-
void Init_Connection(VALUE module)
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
rb_define_const(cConnection, "WRITE_SYNCHRONOUS", INT2FIX(1));
|
769
|
+
void Init_Connection(VALUE module) {
|
770
|
+
cConnection = rb_define_class_under(module, "Connection", rb_cObject);
|
771
|
+
rb_define_alloc_func(cConnection, allocateConnection);
|
772
|
+
rb_define_method(cConnection, "initialize", initializeConnection, -1);
|
773
|
+
rb_define_method(cConnection, "initialize_copy", forbidObjectCopy, 1);
|
774
|
+
rb_define_method(cConnection, "user", getConnectionUser, 0);
|
775
|
+
rb_define_method(cConnection, "open?", isConnectionOpen, 0);
|
776
|
+
rb_define_method(cConnection, "closed?", isConnectionClosed, 0);
|
777
|
+
rb_define_method(cConnection, "close", closeConnection, 0);
|
778
|
+
rb_define_method(cConnection, "database", getConnectionDatabase, 0);
|
779
|
+
rb_define_method(cConnection, "start_transaction", startConnectionTransaction, 0);
|
780
|
+
rb_define_method(cConnection, "to_s", connectionToString, 0);
|
781
|
+
rb_define_method(cConnection, "execute", executeOnConnection, 2);
|
782
|
+
rb_define_method(cConnection, "execute_immediate", executeOnConnectionImmediate, 1);
|
783
|
+
|
784
|
+
rb_define_const(cConnection, "MARK_DATABASE_DAMAGED", INT2FIX(isc_dpb_damaged));
|
785
|
+
rb_define_const(cConnection, "WRITE_POLICY", INT2FIX(isc_dpb_force_write));
|
786
|
+
rb_define_const(cConnection, "CHARACTER_SET", INT2FIX(isc_dpb_lc_ctype));
|
787
|
+
rb_define_const(cConnection, "MESSAGE_FILE", INT2FIX(isc_dpb_lc_messages));
|
788
|
+
rb_define_const(cConnection, "NUMBER_OF_CACHE_BUFFERS", INT2FIX(isc_dpb_num_buffers));
|
789
|
+
rb_define_const(cConnection, "DBA_USER_NAME", INT2FIX(isc_dpb_sys_user_name));
|
790
|
+
rb_define_const(cConnection, "SQL_ROLE_NAME", INT2FIX(isc_dpb_sql_role_name));
|
791
|
+
rb_define_const(cConnection, "WRITE_ASYNCHRONOUS", INT2FIX(0));
|
792
|
+
rb_define_const(cConnection, "WRITE_SYNCHRONOUS", INT2FIX(1));
|
867
793
|
}
|