[Bps-public-commit] r11660 - in Prophet/trunk: . lib/Prophet/Handle
jesse at bestpractical.com
jesse at bestpractical.com
Tue Apr 8 23:51:33 EDT 2008
Author: jesse
Date: Tue Apr 8 23:51:32 2008
New Revision: 11660
Modified:
Prophet/trunk/ (props changed)
Prophet/trunk/Makefile.PL
Prophet/trunk/lib/Prophet/Handle.pm
Prophet/trunk/lib/Prophet/Handle/SVN.pm
Log:
r29543 at 31b: jesse | 2008-04-08 23:51:19 -0400
* Specced out the methods that a handle class needs to implement.
Modified: Prophet/trunk/Makefile.PL
==============================================================================
--- Prophet/trunk/Makefile.PL (original)
+++ Prophet/trunk/Makefile.PL Tue Apr 8 23:51:32 2008
@@ -15,19 +15,18 @@
requires('Test::Exception');
requires('Acme::MetaSyntactic');
requires('UNIVERSAL::require');
-requires('App::Cache');
requires('Class::Data::Inheritable');
requires('DateTime::Format::HTTP');
requires('Devel::Gladiator');
requires('RT::Client::REST');
requires('RT::Client::REST::Ticket');
requires('RT::Client::REST::User');
-requires('SVB::Record');
requires('Term::ReadKey');
requires('Digest::SHA1');
requires('LWP::Simple');
requires('URI');
requires('JSON');
+requires('Module::Pluggable');
requires('Test::HTTP::Server::Simple');
requires('HTTP::Server::Simple');
requires('Test::WWW::Mechanize');
Modified: Prophet/trunk/lib/Prophet/Handle.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/Handle.pm (original)
+++ Prophet/trunk/lib/Prophet/Handle.pm Tue Apr 8 23:51:32 2008
@@ -34,7 +34,7 @@
sub integrate_changeset {
my $self = shift;
- my $changeset = shift;
+ my ($changeset) = validate_pos(@_, { isa => 'Prophet::ChangeSet'});
$self->begin_edit();
$self->record_changeset($changeset);
@@ -42,10 +42,19 @@
$self->commit_edit();
}
+=head2 record_resolutions Prophet::ChangeSet, (Prophet::Handle, a resolution database handle)
+
+Given a resolution changeset and a resolution database handle,
+record all the resolution changesets as well as resolution records
+in the content-addressed-store.
+
+Called ONLY on local resolution creation. (Synced resolutions are just synced as records)
+
+=cut
+
sub record_resolutions {
my $self = shift;
- my $changeset = shift;
- my $res_handle = shift;
+ my ($changeset, $res_handle) = validate_pos(@_, { isa => 'Prophet::ChangeSet'}, { isa => 'Prophet::Handle'});
return unless $changeset->changes;
@@ -55,14 +64,15 @@
$self->commit_edit();
}
-=head2 record_resolution
-
+=head2 record_resolution Prophet::Change
+
Called ONLY on local resolution creation. (Synced resolutions are just synced as records)
=cut
sub record_resolution {
- my ( $self, $change ) = @_;
+ my $self = shift;
+ my ($change) = validate_pos(@_, { isa => 'Prophet::Change'});
return 1 if $self->node_exists(
uuid => $self->uuid,
@@ -79,16 +89,23 @@
);
}
+=head2 record_changeset Prophet::ChangeSet
+
+Inside an edit (transaction), integrate all changes in this transaction
+and then call the _post_process_integrated_changeset() hook
+
+=cut
+
sub record_changeset {
my $self = shift;
- my $changeset = shift;
+ my ($changeset) = validate_pos(@_, { isa => 'Prophet::ChangeSet'});
eval {
my $inside_edit = $self->current_edit ? 1 : 0;
$self->begin_edit() unless ($inside_edit);
$self->_integrate_change($_) for ( $changeset->changes );
- $self->_cleanup_integrated_changeset($changeset);
+ $self->_post_process_integrated_changeset($changeset);
$self->commit_edit() unless ($inside_edit);
};
@@ -97,7 +114,7 @@
sub _integrate_change {
my $self = shift;
- my $change = shift;
+ my ($change) = validate_pos(@_, { isa => 'Prophet::Change'});
my %new_props = map { $_->name => $_->new_value } $change->prop_changes;
@@ -151,6 +168,14 @@
return $self->_record_metadata_for( $MERGETICKET_METATYPE, $source_uuid, 'last-changeset', $sequence_no );
}
+=head2 metadata_storage $RECORD_TYPE, $PROPERTY_NAME
+
+Returns a function which takes a UUID and an optional value to get (or set) metadata rows in a metadata table.
+We use this to record things like merge tickets
+
+
+=cut
+
sub metadata_storage {
my $self = shift;
my ( $type, $prop_name ) = validate_pos( @_, 1, 1 );
@@ -192,4 +217,77 @@
);
}
+=head1 DATA STORE API
+
+=head1 The following functions need to be implemented by any Prophet backing store.
+
+=head2 uuid
+
+Returns this replica's UUID
+
+=head2 create_node { type => $TYPE, uuid => $uuid, props => { key-value pairs }}
+
+Create a new record of type C<$type> with uuid C<$uuid> within the current replica.
+
+Sets the record's properties to the key-value hash passed in as the C<props> argument.
+
+If called from within an edit, it uses the current edit. Otherwise it manufactures and finalizes one of its own.
+
+
+
+=head2 delete_node {uuid => $uuid, type => $type }
+
+Deletes the node C<$uuid> of type C<$type> from the current replica.
+
+Manufactures its own new edit if C<$self->current_edit> is undefined.
+
+=head2 set_node_props { uuid => $uuid, type => $type, props => {hash of kv pairs }}
+
+
+Updates the record of type C<$type> with uuid C<$uuid> to set each property defined by the props hash. It does NOT alter any property not defined by the props hash.
+
+Manufactures its own current edit if none exists.
+
+
+=head2 get_node_props {uuid => $uuid, type => $type, root => $root }
+
+Returns a hashref of all properties for the record of type $type with uuid C<$uuid>.
+
+'root' is an optional argument which you can use to pass in an alternate historical version of the replica to inspect. Code to look at the immediately previous version of a record might look like:
+
+ $handle->get_node_props(
+ type => $record->type,
+ uuid => $record->uuid,
+ root => $self->repo_handle->fs->revision_root( $self->repo_handle->fs->youngest_rev - 1 )
+ );
+
+=head2 node_exists {uuid => $uuid, type => $type, root => $root }
+
+Returns true if the node in question exists. False otherwise
+
+
+=head2 enumerate_nodes { type => $type }
+
+Returns a reference to a list of all the records of type $type
+
+=head2 enumerate_nodes
+
+Returns a reference to a list of all the known types in your Prophet database
+
+
+=head2 type_exists { type => $type }
+
+Returns true if we have any nodes of type C<$type>
+
+
+
+=cut
+
+
+
+=head2 The following functions need to be implemented by any _writable_ prophet backing store
+
+=cut
+
+
1;
Modified: Prophet/trunk/lib/Prophet/Handle/SVN.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/Handle/SVN.pm (original)
+++ Prophet/trunk/lib/Prophet/Handle/SVN.pm Tue Apr 8 23:51:32 2008
@@ -84,7 +84,7 @@
return CREATED_DB_UUID;
}
-sub _cleanup_integrated_changeset {
+sub _post_process_integrated_changeset {
my $self = shift;
my ($changeset) = validate_pos( @_, { isa => 'Prophet::ChangeSet' } );
@@ -172,7 +172,7 @@
my $inside_edit = $self->current_edit ? 1 : 0;
$self->begin_edit() unless ($inside_edit);
- my $file = $self->file_for( uuid => $args{uuid}, type => $args{'type'} );
+ my $file = $self->_file_for( uuid => $args{uuid}, type => $args{'type'} );
$self->current_edit->root->make_file($file);
{
my $stream = $self->current_edit->root->apply_text( $file, undef );
@@ -193,7 +193,7 @@
my $self = shift;
my %args = validate( @_, { uuid => 1, props => 1, type => 1 } );
- my $file = $self->file_for( uuid => $args{uuid}, type => $args{type} );
+ my $file = $self->_file_for( uuid => $args{uuid}, type => $args{type} );
foreach my $prop ( keys %{ $args{'props'} } ) {
eval { $self->current_edit->root->change_node_prop( $file, $prop, $args{'props'}->{$prop}, undef ) };
Carp::confess($@) if ($@);
@@ -215,7 +215,7 @@
my $inside_edit = $self->current_edit ? 1 : 0;
$self->begin_edit() unless ($inside_edit);
- $self->current_edit->root->delete( $self->file_for( uuid => $args{uuid}, type => $args{type} ) );
+ $self->current_edit->root->delete( $self->_file_for( uuid => $args{uuid}, type => $args{type} ) );
$self->commit_edit() unless ($inside_edit);
return 1;
}
@@ -236,7 +236,7 @@
my $inside_edit = $self->current_edit ? 1 : 0;
$self->begin_edit() unless ($inside_edit);
- my $file = $self->file_for( uuid => $args{uuid}, type => $args{'type'} );
+ my $file = $self->_file_for( uuid => $args{uuid}, type => $args{'type'} );
$self->_set_node_props(
uuid => $args{uuid},
props => $args{props},
@@ -265,25 +265,25 @@
my $self = shift;
my %args = validate( @_, { uuid => 1, type => 1, root => undef } );
my $root = $args{'root'} || $self->current_root;
- return $root->node_proplist( $self->file_for( uuid => $args{'uuid'}, type => $args{'type'} ) );
+ return $root->node_proplist( $self->_file_for( uuid => $args{'uuid'}, type => $args{'type'} ) );
}
-=head2 file_for { uuid => $UUID, type => $type }
+=head2 _file_for { uuid => $UUID, type => $type }
Returns a file path within the repository (starting from the root)
=cut
-sub file_for {
+sub _file_for {
my $self = shift;
my %args = validate( @_, { uuid => 1, type => 1 } );
Carp::cluck unless $args{uuid};
- my $file = join( "/", $self->directory_for_type( type => $args{'type'} ), $args{'uuid'} );
+ my $file = join( "/", $self->_directory_for_type( type => $args{'type'} ), $args{'uuid'} );
return $file;
}
-sub directory_for_type {
+sub _directory_for_type {
my $self = shift;
my %args = validate( @_, { type => 1 } );
Carp::cluck unless defined $args{type};
@@ -302,27 +302,47 @@
my %args = validate( @_, { uuid => 1, type => 1, root => undef } );
my $root = $args{'root'} || $self->current_root;
- return $root->check_path( $self->file_for( uuid => $args{'uuid'}, type => $args{'type'} ) );
+ return $root->check_path( $self->_file_for( uuid => $args{'uuid'}, type => $args{'type'} ) );
}
+=head2 enumerate_nodes { type => $type }
+
+Returns a reference to a list of all the records of type $type
+
+=cut
+
sub enumerate_nodes {
my $self = shift;
my %args = validate( @_ => { type => 1 } );
return [ keys %{ $self->current_root->dir_entries( $self->db_uuid . '/' . $args{type} . '/' ) } ];
}
+=head2 enumerate_types
+
+Returns a reference to a list of all the known types in your Prophet database
+
+=cut
+
sub enumerate_types {
my $self = shift;
return [ keys %{ $self->current_root->dir_entries( $self->db_uuid . '/' ) } ];
}
+
+=head2 type_exists { type => $type }
+
+Returns true if we have any nodes of type C<$type>
+
+=cut
+
+
sub type_exists {
my $self = shift;
my %args = validate( @_, { type => 1, root => undef } );
my $root = $args{'root'} || $self->current_root;
- return $root->check_path( $self->directory_for_type( type => $args{'type'}, ) );
+ return $root->check_path( $self->_directory_for_type( type => $args{'type'}, ) );
}
More information about the Bps-public-commit
mailing list