rubyfb 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/CHANGELOG +6 -0
  2. data/LICENSE +411 -0
  3. data/Manifest +73 -0
  4. data/README +460 -0
  5. data/Rakefile +20 -0
  6. data/examples/example01.rb +65 -0
  7. data/ext/AddUser.c +464 -0
  8. data/ext/AddUser.h +37 -0
  9. data/ext/Backup.c +783 -0
  10. data/ext/Backup.h +37 -0
  11. data/ext/Blob.c +421 -0
  12. data/ext/Blob.h +65 -0
  13. data/ext/Common.c +54 -0
  14. data/ext/Common.h +37 -0
  15. data/ext/Connection.c +863 -0
  16. data/ext/Connection.h +50 -0
  17. data/ext/DataArea.c +274 -0
  18. data/ext/DataArea.h +38 -0
  19. data/ext/Database.c +449 -0
  20. data/ext/Database.h +48 -0
  21. data/ext/FireRuby.c +240 -0
  22. data/ext/FireRuby.h +50 -0
  23. data/ext/FireRubyException.c +268 -0
  24. data/ext/FireRubyException.h +51 -0
  25. data/ext/Generator.c +689 -0
  26. data/ext/Generator.h +53 -0
  27. data/ext/RemoveUser.c +212 -0
  28. data/ext/RemoveUser.h +37 -0
  29. data/ext/Restore.c +855 -0
  30. data/ext/Restore.h +37 -0
  31. data/ext/ResultSet.c +809 -0
  32. data/ext/ResultSet.h +60 -0
  33. data/ext/Row.c +965 -0
  34. data/ext/Row.h +55 -0
  35. data/ext/ServiceManager.c +316 -0
  36. data/ext/ServiceManager.h +48 -0
  37. data/ext/Services.c +124 -0
  38. data/ext/Services.h +42 -0
  39. data/ext/Statement.c +785 -0
  40. data/ext/Statement.h +62 -0
  41. data/ext/Transaction.c +684 -0
  42. data/ext/Transaction.h +50 -0
  43. data/ext/TypeMap.c +1182 -0
  44. data/ext/TypeMap.h +51 -0
  45. data/ext/extconf.rb +28 -0
  46. data/ext/mkmf.bat +1 -0
  47. data/lib/SQLType.rb +224 -0
  48. data/lib/active_record/connection_adapters/rubyfb_adapter.rb +805 -0
  49. data/lib/mkdoc +1 -0
  50. data/lib/rubyfb.rb +2 -0
  51. data/lib/rubyfb_lib.so +0 -0
  52. data/lib/src.rb +1800 -0
  53. data/rubyfb.gemspec +31 -0
  54. data/test/AddRemoveUserTest.rb +56 -0
  55. data/test/BackupRestoreTest.rb +99 -0
  56. data/test/BlobTest.rb +57 -0
  57. data/test/CharacterSetTest.rb +63 -0
  58. data/test/ConnectionTest.rb +111 -0
  59. data/test/DDLTest.rb +54 -0
  60. data/test/DatabaseTest.rb +83 -0
  61. data/test/GeneratorTest.rb +50 -0
  62. data/test/KeyTest.rb +140 -0
  63. data/test/ResultSetTest.rb +162 -0
  64. data/test/RoleTest.rb +73 -0
  65. data/test/RowCountTest.rb +65 -0
  66. data/test/RowTest.rb +203 -0
  67. data/test/SQLTest.rb +182 -0
  68. data/test/SQLTypeTest.rb +101 -0
  69. data/test/ServiceManagerTest.rb +29 -0
  70. data/test/StatementTest.rb +135 -0
  71. data/test/TestSetup.rb +11 -0
  72. data/test/TransactionTest.rb +112 -0
  73. data/test/TypeTest.rb +92 -0
  74. data/test/UnitTest.rb +65 -0
  75. metadata +149 -0
