rod 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/.travis.yml +1 -1
  2. data/README.rdoc +38 -10
  3. data/Rakefile +20 -9
  4. data/changelog.txt +25 -0
  5. data/contributors.txt +1 -0
  6. data/data/backward/0.7.0/_join_element.dat +0 -0
  7. data/data/backward/0.7.0/_polymorphic_join_element.dat +0 -0
  8. data/data/backward/0.7.0/char.dat +0 -0
  9. data/data/backward/0.7.0/database.yml +58 -0
  10. data/data/backward/0.7.0/rod_test__automobile.dat +0 -0
  11. data/data/backward/0.7.0/rod_test__caveman.dat +0 -0
  12. data/data/backward/0.7.0/rod_test__dog.dat +0 -0
  13. data/data/backward/0.7.0/rod_test__test_model.dat +0 -0
  14. data/data/portability/_join_element.dat +0 -0
  15. data/data/portability/_polymorphic_join_element.dat +0 -0
  16. data/data/portability/char.dat +0 -0
  17. data/data/portability/database.yml +49 -0
  18. data/data/portability/rod_test__automobile.dat +0 -0
  19. data/data/portability/rod_test__caveman.dat +0 -0
  20. data/data/portability/rod_test__dog.dat +0 -0
  21. data/data/portability/rod_test__test_model.dat +0 -0
  22. data/features/backward.feature +33 -0
  23. data/features/basic.feature +3 -0
  24. data/features/collection_proxy.feature +95 -0
  25. data/features/flat_indexing.feature +44 -2
  26. data/features/hash_indexing.feature +63 -9
  27. data/features/portability.feature +72 -0
  28. data/features/segmented_indexing.feature +45 -2
  29. data/features/steps/collection_proxy.rb +1 -1
  30. data/features/steps/model.rb +48 -5
  31. data/features/steps/rod.rb +15 -16
  32. data/lib/rod.rb +11 -1
  33. data/lib/rod/abstract_database.rb +52 -42
  34. data/lib/rod/berkeley/collection_proxy.rb +96 -0
  35. data/lib/rod/berkeley/database.rb +337 -0
  36. data/lib/rod/berkeley/environment.rb +209 -0
  37. data/lib/rod/berkeley/sequence.rb +222 -0
  38. data/lib/rod/berkeley/transaction.rb +233 -0
  39. data/lib/rod/collection_proxy.rb +76 -1
  40. data/lib/rod/constants.rb +3 -2
  41. data/lib/rod/database.rb +127 -14
  42. data/lib/rod/index/base.rb +12 -3
  43. data/lib/rod/index/hash_index.rb +295 -70
  44. data/lib/rod/index/segmented_index.rb +3 -0
  45. data/lib/rod/model.rb +154 -531
  46. data/lib/rod/property/base.rb +190 -0
  47. data/lib/rod/property/field.rb +258 -0
  48. data/lib/rod/property/plural_association.rb +145 -0
  49. data/lib/rod/property/singular_association.rb +139 -0
  50. data/rod.gemspec +6 -4
  51. data/spec/berkeley/database.rb +83 -0
  52. data/spec/berkeley/environment.rb +58 -0
  53. data/spec/berkeley/sequence.rb +101 -0
  54. data/spec/berkeley/transaction.rb +92 -0
  55. data/spec/collection_proxy.rb +38 -0
  56. data/spec/database.rb +36 -0
  57. data/spec/model.rb +26 -0
  58. data/spec/property/base.rb +73 -0
  59. data/spec/property/field.rb +244 -0
  60. data/spec/property/plural_association.rb +67 -0
  61. data/spec/property/singular_association.rb +65 -0
  62. data/tests/class_compatibility_create.rb +2 -2
  63. data/tests/eff1_test.rb +1 -1
  64. data/tests/eff2_test.rb +1 -1
  65. data/tests/full_runs.rb +1 -1
  66. data/tests/generate_classes_create.rb +14 -14
  67. data/tests/migration_create.rb +47 -47
  68. data/tests/migration_verify.rb +1 -1
  69. data/tests/missing_class_create.rb +6 -6
  70. data/tests/properties_order_create.rb +4 -4
  71. data/tests/read_on_create.rb +33 -34
  72. data/tests/save_struct.rb +40 -39
  73. data/tests/unit/database.rb +1 -1
  74. data/tests/unit/model_tests.rb +73 -65
  75. metadata +71 -15
  76. data/tests/unit/model.rb +0 -36
