[Bps-public-commit] Prophet - A disconnected, replicated p2p database branch, master, updated. 0ddf25873263a6294225f86ecf7badc7cfc8d941

jesse jesse at bestpractical.com
Sun Jan 18 18:12:34 EST 2009


The branch, master has been updated
       via  0ddf25873263a6294225f86ecf7badc7cfc8d941 (commit)
      from  248895f5bf053b61539165f24e8411b64e44cac3 (commit)

Summary of changes:
 lib/Prophet/ForeignReplica.pm  |    5 ++
 lib/Prophet/Replica.pm         |   44 ++++++++++++------
 lib/Prophet/Replica/prophet.pm |   22 +++++++++
 lib/Prophet/Replica/sqlite.pm  |  101 +++++++++++++++++++++-------------------
 lib/Prophet/Test.pm            |   22 +--------
 t/non-conflicting-merge.t      |    5 +--
 t/publish-pull.t               |   10 ----
 t/real-conflicting-merge.t     |   13 -----
 t/simple-conflicting-merge.t   |   12 -----
 9 files changed, 112 insertions(+), 122 deletions(-)

- Log -----------------------------------------------------------------
commit 0ddf25873263a6294225f86ecf7badc7cfc8d941
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Sun Jan 18 18:12:05 2009 -0500

    Starting to move local metadata storage out of the replica proper and
    into a local metadata store.
    
    (Starting with merge tickets)

diff --git a/lib/Prophet/ForeignReplica.pm b/lib/Prophet/ForeignReplica.pm
index 60c4ab2..3caaa91 100644
--- a/lib/Prophet/ForeignReplica.pm
+++ b/lib/Prophet/ForeignReplica.pm
@@ -25,6 +25,11 @@ sub BUILD {
     ));
 }
 
+sub fetch_local_metadata { shift->state_handle->fetch_local_metadata(@_)}
+sub store_local_metadata { shift->state_handle->store_local_metadata(@_)}
+
+
+
 sub conflicts_from_changeset { return; }
 sub can_write_changesets     {1}
 
diff --git a/lib/Prophet/Replica.pm b/lib/Prophet/Replica.pm
index 78fb407..44a0663 100644
--- a/lib/Prophet/Replica.pm
+++ b/lib/Prophet/Replica.pm
@@ -99,6 +99,29 @@ sub get_handle {
 }
 
 
+=head2 store_local_metadata KEY => VALUE
+
+Takes a key and a value.
+
+Store some bit of metadata in a durable local datastore.  Metadata isn't propagated
+when replicas are synced.
+
+Returns true or false.
+
+=cut
+
+=head2 fetch_local_metadata KEY
+
+Takes a scalar key.
+
+Fetches a bit of metadata from the local metadata store.
+
+Returns the value of the key found in the local metadata store. 
+
+Returns undef if there's no value for the key in the local metadata store.
+
+=cut
+
 sub replica_exists {
     return 1; # XXX TODO HACK
 }
