rubyfb 0.5.9 → 0.6

Sign up to get free protection for your applications and to get access to all the features.
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);