sbdb/lib/sbdb/db.rb

157 lines
3.3 KiB
Ruby
Raw Normal View History

2010-02-02 00:52:25 +01:00
require 'bdb'
require 'sbdb/cursor'
module SBDB
2010-02-06 11:50:52 +01:00
TYPES = []
2010-02-02 00:52:25 +01:00
class DB
UNKNOWN = Bdb::Db::UNKNOWN
BTREE = Bdb::Db::BTREE
HASH = Bdb::Db::HASH
QUEUE = Bdb::Db::QUEUE
ARRAY = RECNO = Bdb::Db::RECNO
2010-02-02 18:12:11 +01:00
RDONLY = READLONY = Bdb::DB_RDONLY
CONSUME = Bdb::DB_CONSUME
CONSUME_WAIT = Bdb::DB_CONSUME_WAIT
2010-02-02 00:52:25 +01:00
attr_reader :home
2010-03-09 19:09:22 +01:00
attr_accessor :txn
2010-02-02 00:52:25 +01:00
include Enumerable
def bdb_object() @db end
def sync() @db.sync end
2010-03-12 21:14:38 +01:00
def close( flg = nil) @db.close flg || 0 end
def cursor( &exe) Cursor.new self, &exe end
2010-02-02 00:52:25 +01:00
2010-03-12 21:14:38 +01:00
def at key, txn = nil
@db.get _txn(txn), key.nil? ? nil : key.to_s, nil, 0
2010-02-23 19:39:27 +01:00
rescue Bdb::KeyEmpty
return nil
end
alias [] at
2010-03-12 21:14:38 +01:00
def put key, val, txn = nil
if val.nil?
@db.del _txn(txn), key.to_s, 0
else
2010-03-12 21:14:38 +01:00
@db.put _txn(txn), key.nil? ? nil : key.to_s, val.to_s, 0
end
end
2010-03-12 21:14:38 +01:00
def []= key, val
put key, val
end
2010-03-12 21:14:38 +01:00
def delete key, txn = nil
@db.del _txn(txn), key.to_s
end
alias del delete
2010-02-02 00:52:25 +01:00
class << self
def new *ps, &exe
ret = obj = super( *ps)
2010-03-12 21:14:38 +01:00
begin ret = exe.call obj
2010-02-02 00:52:25 +01:00
ensure
SBDB::raise_barrier &obj.method(:sync)
SBDB::raise_barrier &obj.method(:close)
end if exe
ret
2010-02-02 00:52:25 +01:00
end
alias open new
end
2010-03-12 21:14:38 +01:00
def _txn txn
txn ||= @txn
2011-08-25 13:23:38 +02:00
txn && txn.bdb_object
end
def transaction flg = nil, &exe
block_given? ? home.transaction( flg, &exe) : home.transaction( flg)
end
# Arguments:
# * file
# * name
# * type
# * flags
# * mode
# * env
# or: **file**, **opts**. *opts* must be a *::Hash* with keys like above, excluded *file*.
2010-02-23 19:39:27 +01:00
def initialize file, *args
2010-02-23 20:20:26 +01:00
opts = ::Hash === args.last ? args.pop : {}
opts = {:name => args[0], :type => args[1], :flags => args[2], :mode => args[3], :env => args[4]}.update opts
#type = BTREE if type == UNKNOWN and (flags & CREATE) == CREATE
2010-02-23 19:39:27 +01:00
@home, @db = opts[:env], opts[:env] ? opts[:env].bdb_object.db : Bdb::Db.new
2010-02-23 20:20:26 +01:00
opts[:type] = TYPES.index(self.class) || UNKNOWN
@db.re_len = opts[:re_len] if opts[:re_len]
@txn = nil
txn = opts[:txn] # First is the global txn, second only for open.
begin
2010-03-09 19:09:22 +01:00
@db.open txn && txn.bdb_object, file, opts[:name], opts[:type], opts[:flags] || 0, opts[:mode] || 0
2010-04-14 11:34:27 +02:00
rescue Object => exc
2010-02-02 00:52:25 +01:00
close
raise exc
2010-02-02 00:52:25 +01:00
end
end
2010-03-12 21:14:38 +01:00
def each key = nil, val = nil, &exe
2010-04-03 13:18:50 +02:00
cursor {|c| c.each key, val, &exe }
2010-02-02 00:52:25 +01:00
end
2010-03-12 21:14:38 +01:00
def reverse key = nil, val = nil, &exe
2010-04-03 13:18:50 +02:00
cursor {|c| c.reverse key, val, &exe }
2010-02-02 00:52:25 +01:00
end
2010-04-03 13:12:57 +02:00
def to_hash key = nil, val = nil
2010-04-03 13:09:53 +02:00
ht = {}
2010-04-03 13:18:50 +02:00
each key, val, &ht.method( :[]=)
2010-04-03 13:09:53 +02:00
ht
2010-02-02 00:52:25 +01:00
end
def truncate txn = nil
@db.truncate _txn(txn)
end
2010-02-02 00:52:25 +01:00
end
class Unknown < DB
2010-03-12 21:14:38 +01:00
def self.new file, *ps, &exe
dbt = super( file, *ps) {|db| db.bdb_object.get_type }
TYPES[dbt] ? TYPES[dbt].new( file, *ps, &exe) : super( file, *ps, &exe)
2010-02-02 00:52:25 +01:00
end
end
class Btree < DB
end
2010-02-06 11:50:52 +01:00
TYPES[DB::BTREE] = Btree
2010-02-02 00:52:25 +01:00
class Hash < DB
end
2010-02-06 11:50:52 +01:00
TYPES[DB::HASH] = Hash
2010-02-02 00:52:25 +01:00
module Arrayisch
2010-03-12 21:14:38 +01:00
def [] key
super [key].pack('I')
2010-02-02 15:15:10 +01:00
end
2010-03-29 11:45:57 +02:00
def []= key, val
2010-03-12 21:14:38 +01:00
super [key].pack('I'), val
2010-02-02 15:15:10 +01:00
end
2010-02-22 16:17:25 +01:00
2010-03-12 21:14:38 +01:00
def push val, txn = nil
2010-03-29 11:45:57 +02:00
@db.put _txn(txn), "\0\0\0\0", val, Bdb::DB_APPEND
2010-02-22 16:17:25 +01:00
end
2010-02-02 00:52:25 +01:00
end
class Recno < DB
2010-03-29 11:44:04 +02:00
include Arrayisch
end
2010-02-02 00:52:25 +01:00
Array = Recno
2010-02-06 11:50:52 +01:00
TYPES[DB::RECNO] = Recno
2010-02-02 00:52:25 +01:00
class Queue < DB
2010-03-29 11:44:04 +02:00
include Arrayisch
def unshift txn = nil
@db.get _txn(txn), "\0\0\0\0", nil, Bdb::DB_CONSUME
end
2010-02-02 00:52:25 +01:00
end
2010-02-06 11:50:52 +01:00
TYPES[DB::QUEUE] = Queue
2010-02-02 00:52:25 +01:00
end