@@ -10,50 +10,36 @@ module Rod
10
10
  class Handle
11
11
  end
12
12
 
13
+ # The class given index is associated with.
14
+ attr_reader :klass
15
+
13
16
  # Initializes the index with +path+ and +class+.
14
17
  # Options are not (yet) used.
15
18
  def initialize(path,klass,options={})
16
19
  @path = path + ".db"
17
20
  @klass = klass
18
- open(@path,:create => true)
19
21
  end
20
22
 
21
23
  # Stores the index on disk.
22
24
  def save
23
- raise RodException.new("The index #{self} is not opened!") unless opened?
24
- if @index.empty?
25
- close
26
- return
27
- end
28
- @index.keys.each do |key|
29
- collection = self[key]
30
- key = key.encode("utf-8") if key.is_a?(String)
31
- key = Marshal.dump(key)
32
- collection.save
33
- _put(key,collection.offset,collection.size)
34
- end
35
25
  close
36
26
  end
37
27
 
38
28
  # Clears the contents of the index.
39
29
  def destroy
40
30
  close if opened?
41
- open(@path,:truncate => true)
31
+ remove_file(@path)
42
32
  end
43
33
 
44
- # Simple iterator.
34
+ # Iterates over the keys and corresponding
35
+ # values present in the index.
45
36
  def each
46
37
  if block_given?
47
- @index.each do |key,value|
48
- yield key,value
49
- end
50
- open(@path) unless opened?
38
+ open(@path, :create => true) unless opened?
51
39
  _each_key do |key|
52
40
  next if key.empty?
53
41
  key = Marshal.load(key)
54
- unless @index[key]
55
- yield key,self[key]
56
- end
42
+ yield key,self[key]
57
43
  end
58
44
  else
59
45
  enum_for(:each)
@@ -63,12 +49,45 @@ module Rod
63
49
  # Copies the index from the given +index+.
64
50
  # The index have to cleared before being copied.
65
51
  def copy(index)
66
- close if opened?
67
- open(@path,:truncate => true)
52
+ self.destroy
68
53
  super(index)
69
54
  end
70
55
 
56
+ # Delets given +value+ for the given +key+.
57
+ # If the +value+ is nil, then the key is removed
58
+ # with all the values.
59
+ def delete(key,value=nil)
60
+ _delete(key,value)
61
+ end
62
+
63
+ # Registers given +rod_id+ for the given +key+.
64
+ def put(key,rod_id)
65
+ _put(key,rod_id)
66
+ end
67
+
68
+ # Iterates over all values for a given +key+. Raises
69
+ # KeyMissing if the key is not present.
70
+ def each_for(key)
71
+ _get(key) do |value|
72
+ yield value
73
+ end
74
+ end
75
+
76
+ # Returns the first value for a given +key+ or
77
+ # raises keyMissing exception if it is not present.
78
+ def get_first(key)
79
+ _get_first(key)
80
+ end
81
+
82
+
71
83
  protected
84
+ # Returns an empty BDB based collection proxy.
85
+ def empty_collection_proxy(key)
86
+ key = key.encode("utf-8") if key.is_a?(String)
87
+ key = Marshal.dump(key)
88
+ Rod::Berkeley::CollectionProxy.new(self,key)
89
+ end
90
+
72
91
  # Opens the index - initializes the index C structures
73
92
  # and the cache.
74
93
  # Options:
@@ -78,7 +97,6 @@ module Rod
78
97
  raise RodException.new("The index #{@path} is already opened!") if opened?
79
98
  _open(path,options)
80
99
  @opened = true
81
- @index = {} if @index.nil?
82
100
  end
83
101
 
84
102
  # Closes the disk - frees the C structure and clears the cache.
@@ -86,7 +104,6 @@ module Rod
86
104
  return unless opened?
87
105
  _close()
88
106
  @opened = false
89
- @index.clear
90
107
  end
91
108
 
92
109
  # Checks if the index is opened.
@@ -96,20 +113,14 @@ module Rod
96
113
 
97
114
  # Returns a value of the index for a given +key+.
98
115
  def get(key)
99
- return @index[key] if @index.has_key?(key)
100
- begin
101
- open(@path) unless opened?
102
- key = key.encode("utf-8") if key.is_a?(String)
103
- value = _get(Marshal.dump(key))
104
- rescue Rod::KeyMissing => ex
105
- value = nil
106
- end
107
- @index[key] = value
116
+ # TODO # 208
117
+ open(@path,:create => true) unless opened?
118
+ empty_collection_proxy(key)
108
119
  end
