update
delete
dbh
- txn_do
txn_commit
txn_rollback
sth
);
}
+=head2 execute_reliably ($coderef, ?@args)
+
+Given a coderef, saves the current state of the L</read_handler>, forces it to
+use reliable storage (ie sets it to the master), executes a coderef and then
+restores the original state.
+
+Example:
+
+ my $reliably = sub {
+ my $name = shift @_;
+ $schema->resultset('User')->create({name=>$name});
+ my $user_rs = $schema->resultset('User')->find({name=>$name});
+ };
+
+ $schema->storage->execute_reliably($reliably, 'John');
+
+Use this when you must be certain of your database state, such as when you just
+inserted something and need to get a resultset including it, etc.
+
+=cut
+
+sub execute_reliably {
+ my ($self, $coderef, @args) = @_;
+
+ unless( ref $coderef eq 'CODE') {
+ $self->throw_exception('Second argument must be a coderef');
+ }
+
+ ##Get copy of master storage
+ my $master = $self->master;
+
+ ##Get whatever the current read hander is
+ my $current = $self->read_handler;
+
+ ##Set the read handler to master
+ $self->read_handler($master);
+
+ ## do whatever the caller needs
+ eval {
+ $coderef->(@args);
+ };
+
+ if($@) {
+ $self->throw_exception("coderef returned an error: $@");
+ }
+
+ ##Reset to the original state
+ $self->schema->storage->read_handler($current);
+}
+
=head2 set_reliable_storage
Sets the current $schema to be 'reliable', that is all queries, both read and
$schema->storage->read_handler($write_handler);
}
+=head2 txn_do ($coderef)
+
+Overload to the txn_do method, which is delegated to whatever the
+L<write_handler> is set to. We overload this in order to wrap in inside a
+L</execute_reliably> method.
+
+=cut
+
+sub txn_do {
+ my($self, $coderef, @args) = @_;
+ $self->execute_reliably($coderef, @args);
+}
+
=head2 connected
Check that the master and at least one of the replicants is connected.
=head1 AUTHOR
-Norbert Csongrádi <bert@cpan.org>
+ John Napiorkowski <john.napiorkowski@takkle.com>
-Peter Siklósi <einon@einon.hu>
+Based on code originated by:
-John Napiorkowski <john.napiorkowski@takkle.com>
+ Norbert Csongrádi <bert@cpan.org>
+ Peter Siklósi <einon@einon.hu>
=head1 LICENSE
use warnings;
use lib qw(t/lib);
use Test::More;
+use Test::Exception;
use DBICTest;
BEGIN {
eval "use Moose; use Test::Moose";
plan $@
? ( skip_all => 'needs Moose for testing' )
- : ( tests => 50 );
+ : ( tests => 57 );
}
use_ok 'DBIx::Class::Storage::DBI::Replicated::Pool';
=> "both replicants reactivated";
}
+## Test the reliably callback
+
+ok my $reliably = sub {
+
+ ok $replicated->schema->resultset('Artist')->find(5)
+ => 'replicant reactivated';
+
+} => 'created coderef properly';
+
+$replicated->schema->storage->execute_reliably($reliably);
+
+## Try something with an error
+
+ok my $unreliably = sub {
+
+ ok $replicated->schema->resultset('ArtistXX')->find(5)
+ => 'replicant reactivated';
+
+} => 'created coderef properly';
+
+throws_ok {$replicated->schema->storage->execute_reliably($unreliably)}
+ qr/coderef returned an error: Can't find source for ArtistXX/
+ => 'Bad coderef throws proper error';
+
+## make sure transactions are set to execute_reliably
+
+ok my $transaction = sub {
+
+ $replicated
+ ->schema
+ ->populate('Artist', [
+ [ qw/artistid name/ ],
+ [ 666, "Children of the Grave"],
+ ]);
+
+ ok my $result = $replicated->schema->resultset('Artist')->find(666);
+
+};
+
+$replicated->schema->txn_do($transaction);
+
+## Make sure replication came back
+
+ok $replicated->schema->resultset('Artist')->find(5)
+ => 'replicant reactivated';
+
## Delete the old database files
$replicated->cleanup;