75 lines
1.7 KiB
Ruby
75 lines
1.7 KiB
Ruby
require 'bdb/base'
|
|
|
|
class Bdb::PartitionedDatabase < Bdb::Base
|
|
SEPARATOR = '__'
|
|
PARTITION_PATTERN = /^[-\w]*$/
|
|
|
|
def initialize(base_name, opts = {})
|
|
@base_name = base_name
|
|
@partition_by = opts.delete(:partition_by)
|
|
super(opts)
|
|
end
|
|
attr_reader :base_name, :partition_by, :partition
|
|
|
|
def databases
|
|
@databases ||= {}
|
|
end
|
|
|
|
def database(partition = nil)
|
|
partition ||= self.partition
|
|
raise 'partition value required' if partition.nil?
|
|
partition = partition.to_s
|
|
raise "invalid partition value: #{partition}" unless partition =~ PARTITION_PATTERN
|
|
|
|
databases[partition] ||= begin
|
|
name = [partition, base_name].join(SEPARATOR)
|
|
database = Bdb::Database.new(name, config)
|
|
indexes.each do |field, opts|
|
|
database.index_by(field, opts)
|
|
end
|
|
database
|
|
end
|
|
end
|
|
|
|
def partitions
|
|
Dir[environment.path + "/*#{SEPARATOR}#{base_name}"].collect do |file|
|
|
File.basename(file).split(SEPARATOR).first
|
|
end
|
|
end
|
|
|
|
def with_partition(partition)
|
|
@partition, old_partition = partition, @partition
|
|
yield
|
|
ensure
|
|
@partition = old_partition
|
|
end
|
|
|
|
def close
|
|
databases.each do |partition, database|
|
|
database.close
|
|
end
|
|
@databases.clear
|
|
end
|
|
|
|
def get(*keys, &block)
|
|
opts = keys.last.kind_of?(Hash) ? keys.last : {}
|
|
database(opts[partition_by]).get(*keys, &block)
|
|
end
|
|
|
|
def set(key, value, opts = {})
|
|
partition = get_field(partition_by, value)
|
|
database(partition).set(key, value, opts)
|
|
end
|
|
|
|
def delete(key, opts = {})
|
|
database(opts[partition_by]).delete(key)
|
|
end
|
|
|
|
# Deletes all records in the database. Beware!
|
|
def truncate!
|
|
partitions.each do |partition|
|
|
database(partition).truncate!
|
|
end
|
|
end
|
|
end
|