109
120
 
110
- # Sets the +value+ for the +key+ in the internal cache.
111
- def set(key,value)
112
- @index[key] = value
121
+ # Sets the +proxy+ for the +key+ in the internal cache.
122
+ def set(key,proxy)
123
+ # do nothing - the value is set in proxy#<< method
113
124
  end
114
125
 
115
126
  # C definition of the RodException.
@@ -164,14 +175,139 @@ module Rod
164
175
  str.margin
165
176
  end
166
177
 
178
+ # The cursor free method.
179
+ def self.cursor_free
180
+ str =<<-END
181
+ |void cursor_free(DBC *cursor){
182
+ | int return_value;
183
+ | if(cursor != NULL){
184
+ | return_value = cursor->close(cursor);
185
+ | if(return_value != 0){
186
+ | rb_raise(rodException(),"%s",db_strerror(return_value));
187
+ | }
188
+ | }
189
+ |}
190
+ END
191
+ str.margin
192
+ end
193
+
194
+ # The cursor closing method.
195
+ def self.close_cursor
196
+ str =<<-END
197
+ |VALUE close_cursor(VALUE cursor_object){
198
+ | DBC *cursor;
199
+ | int return_value;
200
+ |
201
+ | Data_Get_Struct(cursor_object,DBC,cursor);
202
+ | if(cursor != NULL){
203
+ | return_value = cursor->close(cursor);
204
+ | DATA_PTR(cursor_object) = NULL;
205
+ | if(return_value != 0){
206
+ | rb_raise(rodException(),"%s",db_strerror(return_value));
207
+ | }
208
+ | }
209
+ | return Qnil;
210
+ |}
211
+ END
212
+ str.margin
213
+ end
214
+
215
+ def self.iterate_over_values
216
+ str =<<-END
217
+ |VALUE iterate_over_values(VALUE arguments){
218
+ | DBT db_key, db_value;
219
+ | DBC *cursor;
220
+ | unsigned long rod_id, index;
221
+ | VALUE key, result, cursor_object;
222
+ | int return_value;
223
+ |
224
+ | index = 0;
225
+ | key = rb_ary_shift(arguments);
226
+ | cursor_object = rb_ary_shift(arguments);
227
+ | Data_Get_Struct(cursor_object,DBC,cursor);
228
+ |
229
+ | memset(&db_value, 0, sizeof(DBT));
230
+ | db_value.data = &rod_id;
231
+ | db_value.ulen = sizeof(unsigned long);
232
+ | db_value.flags = DB_DBT_USERMEM;
233
+ |
234
+ | memset(&db_key, 0, sizeof(DBT));
235
+ | db_key.data = RSTRING_PTR(key);
236
+ | db_key.size = RSTRING_LEN(key);
237
+ |
238
+ | return_value = cursor->get(cursor, &db_key, &db_value, DB_SET);
239
+ | if(return_value == DB_NOTFOUND){
240
+ | rb_raise(keyMissingException(),"%s",db_strerror(return_value));
241
+ | } else if(return_value != 0){
242
+ | rb_raise(rodException(),"%s",db_strerror(return_value));
243
+ | }
244
+ | while(return_value != DB_NOTFOUND){
245
+ | index++;
246
+ |#ifdef __BYTE_ORDER
247
+ |# if __BYTE_ORDER == __BIG_ENDIAN
248
+ | rod_id = bswap_64(rod_id);
249
+ |# endif
250
+ |#endif
251
+ | rb_yield(ULONG2NUM(rod_id));
252
+ | return_value = cursor->get(cursor, &db_key, &db_value, DB_NEXT_DUP);
253
+ | if(return_value != 0 && return_value != DB_NOTFOUND){
254
+ | rb_raise(rodException(),"%s",db_strerror(return_value));
255
+ | }
256
+ | }
257
+ | return Qnil;
258
+ |}
259
+ END
260
+ str.margin
261
+ end
262
+
263
+ def self.iterate_over_keys
264
+ str =<<-END
265
+ |VALUE iterate_over_keys(VALUE cursor_object){
266
+ | DBT db_key, db_value;
267
+ | DBC *cursor;
268
+ | int return_value;
269
+ | rod_entry_struct *entry;
270
+ | VALUE key;
271
+ |
272
+ | Data_Get_Struct(cursor_object,DBC,cursor);
273
+ | memset(&db_key, 0, sizeof(DBT));
274
+ | memset(&db_value, 0, sizeof(DBT));
275
+ | db_key.flags = DB_DBT_MALLOC;
276
+ | while((return_value = cursor->get(cursor, &db_key, &db_value, DB_NEXT_NODUP)) == 0){
277
+ | key = rb_str_new((char *)db_key.data,db_key.size);
278
+ | free(db_key.data);
279
+ | rb_yield(key);
280
+ | }
281
+ | if(return_value != DB_NOTFOUND){
282
+ | rb_raise(rodException(),"%s",db_strerror(return_value));
283
+ | }
284
+ | return Qnil;
285
+ |}
286
+ END
287
+ str.margin
288
+ end
289
+
290
+ # You can set arbitrary ROD hash index link flags via
291
+ # ROD_BDB_LINK_FLAGS env. variable.
292
+ def self.rod_link_flags
293
+ ENV['ROD_BDB_LINK_FLAGS'] || '-ldb'
294
+ end
295
+
167
296
  self.inline(:C) do |builder|
