[Bps-public-commit] r14322 - in Prophet/branches/history: . lib/Prophet
jesse at bestpractical.com
jesse at bestpractical.com
Sun Jul 20 18:54:01 EDT 2008
Author: jesse
Date: Sun Jul 20 18:54:00 2008
New Revision: 14322
Modified:
Prophet/branches/history/ (props changed)
Prophet/branches/history/lib/Prophet/Record.pm
Prophet/branches/history/lib/Prophet/Replica/Native.pm
Log:
r40251 at 68-246-244-17: jesse | 2008-07-20 11:20:06 -0700
* Rototilling how we handle deleted records so we can track history more easily
Modified: Prophet/branches/history/lib/Prophet/Record.pm
==============================================================================
--- Prophet/branches/history/lib/Prophet/Record.pm (original)
+++ Prophet/branches/history/lib/Prophet/Record.pm Sun Jul 20 18:54:00 2008
@@ -34,10 +34,7 @@
isa => 'Str',
required => 1,
predicate => 'has_type',
- default => sub {
- my $self = shift;
- $self->record_type;
- },
+ default => sub { undef}
);
has uuid => (
@@ -72,7 +69,7 @@
my $UUIDGEN = Data::UUID->new();
-sub record_type { $_[0]->has_type ? $_[0]->type : undef }
+sub record_type { $_[0]->type }
=head1 METHODS
@@ -121,7 +118,7 @@
my $self = shift;
my $collection = $collection_class->new(
handle => $self->handle,
- type => $collection_class->record_class->record_type
+ type => $collection_class->record_class->type
);
$collection->matching( sub { ($_[0]->prop( $args{by} )||'') eq $self->uuid }
);
@@ -301,6 +298,15 @@
}
+
+sub changesets {
+ my $self = shift;
+ my @changeset_ids = $self->handle->list_record_changesets(record_uuid =>
+ $self->uuid
+ );
+}
+
+
sub validate_props {
my $self = shift;
my $props = shift;
@@ -452,5 +458,4 @@
__PACKAGE__->meta->make_immutable;
no Moose;
no MooseX::ClassAttribute;
-
1;
Modified: Prophet/branches/history/lib/Prophet/Replica/Native.pm
==============================================================================
--- Prophet/branches/history/lib/Prophet/Replica/Native.pm (original)
+++ Prophet/branches/history/lib/Prophet/Replica/Native.pm Sun Jul 20 18:54:00 2008
@@ -19,6 +19,13 @@
is => 'rw',
);
+
+has replica_version => (
+ is => 'ro',
+ lazy => 1,
+ default => sub { shift->_read_file('replica-version') }
+);
+
has fs_root_parent => (
is => 'rw',
lazy => 1,
@@ -37,14 +44,18 @@
},
);
-has target_replica => (
+has current_edit => (
is => 'rw',
);
-has current_edit => (
- is => 'rw',
+has current_edit_records => (
+ metaclass => 'Collection::Array',
+ is => 'rw',
+ isa => 'ArrayRef',
+ default => sub { [] },
);
+
has '+resolution_db_handle' => (
isa => 'Prophet::Replica | Undef',
lazy => 1,
@@ -96,7 +107,7 @@
sub _probe_or_create_db {
my $self = shift;
- return if $self->_read_file('replica-version');
+ return if $self->replica_version;
if ( $self->fs_root_parent ) {
@@ -222,13 +233,36 @@
data => $args{props},
cas_dir => $self->record_cas_dir
);
- $self->_write_record_index_entry(
- uuid => $args{uuid},
+
+ my $record = {uuid => $args{uuid},
type => $args{type},
- cas_key => $cas_key
- );
+ cas_key => $cas_key};
+
+ $self->_prepare_record_index_update(
+ uuid => $args{uuid},
+ type => $args{type},
+ cas_key => $cas_key);
+}
+
+
+sub _prepare_record_index_update {
+ my $self = shift;
+ my %record = (@_);
+
+ # If we're inside an edit, we can record the changeset info into the index
+ if ( $self->current_edit) {
+ push @{$self->current_edit_records}, \%record;
+
+ } else {
+ # If we're not inside an edit, we're likely exporting the replica
+ # TODO: the replica exporter code should probably be retooled
+ $self->_write_record_index_entry(%record);
+ }
+
}
+use constant RECORD_INDEX_SIZE => ( 4 + 20 );
+
sub _write_record_index_entry {
my $self = shift;
my %args = validate( @_, { type => 1, uuid => 1, cas_key => 1 } );
@@ -251,44 +285,48 @@
close $record_index;
}
-sub _delete_record_index {
- my $self = shift;
+sub _read_record_index_entry {
+ my $self = shift;
my %args = validate( @_, { type => 1, uuid => 1 } );
- my $idx_filename = $self->_record_index_filename(
- uuid => $args{uuid},
- type => $args{type}
- );
- file( $self->fs_root => $idx_filename )->remove
- || die "Could not delete record $idx_filename: " . $!;
-}
-use constant RECORD_INDEX_SIZE => ( 4 + 20 );
-sub _read_serialized_record {
- my $self = shift;
- my %args = validate( @_, { type => 1, uuid => 1 } );
my $idx_filename = $self->_record_index_filename(
uuid => $args{uuid},
type => $args{type}
);
+
+
my $index = $self->_read_file($idx_filename);
return undef unless $index;
- # XXX TODO THIS CODE IS FUCKING HACKY AND SHOULD BE SHOT;
+ # XXX TODO THIS CODE IS HACKY AND SHOULD BE SHOT;
my $count = length($index) / RECORD_INDEX_SIZE;
my ( $seq, $key ) = unpack( 'NH40',
substr( $index, ( $count - 1 ) * RECORD_INDEX_SIZE, RECORD_INDEX_SIZE )
);
- # XXX: deserialize the changeset content from the cas with $key
- my $casfile = file(
- $self->record_cas_dir,
- substr( $key, 0, 1 ),
- substr( $key, 1, 1 ), $key
+ return ($seq,$key);
+}
+
+sub _delete_record_index {
+ my $self = shift;
+ my %args = validate( @_, { type => 1, uuid => 1 } );
+ my $idx_filename = $self->_record_index_filename(
+ uuid => $args{uuid},
+ type => $args{type}
);
+ file( $self->fs_root => $idx_filename )->remove
+ || die "Could not delete record $idx_filename: " . $!;
+}
+
+sub _read_serialized_record {
+ my $self = shift;
+ my %args = validate( @_, { type => 1, uuid => 1 } );
- # That's the props
+ my $casfile = $self->_record_cas_filename(type => $args{'type'}, uuid => $args{'uuid'});
+
+ return undef unless $casfile;
return from_json( $self->_read_file($casfile), { utf8 => 1} );
}
@@ -303,6 +341,24 @@
);
}
+sub _record_cas_filename {
+ my $self = shift;
+ my %args = validate( @_, { type => 1, uuid => 1 } );
+
+ my ($seq,$key) = $self->_read_record_index_entry( type => $args{'type'}, uuid => $args{'uuid'});
+
+
+ return undef unless ($key and ($key ne '0'x40));
+ # XXX: deserialize the changeset content from the cas with $key
+ my $casfile = file(
+ $self->record_cas_dir,
+ substr( $key, 0, 1 ),
+ substr( $key, 1, 1 ), $key
+ );
+
+ return $casfile;
+}
+
sub _record_type_root {
my $self = shift;
my $type = shift;
@@ -517,6 +573,9 @@
$self->current_edit->original_source_uuid( $self->uuid )
unless ( $self->current_edit->original_source_uuid );
$self->current_edit->sequence_no($sequence);
+ for my $record (@{$self->current_edit_records}) {
+ $self->_write_record_index_entry(%$record);
+ }
$self->_write_changeset_to_index( $self->current_edit );
}
@@ -577,8 +636,6 @@
my $inside_edit = $self->current_edit ? 1 : 0;
$self->begin_edit() unless ($inside_edit);
-# XXX TODO Write out an entry to the record's index file marking it as a special deleted uuid? - this has lots of ramifications for list, load, exists, create
- $self->_delete_record_index( uuid => $args{uuid}, type => $args{type} );
my $change = Prophet::Change->new(
{ record_type => $args{'type'},
@@ -587,6 +644,8 @@
}
);
$self->current_edit->add_change( change => $change );
+
+ $self->_prepare_record_index_update( uuid => $args{uuid}, type => $args{type}, cas_key => '0'x40);
$self->commit_edit() unless ($inside_edit);
return 1;
@@ -650,14 +709,11 @@
my $self = shift;
my %args = validate( @_, { uuid => 1, type => 1 } );
return undef unless $args{'uuid'};
- return $self->_file_exists(
- $self->_record_index_filename(
+ return $self->_record_cas_filename(
type => $args{'type'},
uuid => $args{'uuid'}
- )
- );
+ ) ? 1 : 0;
- # TODO, check that the index file doesn't have a 'deleted!' note
}
sub list_records {
@@ -665,11 +721,14 @@
my %args = validate( @_ => { type => 1 } );
#return just the filenames, which, File::Find::Rule doesn't seem capable of
- return [
- map { my @path = split( qr'/', $_ ); pop @path }
+ my @record_uuids = map { my @path = split( qr'/', $_ ); pop @path }
File::Find::Rule->file->maxdepth(3)->in(
dir( $self->fs_root, $self->_record_type_root( $args{'type'} ) )
- )
+ );
+
+
+
+ return [grep {$self->_record_cas_filename(type => $args{'type'}, uuid => $_ ) }@record_uuids
];
}
More information about the Bps-public-commit
mailing list