[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