rubyfb 0.5.9 → 0.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/ext/Generator.c CHANGED
@@ -33,51 +33,19 @@
33
33
  #include "rfbint.h"
34
34
 
35
35
  /* Function prototypes. */
36
- static VALUE allocateGenerator(VALUE);
37
36
  static VALUE initializeGenerator(VALUE, VALUE, VALUE);
38
37
  static VALUE getGeneratorName(VALUE);
39
38
  static VALUE getGeneratorConnection(VALUE);
40
- static VALUE getLastGeneratorValue(VALUE);
41
- static VALUE getNextGeneratorValue(VALUE, VALUE);
42
- static VALUE dropGenerator(VALUE);
43
- static VALUE doesGeneratorExist(VALUE, VALUE, VALUE);
44
- static VALUE createGenerator(VALUE, VALUE, VALUE);
45
- int checkForGenerator(const char *, isc_db_handle *);
46
- int installGenerator(const char *, isc_db_handle *);
47
- int deleteGenerator(const char *, isc_db_handle *);
39
+ static VALUE getLastGeneratorValue(int, VALUE*, VALUE);
40
+ static VALUE getNextGeneratorValue(int, VALUE*, VALUE);
41
+ static VALUE dropGenerator(int, VALUE*, VALUE);
42
+ static VALUE doesGeneratorExist(int, VALUE*, VALUE);
43
+ static VALUE createGenerator(int, VALUE*, VALUE);
48
44
  XSQLDA *createStorage(void);
49
- int32_t getGeneratorValue(const char *, int, isc_db_handle *);
50
45
 
51
46
  /* Globals. */
52
47
  VALUE cGenerator;
53
48
 
54
-
55
- /**
56
- * This function provides for the allocation of new Generator objects through
57
- * the Ruby language.
58
- *
59
- * @param klass A reference to the Generator Class object.
60
- *
61
- * @return A reference to the newly allocated Generator object.
62
- *
63
- */
64
- static VALUE allocateGenerator(VALUE klass) {
65
- VALUE instance = Qnil;
66
- GeneratorHandle *generator = ALLOC(GeneratorHandle);
67
-
68
- if(generator != NULL) {
69
- generator->connection = NULL;
70
- instance = Data_Wrap_Struct(klass, NULL, generatorFree,
71
- generator);
72
- } else {
73
- rb_raise(rb_eNoMemError,
74
- "Memory allocation failure allocating a generator.");
75
- }
76
-
77
- return(instance);
78
- }
79
-
80
-
81
49
  /**
82
50
  * This function provides the initialize method for the Generator class.
83
51
  *
@@ -93,9 +61,6 @@ static VALUE allocateGenerator(VALUE klass) {
93
61
  static VALUE initializeGenerator(VALUE self,
94
62
  VALUE name,
95
63
  VALUE connection) {
96
- GeneratorHandle *generator = NULL;
97
- ConnectionHandle *handle = NULL;
98
-
99
64
  if(TYPE(name) != T_STRING) {
100
65
  rb_fireruby_raise(NULL, "Invalid generator name specified.");
101
66
  }
@@ -108,10 +73,6 @@ static VALUE initializeGenerator(VALUE self,
108
73
  rb_iv_set(self, "@name", name);
109
74
  rb_iv_set(self, "@connection", connection);
110
75
 
111
- Data_Get_Struct(connection, ConnectionHandle, handle);
112
- Data_Get_Struct(self, GeneratorHandle, generator);
113
- generator->connection = &handle->handle;
114
-
115
76
  return(self);
116
77
  }
117
78
 
@@ -144,6 +105,21 @@ static VALUE getGeneratorConnection(VALUE self) {
144
105
  return(rb_iv_get(self, "@connection"));
145
106
  }
146
107
 
108
+ VALUE selectGeneratorValue(VALUE self, int step, VALUE transaction) {
109
+ VALUE result_set = Qnil,
110
+ row = Qnil,
111
+ connection = rb_iv_get(self, "@connection"),
112
+ name = rb_iv_get(self, "@name");
113
+ char sql[100];
114
+
115
+ sprintf(sql, "SELECT GEN_ID(%s, %d) FROM RDB$DATABASE", StringValuePtr(name), step);
116
+ result_set = rb_execute_sql(connection, rb_str_new2(sql), Qnil, transaction);
117
+ row = rb_funcall(result_set, rb_intern("fetch"), 0);
118
+ rb_funcall(result_set, rb_intern("close"), 0);
119
+
120
+ row = rb_funcall(row, rb_intern("values"), 0);
121
+ return rb_funcall(row, rb_intern("first"), 0);
122
+ }
147
123
 
148
124
  /**
149
125
  * This function fetches the last value retrieved from a Generator.
@@ -153,16 +129,11 @@ static VALUE getGeneratorConnection(VALUE self) {
153
129
  * @return A reference to the last value retrieved from the generator.
154
130
  *
155
131
  */
