1package Data::Localize::Storage::BerkeleyDB; 2use Moo; 3use BerkeleyDB; 4use Carp (); 5use Encode (); 6use File::Spec (); 7use File::Temp (); 8use Data::Localize (); 9BEGIN { 10 if (Data::Localize::DEBUG) { 11 require Data::Localize::Log; 12 Data::Localize::Log->import; 13 } 14} 15with 'Data::Localize::Storage'; 16 17has '_db' => ( 18 is => 'rw', 19 init_arg => 'db', 20); 21 22has 'store_as_refs' => ( 23 is => 'ro', 24 default => sub { 0 }, 25); 26 27sub is_volatile { 0 } 28 29sub BUILD { 30 my ($self, $args) = @_; 31 if (! $self->_db) { 32 my $class = $args->{bdb_class} || 'Hash'; 33 if ($class !~ s/^\+//) { 34 $class = "BerkeleyDB::$class"; 35 } 36 Module::Load::load($class); 37 38 my $dir = ($args->{dir} ||= File::Temp::tempdir(CLEANUP => 1)); 39 $args->{bdb_args} ||= { 40 -Filename => File::Spec->catfile($dir, $self->lang), 41 -Flags => BerkeleyDB::DB_CREATE(), 42 }; 43 44 if (Data::Localize::DEBUG) { 45 local $Log::Minimal::AUTODUMP = 1; 46 debugf("Storage::BerkeleyDB Automatically building storage db with class = %s, args = %s", $class, $args->{bdb_args}); 47 } 48 $self->_db( $class->new( $args->{bdb_args} || {} ) || 49 Carp::confess("Failed to create $class: $BerkeleyDB::Error") 50 ); 51 } 52 53 if ( $self->store_as_refs ) { 54 require Storable; 55 } 56 57 $self; 58} 59 60sub get { 61 my ($self, $key, $flags) = @_; 62 my $value; 63 my $rc = $self->_db->db_get($key, $value, $flags || 0); 64 if ($rc == 0) { 65 if ( $self->store_as_refs ) { 66 # Storeable handles utf8 correctly 67 my $thawed = Storable::thaw( $value ); 68 return $thawed->{'__' . __PACKAGE__ . '::key__'} 69 if exists $thawed->{'__' . __PACKAGE__ . '::key__'}; 70 return $thawed; 71 } 72 else { 73 # BerkeleyDB gives us values with the flags off, so put them back on 74 return Encode::decode_utf8($value); 75 } 76 } 77 return (); 78} 79 80sub set { 81 my ($self, $key, $value, $flags) = @_; 82 83 if (Data::Localize::DEBUG) { 84 debugf("Storage::BerkeleyDB: Set %s -> %s", $key, $value); 85 } 86 87 if ( $self->store_as_refs ) { 88 unless ( ref $value ) { 89 $value = { ('__' . __PACKAGE__ . '::key__') => $value }; 90 } 91 $value = Storable::freeze( $value ); 92 } 93 94 my $rc = $self->_db->db_put($key, $value, $flags || 0); 95 if ($rc != 0) { 96 Carp::confess("Failed to set value $key"); 97 } 98} 99 1001; 101 102__END__ 103 104=head1 NAME 105 106Data::Localize::Storage::BerkeleyDB - BerkeleyDB Backend 107 108=head1 SYNOPSIS 109 110 use Data::Localize::Storage::BerkeleyDB; 111 112 Data::Localize::Storage::BerkeleDB->new( 113 bdb_class => 'Hash', # default 114 bdb_args => { 115 -Filename => .... 116 -Flags => BerkeleyDB::DB_CREATE 117 } 118 ); 119 120=head1 METHODS 121 122=head2 get 123 124=head2 set 125 126=head2 is_volatile 127 128=cut 129