168
297
  builder.include '<db.h>'
169
298
  builder.include '<stdio.h>'
170
- builder.add_compile_flags '-ldb-4.8'
299
+ builder.include '<byteswap.h>'
300
+ builder.include '<endian.h>'
301
+ builder.include '<stdint.h>'
302
+ builder.add_link_flags self.rod_link_flags
171
303
  builder.prefix(self.entry_struct)
172
304
  builder.prefix(self.rod_exception)
173
305
  builder.prefix(self.key_missing_exception)
174
306
  builder.prefix(self.convert_key)
307
+ builder.prefix(self.cursor_free)
308
+ builder.prefix(self.close_cursor)
309
+ builder.prefix(self.iterate_over_values)
310
+ builder.prefix(self.iterate_over_keys)
175
311
 
176
312
 
177
313
  str =<<-END
@@ -182,11 +318,17 @@ module Rod
182
318
  | VALUE handleClass;
183
319
  | VALUE handle;
184
320
  | VALUE mod;
321
+ |
185
322
  | db_pointer = ALLOC(DB);
186
323
  | return_value = db_create(&db_pointer,NULL,0);
187
324
  | if(return_value != 0){
188
325
  | rb_raise(rodException(),"%s",db_strerror(return_value));
189
326
  | }
327
+ | return_value = db_pointer->set_flags(db_pointer,DB_DUPSORT);
328
+ | if(return_value != 0){
329
+ | db_pointer->close(db_pointer,0);
330
+ | rb_raise(rodException(),"%s",db_strerror(return_value));
331
+ | }
190
332
  |
191
333
  | flags = 0;
192
334
  | if(rb_hash_aref(options,ID2SYM(rb_intern("create"))) == Qtrue){
@@ -196,9 +338,11 @@ module Rod
196
338
  | flags |= DB_TRUNCATE;
197
339
  | }
198
340
  |
341
+ | db_pointer->set_cachesize(db_pointer,0,5 * 1024 * 1024,0);
199
342
  | return_value = db_pointer->open(db_pointer,NULL,path,
200
343
  | NULL,DB_HASH,flags,0);
201
344
  | if(return_value != 0){
345
+ | db_pointer->close(db_pointer,0);
202
346
  | rb_raise(rodException(),"%s",db_strerror(return_value));
203
347
  | }
204
348
  | mod = rb_const_get(rb_cObject, rb_intern("Rod"));
