From: rkinyon Date: Fri, 28 Apr 2006 00:33:52 +0000 (+0000) Subject: 0.99_01 ready for releas\e X-Git-Tag: 0-99_02~1 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=eff6a245e56d0baacaa24e1d49dbdc4f6de80335;p=dbsrgits%2FDBM-Deep.git 0.99_01 ready for releas\e --- diff --git a/MANIFEST.SKIP b/MANIFEST.SKIP index 96426fe..b008153 100644 --- a/MANIFEST.SKIP +++ b/MANIFEST.SKIP @@ -15,3 +15,5 @@ cover_db \.old$ ^#.*#$ ^\.# +^\.DS_Store +^__MACOSX diff --git a/lib/DBM/Deep.pm b/lib/DBM/Deep.pm index cfa458b..395aefd 100644 --- a/lib/DBM/Deep.pm +++ b/lib/DBM/Deep.pm @@ -694,10 +694,10 @@ DBM::Deep - A pure perl multi-level hash/array DBM use DBM::Deep; my $db = DBM::Deep->new( "foo.db" ); - $db->{key} = 'value'; # tie() style + $db->{key} = 'value'; print $db->{key}; - $db->put('key' => 'value'); # OO style + $db->put('key' => 'value'); print $db->get('key'); # true multi-level support @@ -706,33 +706,29 @@ DBM::Deep - A pure perl multi-level hash/array DBM 42, 99, ]; -=head1 DESCRIPTION - -A unique flat-file database module, written in pure perl. True -multi-level hash/array support (unlike MLDBM, which is faked), hybrid -OO / tie() interface, cross-platform FTPable files, and quite fast. Can -handle millions of keys and unlimited hash levels without significant -slow-down. Written from the ground-up in pure perl -- this is NOT a -wrapper around a C-based DBM. Out-of-the-box compatibility with Unix, -Mac OS X and Windows. + tie my %db, 'DBM::Deep', 'foo.db'; + $db{key} = 'value'; + print $db{key}; -=head1 VERSION DIFFERENCES + tied(%db)->put('key' => 'value'); + print tied(%db)->get('key'); -B: 0.99_01 and above have significant file format differences from 0.98 and -before. While attempts have been made to be backwards compatible, no guarantees. +=head1 DESCRIPTION -=head1 INSTALLATION +A unique flat-file database module, written in pure perl. True multi-level +hash/array support (unlike MLDBM, which is faked), hybrid OO / tie() +interface, cross-platform FTPable files, ACID transactions, and is quite fast. +Can handle millions of keys and unlimited levels without significant +slow-down. Written from the ground-up in pure perl -- this is NOT a wrapper +around a C-based DBM. Out-of-the-box compatibility with Unix, Mac OS X and +Windows. -Hopefully you are using Perl's excellent CPAN module, which will download -and install the module for you. If not, get the tarball, and run these -commands: +=head1 VERSION DIFFERENCES - tar zxf DBM-Deep-* - cd DBM-Deep-* - perl Makefile.PL - make - make test - make install +B: 0.99_01 and above have significant file format differences from 0.983 and +before. There will be a backwards-compatibility layer in 1.00, but that is +slated for a later 0.99_x release. This version is B backwards compatible +with 0.983 and before. =head1 SETUP @@ -742,7 +738,7 @@ Perl's tie() function. Both are examined here. =head2 OO CONSTRUCTION The recommended way to construct a DBM::Deep object is to use the new() -method, which gets you a blessed, tied hash or array reference. +method, which gets you a blessed I tied hash (or array) reference. my $db = DBM::Deep->new( "foo.db" ); @@ -752,11 +748,11 @@ opened in "r+" (read/write) mode, and the type of object returned is a hash, unless otherwise specified (see L below). You can pass a number of options to the constructor to specify things like -locking, autoflush, etc. This is done by passing an inline hash: +locking, autoflush, etc. This is done by passing an inline hash (or hashref): my $db = DBM::Deep->new( - file => "foo.db", - locking => 1, + file => "foo.db", + locking => 1, autoflush => 1 ); @@ -765,8 +761,6 @@ the "file" parameter, as opposed to being the sole argument to the constructor. This is required if any options are specified. See L below for the complete list. - - You can also start with an array instead of a hash. For this, you must specify the C parameter: @@ -784,8 +778,8 @@ the wrong type is passed in. Alternately, you can create a DBM::Deep handle by using Perl's built-in tie() function. The object returned from tie() can be used to call methods, -such as lock() and unlock(), but cannot be used to assign to the DBM::Deep -file (as expected with most tie'd objects). +such as lock() and unlock(). (That object can be retrieved from the tied +variable at any time using tied() - please see L for more info. my %hash; my $db = tie %hash, "DBM::Deep", "foo.db"; @@ -828,6 +822,11 @@ needs. If you open it read-only and attempt to write, an exception will be throw open it write-only or append-only, an exception will be thrown immediately as DBM::Deep needs to read from the fh. +=item * audit_file / audit_fh + +These are just like file/fh, except for auditing. Please see L for +more information. + =item * file_offset This is the offset within the file that the DBM::Deep db starts. Most of the time, you will @@ -853,11 +852,12 @@ parameter, and defaults to CTYPE_HASH>. =item * locking -Specifies whether locking is to be enabled. DBM::Deep uses Perl's Fnctl flock() -function to lock the database in exclusive mode for writes, and shared mode for -reads. Pass any true value to enable. This affects the base DB handle I that use the same DB file. This is an optional -parameter, and defaults to 0 (disabled). See L below for more. +Specifies whether locking is to be enabled. DBM::Deep uses Perl's flock() +function to lock the database in exclusive mode for writes, and shared mode +for reads. Pass any true value to enable. This affects the base DB handle +I that use the same DB file. This is an +optional parameter, and defaults to 0 (disabled). See L below for +more. =item * autoflush @@ -913,7 +913,7 @@ You can even step through hash keys using the normal Perl C function: Remember that Perl's C function extracts I key from the hash and pushes them onto an array, all before the loop even begins. If you have an -extra large hash, this may exhaust Perl's memory. Instead, consider using +extremely large hash, this may exhaust Perl's memory. Instead, consider using Perl's C function, which pulls keys/values one at a time, using very little memory: @@ -960,7 +960,8 @@ or simply be a nested array reference inside a hash. Example: In addition to the I interface, you can also use a standard OO interface to manipulate all aspects of DBM::Deep databases. Each type of object (hash or array) has its own methods, but both types share the following common methods: -C, C, C, C and C. +C, C, C, C and C. C and +C are aliases to C and C, respectively. =over @@ -1022,7 +1023,8 @@ q.v. Locking. =item * optimize() -Recover lost disk space. +Recover lost disk space. This is important to do, especially if you use +transactions. =item * import() / export() @@ -1231,7 +1233,8 @@ The C method can be called on any database level (not just the base level), and works with both hash and array DB types. B Make sure your existing structure has no circular references in it. -These will cause an infinite loop when importing. +These will cause an infinite loop when importing. There are plans to fix this +in a later release. =head2 EXPORTING @@ -1259,7 +1262,8 @@ large databases -- you can store a lot more data in a DBM::Deep object than an in-memory Perl structure. B Make sure your database has no circular references in it. -These will cause an infinite loop when exporting. +These will cause an infinite loop when exporting. There are plans to fix this +in a later release. =head1 FILTERS @@ -1519,6 +1523,41 @@ object tree (such as I or even the built-in C or C methods) will result in an infinite loop. This will be fixed in a future release. +=head1 AUDITING + +New in 0.99_01 is the ability to audit your databases actions. By passing in +audit_file (or audit_fh) to the constructor, all actions will be logged to +that file. The format is one that is suitable for eval'ing against the +database to replay the actions. Please see t/33_audit_trail.t for an example +of how to do this. + +=head1 TRANSACTIONS + +New in 0.99_01 is ACID transactions. Every DBM::Deep object is completely +transaction-ready - it is not an option you have to turn on. Three new methods +have been added to support them. They are: + +=over 4 + +=item * begin_work() + +This starts a transaction. + +=item * commit() + +This applies the changes done within the transaction to the mainline and ends +the transaction. + +=item * rollback() + +This discards the changes done within the transaction to the mainline and ends +the transaction. + +=back + +Transactions in DBM::Deep are done using the MVCC method, the same method used +by the InnoDB MySQL table type. + =head1 CAVEATS / ISSUES / BUGS This section describes all the known issues with DBM::Deep. It you have found @@ -1838,30 +1877,32 @@ built-in hashes. =head1 CODE COVERAGE -We use B to test the code coverage of our tests, below is the -B report on this module's test suite. +B is used to test the code coverage of the tests. Below is the +B report on this distribution's test suite. - ----------------------------------- ------ ------ ------ ------ ------ ------ - File stmt bran cond sub time total - ----------------------------------- ------ ------ ------ ------ ------ ------ - blib/lib/DBM/Deep.pm 94.9 80.6 73.0 100.0 37.9 90.4 - blib/lib/DBM/Deep/Array.pm 100.0 91.1 100.0 100.0 18.2 98.1 - blib/lib/DBM/Deep/Engine.pm 98.9 87.3 80.0 100.0 34.2 95.2 - blib/lib/DBM/Deep/Hash.pm 100.0 87.5 100.0 100.0 9.7 97.3 - Total 97.9 85.9 79.7 100.0 100.0 94.3 - ----------------------------------- ------ ------ ------ ------ ------ ------ + ---------------------------- ------ ------ ------ ------ ------ ------ ------ + File stmt bran cond sub pod time total + ---------------------------- ------ ------ ------ ------ ------ ------ ------ + blib/lib/DBM/Deep.pm 96.2 89.0 75.0 95.8 89.5 36.0 92.9 + blib/lib/DBM/Deep/Array.pm 96.1 88.3 100.0 96.4 100.0 15.9 94.7 + blib/lib/DBM/Deep/Engine.pm 96.6 86.6 89.5 100.0 0.0 20.0 91.0 + blib/lib/DBM/Deep/File.pm 99.4 88.3 55.6 100.0 0.0 19.6 89.5 + blib/lib/DBM/Deep/Hash.pm 98.5 83.3 100.0 100.0 100.0 8.5 96.3 + Total 96.9 87.4 81.2 98.0 38.5 100.0 92.1 + ---------------------------- ------ ------ ------ ------ ------ ------ ------ =head1 MORE INFORMATION Check out the DBM::Deep Google Group at L -or send email to L. - -=head1 AUTHORS +or send email to L. You can also visit #dbm-deep on +irc.perl.org -Joseph Huckaby, L +=head1 MAINTAINERS Rob Kinyon, L +Originally written by Joseph Huckaby, L + Special thanks to Adam Sah and Rich Gaushell! You know why :-) =head1 SEE ALSO diff --git a/lib/DBM/Deep/Engine.pm b/lib/DBM/Deep/Engine.pm index 3b6a9cb..be720be 100644 --- a/lib/DBM/Deep/Engine.pm +++ b/lib/DBM/Deep/Engine.pm @@ -113,14 +113,14 @@ sub calculate_sizes { sub write_file_header { my $self = shift; - my $loc = $self->_fileobj->request_space( length( SIG_FILE ) + 21 ); + my $loc = $self->_fileobj->request_space( length( SIG_FILE ) + 33 ); $self->_fileobj->print_at( $loc, SIG_FILE, SIG_HEADER, pack('N', 1), # header version - pack('N', 12), # header size - pack('N', 0), # currently running transaction IDs + pack('N', 24), # header size + pack('N4', 0, 0, 0, 0), # currently running transaction IDs pack('n', $self->{long_size}), pack('A', $self->{long_pack}), pack('n', $self->{data_size}), @@ -154,7 +154,7 @@ sub read_file_header { } my $buffer2 = $self->_fileobj->read_at( undef, $size ); - my ($running_transactions, @values) = unpack( 'N n A n A n', $buffer2 ); + my ($a1, $a2, $a3, $a4, @values) = unpack( 'N4 n A n A n', $buffer2 ); $self->_fileobj->set_transaction_offset( 13 ); diff --git a/lib/DBM/Deep/File.pm b/lib/DBM/Deep/File.pm index 72c2540..be03615 100644 --- a/lib/DBM/Deep/File.pm +++ b/lib/DBM/Deep/File.pm @@ -312,7 +312,7 @@ sub begin_transaction { $self->lock; my $buffer = $self->read_at( $self->{transaction_offset}, 4 ); - my ($next, @trans) = unpack( 'C C C C', $buffer ); + my ($next, @trans) = unpack( 'C C C C C C C C C C C C C C C C', $buffer ); $self->{transaction_id} = ++$next; @@ -326,7 +326,7 @@ sub begin_transaction { $self->print_at( $self->{transaction_offset}, - pack( 'C C C C', $next, @trans), + pack( 'C C C C C C C C C C C C C C C C', $next, @trans), ); $self->unlock; @@ -344,13 +344,13 @@ sub end_transaction { $self->lock; my $buffer = $self->read_at( $self->{transaction_offset}, 4 ); - my ($next, @trans) = unpack( 'C C C C', $buffer ); + my ($next, @trans) = unpack( 'C C C C C C C C C C C C C C C C', $buffer ); @trans = grep { $_ != $self->{transaction_id} } @trans; $self->print_at( $self->{transaction_offset}, - pack( 'C C C C', $next, @trans), + pack( 'C C C C C C C C C C C C C C C C', $next, @trans), ); #XXX Need to free the space used by the current transaction @@ -375,7 +375,7 @@ sub current_transactions { $self->lock; my $buffer = $self->read_at( $self->{transaction_offset}, 4 ); - my ($next, @trans) = unpack( 'C C C C', $buffer ); + my ($next, @trans) = unpack( 'C C C C C C C C C C C C C C C C', $buffer ); $self->unlock; diff --git a/t/03_bighash.t b/t/03_bighash.t index 3d9baa4..cf082bd 100644 --- a/t/03_bighash.t +++ b/t/03_bighash.t @@ -8,6 +8,8 @@ use t::common qw( new_fh ); use_ok( 'DBM::Deep' ); +diag "This test can take up to a minute to run. Please be patient."; + my ($fh, $filename) = new_fh(); my $db = DBM::Deep->new( file => $filename, diff --git a/t/05_bigarray.t b/t/05_bigarray.t index 93a3db9..24b9071 100644 --- a/t/05_bigarray.t +++ b/t/05_bigarray.t @@ -7,6 +7,8 @@ use t::common qw( new_fh ); use_ok( 'DBM::Deep' ); +diag "This test can take up to a minute to run. Please be patient."; + my ($fh, $filename) = new_fh(); my $db = DBM::Deep->new( file => $filename,