@@ -315,7 +338,7 @@ sub record_changeset_and_integration {
     $self->begin_edit(source => $changeset);
     $self->record_changes($changeset);
 
-    $self->record_changeset_integration($changeset);
+    $self->record_integration_of_changeset($changeset);
 
     $self->_set_original_source_metadata_for_current_edit($changeset);
     $self->commit_edit;
@@ -323,16 +346,6 @@ sub record_changeset_and_integration {
     return;
 }
 
-sub record_changeset_integration {
-    my $self = shift;
-    my $changeset = shift;
-    my $state_handle = $self->state_handle;
-    my $inside_edit = $state_handle->current_edit ? 1 : 0;
-    $state_handle->begin_edit(source => $changeset) unless ($inside_edit);
-    $state_handle->record_integration_of_changeset($changeset);
-    $state_handle->commit_edit() unless ($inside_edit);
-}
-
 =head3 last_changeset_from_source $SOURCE_UUID
 
 Returns the last changeset id seen from the replica identified by $SOURCE_UUID.
@@ -343,10 +356,13 @@ sub last_changeset_from_source {
     my $self = shift;
     my ($source) = validate_pos( @_, { type => SCALAR } );
 
-    my $last =  $self->state_handle->metadata_storage( $MERGETICKET_METATYPE, 'last-changeset' )->($source) || 0;
-    return $last;
+    return $self->fetch_local_metadata('last-changeset-from-'.$source)||0;
 }
 
+
+
+
+
 =head3 has_seen_changeset L<Prophet::ChangeSet>
 
 Returns true if we've previously integrated this changeset, even if we
@@ -922,7 +938,7 @@ sub record_integration_of_changeset {
     my ($changeset) = validate_pos( @_, { isa => 'Prophet::ChangeSet' } );
 
     # Record a merge ticket for the changeset's "original" source
-    return $self->_record_metadata_for( $MERGETICKET_METATYPE, $changeset->original_source_uuid, 'last-changeset', $changeset->original_sequence_no );
+    return $self->store_local_metadata('last-changeset-from-'.  $changeset->original_source_uuid => $changeset->original_sequence_no); 
 
 }
 
diff --git a/lib/Prophet/Replica/prophet.pm b/lib/Prophet/Replica/prophet.pm
index e79ef86..302f79a 100644
--- a/lib/Prophet/Replica/prophet.pm
+++ b/lib/Prophet/Replica/prophet.pm
@@ -81,6 +81,8 @@ use constant changeset_cas_dir =>
 use constant record_dir      => 'records';
 use constant userdata_dir    => 'userdata';
 use constant changeset_index => 'changesets.idx';
+use constant local_metadata_dir => 'local_metadata';
+
 
 =head1 Replica Format
 
@@ -252,6 +254,26 @@ sub set_replica_version {
     return $version;
 }
 
+
+sub store_local_metadata {
+    my $self = shift;
+    my $key = shift;
+    my $value = shift;
+    $self->_write_file(
+        path    =>File::Spec->catfile( $self->local_metadata_dir,  $key),
+        content => $value,
+    );
+
+
+}
+
+sub fetch_local_metadata {
+    my $self = shift;
+    my $key = shift;
+    $self->_read_file(File::Spec->catfile($self->local_metadata_dir, $key));
+
+}
+
 sub can_initialize {
     my $self = shift;
     if ( $self->fs_root_parent && -w $self->fs_root_parent ) {
diff --git a/lib/Prophet/Replica/sqlite.pm b/lib/Prophet/Replica/sqlite.pm
index 20b51bb..5d65d05 100644
--- a/lib/Prophet/Replica/sqlite.pm
+++ b/lib/Prophet/Replica/sqlite.pm
@@ -24,7 +24,7 @@ sub db_file { shift->fs_root ."/db.sqlite"}
 
 has '+db_uuid' => (
     lazy    => 1,
-    default => sub { shift->_fetch_metadata('database-uuid') },
+    default => sub { shift->fetch_local_metadata('database-uuid') },
 );
 
 has _uuid => ( is => 'rw', );
@@ -34,7 +34,7 @@ has replica_version => (
     writer  => '_set_replica_version',
     isa     => 'Int',
     lazy    => 1,
-    default => sub { shift->_fetch_metadata('replica-version') || 0 }
+    default => sub { shift->fetch_local_metadata('replica-version') || 0 }
 );
 
 has fs_root_parent => (
@@ -128,15 +128,16 @@ sub __store_data {
     
 }
 
-sub _fetch_metadata {
+sub fetch_local_metadata {
     my $self = shift;
     my $key = shift;
     return $self->__fetch_data( 'local_metadata', $key );
 }
 
-sub _store_metadata {
+sub store_local_metadata {
     my $self = shift;
-    $self->__store_data( table => 'local_metadata', @_ );
+    my ($key, $value) = (@_);
+    $self->__store_data( table => 'local_metadata', key => $key, value => $value);
 }
 
 sub _fetch_userdata {
@@ -174,7 +175,7 @@ sub set_replica_version {
 
     $self->_set_replica_version($version);
 
-    $self->_store_metadata( key   => 'replica-version', value => $version,);
+    $self->store_local_metadata( 'replica-version' => $version,);
 
     return $version;
 }
@@ -197,7 +198,8 @@ sub initialize {
     my $self = shift;
     my %args = validate(
         @_,
-        {   db_uuid    => 0,
+        {
+            db_uuid    => 0,
             resdb_uuid => 0,
         }
     );
@@ -205,31 +207,32 @@ sub initialize {
     if ( !$self->fs_root_parent ) {
 
         if ( $self->can_write_changesets ) {
-            die
-                "We can only create local prophet replicas. It looks like you're trying to create "
-                . $self->url;
-        } else {
+            die "We can only create local prophet replicas. It looks like you're trying to create "
+              . $self->url;
+        }
+        else {
             die "Prophet couldn't find a replica at \""
-                . $self->url
-                . "\"\n\n"
-                . "Please check the URL and try again.\n";
+              . $self->url
+              . "\"\n\n"
+              . "Please check the URL and try again.\n";
 
         }
     }
 
     return if $self->replica_exists;
-    mkpath([$self->fs_root]);
+    mkpath( [ $self->fs_root ] );
+
     #$self->dbh->begin_work;
-for (
+    for (
 
-q{
+        q{
 CREATE TABLE records (
     luid INTEGER PRIMARY KEY AUTOINCREMENT,
     uuid text,
     type text
 )
 },
-q{
+        q{
 CREATE TABLE record_props (
     uuid text,
     prop text,
@@ -275,20 +278,20 @@ CREATE TABLE userdata (
 )
 },
 
+        q{create index uuid_idx on record_props(uuid)},
+        q{create index typeuuuid on records(type, uuid)},
+        q{create index keyidx on userdata(key)}
 
-q{create index uuid_idx on record_props(uuid)},
-q{create index typeuuuid on records(type, uuid)},
-q{create index keyidx on userdata(key)}
-
-
-) {
+      )
+    {
         $self->dbh->do($_) || warn $self->dbh->errstr;
     }
 
     $self->set_db_uuid( $args{'db_uuid'} || Data::UUID->new->create_str );
     $self->set_replica_uuid( Data::UUID->new->create_str );
     $self->set_replica_version(2);
-    $self->resolution_db_handle->initialize( db_uuid => $args{resdb_uuid} ) if !$self->is_resdb;
+    $self->resolution_db_handle->initialize( db_uuid => $args{resdb_uuid} )
+      if !$self->is_resdb;
     $self->after_initialize->($self);
 }
 
@@ -308,27 +311,21 @@ Return the replica  UUID
 
 sub uuid {
     my $self = shift;
-    $self->_uuid( $self->_fetch_metadata('replica-uuid') ) unless $self->_uuid;
+    $self->_uuid( $self->fetch_local_metadata('replica-uuid') ) unless $self->_uuid;
     return $self->_uuid;
 }
 
 sub set_replica_uuid {
     my $self = shift;
     my $uuid = shift;
-    $self->_store_metadata(
-        key    => 'replica-uuid',
-        value => $uuid
-    );
+    $self->store_local_metadata( 'replica-uuid' => $uuid);
 
 }
 
 before set_db_uuid => sub {
     my $self = shift;
     my $uuid = shift;
-    $self->_store_metadata(
-        key    => 'database-uuid',
-        value => $uuid
-    );
+    $self->store_local_metadata( 'database-uuid', => $uuid);
 };
 
 =head1 Internals of record handling
@@ -767,7 +764,6 @@ sub find_or_create_luid {
     return $sth->fetchrow_array;
 }
 
-
 sub find_luid_by_uuid {
     my $self = shift;
     my %args = validate( @_, { uuid => 1 } );
@@ -777,7 +773,6 @@ sub find_luid_by_uuid {
     return $sth->fetchrow_array;
 }
 
-
 sub find_uuid_by_luid {
     my $self = shift;
     my %args = validate( @_, { luid => 1 } );
@@ -788,30 +783,40 @@ sub find_uuid_by_luid {
     return $sth->fetchrow_array;
 }
 
+sub _upgrade_replica_to_v2 {
+    my $self = shift;
 
+    $self->_do_db_upgrades(
+        statements => [
+            q{CREATE TABLE new_records (luid INTEGER PRIMARY KEY, uuid TEXT, type TEXT)},
+            q{INSERT INTO new_records (uuid, type) SELECT uuid, type FROM records},
+            q{DROP TABLE records},
+            q{ALTER TABLE new_records RENAME TO records}
+        ],
+        version => 2
+    );
 
+}
 
-sub _upgrade_replica_to_v2 {
+sub _do_db_upgrades {
     my $self = shift;
-    $self->dbh->begin_work;
-
-for (
-    q{CREATE TABLE new_records (luid INTEGER PRIMARY KEY, uuid TEXT, type TEXT)},
-   q{INSERT INTO new_records (uuid, type) SELECT uuid, type FROM records},
-   q{DROP TABLE records},
-   q{ALTER TABLE new_records RENAME TO records}
+    my %args = (
+        statements => undef,
+        version    => undef,
+        @_
+    );
 
-) {
-        $self->dbh->do($_) || warn $self->dbh->errstr;
+    $self->dbh->begin_work;
+    foreach my $s ( @{ $args{statements} } ) {
+        $self->dbh->do($s) || warn $self->dbh->errstr;
     }
+    $self->set_replica_version( $args{version} );
 
-    $self->set_replica_version(2);
     $self->dbh->commit;
 
 }
 
 
-
 sub DEMOLISH { shift->dbh->disconnect }
 __PACKAGE__->meta->make_immutable;
 no Moose;
diff --git a/lib/Prophet/Test.pm b/lib/Prophet/Test.pm
index b42b287..485c832 100644
--- a/lib/Prophet/Test.pm
+++ b/lib/Prophet/Test.pm
@@ -3,7 +3,7 @@ use warnings;
 
 package Prophet::Test;
 use base qw/Test::More Exporter/;
-our @EXPORT = qw/as_alice as_bob as_charlie as_david as_user run_ok repo_uri_for run_script run_output_matches run_output_matches_unordered replica_last_rev replica_merge_tickets replica_uuid_for ok_added_revisions replica_uuid database_uuid database_uuid_for
+our @EXPORT = qw/as_alice as_bob as_charlie as_david as_user run_ok repo_uri_for run_script run_output_matches run_output_matches_unordered replica_last_rev replica_uuid_for ok_added_revisions replica_uuid database_uuid database_uuid_for
     serialize_conflict serialize_changeset in_gladiator diag is_script_output run_command set_editor load_record
     /;
 
@@ -275,26 +275,6 @@ sub database_uuid {
     return eval { $cli->handle->db_uuid};
 }
 
-=head2 replica_merge_tickets
-
-Returns a hash of key-value pairs of the form 
-
- { uuid => revno,
-   uuid => revno,  
-}
-
-=cut
-
-sub replica_merge_tickets {
-    my $self    = shift;
-    my $cli     = Prophet::CLI->new();
-    require Prophet::Collection;
-    my $tickets = Prophet::Collection->new( handle => $cli->handle, type => $Prophet::Replica::MERGETICKET_METATYPE );
-    $tickets->matching( sub {1} );
-    return { map { $_->uuid => $_->prop('last-changeset') } $tickets->items };
-
-}
-
 sub replica_last_rev {
     my $cli = Prophet::CLI->new();
     return $cli->handle->latest_sequence_no;
diff --git a/t/non-conflicting-merge.t b/t/non-conflicting-merge.t
index f347a64..d2f6a7f 100644
--- a/t/non-conflicting-merge.t
+++ b/t/non-conflicting-merge.t
@@ -3,7 +3,7 @@
 use warnings;
 use strict;
 
-use Prophet::Test tests => 27;
+use Prophet::Test tests => 24;
 
 as_alice {
     run_ok( 'prophet', ['init']);
@@ -54,7 +54,6 @@ as_alice {
     is( scalar @out, 2, "We found only two rows of output" );
 
     is( replica_last_rev(), $last_rev, "We have not recorded another transaction" );
-    is_deeply( replica_merge_tickets(), { replica_uuid_for('bob') => as_bob { replica_last_rev() } } );
 
 };
 
@@ -77,13 +76,11 @@ as_bob {
     is( replica_last_rev, $last_rev + 1, "only one rev from alice is sycned" );
 
    # last rev of alice is originated from bob (us), so not synced to bob, hence the merge ticket is at the previous rev.
-    is_deeply( replica_merge_tickets(), { replica_uuid_for('alice') => as_alice { replica_last_rev() - 1 } } );
     $last_rev = replica_last_rev();
 
     diag('Sync from alice to bob again');
     run_ok( 'prophet', [ 'merge',  '--to', repo_uri_for('bob'), '--from', repo_uri_for('alice'), '--force' ], "Sync ran ok!" );
 
-    is_deeply( replica_merge_tickets(), { replica_uuid_for('alice') => as_alice { replica_last_rev() - 1 } } );
     is( replica_last_rev(), $last_rev, "We have not recorded another transaction after a second sync" );
 
 };
diff --git a/t/publish-pull.t b/t/publish-pull.t
index 17adc61..b47972a 100644
--- a/t/publish-pull.t
+++ b/t/publish-pull.t
@@ -133,16 +133,6 @@ sub changeset_ok {
                                ? $args{sequence_no} - 1
                                : undef;
 
-        $changes->{ replica_uuid_for('alice') } = {
-            change_type  => $change_type,
-            record_type  => $Prophet::Replica::MERGETICKET_METATYPE,
-            prop_changes => {
-                'last-changeset' => {
-                    old_value => $prev_changeset_num,
-                    new_value => $args{sequence_no},
-                }
-            }
-        };
     }
 
     is_deeply($changeset, {
diff --git a/t/real-conflicting-merge.t b/t/real-conflicting-merge.t
index 687ed09..e5d3702 100644
--- a/t/real-conflicting-merge.t
+++ b/t/real-conflicting-merge.t
@@ -209,19 +209,6 @@ sub check_bob_final_state_ok {
                             }
 
                     },
-                    as_alice {
-                        replica_uuid();
-                    } => {
-                        record_type    => $Prophet::Replica::MERGETICKET_METATYPE,
-                        change_type  => 'update_file',
-                        prop_changes => {
-                            'last-changeset' => {
-                                old_value => $ALICE_LAST_REV_CACHE - 1,
-                                new_value => $ALICE_LAST_REV_CACHE
-                            }
-                            }
-
-                    }
                 }
             },
 
diff --git a/t/simple-conflicting-merge.t b/t/simple-conflicting-merge.t
index 5bb6fb4..4bdbfa0 100644
--- a/t/simple-conflicting-merge.t
+++ b/t/simple-conflicting-merge.t
@@ -174,18 +174,6 @@ as_bob {
                     prop_changes => { status => { old_value => 'new', new_value => 'stalled' } }
                 },
 
-                replica_uuid_for('alice') => {
-                    change_type  => 'update_file',
-                    record_type    => $Prophet::Replica::MERGETICKET_METATYPE,
-                    prop_changes => {
-                        'last-changeset' => {
-                            old_value => ($alice->latest_sequence_no-1),
-                            new_value => $alice->latest_sequence_no
-                        }
-                        }
-
-                    }
-
                 }
 
         },

-----------------------------------------------------------------------



More information about the Bps-public-commit mailing list