Why not adopt me?
NAME
Bot::Cobalt::DB - Locking Berkeley DBs with serialization
SYNOPSIS
use Bot::Cobalt::DB;
## ... perhaps in a Cobalt_register ...
my $db_path = $core->var ."/MyDatabase.db";
$self->{DB} = Bot::Cobalt::DB->new(
File => $db_path,
);
## Open (and lock):
$self->{DB}->dbopen;
## Do some work:
$self->{DB}->put("SomeKey",
{ Some => {
Deep => { Structure => 1, },
}, },
);
for my $key ($self->{DB}->dbkeys) {
my $this_hash = $self->{DB}->get($key);
}
$self->{DB}->dbclose;
DESCRIPTION
Bot::Cobalt::DB provides a simple object-oriented interface to basic DB_File (Berkeley DB 1.x) usage.
BerkDB is a fast and simple key/value store. This module uses JSON to store nested Perl data structures, providing easy database-backed storage for Bot::Cobalt plugins.
Performance will suffer miserably if you don't have JSON::XS!
Constructor
new() is used to create a new Bot::Cobalt::DB object representing your Berkeley DB:
my $db = Bot::Cobalt::DB->new(
File => $path_to_db,
## Optional arguments:
# Database file mode
Perms => $octal_mode,
## Locking timeout in seconds
## Defaults to 5s:
Timeout => 10,
## Normally, references are serialized transparently.
## If Raw is enabled, no serialization filter is used and you're
## on your own.
Raw => 0,
);
Opening and closing
Database operations should be contained within a dbopen/dbclose:
## open, put, close:
$db->dbopen || croak "dbopen failure";
$db->put($key, $data);
$db->dbclose;
## open for read-only, read, close:
$db->dbopen(ro => 1) || croak "dbopen failure";
my $data = $db->get($key);
$db->dbclose;
Methods will fail if the DB is not open.
If the DB for this object is open when the object is DESTROY'd, Bot::Cobalt::DB will attempt to close it safely.
Locking
Proper locking is done -- that means the DB is 're-tied' after a lock is granted and state cannot change between database open and lock time.
The attempt to gain a lock will time out after five seconds (and dbopen() will return boolean false).
The lock is cleared on dbclose.
If the Bot::Cobalt::DB object is destroyed, it will attempt to dbclose for you, but it is good practice to keep track of your open/close calls and attempt to close as quickly as possible.
Methods
dbopen
dbopen opens and locks the database. If 'ro => 1' is specified, this is a LOCK_SH shared (read) lock; otherwise it is a LOCK_EX exclusive (write) lock.
Try to call a dbclose as quickly as possible to reduce locking contention.
is_open
Returns a boolean value representing whether or not the DB is currently open and locked.
dbclose
dbclose closes and unlocks the database.
put
The put method adds an entry to the database:
$db->put($key, $value);
The value can be any data structure serializable by JSON::XS; that is to say, any shallow or deep data structure NOT including blessed references.
(Yes, Storable is faster. JSON is used because it is trivially portable to any language that can interface with BerkDB.)
get
The get method retrieves a (deserialized) key.
$db->put($key, { Some => 'hash' } );
## . . . later on . . .
my $ref = $db->get($key);
del
The del method removes a key from the database.
$db->del($key);
dbkeys
dbkeys will return a list of keys in list context, or the number of keys in the database in scalar context.
dbdump
You can serialize/export the entirety of the DB via dbdump.
## YAML::Syck
my $yamlified = $db->dbdump('YAML');
## YAML::XS
my $yamlified = $db->dbdump('YAMLXS');
## JSON (::XS or ::PP)
my $jsonified = $db->dbdump('JSON');
See Bot::Cobalt::Serializer for more on freeze()
and valid formats.
As of 2.00_24, a tool called cobalt2-dbdump is available as a simple frontend to this functionality. See cobalt2-dbdump --help
FORMAT
Bot::Cobalt::DB databases are Berkeley DB 1.x, with NULL-terminated records and values stored as JSON.
They should be fairly easy to parse in a language of your choice.
AUTHOR
Jon Portnoy <avenj@cobaltirc.org>