156
- static VALUE getLastGeneratorValue(VALUE self) {
157
- VALUE name = rb_iv_get(self, "@name");
158
- GeneratorHandle *generator = NULL;
159
- int32_t number = 0;
132
+ static VALUE getLastGeneratorValue(int argc, VALUE *argv, VALUE self) {
133
+ VALUE transaction= Qnil;
134
+ rb_scan_args(argc, argv, "01", &transaction);
160
135
 
161
- Data_Get_Struct(self, GeneratorHandle, generator);
162
-
163
- number = getGeneratorValue(StringValuePtr(name), 0, generator->connection);
164
-
165
- return(INT2NUM(number));
136
+ return selectGeneratorValue(self, 0, transaction);
166
137
  }
167
138
 
168
139
 
@@ -176,22 +147,16 @@ static VALUE getLastGeneratorValue(VALUE self) {
176
147
  * @return A reference to an integer containing the next generator value.
177
148
  *
178
149
  */
179
- static VALUE getNextGeneratorValue(VALUE self, VALUE step) {
180
- VALUE name = rb_iv_get(self, "@name");
181
- GeneratorHandle *generator = NULL;
182
- int32_t number = 0;
183
-
184
- Data_Get_Struct(self, GeneratorHandle, generator);
150
+ static VALUE getNextGeneratorValue(int argc, VALUE *argv, VALUE self) {
151
+ VALUE step, transaction= Qnil;
152
+ rb_scan_args(argc, argv, "11", &step, &transaction);
185
153
 
186
154
  /* Check the step type. */
187
155
  if(TYPE(step) != T_FIXNUM) {
188
156
  rb_fireruby_raise(NULL, "Invalid generator step value.");
189
157
  }
190
158
 
191
- number = getGeneratorValue(StringValuePtr(name), FIX2INT(step),
192
- generator->connection);
193
-
194
- return(INT2NUM(number));
159
+ return selectGeneratorValue(self, FIX2INT(step), transaction);
195
160
  }
196
161
 
197
162
 
@@ -203,15 +168,16 @@ static VALUE getNextGeneratorValue(VALUE self, VALUE step) {
203
168
  * @return A reference to the Generator object dropped.
204
169
  *
205
170
  */
206
- static VALUE dropGenerator(VALUE self) {
207
- GeneratorHandle *generator = NULL;
208
- VALUE name;
171
+ static VALUE dropGenerator(int argc, VALUE *argv, VALUE self) {
172
+ VALUE name, connection, transaction = Qnil;
173
+ char sql[100];
209
174
 
210
- Data_Get_Struct(self, GeneratorHandle, generator);
211
175
  name = rb_iv_get(self, "@name");
176
+ connection = rb_iv_get(self, "@connection");
177
+ rb_scan_args(argc, argv, "01", &transaction);
212
178
 
213
- /* Drop the generator. */
214
- deleteGenerator(StringValuePtr(name), generator->connection);
179
+ sprintf(sql, "DROP GENERATOR %s", StringValuePtr(name));
180
+ rb_execute_sql(connection, rb_str_new2(sql), Qnil, transaction);
215
181
 
216
182
  return(self);
217
183
  }
@@ -230,24 +196,24 @@ static VALUE dropGenerator(VALUE self) {
230
196
  * otherwise.
231
197
  *
232
198
  */
233
- static VALUE doesGeneratorExist(VALUE klass, VALUE name, VALUE connection) {
234
- VALUE exists = Qfalse;
235
- ConnectionHandle *handle = NULL;
199
+ static VALUE doesGeneratorExist(int argc, VALUE *argv, VALUE klass) {
200
+ VALUE name, connection, transaction = Qnil,
201
+ exists = Qfalse,
202
+ result_set = Qnil;
203
+ char sql[200]; // 93(statement) + 2*(31)max_generator_name = 155
236
204
 
205
+ rb_scan_args(argc, argv, "21", &name, &connection, &transaction);
237
206
  if(TYPE(connection) != T_DATA ||
238
207
  RDATA(connection)->dfree != (RUBY_DATA_FUNC)connectionFree) {
239
208
  rb_fireruby_raise(NULL, "Invalid connection specified.");
240
209
  }
241
210
 
242
- Data_Get_Struct(connection, ConnectionHandle, handle);
243
-
244
- if(handle->handle == 0) {
245
- rb_fireruby_raise(NULL, "Connection is closed.");
246
- }
247
-
248
- if(checkForGenerator(StringValuePtr(name), &handle->handle)) {
211
+ sprintf(sql, "SELECT RDB$GENERATOR_NAME FROM RDB$GENERATORS WHERE RDB$GENERATOR_NAME in ('%s', UPPER('%s'))", StringValuePtr(name), StringValuePtr(name));
212
+ result_set = rb_execute_sql(connection, rb_str_new2(sql), Qnil, transaction);
213
+ if(Qnil != rb_funcall(result_set, rb_intern("fetch"), 0)) {
249
214
  exists = Qtrue;
250
215
  }
216
+ rb_funcall(result_set, rb_intern("close"), 0);
251
217
 
252
218
  return(exists);
253
219
  }
@@ -267,10 +233,11 @@ static VALUE doesGeneratorExist(VALUE klass, VALUE name, VALUE connection) {
267
233
  * @return A reference to a Generator object.
268
234
  *
269
235
  */
270
- static VALUE createGenerator(VALUE klass, VALUE name, VALUE connection) {
271
- VALUE result = Qnil;
272
- ConnectionHandle *handle = NULL;
236
+ static VALUE createGenerator(int argc, VALUE *argv, VALUE klass) {
237
+ VALUE name, connection, transaction = Qnil;
238
+ char sql[100];
273
239
 
240
+ rb_scan_args(argc, argv, "21", &name, &connection, &transaction);
274
241
  if(TYPE(name) != T_STRING) {
275
242
  rb_fireruby_raise(NULL, "Invalid generator name specified.");
276
243
  }
@@ -281,193 +248,12 @@ static VALUE createGenerator(VALUE klass, VALUE name, VALUE connection) {
281
248
  "Invalid connection specified for generator creation.");
282
249
  }
283
250
 
284
- Data_Get_Struct(connection, ConnectionHandle, handle);
285
- if(handle->handle != 0) {
286
- installGenerator(StringValuePtr(name), &handle->handle);
287
- result = rb_generator_new(name, connection);
288
- } else {
289
- rb_fireruby_raise(NULL,
290
- "Closed connection specified for generator creation.");
291
- }
292
-
293
- return(result);
294
- }
295
-
296
-
297
- /**
298
- * This function executes a check for a named generator.
299
- *
300
- * @param name A pointer to the string containing the generator name
301
- * to check for.
302
- * @param connection A pointer to the connection to be used to perform the
303
- * check.
304
- *
305
- * @return Returns 0 if the generator does not exist, 1 if the generator does
306
- * exist or -1 if there was an error.
307
- *
308
- */
309
- int checkForGenerator(const char *name, isc_db_handle *connection) {
310
- int result = -1;
311
- isc_stmt_handle statement = 0;
312
- ISC_STATUS status[ISC_STATUS_LENGTH];
313
-
314
- if(isc_dsql_allocate_statement(status, connection, &statement) == 0) {
315
- isc_tr_handle transaction = 0;
316
-
317
- if(isc_start_transaction(status, &transaction, 1, connection, 0,
318
- NULL) == 0) {
319
- XSQLDA *da = (XSQLDA *)ALLOC_N(char, XSQLDA_LENGTH(1));
320
-
321
- if(da != NULL) {
322
- char sql[100];
323
-
324
- da->version = SQLDA_VERSION1;
325
- da->sqln = 1;
326
- sprintf(sql, "SELECT COUNT(*) FROM %sS WHERE %s_NAME = UPPER('%s')",
327
- "RDB$GENERATOR", "RDB$GENERATOR", name);
328
- if(isc_dsql_prepare(status, &transaction, &statement, strlen(sql),
329
- sql, 3, da) == 0) {
330
- /* Prepare the XSQLDA and provide it with data room. */
331
- allocateOutXSQLDA(da->sqld, &statement, 3);
332
- prepareDataArea(da);
333
- if(isc_dsql_execute(status, &transaction, &statement,
334
- 3, da) == 0) {
335
- if(isc_dsql_fetch(status, &statement, 3, da) == 0) {
336
- int32_t count = *((long *)da->sqlvar->sqldata);
337
-
338
- result = (count > 0 ? 1 : 0);
339
- } else {
340
- rb_fireruby_raise(status,
341
- "Error checking for generator.");
342
- }
343
- } else {
344
- rb_fireruby_raise(status,
345
- "Error checking for generator.");
346
- }
347
- } else {
348
- rb_fireruby_raise(status, "Error checking for generator.");
349
- }
350
-
351
- releaseDataArea(da);
352
- } else {
353
- rb_raise(rb_eNoMemError, "Memory allocation failure checking " \
354
- "generator existence.");
355
- }
356
-
357
- if(transaction != 0) {
358
- isc_commit_transaction(status, &transaction);
359
- }
360
- } else {
361
- rb_fireruby_raise(status, "Error checking for generator.");
362
- }
363
-
364
- isc_dsql_free_statement(status, &statement, DSQL_drop);
365
- }
366
-
367
- return(result);
368
- }
369
-
370
-
371
- /**
372
- * This function creates a new generator within a database.
373
- *
374
- * @param name A pointer to the string containing the generator name
375
- * to be created.
376
- * @param connection A pointer to the connection to be used to create the new
377
- * generator.
378
- *
379
- * @return Returns 0 if the generator was created or -1 if there was an error.
380
- *
381
- */
382
- int installGenerator(const char *name, isc_db_handle *connection) {
383
- int result = -1;
384
- isc_stmt_handle statement = 0;
385
- ISC_STATUS status[ISC_STATUS_LENGTH];
386
-
387
- if(isc_dsql_allocate_statement(status, connection, &statement) == 0) {
388
- isc_tr_handle transaction = 0;
389
-
390
- if(isc_start_transaction(status, &transaction, 1, connection, 0,
391
- NULL) == 0) {
392
- char sql[100];
393
-
394
- sprintf(sql, "CREATE GENERATOR %s", name);
395
- if(isc_dsql_prepare(status, &transaction, &statement, strlen(sql),
396
- sql, 3, NULL) == 0) {
397
- if(isc_dsql_execute(status, &transaction, &statement,
398
- 3, NULL) == 0) {
399
- result = 0;
400
- } else {
401
- rb_fireruby_raise(status, "Error creating generator.");
402
- }
403
- } else {
404
- rb_fireruby_raise(status, "Error creating generator.");
405
- }
406
-
407
- if(transaction != 0) {
408
- isc_commit_transaction(status, &transaction);
409
- }
410
- } else {
411
- rb_fireruby_raise(status, "Error creating generator.");
412
- }
413
-
414
- isc_dsql_free_statement(status, &statement, DSQL_drop);
415
- }
416
-
417
- return(result);
418
- }
419
-
251
+ sprintf(sql, "CREATE GENERATOR %s", StringValuePtr(name));
252
+ rb_execute_sql(connection, rb_str_new2(sql), Qnil, transaction);
420
253
 
421
- /**
422
- * This function drops an existing generator within a database.
423
- *
424
- * @param name A pointer to the string containing the generator name
425
- * to be dropped.
426
- * @param connection A pointer to the connection to be used to drop the
427
- * generator.
428
- *
429
- * @return Returns 0 if the generator was dropped or -1 if there was an error.
430
- *
431
- */
432
- int deleteGenerator(const char *name, isc_db_handle *connection) {
433
- int result = -1;
434
- isc_stmt_handle statement = 0;
435
- ISC_STATUS status[ISC_STATUS_LENGTH];
436
-
437
- if(isc_dsql_allocate_statement(status, connection, &statement) == 0) {
438
- isc_tr_handle transaction = 0;
439
-
440
- if(isc_start_transaction(status, &transaction, 1, connection, 0,
441
- NULL) == 0) {
442
- char sql[100];
443
-
444
- sprintf(sql, "DROP GENERATOR %s", name);
445
- if(isc_dsql_prepare(status, &transaction, &statement, strlen(sql),
446
- sql, 3, NULL) == 0) {
447
- if(isc_dsql_execute(status, &transaction, &statement,
448
- 3, NULL) == 0) {
449
- result = 0;
450
- } else {
451
- rb_fireruby_raise(status, "Error dropping generator.");
452
- }
453
- } else {
454
- rb_fireruby_raise(status, "Error dropping generator.");
455
- }
456
-
457
- if(transaction != 0) {
458
- isc_commit_transaction(status, &transaction);
459
- }
460
- } else {
461
- rb_fireruby_raise(status, "Error dropping generator.");
462
- }
463
-
464
- isc_dsql_free_statement(status, &statement, DSQL_drop);
465
- }
466
-
467
- return(result);
254
+ return rb_generator_new(name, connection);
468
255
  }
469
256
 
470
-
471
257
  /**
472
258
  * This function prepares storage space for statements that will fetch values
473
259
  * from a generator.
@@ -498,52 +284,6 @@ XSQLDA *createStorage(void) {
498
284
  }
499
285
 
500
286
 
501
- /**
502
- * This function executes a SQL statement to fetch a value from a named
503
- * generator in the database.
504
- *
505
- * @param name The name of the generator to fetch the value from.
506
- * @param step The step interval to be used in the call to the database
507
- * generator.
508
- * @param connection The connection to make the call through.
509
- *
510
- * @return A long integer containing the generator value.
511
- *
512
- */
513
- int32_t getGeneratorValue(const char *name, int step, isc_db_handle *connection) {
514
- int32_t result = 0;
515
- ISC_STATUS status[ISC_STATUS_LENGTH];
516
- isc_tr_handle transaction = 0;
517
- XSQLDA *da = createStorage();
518
-
519
- if(isc_start_transaction(status, &transaction, 1, connection, 0, NULL) == 0) {
520
- char sql[100];
521
-
522
- sprintf(sql, "SELECT GEN_ID(%s, %d) FROM RDB$DATABASE", name, step);
523
- if(isc_dsql_exec_immed2(status, connection, &transaction, 0, sql,
524
- 3, NULL, da) == 0) {
525
- result = *((int32_t *)da->sqlvar->sqldata);
526
- } else {
527
- ISC_STATUS local[20];
528
-
529
- isc_rollback_transaction(local, &transaction);
530
- rb_fireruby_raise(status, "Error obtaining generator value.");
531
- }
532
-
533
- isc_commit_transaction(status, &transaction);
534
- } else {
535
- rb_fireruby_raise(status, "Error obtaining generator value.");
536
- }
537
-
538
- /* Clean up. */
539
- if(da != NULL) {
540
- releaseDataArea(da);
541
- }
542
-
543
- return(result);
544
- }
545
-
546
-
547
287
  /**
548
288
  * This function provides a means of programmatically creating a Generator
549
289
  * object.
@@ -556,30 +296,13 @@ int32_t getGeneratorValue(const char *name, int step, isc_db_handle *connection)
556
296
  *
557
297
  */
558
298
  VALUE rb_generator_new(VALUE name, VALUE connection) {
559
- VALUE instance = allocateGenerator(cGenerator);
299
+ VALUE args[2];
300
+ args[0] = name;
301
+ args[1] = connection;
560
302
 
561
- initializeGenerator(instance, name, connection);
562
-
563
- return(instance);
564
- }
565
-
566
-
567
- /**
568
- * This function integrates with the Ruby garbage collector to insure that all
569
- * of the resources associated with a Generator object are release whenever a
570
- * Generator object is collected.
571
- *
572
- * @param generator A pointer to the GeneratorHandle structure associated
573
- * with the Generator object being collected.
574
- *
575
- */
576
- void generatorFree(void *generator) {
577
- if(generator != NULL) {
578
- free((GeneratorHandle *)generator);
579
- }
303
+ return rb_class_new_instance(2, args, cGenerator);
580
304
  }
581
305
 
582
-
583
306
  /**
584
307
  * This function initializes the Generator class within the Ruby environment.
585
308
  * The class is established under the module specified to the function.
@@ -589,14 +312,13 @@ void generatorFree(void *generator) {
589
312
  */
590
313
  void Init_Generator(VALUE module) {
591
314
  cGenerator = rb_define_class_under(module, "Generator", rb_cObject);
592
- rb_define_alloc_func(cGenerator, allocateGenerator);
593
315
  rb_define_method(cGenerator, "initialize", initializeGenerator, 2);
594
316
  rb_define_method(cGenerator, "initialize_copy", forbidObjectCopy, 1);
595
- rb_define_method(cGenerator, "last", getLastGeneratorValue, 0);
596
- rb_define_method(cGenerator, "next", getNextGeneratorValue, 1);
317
+ rb_define_method(cGenerator, "last", getLastGeneratorValue, -1);
318
+ rb_define_method(cGenerator, "next", getNextGeneratorValue, -1);
597
319
  rb_define_method(cGenerator, "connection", getGeneratorConnection, 0);
598
320
  rb_define_method(cGenerator, "name", getGeneratorName, 0);
599
- rb_define_method(cGenerator, "drop", dropGenerator, 0);
600
- rb_define_module_function(cGenerator, "exists?", doesGeneratorExist, 2);
601
- rb_define_module_function(cGenerator, "create", createGenerator, 2);
321
+ rb_define_method(cGenerator, "drop", dropGenerator, -1);
322
+ rb_define_module_function(cGenerator, "exists?", doesGeneratorExist, -1);
323
+ rb_define_module_function(cGenerator, "create", createGenerator, -1);
602
324
  }
data/ext/Generator.h CHANGED
@@ -39,11 +39,6 @@
39
39
  #define RUBY_H_INCLUDED
40
40
  #endif
41
41
 
42
- /* Type definitions. */
43
- typedef struct {
44
- isc_db_handle *connection;
45
- } GeneratorHandle;
46
-
47
42
  /* Function prototypes. */
48
43
  void Init_Generator(VALUE);
49
44
  VALUE rb_generator_new(VALUE, VALUE);