use BUILDARGS intead of wrapping new, added make_immutable, removed unnneeded test...
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / Replicated / Balancer.pm
index 241d666..316653a 100644 (file)
@@ -140,21 +140,39 @@ around 'next_storage' => sub {
   return $next ? $next:$self->master; 
 };
 
-=head2 before: select
+=head2 increment_storage
 
-Advice on the select attribute.  Each time we use a replicant
-we need to change it via the storage pool algorithm.  That way we are spreading
-the load evenly (hopefully) across existing capacity.
+Rolls the Storage to whatever is next in the queue, as defined by the Balancer.
 
 =cut
 
-before 'select' => sub {
+sub increment_storage {
   my $self = shift @_;
   my $next_replicant = $self->next_storage;
   $self->current_replicant($next_replicant);
+}
+
+=head2 around: select
+
+Advice on the select attribute.  Each time we use a replicant
+we need to change it via the storage pool algorithm.  That way we are spreading
+the load evenly (hopefully) across existing capacity.
+
+=cut
+
+around 'select' => sub {
+  my ($select, $self, @args) = @_;
+  
+  if (my $forced_pool = $args[-1]->{force_pool}) {
+    delete $args[-1]->{force_pool};
+    return $self->_get_forced_pool($forced_pool)->select(@args); 
+  } else {
+    $self->increment_storage;
+    return $self->$select(@args);
+  }
 };
 
-=head2 before: select_single
+=head2 around: select_single
 
 Advice on the select_single attribute.  Each time we use a replicant
 we need to change it via the storage pool algorithm.  That way we are spreading
@@ -162,10 +180,16 @@ the load evenly (hopefully) across existing capacity.
 
 =cut
 
-before 'select_single' => sub {
-  my $self = shift @_;
-  my $next_replicant = $self->next_storage;
-  $self->current_replicant($next_replicant);
+around 'select_single' => sub {
+  my ($select_single, $self, @args) = @_;
+  
+  if (my $forced_pool = $args[-1]->{force_pool}) {
+       delete $args[-1]->{force_pool};
+       return $self->_get_forced_pool($forced_pool)->select_single(@args); 
+  } else {
+       $self->increment_storage;
+    return $self->$select_single(@args);
+  }
 };
 
 =head2 before: columns_info_for
@@ -178,10 +202,28 @@ the load evenly (hopefully) across existing capacity.
 
 before 'columns_info_for' => sub {
   my $self = shift @_;
-  my $next_replicant = $self->next_storage;
-  $self->current_replicant($next_replicant);
+  $self->increment_storage;
 };
 
+=head2 _get_forced_pool ($name)
+
+Given an identifier, find the most correct storage object to handle the query.
+
+=cut
+
+sub _get_forced_pool {
+  my ($self, $forced_pool) = @_;
+  if(blessed $forced_pool) {
+    return $forced_pool;
+  } elsif($forced_pool eq 'master') {
+    return $self->master;
+  } elsif(my $replicant = $self->pool->replicants($forced_pool)) {
+    return $replicant;
+  } else {
+    $self->master->throw_exception("$forced_pool is not a named replicant.");
+  }   
+}
+
 =head1 AUTHOR
 
 John Napiorkowski <john.napiorkowski@takkle.com>