@@ -216,6 +360,7 @@ module Rod
216
360
  |void _close(){
217
361
  | VALUE handle;
218
362
  | DB *db_pointer;
363
+ |
219
364
  | handle = rb_iv_get(self,"@handle");
220
365
  | Data_Get_Struct(handle,DB,db_pointer);
221
366
  | if(db_pointer != NULL){
@@ -229,44 +374,63 @@ module Rod
229
374
  builder.c(str.margin)
230
375
 
231
376
  str =<<-END
232
- |void _each_key(){
377
+ |// Iterate over all keys in the database.
378
+ |// The value returned is the index itself.
379
+ |VALUE _each_key(){
233
380
  | VALUE handle;
234
381
  | DB *db_pointer;
235
382
  | DBC *cursor;
236
- | DBT db_key, db_value;
237
- | int return_value;
238
- | rod_entry_struct *entry;
239
- | VALUE key;
383
+ | VALUE key, cursor_object;
240
384
  |
241
385
  | handle = rb_iv_get(self,"@handle");
242
386
  | Data_Get_Struct(handle,DB,db_pointer);
243
387
  | if(db_pointer != NULL){
244
388
  | db_pointer->cursor(db_pointer,NULL,&cursor,0);
245
- | memset(&db_key, 0, sizeof(DBT));
246
- | memset(&db_value, 0, sizeof(DBT));
247
- | db_key.flags = DB_DBT_MALLOC;
248
- | while((return_value = cursor->get(cursor, &db_key, &db_value, DB_NEXT)) == 0){
249
- | key = rb_str_new((char *)db_key.data,db_key.size);
250
- | free(db_key.data);
251
- | rb_yield(key);
252
- | }
253
- | if(return_value != DB_NOTFOUND){
254
- | rb_raise(rodException(),"%s",db_strerror(return_value));
255
- | }
256
- | cursor->close(cursor);
389
+ | cursor_object = Data_Wrap_Struct(rb_cObject,NULL,cursor_free,cursor);
390
+ | rb_ensure(iterate_over_keys,cursor_object,close_cursor,cursor_object);
257
391
  | } else {
258
392
  | rb_raise(rodException(),"DB handle is NULL\\n");
259
393
  | }
394
+ | return self;
260
395
  |}
261
396
  END
262
397
  builder.c(str.margin)
263
398
 
264
399
  str =<<-END
400
+ |// Iterate over values for a given key.
401
+ |// A KeyMissing exception is raised if the key is missing.
402
+ |// The value returned is the index itself.
265
403
  |VALUE _get(VALUE key){
266
404
  | VALUE handle;
267
405
  | DB *db_pointer;
406
+ | DBC *cursor;
407
+ | VALUE cursor_object, iterate_arguments;
408
+ |
409
+ | handle = rb_iv_get(self,"@handle");
410
+ | Data_Get_Struct(handle,DB,db_pointer);
411
+ | if(db_pointer != NULL){
412
+ | db_pointer->cursor(db_pointer,NULL,&cursor,0);
413
+ | cursor_object = Data_Wrap_Struct(rb_cObject,NULL,cursor_free,cursor);
414
+ | iterate_arguments = rb_ary_new();
415
+ | rb_ary_push(iterate_arguments,key);
416
+ | rb_ary_push(iterate_arguments,cursor_object);
417
+ | rb_ensure(iterate_over_values,iterate_arguments,close_cursor,cursor_object);
418
+ | } else {
419
+ | rb_raise(rodException(),"DB handle is NULL\\n");
420
+ | }
421
+ | return self;
422
+ |}
423
+ END
424
+ builder.c(str.margin)
425
+
426
+ str =<<-END
427
+ |// Returns the first value for a given +key+ or raises
428
+ |// KeyMissing if the key is not present.
429
+ |VALUE _get_first(VALUE key){
430
+ | VALUE handle;
431
+ | DB *db_pointer;
268
432
  | DBT db_key, db_value;
269
- | rod_entry_struct entry;
433
+ | unsigned long rod_id;
270
434
  | VALUE result;
271
435
  | int return_value;
272
436
  |
@@ -274,8 +438,8 @@ module Rod
274
438
  | Data_Get_Struct(handle,DB,db_pointer);
275
439
  | if(db_pointer != NULL){
276
440
  | memset(&db_value, 0, sizeof(DBT));
277
- | db_value.data = &entry;
278
- | db_value.ulen = sizeof(rod_entry_struct);
441
+ | db_value.data = &rod_id;
442
+ | db_value.ulen = sizeof(unsigned long);
279
443
  | db_value.flags = DB_DBT_USERMEM;
280
444
  |
281
445
  | memset(&db_key, 0, sizeof(DBT));
@@ -287,26 +451,28 @@ module Rod
287
451
  | rb_raise(keyMissingException(),"%s",db_strerror(return_value));
288
452
  | } else if(return_value != 0){
289
453
  | rb_raise(rodException(),"%s",db_strerror(return_value));
290
- | } else {
291
- | result = rb_ary_new();
292
- | rb_ary_push(result,ULONG2NUM(entry.offset));
293
- | rb_ary_push(result,ULONG2NUM(entry.size));
294
- | return result;
295
454
  | }
455
+ |#ifdef __BYTE_ORDER
456
+ |# if __BYTE_ORDER == __BIG_ENDIAN
457
+ | rod_id = bswap_64(rod_id);
458
+ |# endif
459
+ |#endif
460
+ | return ULONG2NUM(rod_id);
296
461
  | } else {
297
462
  | rb_raise(rodException(),"DB handle is NULL\\n");
298
463
  | }
464
+ | // This should never be reached.
465
+ | rb_raise(rodException(),"Invalid _get_first implementation!\\n");
299
466
  | return Qnil;
300
467
  |}
301
468
  END
302
469
  builder.c(str.margin)
303
470
 
304
471
  str =<<-END
305
- |void _put(VALUE key,unsigned long offset,unsigned long size){
472
+ |void _put(VALUE key,unsigned long rod_id){
306
473
  | VALUE handle;
307
474
  | DB *db_pointer;
308
475
  | DBT db_key, db_value;
309
- | rod_entry_struct entry;
310
476
  | int return_value;
311
477
  |
312
478
  | handle = rb_iv_get(self,"@handle");
@@ -315,10 +481,13 @@ module Rod
315
481
  | db_key.data = RSTRING_PTR(key);
316
482
  | db_key.size = RSTRING_LEN(key);
317
483
  | memset(&db_value, 0, sizeof(DBT));
318
- | entry.offset = offset;
319
- | entry.size = size;
320
- | db_value.data = &entry;
321
- | db_value.size = sizeof(rod_entry_struct);
484
+ |#ifdef __BYTE_ORDER
485
+ |# if __BYTE_ORDER == __BIG_ENDIAN
486
+ | rod_id = bswap_64(rod_id);
487
+ |# endif
488
+ |#endif
489
+ | db_value.data = &rod_id;
490
+ | db_value.size = sizeof(unsigned long);
322
491
  | if(db_pointer != NULL){
323
492
  | return_value = db_pointer->put(db_pointer, NULL, &db_key, &db_value, 0);
324
493
  | if(return_value != 0){
@@ -330,6 +499,62 @@ module Rod
330
499
  |}
331
500
  END
332
501
  builder.c(str.margin)
502
+
503
+ str =<<-END
504
+ |void _delete(VALUE key,VALUE value){
505
+ | VALUE handle;
506
+ | DB *db_pointer;
507
+ | DBT db_key, db_value;
508
+ | DBC *cursor;
509
+ | int return_value;
510
+ | unsigned long rod_id = 0;
511
+ |
512
+ | handle = rb_iv_get(self,"@handle");
513
+ | Data_Get_Struct(handle,DB,db_pointer);
514
+ | memset(&db_key, 0, sizeof(DBT));
515
+ | db_key.data = RSTRING_PTR(key);
516
+ | db_key.size = RSTRING_LEN(key);
517
+ | memset(&db_value, 0, sizeof(DBT));
518
+ |
519
+ | if(db_pointer != NULL){
520
+ | if(value == Qnil){
521
+ | return_value = db_pointer->del(db_pointer, NULL, &db_key, 0);
522
+ | if(return_value == DB_NOTFOUND){
523
+ | rb_raise(keyMissingException(),"%s",db_strerror(return_value));
524
+ | } else if(return_value != 0){
525
+ | rb_raise(rodException(),"%s",db_strerror(return_value));
526
+ | }
527
+ | } else {
528
+ | rod_id = NUM2ULONG(value);
529
+ |#ifdef __BYTE_ORDER
530
+ |# if __BYTE_ORDER == __BIG_ENDIAN
531
+ | rod_id = bswap_64(rod_id);
532
+ |# endif
533
+ |#endif
534
+ | memset(&db_value, 0, sizeof(DBT));
535
+ | db_value.data = &rod_id;
536
+ | db_value.size = sizeof(unsigned long);
537
+ | db_pointer->cursor(db_pointer,NULL,&cursor,0);
538
+ | return_value = cursor->get(cursor,&db_key,&db_value,DB_GET_BOTH);
539
+ | if(return_value == DB_NOTFOUND){
540
+ | cursor->close(cursor);
541
+ | rb_raise(keyMissingException(),"%s",db_strerror(return_value));
542
+ | } else if(return_value != 0){
543
+ | cursor->close(cursor);
544
+ | rb_raise(rodException(),"%s",db_strerror(return_value));
545
+ | }
546
+ | return_value = cursor->del(cursor,0);
547
+ | cursor->close(cursor);
548
+ | if(return_value != 0){
549
+ | rb_raise(rodException(),"%s",db_strerror(return_value));
550
+ | }
551
+ | }
552
+ | } else {
553
+ | rb_raise(rodException(),"DB handle is NULL\\n");
554
+ | }
555
+ |}
556
+ END
557
+ builder.c(str.margin)
333
558
  end
334
559
  end
335
560
  end