sub commit {
my $self = shift->_get_self;
- # At this point, we need to replay the actions taken
- $self->_fileobj->end_transaction;
+ $self->_fileobj->commit_transaction;
return 1;
}
my $base = '';
if ( my $parent = $self->{parent} ) {
my $child = $self;
- while ( 1 ) {
+ while ( $parent->{parent} ) {
$base = (
$parent->_type eq TYPE_HASH
? "\{$child->{parent_key}\}"
: "\[$child->{parent_key}\]"
+# "->get('$child->{parent_key}')"
) . $base;
$child = $parent;
$parent = $parent->{parent};
- last unless $parent;
+# last unless $parent;
+ }
+ if ( $base ) {
+ $base = "\$db->get( '$child->{parent_key}' )->" . $base;
+ }
+ else {
+ $base = "\$db->get( '$child->{parent_key}' )";
}
}
- return '$db->' . $base;
+# return '$db->' . $base;
+# return '$db' . $base;
+ return $base;
}
sub STORE {
}
if ( defined $orig_key ) {
- my $lhs = $self->_find_parent;
- if ( $self->_type eq TYPE_HASH ) {
- $lhs .= "\{$orig_key\}";
- }
- else {
- $lhs .= "\[$orig_key\]";
- }
-
my $rhs;
my $r = Scalar::Util::reftype( $value ) || '';
$rhs = "bless $rhs, '$c'";
}
- $self->_fileobj->audit( "$lhs = $rhs;" );
+ my $lhs = $self->_find_parent;
+ if ( $lhs ) {
+ if ( $self->_type eq TYPE_HASH ) {
+ $lhs .= "->\{$orig_key\}";
+ }
+ else {
+ $lhs .= "->\[$orig_key\]";
+ }
+
+ $lhs .= "=$rhs;";
+ }
+ else {
+ $lhs = "\$db->put('$orig_key',$rhs);";
+ }
+
+# $self->_fileobj->audit( "$lhs = $rhs;" );
+# $self->_fileobj->audit( "$lhs $rhs);" );
+ $self->_fileobj->audit($lhs);
}
##
if ( defined $orig_key ) {
my $lhs = $self->_find_parent;
- if ( $self->_type eq TYPE_HASH ) {
- $lhs .= "\{$orig_key\}";
+# if ( $self->_type eq TYPE_HASH ) {
+# $lhs .= "\{$orig_key\}";
+# }
+# else {
+# $lhs .= "\[$orig_key]\]";
+# }
+
+# $self->_fileobj->audit( "delete $lhs;" );
+# $self->_fileobj->audit( "$lhs->delete('$orig_key');" );
+ if ( $lhs ) {
+ $self->_fileobj->audit( "delete $lhs;" );
}
else {
- $lhs .= "\[$orig_key]\]";
+ $self->_fileobj->audit( "\$db->delete('$orig_key');" );
}
-
- $self->_fileobj->audit( "delete $lhs;" );
}
##
# $args. They are here for documentation purposes.
transaction_id => 0,
transaction_offset => 0,
+ trans_audit => undef,
base_db_obj => undef,
}, $class;
}
sub set_db {
- unless ( $_[0]{base_db_obj} ) {
- $_[0]{base_db_obj} = $_[1];
- Scalar::Util::weaken( $_[0]{base_db_obj} );
+ my $self = shift;
+ unless ( $self->{base_db_obj} ) {
+ $self->{base_db_obj} = shift;
+ Scalar::Util::weaken( $self->{base_db_obj} );
}
+
+ return;
}
sub open {
sub audit {
my $self = shift;
+ my ($string) = @_;
if ( my $afh = $self->{audit_fh} ) {
- my ($string) = @_;
-
flock( $afh, LOCK_EX );
if ( $string =~ /^#/ ) {
flock( $afh, LOCK_UN );
}
+ if ( $self->{trans_audit} ) {
+ push @{$self->{trans_audit}}, $string;
+ }
+
return 1;
}
$self->unlock;
+ $self->{trans_audit} = [];
+
return $self->{transaction_id};
}
$buffer = unpack( 'N', $buffer );
# Unset $self->{transaction_id} bit
+ $buffer ^= (1 << $self->{transaction_id}-1);
seek( $fh, $self->{transaction_offset} + $self->{file_offset}, SEEK_SET );
print( $fh pack( 'N', $buffer ) );
$self->unlock;
$self->{transaction_id} = 0;
+ $self->{trans_audit} = undef;
+
+ return 1;
}
sub current_transactions {
sub transaction_id { return $_[0]->{transaction_id} }
-#sub commit {
-#}
+sub commit_transaction {
+ my $self = shift;
+
+ my @audit = @{$self->{trans_audit}};
+
+ $self->end_transaction;
+
+ {
+ my $db = $self->{base_db_obj};
+ for ( @audit ) {
+ eval "$_;";
+ warn "$_: $@\n" if $@;
+ }
+ }
+
+ return 1;
+}
1;
__END__
$db1->commit;
-TODO: {
- local $TODO = 'Need to finish auditing first before commit will work.';
- is( $db1->{x}, 'z', "After commit, DB1's X is Y" );
- is( $db2->{x}, 'z', "After commit, DB2's X is Y" );
-}
+is( $db1->{x}, 'z', "After commit, DB1's X is Y" );
+is( $db2->{x}, 'z', "After commit, DB2's X is Y" );
is( $db1->{other_x}, 'foo', "After DB1 transaction is over, DB1 can see other_x" );
is( $db2->{other_x}, 'foo', "After DB1 transaction is over, DB2 can still see other_x" );
for ( @$audit ) {
eval "$_";
+ warn "$_ -> $@\n" if $@;
}
my $export2 = $db->export;
+# use Data::Dumper;warn Dumper $export2;
cmp_deeply( $export2, $export, "And recovery works" );
}