data/ext/Backup.c ADDED
@@ -0,0 +1,783 @@
1
+ /*------------------------------------------------------------------------------
2
+ * Backup.c
3
+ *----------------------------------------------------------------------------*/
4
+ /**
5
+ * Copyright � Peter Wood, 2005
6
+ *
7
+ * The contents of this file are subject to the Mozilla Public License Version
8
+ * 1.1 (the "License"); you may not use this file except in compliance with the
9
+ * License. You may obtain a copy of the License at
10
+ *
11
+ * http://www.mozilla.org/MPL/
12
+ *
13
+ * Software distributed under the License is distributed on an "AS IS" basis,
14
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
15
+ * the specificlanguage governing rights and limitations under the License.
16
+ *
17
+ * The Original Code is the FireRuby extension for the Ruby language.
18
+ *
19
+ * The Initial Developer of the Original Code is Peter Wood. All Rights
20
+ * Reserved.
21
+ *
22
+ * @author Peter Wood
23
+ * @version 1.0
24
+ */
25
+
26
+ /* Includes. */
27
+ #include "Backup.h"
28
+ #include "ibase.h"
29
+ #include "ServiceManager.h"
30
+ #include "Services.h"
31
+
32
+ /* Function prototypes. */
33
+ static VALUE getBackupFile(VALUE);
34
+ static VALUE setBackupFile(VALUE, VALUE);
35
+ static VALUE getBackupDatabase(VALUE);
36
+ static VALUE setBackupDatabase(VALUE, VALUE);
37
+ static VALUE getBackupBlockingFactor(VALUE);
38
+ static VALUE setBackupBlockingFactor(VALUE, VALUE);
39
+ static VALUE getBackupIgnoreChecksums(VALUE);
40
+ static VALUE setBackupIgnoreChecksums(VALUE, VALUE);
41
+ static VALUE getBackupIgnoreLimbo(VALUE);
42
+ static VALUE setBackupIgnoreLimbo(VALUE, VALUE);
43
+ static VALUE getBackupMetadataOnly(VALUE);
44
+ static VALUE setBackupMetadataOnly(VALUE, VALUE);
45
+ static VALUE getBackupGarbageCollect(VALUE);
46
+ static VALUE setBackupGarbageCollect(VALUE, VALUE);
47
+ static VALUE getBackupNonTransportable(VALUE);
48
+ static VALUE setBackupNonTransportable(VALUE, VALUE);
49
+ static VALUE getBackupConvertTables(VALUE);
50
+ static VALUE setBackupConvertTables(VALUE, VALUE);
51
+ static VALUE executeBackup(VALUE, VALUE);
52
+ static VALUE getBackupLog(VALUE);
53
+ static void createBackupBuffer(VALUE, VALUE, VALUE, char **, short *);
54
+
55
+
56
+ /* Globals. */
57
+ VALUE cBackup;
58
+
59
+ /* Definitions. */
60
+ #define IGNORE_CHECKSUMS rb_str_new2("IGNORE_CHECKSUMS")
61
+ #define IGNORE_LIMBO rb_str_new2("IGNORE_LIMBO")
62
+ #define METADATA_ONLY rb_str_new2("METADATA_ONLY")
63
+ #define NO_GARBAGE_COLLECT rb_str_new2("NO_GARBAGE_COLLECT")
64
+ #define NON_TRANSPORTABLE rb_str_new2("NON_TRANSPORTABLE")
65
+ #define CONVERT_TABLES rb_str_new2("CONVERT_TABLES")
66
+ #define VERBOSE_BACKUP INT2FIX(isc_spb_verbose)
67
+ #define START_BUFFER_SIZE 1024
68
+
69
+
70
+ /**
71
+ * This function provides the initialize method for the Backup class.
72
+ *
73
+ * @param self A reference to the Backup object to be initialized.
74
+ * @param database A reference to a File or String containing the server path
75
+ * and name of the primary database file.
76
+ * @param file A reference to a File or String containing the server path
77
+ * and name of the database backup file.
78
+ *
79
+ * @return A reference to the newly initialized Backup object.
80
+ *
81
+ */
82
+ VALUE initializeBackup(VALUE self, VALUE database, VALUE file)
83
+ {
84
+ VALUE path = Qnil,
85
+ files = rb_hash_new();
86
+
87
+ /* Extract the database file details. */
88
+ if(TYPE(database) == T_FILE)
89
+ {
90
+ path = rb_funcall(database, rb_intern("path"), 0);
91
+ }
92
+ else
93
+ {
94
+ path = rb_funcall(database, rb_intern("to_s"), 0);
95
+ }
96
+
97
+ /* Get the back file details. */
98
+ if(TYPE(file) == T_FILE)
99
+ {
100
+ rb_hash_aset(files, rb_funcall(file, rb_intern("path"), 0), Qnil);
101
+ }
102
+ else
103
+ {
104
+ rb_hash_aset(files, rb_funcall(file, rb_intern("to_s"), 0), Qnil);
105
+ }
106
+
107
+ rb_iv_set(self, "@database", path);
108
+ rb_iv_set(self, "@files", files);
109
+ rb_iv_set(self, "@options", rb_hash_new());
110
+ rb_iv_set(self, "@log", Qnil);
111
+
112
+ return(self);
113
+ }
114
+
115
+
116
+ /**
117
+ * This function provides the backup_file attribute accessor for the Backup
118
+ * class.
119
+ *
120
+ * @param self A reference to the Backup object to make the call on.
121
+ *
122
+ * @return A reference to a String containing the backup file path/name.
123
+ *
124
+ */
125
+ VALUE getBackupFile(VALUE self)
126
+ {
127
+ VALUE files = rb_iv_get(self, "@files");
128
+
129
+ return(rb_ary_entry(rb_funcall(files, rb_intern("keys"), 0), 0));
130
+ }
131
+
132
+
133
+ /**
134
+ * This function provides the backup_file attribute mutator for the Backup
135
+ * class.
136
+ *
137
+ * @param self A reference to the Backup object to make the call on.
138
+ * @param file A reference to a File or String containing the path and name
139
+ * of the backup file.
140
+ *
141
+ */
142
+ VALUE setBackupFile(VALUE self, VALUE file)
143
+ {
144
+ VALUE files = rb_hash_new();
145
+
146
+ if(TYPE(file) == T_FILE)
147
+ {
148
+ rb_hash_aset(files, rb_funcall(file, rb_intern("path"), 0), Qnil);
149
+ }
150
+ else
151
+ {
152
+ rb_hash_aset(files, rb_funcall(file, rb_intern("to_s"), 0), Qnil);
153
+ }
154
+ rb_iv_set(self, "@files", files);
155
+
156
+ return(self);
157
+ }
158
+
159
+
160
+ /**
161
+ * This function provides the database attribute accessor for the Backup class.
162
+ *
163
+ * @param self A reference to the Backup object to make the call on.
164
+ *
165
+ * @return A reference to a String containing the path and name of the main
166
+ * database file to be backed up.
167
+ *
168
+ */
169
+ VALUE getBackupDatabase(VALUE self)
170
+ {
171
+ return(rb_iv_get(self, "@database"));
172
+ }
173
+
174
+
175
+ /**
176
+ * This function provides the database attribute mutator for the Backup class.
177
+ *
178
+ * @param self A reference to the Backup object to make the call on.
179
+ * @param setting A reference to a File or String containing the new path and
180
+ * name details of the main database file to be backed up.
181
+ *
182
+ * @return A reference to the Backup object that has been updated.
183
+ *
184
+ */
185
+ VALUE setBackupDatabase(VALUE self, VALUE setting)
186
+ {
187
+ if(TYPE(setting) == T_FILE)
188
+ {
189
+ rb_iv_set(self, "@database", rb_funcall(setting, rb_intern("path"), 0));
190
+ }
191
+ else
192
+ {
193
+ rb_iv_set(self, "@database", rb_funcall(setting, rb_intern("to_s"), 0));
194
+ }
195
+
196
+ return(self);
197
+ }
198
+
199
+
200
+ /**
201
+ * This function provides the blocking_factor attribute accessor for the Backup
202
+ * class.
203
+ *
204
+ * @param self A reference to the Backup object to make the call on.
205
+ *
206
+ * @return A reference to the current backup blocking factor setting for the
207
+ * Backup object.
208
+ *
209
+ */
210
+ VALUE getBackupBlockingFactor(VALUE self)
211
+ {
212
+ VALUE options = rb_iv_get(self, "@options");
213
+
214
+ return(rb_hash_aref(options, INT2FIX(isc_spb_bkp_factor)));
215
+ }
216
+
217
+
218
+ /**
219
+ * This function provides the blocking_factor attribute mutator for the Backup
220
+ * class.
221
+ *
222
+ * @param self A reference to the Backup object to make the call on.
223
+ * @param setting A reference to an integer containing the new blocking factor
224
+ * setting (in bytes).
225
+ *
226
+ * @return A reference to the newly updated Backup object.
227
+ *
228
+ */
229
+ VALUE setBackupBlockingFactor(VALUE self, VALUE setting)
230
+ {
231
+ VALUE options = rb_iv_get(self, "@options");
232
+
233
+ if(rb_obj_is_kind_of(setting, rb_cInteger) == Qfalse)
234
+ {
235
+ rb_fireruby_raise(NULL, "Invalid blocking factor specified for Backup.");
236
+ }
237
+ rb_hash_aset(options, INT2FIX(isc_spb_bkp_factor), setting);
238
+
239
+ return(self);
240
+ }
241
+
242
+
243
+ /**
244
+ * This function provides the ignore_checksums attribute accessor for the Backup
245
+ * class.
246
+ *
247
+ * @param self A reference to the Backup object to make the call on.
248
+ *
249
+ * @return Either true or false.
250
+ *
251
+ */
252
+ VALUE getBackupIgnoreChecksums(VALUE self)
253
+ {
254
+ VALUE result = Qfalse,
255
+ options = rb_iv_get(self, "@options"),
256
+ value = rb_hash_aref(options, IGNORE_CHECKSUMS);
257
+
258
+ if(value != Qnil)
259
+ {
260
+ result = value;
261
+ }
262
+
263
+ return(result);
264
+ }
265
+
266
+
267
+ /**
268
+ * This function provides the ignore_checksums attribute mutator for the Backup
269
+ * class.
270
+ *
271
+ * @param self A reference to the Backup object to make the call on.
272
+ * @param setting Either true or false. All other settings are ignored.
273
+ *
274
+ * @return A reference to the newly updated Backup object.
275
+ *
276
+ */
277
+ VALUE setBackupIgnoreChecksums(VALUE self, VALUE setting)
278
+ {
279
+ VALUE options = rb_iv_get(self, "@options");
280
+
281
+ if(setting == Qtrue || setting == Qfalse)
282
+ {
283
+ rb_hash_aset(options, IGNORE_CHECKSUMS, setting);
284
+ }
285
+
286
+ return(self);
287
+ }
288
+
289
+
290
+ /**
291
+ * This function provides the ignore_limbo attribute accessor for the Backup
292
+ * class.
293
+ *
294
+ * @param self A reference to the Backup object to make the call on.
295
+ *
296
+ * @return Either true or false.
297
+ *
298
+ */
299
+ VALUE getBackupIgnoreLimbo(VALUE self)
300
+ {
301
+ VALUE result = Qfalse,
302
+ options = rb_iv_get(self, "@options"),
303
+ value = rb_hash_aref(options, IGNORE_LIMBO);
304
+
305
+ if(value != Qnil)
306
+ {
307
+ result = value;
308
+ }
309
+
310
+ return(result);
311
+ }
312
+
313
+
314
+ /**
315
+ * This function provides the ignore_limbo attribute mutator for the Backup
316
+ * class.
317
+ *
318
+ * @param self A reference to the Backup object to make the call on.
319
+ * @param setting Either true or false. All other settings are ignored.
320
+ *
321
+ * @return A reference to the newly updated Backup object.
322
+ *
323
+ */
324
+ VALUE setBackupIgnoreLimbo(VALUE self, VALUE setting)
325
+ {
326
+ VALUE options = rb_iv_get(self, "@options");
327
+
328
+ if(setting == Qtrue || setting == Qfalse)
329
+ {
330
+ rb_hash_aset(options, IGNORE_LIMBO, setting);
331
+ }
332
+
333
+ return(self);
334
+ }
335
+
336
+
337
+ /**
338
+ * This function provides the metadata_only attribute accessor for the Backup
339
+ * class.
340
+ *
341
+ * @param self A reference to the Backup object to make the call on.
342
+ *
343
+ * @return Either true or false.
344
+ *
345
+ */
346
+ VALUE getBackupMetadataOnly(VALUE self)
347
+ {
348
+ VALUE result = Qfalse,
349
+ options = rb_iv_get(self, "@options"),
350
+ value = rb_hash_aref(options, METADATA_ONLY);
351
+
352
+ if(value != Qnil)
353
+ {
354
+ result = value;
355
+ }
356
+
357
+ return(result);
358
+ }
359
+
360
+
361
+ /**
362
+ * This function provides the metadata_only attribute mutator for the Backup
363
+ * class.
364
+ *
365
+ * @param self A reference to the Backup object to make the call on.
366
+ * @param setting Either true or false. All other settings are ignored.
367
+ *
368
+ * @return A reference to the newly updated Backup object.
369
+ *
370
+ */
371
+ VALUE setBackupMetadataOnly(VALUE self, VALUE setting)
372
+ {
373
+ VALUE options = rb_iv_get(self, "@options");
374
+
375
+ if(setting == Qtrue || setting == Qfalse)
376
+ {
377
+ rb_hash_aset(options, METADATA_ONLY, setting);
378
+ }
379
+
380
+ return(self);
381
+ }
382
+
383
+
384
+ /**
385
+ * This function provides the garbage_collection attribute accessor for the
386
+ * Backup class.
387
+ *
388
+ * @param self A reference to the Backup object to make the call on.
389
+ *
390
+ * @return Either true or false.
391
+ *
392
+ */
393
+ VALUE getBackupGarbageCollect(VALUE self)
394
+ {
395
+ VALUE result = Qtrue,
396
+ options = rb_iv_get(self, "@options"),
397
+ value = rb_hash_aref(options, NO_GARBAGE_COLLECT);
398
+
399
+ if(value != Qnil)
400
+ {
401
+ result = value;
402
+ }
403
+
404
+ return(result);
405
+ }
406
+
407
+
408
+ /**
409
+ * This function provides the garbage_collection attribute mutator for the
410
+ * Backup class.
411
+ *
412
+ * @param self A reference to the Backup object to make the call on.
413
+ * @param setting Either true or false. All other settings are ignored.
414
+ *
415
+ * @return A reference to the newly updated Backup object.
416
+ *
417
+ */
418
+ VALUE setBackupGarbageCollect(VALUE self, VALUE setting)
419
+ {
420
+ VALUE options = rb_iv_get(self, "@options");
421
+
422
+ if(setting == Qtrue || setting == Qfalse)
423
+ {
424
+ rb_hash_aset(options, NO_GARBAGE_COLLECT, setting);
425
+ }
426
+
427
+ return(self);
428
+ }
429
+
430
+
431
+ /**
432
+ * This function provides the non_transportable attribute accessor for the
433
+ * Backup class.
434
+ *
435
+ * @param self A reference to the Backup object to make the call on.
436
+ *
437
+ * @return Either true or false.
438
+ *
439
+ */
440
+ VALUE getBackupNonTransportable(VALUE self)
441
+ {
442
+ VALUE result = Qfalse,
443
+ options = rb_iv_get(self, "@options"),
444
+ value = rb_hash_aref(options, NON_TRANSPORTABLE);
445
+
446
+ if(value != Qnil)
447
+ {
448
+ result = value;
449
+ }
450
+
451
+ return(result);
452
+ }
453
+
454
+
455
+ /**
456
+ * This function provides the non_transportable attribute mutator for the Backup
457
+ * class.
458
+ *
459
+ * @param self A reference to the Backup object to make the call on.
460
+ * @param setting Either true or false. All other settings are ignored.
461
+ *
462
+ * @return A reference to the newly updated Backup object.
463
+ *
464
+ */
465
+ VALUE setBackupNonTransportable(VALUE self, VALUE setting)
466
+ {
467
+ VALUE options = rb_iv_get(self, "@options");
468
+
469
+ if(setting == Qtrue || setting == Qfalse)
470
+ {
471
+ rb_hash_aset(options, NON_TRANSPORTABLE, setting);
472
+ }
473
+
474
+ return(self);
475
+ }
476
+
477
+
478
+ /**
479
+ * This function provides the convert_tables attribute accessor for the Backup
480
+ * class.
481
+ *
482
+ * @param self A reference to the Backup object to make the call on.
483
+ *
484
+ * @return Either true or false.
485
+ *
486
+ */
487
+ VALUE getBackupConvertTables(VALUE self)
488
+ {
489
+ VALUE result = Qfalse,
490
+ options = rb_iv_get(self, "@options"),
491
+ value = rb_hash_aref(options, CONVERT_TABLES);
492
+
493
+ if(value != Qnil)
494
+ {
495
+ result = value;
496
+ }
497
+
498
+ return(result);
499
+ }
500
+
501
+
502
+ /**
503
+ * This function provides the convert_tables attribute mutator for the Backup
504
+ * class.
505
+ *
506
+ * @param self A reference to the Backup object to make the call on.
507
+ * @param setting Either true or false. All other settings are ignored.
508
+ *
509
+ * @return A reference to the newly updated Backup object.
510
+ *
511
+ */
512
+ VALUE setBackupConvertTables(VALUE self, VALUE setting)
513
+ {
514
+ VALUE options = rb_iv_get(self, "@options");
515
+
516
+ if(setting == Qtrue || setting == Qfalse)
517
+ {
518
+ rb_hash_aset(options, CONVERT_TABLES, setting);
519
+ }
520
+
521
+ return(self);
522
+ }
523
+
524
+
525
+ /**
526
+ * This function provides the execute method for the Backup class.
527
+ *
528
+ * @param self A reference to the Backup object to be executed.
529
+ * @param manager A reference to the ServiceManager object that will be used
530
+ * to execute the backup.
531
+ *
532
+ * @return A reference to the Backup object executed.
533
+ *
534
+ */
535
+ VALUE executeBackup(VALUE self, VALUE manager)
536
+ {
537
+ ManagerHandle *handle = NULL;
538
+ short length = 0;
539
+ char *buffer = NULL;
540
+ ISC_STATUS status[20];
541
+
542
+ /* Check that the service manager is connected. */
543
+ Data_Get_Struct(manager, ManagerHandle, handle);
544
+ if(handle->handle == 0)
545
+ {
546
+ rb_fireruby_raise(NULL,
547
+ "Database backup error. Service manager not connected.");
548
+ }
549
+
550
+ createBackupBuffer(rb_iv_get(self, "@database"), rb_iv_get(self, "@files"),
551
+ rb_iv_get(self, "@options"), &buffer, &length);
552
+
553
+ /* Start the service request. */
554
+ if(isc_service_start(status, &handle->handle, NULL, length, buffer))
555
+ {
556
+ free(buffer);
557
+ rb_fireruby_raise(status, "Error performing database backup.");
558
+ }
559
+ free(buffer);
560
+
561
+ /* Query the service until it has completed. */
562
+ rb_iv_set(self, "@log", queryService(&handle->handle));
563
+
564
+ return(self);
565
+ }
566
+
567
+
568
+ /**
569
+ * This function provides the log attribute accessor for the Backup class.
570
+ *
571
+ * @param self A reference to the Backup object to make the call on.
572
+ *
573
+ * @return A reference to the current log attribute value.
574
+ *
575
+ */
576
+ VALUE getBackupLog(VALUE self)
577
+ {
578
+ return(rb_iv_get(self, "@log"));
579
+ }
580
+
581
+
582
+ /**
583
+ * This function creates a service parameter buffer for backup service
584
+ * requests.
585
+ *
586
+ * @param from A reference to a String containing the path and name of the
587
+ * database file to be backed up.
588
+ * @param to Either a reference to a String containing the path and name
589
+ * of the backup file or a hash matching file path/names to
590
+ * their permitted sizes.
591
+ * @param options A reference to a Hash containing the parameter options to
592
+ * be used.
593
+ * @param buffer A pointer that will be set to the generated parameter
594
+ * buffer.
595
+ * @param length A pointer to a short integer that will be assigned the
596
+ * length of buffer.
597
+ *
598
+ */
599
+ void createBackupBuffer(VALUE from, VALUE to, VALUE options, char **buffer,
600
+ short *length)
601
+ {
602
+ ID id = rb_intern("key?");
603
+ VALUE names = rb_funcall(to, rb_intern("keys"), 0),
604
+ sizes = rb_funcall(to, rb_intern("values"), 0),
605
+ count = rb_funcall(names, rb_intern("size"), 0);
606
+ char *position = NULL;
607
+ short number,
608
+ flags = 0,
609
+ extras = 0,
610
+ blocking = 0,
611
+ size = TYPE(count) == T_FIXNUM ? FIX2INT(count) : NUM2INT(count),
612
+ i;
613
+
614
+ /* Check if extra options have been provided. */
615
+ if(TYPE(options) != T_NIL)
616
+ {
617
+ VALUE temp = rb_funcall(options, rb_intern("size"), 0);
618
+
619
+ extras = TYPE(temp) == T_FIXNUM ? FIX2INT(temp) : NUM2INT(temp);
620
+ }
621
+
622
+ /* Calculate the length needed for the buffer. */
623
+ *length = 2;
624
+ *length += strlen(STR2CSTR(from)) + 3;
625
+
626
+ /* Count file name and length sizes. */
627
+ for(i = 0; i < size; i++)
628
+ {
629
+ *length += strlen(STR2CSTR(rb_ary_entry(names, i))) + 3;
630
+ if(i != size - 1)
631
+ {
632
+ VALUE num = rb_funcall(rb_ary_entry(sizes, i), rb_intern("to_s"), 0);
633
+
634
+ *length += strlen(STR2CSTR(num)) + 3;
635
+ }
636
+ }
637
+
638
+ if(extras)
639
+ {
640
+ if(rb_funcall(options, id, 1, INT2FIX(isc_spb_bkp_factor)) == Qtrue)
641
+ {
642
+ *length += 5;
643
+ blocking = 1;
644
+ }
645
+
646
+ if(rb_funcall(options, id, 1, IGNORE_CHECKSUMS) == Qtrue ||
647
+ rb_funcall(options, id, 1, IGNORE_LIMBO) == Qtrue ||
648
+ rb_funcall(options, id, 1, METADATA_ONLY) == Qtrue ||
649
+ rb_funcall(options, id, 1, NO_GARBAGE_COLLECT) == Qtrue ||
650
+ rb_funcall(options, id, 1, NON_TRANSPORTABLE) == Qtrue ||
651
+ rb_funcall(options, id, 1, CONVERT_TABLES) == Qtrue)
652
+ {
653
+ *length += 5;
654
+ flags = 1;
655
+ }
656
+ }
657
+
658
+ /* Allocate the buffer. */
659
+ *buffer = position = ALLOC_N(char, *length);
660
+ if(*buffer == NULL)
661
+ {
662
+ rb_raise(rb_eNoMemError,
663
+ "Memory allocation error preparing database back up.");
664
+ }
665
+ memset(*buffer, 0, *length);
666
+
667
+ /* Populate the buffer. */
668
+ *position++ = isc_action_svc_backup;
669
+
670
+ *position++ = isc_spb_dbname;
671
+ number = strlen(STR2CSTR(from));
672
+ ADD_SPB_LENGTH(position, number);
673
+ memcpy(position, STR2CSTR(from), number);
674
+ position += number;
675
+
676
+ for(i = 0; i < size; i++)
677
+ {
678
+ VALUE name = rb_ary_entry(names, i);
679
+
680
+ *position++ = isc_spb_bkp_file;
681
+ number = strlen(STR2CSTR(name));
682
+ ADD_SPB_LENGTH(position, number);
683
+ memcpy(position, STR2CSTR(name), number);
684
+ position += number;
685
+
686
+ if(i != size - 1)
687
+ {
688
+ VALUE max = rb_ary_entry(sizes, i);
689
+
690
+ max = rb_funcall(max, rb_intern("to_s"), 0);
691
+ *position++ = isc_spb_bkp_length;
692
+ number = strlen(STR2CSTR(max));
693
+ ADD_SPB_LENGTH(position, number);
694
+ memcpy(position, STR2CSTR(max), number);
695
+ position += number;
696
+ }
697
+ }
698
+
699
+ if(extras && blocking)
700
+ {
701
+ VALUE key = INT2FIX(isc_spb_bkp_factor),
702
+ temp = rb_funcall(options, rb_intern("fetch"), 1, key);
703
+ unsigned long size = TYPE(temp) == T_FIXNUM ? FIX2INT(temp) : NUM2INT(temp);
704
+
705
+ *position++ = isc_spb_bkp_factor;
706
+ memcpy(position, &size, 4);
707
+ position += 4;
708
+ }
709
+
710
+ if(extras && flags)
711
+ {
712
+ unsigned long mask = 0;
713
+
714
+ if(rb_funcall(options, id, 1, IGNORE_CHECKSUMS) == Qtrue)
715
+ {
716
+ mask |= isc_spb_bkp_ignore_checksums;
717
+ }
718
+
719
+ if(rb_funcall(options, id, 1, IGNORE_LIMBO) == Qtrue)
720
+ {
721
+ mask |= isc_spb_bkp_ignore_limbo;
722
+ }
723
+
724
+ if(rb_funcall(options, id, 1, METADATA_ONLY) == Qtrue)
725
+ {
726
+ mask |= isc_spb_bkp_metadata_only;
727
+ }
728
+
729
+ if(rb_funcall(options, id, 1, NO_GARBAGE_COLLECT) == Qtrue)
730
+ {
731
+ mask |= isc_spb_bkp_no_garbage_collect;
732
+ }
733
+
734
+ if(rb_funcall(options, id, 1, NON_TRANSPORTABLE) == Qtrue)
735
+ {
736
+ mask |= isc_spb_bkp_non_transportable;
737
+ }
738
+
739
+ if(rb_funcall(options, id, 1, CONVERT_TABLES) == Qtrue)
740
+ {
741
+ mask |= isc_spb_bkp_convert;
742
+ }
743
+
744
+ *position++ = isc_spb_options;
745
+ memcpy(position, &mask, 4);
746
+ position += 4;
747
+ }
748
+
749
+ *position++ = isc_spb_verbose;
750
+ }
751
+
752
+
753
+ /**
754
+ * This function initialize the Backup class in the Ruby environment.
755
+ *
756
+ * @param module The module to create the new class definition under.
757
+ *
758
+ */
759
+ void Init_Backup(VALUE module)
760
+ {
761
+ cBackup = rb_define_class_under(module, "Backup", rb_cObject);
762
+ rb_define_method(cBackup, "initialize", initializeBackup, 2);
763
+ rb_define_method(cBackup, "backup_file", getBackupFile, 0);
764
+ rb_define_method(cBackup, "backup_file=", setBackupFile, 1);
765
+ rb_define_method(cBackup, "database", getBackupDatabase, 0);
766
+ rb_define_method(cBackup, "database=", setBackupDatabase, 1);
767
+ rb_define_method(cBackup, "blocking_factor", getBackupBlockingFactor, 0);
768
+ rb_define_method(cBackup, "blocking_factor=", setBackupBlockingFactor, 1);
769
+ rb_define_method(cBackup, "ignore_checksums", getBackupIgnoreChecksums, 0);
770
+ rb_define_method(cBackup, "ignore_checksums=", setBackupIgnoreChecksums, 1);
771
+ rb_define_method(cBackup, "ignore_limbo", getBackupIgnoreLimbo, 0);
772
+ rb_define_method(cBackup, "ignore_limbo=", setBackupIgnoreLimbo, 1);
773
+ rb_define_method(cBackup, "metadata_only", getBackupMetadataOnly, 0);
774
+ rb_define_method(cBackup, "metadata_only=", setBackupMetadataOnly, 1);
775
+ rb_define_method(cBackup, "garbage_collect", getBackupGarbageCollect, 0);
776
+ rb_define_method(cBackup, "garbage_collect=", setBackupGarbageCollect, 1);
777
+ rb_define_method(cBackup, "non_transportable", getBackupNonTransportable, 0);
778
+ rb_define_method(cBackup, "non_transportable=", setBackupNonTransportable, 1);
779
+ rb_define_method(cBackup, "convert_tables", getBackupConvertTables, 0);
780
+ rb_define_method(cBackup, "convert_tables=", setBackupConvertTables, 1);
781
+ rb_define_method(cBackup, "execute", executeBackup, 1);
782
+ rb_define_method(cBackup, "log", getBackupLog, 0);
783
+ }