[Bast-commits] r3936 - in DBIx-Class-Partitioned/1.000/trunk:
lib/DBIx/Class t t/lib/My/Schema
edenc at dev.catalyst.perl.org
edenc at dev.catalyst.perl.org
Tue Jan 15 14:48:39 GMT 2008
Author: edenc
Date: 2008-01-15 14:48:39 +0000 (Tue, 15 Jan 2008)
New Revision: 3936
Removed:
DBIx-Class-Partitioned/1.000/trunk/t/lib/My/Schema/InactiveUser.pm
Modified:
DBIx-Class-Partitioned/1.000/trunk/lib/DBIx/Class/Partitioned.pm
DBIx-Class-Partitioned/1.000/trunk/t/01-basic.t
DBIx-Class-Partitioned/1.000/trunk/t/lib/My/Schema/User.pm
DBIx-Class-Partitioned/1.000/trunk/t/test.db
Log:
partitions simulating materialized view
Modified: DBIx-Class-Partitioned/1.000/trunk/lib/DBIx/Class/Partitioned.pm
===================================================================
--- DBIx-Class-Partitioned/1.000/trunk/lib/DBIx/Class/Partitioned.pm 2008-01-14 13:25:00 UTC (rev 3935)
+++ DBIx-Class-Partitioned/1.000/trunk/lib/DBIx/Class/Partitioned.pm 2008-01-15 14:48:39 UTC (rev 3936)
@@ -3,7 +3,6 @@
use warnings;
use strict;
use base qw/DBIx::Class/;
-use Data::Dump;
=head1 NAME
@@ -24,31 +23,29 @@
use base qw/DBIx::Class/;
__PACKAGE__->load_components(qw/Partitioned Core/);
- __PACKAGE__->partitions(qw/active_user inactive_user/);
+ __PACKAGE__->table('user');
+ __PACKAGE__->partitions(qw/active_user/);
__PACKAGE__->add_columns(qw/id foo is_expired/);
- __PACKAGE__->select_partition_via('is_active');
- sub is_active { shift->is_expired ? 'active_user' : 'inactive_user' }
+ sub is_active { return 'active_user' if !shift->is_expired; return }
# meanwhile in a nearby piece of code...
my $user_rs = $schema->resultset('User');
- my @rows = $user_rs->all; # selects rows from active_user and inactive_user
- $user_rs->create({ foo => 'bar', is_active => 1 }); # inserts to active_user
- $user_rs->create({ foo => 'baz', is_active => 0 }); # inserts to inactive_user
+ $user_rs->search_partition('active_user');
+ my @rows = $user_rs->all; # selects rows from active_user
+ $user_rs->create({ foo => 'bar', is_active => 1 }); # inserts to active_user and user
=cut
__PACKAGE__->mk_classdata('_partitions');
-__PACKAGE__->mk_classdata('ident_rel');
+__PACKAGE__->mk_group_accessors(
+ 'simple' => qw/_current_partition is_partition_row/ );
sub partitions {
my ( $class, @parts ) = @_;
$class->_partitions( {} );
- my $union =
- '(' . join( ' UNION ALL ', map { "SELECT * FROM $_" } @parts ) . ')';
my $source = $class->result_source_instance;
- $source->name( \$union );
foreach my $partition (@parts) {
my $new_source = $source->new($source);
my $new_source_name = join '::', map { ucfirst } split '_', $partition;
@@ -56,6 +53,7 @@
$new_source->name($partition);
foreach my $rel_name ( $source->relationships ) {
my $rel_info = $source->relationship_info($rel_name);
+ $rel_info->{attrs}{cascade_delete} = 0;
$new_source->add_relationship( $rel_name,
@{$rel_info}{qw/source cond attrs/} );
}
@@ -81,51 +79,92 @@
return;
}
-sub set_partition_source {
- my ($self) = @_;
- my $partition_name = $self->_partition_name;
- $self->result_source( $self->partition($partition_name) );
-}
-
sub new {
my $class = shift;
my $self = $class->next::method(@_);
- my $ident_source_name =
- $self->relationship_info( $self->ident_rel )->{source};
- my $ident_source = $self->result_source->schema->source($ident_source_name);
- my $ident_row =
- $self->create_related( $self->ident_rel,
- { map { $_ => undef } $ident_source->columns } );
- $ident_row->discard_changes;
- my %pks = $ident_row->get_columns;
- $self->$_( $pks{$_} ) for keys %pks;
- $self->set_partition_source;
+ if ( my $partition_name = $self->_partition_name ) {
+ $self->_current_partition($partition_name);
+ }
return $self;
}
sub inflate_result {
- my $self = shift->next::method(@_);
- $self->set_partition_source;
+ my $class = shift;
+ my $self = $class->next::method(@_);
+ if ( my $partition_name = $self->_partition_name ) {
+ $self->_current_partition($partition_name);
+ }
return $self;
}
+sub insert {
+ my $self = shift;
+ if ( !$self->in_storage
+ && !$self->is_partition_row
+ && ( my $part = $self->_partition_name ) )
+ {
+ my $partition = $self->partition($part)
+ or confess("couldn't find partition '${part}'");
+ my $row = $partition->resultset->new_result( { $self->get_columns } );
+ $row->is_partition_row(1);
+ $row->insert;
+ $self->_current_partition($part);
+ }
+ return $self->next::method(@_);
+}
+
sub update {
- my $self = shift;
- my $old_partition = $self->result_source;
- $self->set_partition_source;
- my $new_partition = $self->result_source;
- if ( $new_partition->source_name ne $old_partition->source_name ) {
- $self->result_source($old_partition);
- $self->delete;
- $self->result_source($new_partition);
- $self->insert;
+ my $self = shift;
+ $self->next::method(@_);
+ my $old_part = $self->_current_partition;
+ my $new_part = $self->_partition_name;
+
+ if ( $old_part && $new_part ) {
+ my $part_row =
+ $self->partition($old_part)
+ ->resultset->find( { $self->get_columns } );
+ if ( $old_part ne $new_part ) {
+ $part_row->delete;
+ my $row =
+ $self->partition($new_part)
+ ->resultset->new_result( { $self->get_columns } );
+ $row->is_partition_row(1);
+ $row->insert;
+ $self->_current_partition($new_part);
+ }
+ else {
+ $part_row->set_columns( { $self->get_columns } );
+ $part_row->update;
+ }
}
- else {
- $self->next::method(@_);
+ elsif ( !$old_part && $new_part ) {
+ my $row =
+ $self->partition($new_part)
+ ->resultset->new_result( { $self->get_columns } );
+ $row->is_partition_row(1);
+ $row->insert;
+ $self->_current_partition($new_part);
}
+ elsif ( $old_part && !$new_part ) {
+ my $row = $self->partition($old_part)->resultset->find( { $self->get_columns } );
+ $row->is_partition_row(1);
+ $row->delete;
+ $self->_current_partition('');
+ }
return $self;
}
+sub delete {
+ my $self = shift;
+ $self->next::method(@_);
+ if ( my $part = $self->_current_partition && !$self->is_partition_row) {
+ $self->partition($part)->resultset->find( { $self->get_columns } )
+ ->delete;
+ $self->_current_partition('');
+ }
+ return $self;
+}
+
=head1 AUTHOR
Eden Cardim, C<< <edenc at shadowcatsystems.co.uk> >>
Modified: DBIx-Class-Partitioned/1.000/trunk/t/01-basic.t
===================================================================
--- DBIx-Class-Partitioned/1.000/trunk/t/01-basic.t 2008-01-14 13:25:00 UTC (rev 3935)
+++ DBIx-Class-Partitioned/1.000/trunk/t/01-basic.t 2008-01-15 14:48:39 UTC (rev 3936)
@@ -7,6 +7,7 @@
my $schema = My::Schema->connect('dbi:SQLite:dbname=t/test.db');
my $test = sub {
my $user_rs = $schema->resultset('User');
+ $user_rs->partition( 'active_user' );
my $data = { foo => 'bar', is_expired => 0 };
isa_ok( my $user = $user_rs->create($data), 'My::Schema::User' );
$user->add_to_affiliations( { name => 'foo' } );
@@ -24,12 +25,9 @@
is( $user->posts->first->content, 'bar' );
$data->{is_expired} = 1;
- isa_ok( $user_rs->create($data), 'My::Schema::User' );
- row_fields_equal(
- $user = $user_rs->search($data)->single,
- $schema->resultset('InactiveUser')->search($data)->single,
- [qw/id foo is_expired/]
- );
+ isa_ok( $user = $user_rs->create($data), 'My::Schema::User' );
+ ok( !$schema->resultset('ActiveUser')->search( { $user->get_columns } )
+ ->count );
$user->add_to_affiliations( $schema->resultset('Affiliation')->first );
$user->add_to_posts( { title => 'foo', content => 'bar' } );
is( $user->affiliations->first->name, 'foo' );
@@ -39,11 +37,13 @@
$user->update;
ok( $schema->resultset('ActiveUser')->search( { $user->get_columns } )
->count );
- ok( !$schema->resultset('InactiveUser')->search( { $user->get_columns } )
- ->count );
is( $user->affiliations->first->name, 'foo' );
is( $user->posts->first->title, 'foo' );
is( $user->posts->first->content, 'bar' );
+ $user->is_expired(1);
+ $user->update;
+ ok( !$schema->resultset('ActiveUser')->search( { $user->get_columns } )
+ ->count );
die 'rollback';
};
eval { $schema->txn_do($test) };
@@ -54,6 +54,6 @@
ok($row1);
ok($row2);
foreach my $field (@$fields) {
- is( $row1->$field, $row2->$field );
+ is( $row1->$field, $row2->$field, "$field: " . $row1->$field );
}
}
Deleted: DBIx-Class-Partitioned/1.000/trunk/t/lib/My/Schema/InactiveUser.pm
===================================================================
--- DBIx-Class-Partitioned/1.000/trunk/t/lib/My/Schema/InactiveUser.pm 2008-01-14 13:25:00 UTC (rev 3935)
+++ DBIx-Class-Partitioned/1.000/trunk/t/lib/My/Schema/InactiveUser.pm 2008-01-15 14:48:39 UTC (rev 3936)
@@ -1,23 +0,0 @@
-package My::Schema::InactiveUser;
-
-use warnings;
-use strict;
-
-use base qw/DBIx::Class/;
-
-__PACKAGE__->load_components(qw/Core/);
-__PACKAGE__->table('inactive_user');
-
-__PACKAGE__->add_column(
- id => { is_auto_increment => 1, data_type => 'integer' } );
-__PACKAGE__->add_columns(qw/foo is_expired/);
-__PACKAGE__->set_primary_key('id');
-
-__PACKAGE__->has_many( 'posts', 'Post', { 'foreign.user_id' => 'self.id' } );
-
-__PACKAGE__->has_many( 'user_affiliations',
- 'UserAffiliation' => { 'foreign.user_id' => 'self.id' } );
-
-__PACKAGE__->many_to_many( 'affiliations', 'user_affiliations', 'affiliation' );
-
-1;
Modified: DBIx-Class-Partitioned/1.000/trunk/t/lib/My/Schema/User.pm
===================================================================
--- DBIx-Class-Partitioned/1.000/trunk/t/lib/My/Schema/User.pm 2008-01-14 13:25:00 UTC (rev 3935)
+++ DBIx-Class-Partitioned/1.000/trunk/t/lib/My/Schema/User.pm 2008-01-15 14:48:39 UTC (rev 3936)
@@ -12,31 +12,49 @@
__PACKAGE__->add_columns(qw/foo is_expired/);
__PACKAGE__->set_primary_key('id');
-__PACKAGE__->has_one(
- 'user_ident',
- 'UserIdent' => { 'foreign.id' => 'self.id' },
- { cascade_delete => 0 }
-);
+__PACKAGE__->has_many( 'posts', 'Post' => { 'foreign.user_id' => 'self.id' } );
-__PACKAGE__->has_many(
- 'posts',
- 'Post' => { 'foreign.user_id' => 'self.id' },
- { cascade_delete => 0 }
-);
+__PACKAGE__->has_many( 'user_affiliations',
+ 'UserAffiliation' => { 'foreign.user_id' => 'self.id' } );
-__PACKAGE__->has_many(
- 'user_affiliations',
- 'UserAffiliation' => { 'foreign.user_id' => 'self.id' },
- { cascade_delete => 0 }
-);
-
__PACKAGE__->many_to_many( 'affiliations', 'user_affiliations', 'affiliation' );
-__PACKAGE__->partitions(qw/inactive_user active_user/);
-__PACKAGE__->ident_rel('user_ident');
+__PACKAGE__->partitions(qw/active_user/);
sub _partition_name {
- return shift->is_expired ? 'inactive_user' : 'active_user';
+ return 'active_user' if !shift->is_expired;
+ return;
}
+__PACKAGE__->resultset_class('My::ResultSet::User');
+
+package My::ResultSet::User;
+
+use warnings;
+use strict;
+
+use base qw/DBIx::Class::ResultSet/;
+
+__PACKAGE__->mk_group_accessors( 'simple' => qw/partition/ );
+
+sub search_rs {
+ my $self = shift;
+ my $new = $self->next::method(@_);
+ $new->partition( $self->partition );
+ return $new;
+}
+
+sub cursor {
+ my $self = shift;
+ if ( $self->partition ) {
+ my $source = $self->result_source;
+ $self->result_source(
+ $self->result_class->partition( $self->partition ) );
+ my $cursor = $self->next::method(@_);
+ $self->result_source($source);
+ return $cursor;
+ }
+ return $self->next::method(@_);
+}
+
1;
Modified: DBIx-Class-Partitioned/1.000/trunk/t/test.db
===================================================================
(Binary files differ)
More information about the Bast-commits
mailing list