NAME
DBIx::Class::Schema::Slave - DBIx::Class::Schema for slave (EXPERIMENTAL)
SYNOPSIS
# In your MyApp::Schema class
package MyApp::Schema;
__PACKAGE__->load_components( qw/ Schema::Slave / );
__PACKAGE__->slave_moniker('::Slave');
__PACKAGE__->slave_connect_info( [
[ 'dbi:mysql:database:hostname=host', 'username', 'passsword', { ... } ],
[ 'dbi:mysql:database:hostname=host', 'username', 'passsword', { ... } ],
[ 'dbi:mysql:database:hostname=host', 'username', 'passsword', { ... } ],
...,
] );
# Somewhere in your code
use MyApp::Schema;
# First, connect to master
my $schema = MyApp::Schema->connect( @master_connect_info );
# Retrieving from master
my $master = $schema->resultset('Track')->find( $id );
# Retrieving from slave
my $slave = $schema->resultset('Track::Slave')->find( $id );
See DBIx::Class::Schema.
DESCRIPTION
DBIx::Class::Schema::Slave is DBIx::Class::Schema for slave. DBIx::Class::Schema::Slave creates result_source
classes for slave automatically, and connects slave datasources as you like (or at rondom). You can retrieve rows from either master or slave in the same way DBIx::Class::Schema provies but you can neither add nor remove rows from slave.
SETTIN UP DBIx::Class::Schema::Slave
Setting it up manually
First, you should load DBIx::Class::Schema::Slave as component in your MyApp::Schema.
# In your MyApp::Schema
package MyApp::Schema;
__PACKAGE__->load_components( qw/ Schema::Slave / );
Set "slave_moniker" as you like.
__PACKAGE__->slave_moniker('::Slave');
Set "slave_connect_info" as ARRAYREF
of ARRAYREF
.
__PACKAGE__->slave_connect_info( [
[ 'dbi:mysql:database:hostname=host', 'user', 'passsword', { ... } ],
[ 'dbi:mysql:database:hostname=host', 'user', 'passsword', { ... } ],
[ 'dbi:mysql:database:hostname=host', 'user', 'passsword', { ... } ],
...,
] );
Next, you have MyApp::Schema::Artist, MyApp::Schema::Album, MyApp::Schema::Track, load these result_source
classes.
__PACKAGE__->load_classes( qw/ Artist Album Track / );
In running "load_classes", DBIx::Class::Schema::Slave creates slave result_source
classes MyApp::Schema::Artist::Slave, MyApp::Schema::Album::Slave and MyApp::Schema::Track::Slave automatically. If you set ::MySlave
to "slave_moniker", it creates MyApp::Schema::Artist::MySlave, MyApp::Schema::Album::MySlave and MyApp::Schema::Track::MySlave. If you wouldn't connect to slave, always connect to master, you can provide some result_source
classes to "load_classes".
# Schema::Artist::Slave wouldn't be created
__PACKAGE__->load_classes( qw/ Album Track / );
I recommend every result_source
classes to be loaded.
# Every result_source classes are loaded
__PACKAGE__->load_classes;
Next, load DBIx::Class::Row::Slave as component in your result_source
classes.
# In your MyApp::Schema::Artist;
package MyApp::Schema::Artist;
__PACKEAGE__->load_components( qw/ ... Row::Slave Core / );
# Some definitions or methods go on
Using DBIx::Class::Schema::Loader
DBIx::Class::Schema::Slave DOES NOT work out with DBIx::Class::Schema::Loader. At present, you make result_source
classes by calling "make_schema_at" in DBIx::Class::Schema::Loader and load them in your DBIx::Class::Schema based MyApp::Schema. Maybe, it will be settled at next version or after the next, or ...
Connecting (Create Schema instance)
To connect your Schema, you provive connect_info
for master not for slave.
my $schema = MyApp::Schema->connect( @master_connect_info );
Retrieving
Retrieving from master, you don't have to care about anything.
my $album_master = $schema->resultset('Album')->find( $id );
my $itr_album_master = $schema->resultset('Album')->search( { ... }, { ... } );
Retrieving from slave, you should set slave moniker to "resultset".
my $track_slave = $schema->resultset('Album::Slave')->find( $id );
my $itr_track_slave = $schema->resultset('Album::Slave')->search( { ... }, { ... } );
Adding and removing rows
You can either create a new record or remove some rows from master. But you can neither create a new record nor remove some rows from slave.
# These complete normally
my $track = $schema->resultset('Track')->create( {
created_on => $dt->now || undef,
modified_on => $dt->now || undef,
album_id => $album->id || undef,
title => $title || undef,
time => $time || undef,
} );
$track->title('WORLD\'S END SUPERNOVA');
$track->update;
$track->delete;
# You got an error!
# DBIx::Class::ResultSet::create(): Can't insert via result source "Track::Slave". This is slave connection.
my $track = $schema->resultset('Track::Slave')->create( {
created_on => $dt->now || undef,
modified_on => $dt->now || undef,
album_id => $album->id || undef,
title => $title || undef,
time => $time || undef,
} );
$track->title('TEAM ROCK');
# You got an error!
# DBIx::Class::ResultSet::update(): Can't update via result source "Track::Slave". This is slave connection.
$track->update;
# And, you got an error!
# DBIx::Class::ResultSet::delete(): Can't delete via result source "Track::Slave". This is slave connection.
$track->delete;
Don't call "update_all" in DBIx::Class::ResultSet, "delete_all" in DBIx::Class::ResultSet and "populate" in DBIx::Class::ResultSet via slave result_source
s. Also you should not call "find_or_new" in DBIx::Class::ResultSet, "find_or_create" in DBIx::Class::ResultSet and "update_or_create" in DBIx::Class::ResultSet via slave result_source
s.
CLASS DATA
slave_moniker
Moniker for slave. ::Slave
default.
# In your MyApp::Schema
__PACKAGE__->slave_moniker('::Slave');
IMPORTANT: If you have already MyApp::Schema::Artist::Slave, DO NOT set ::Slave
to slave_moniker
. Set ::SlaveFor
or something else.
slave_connect_info
connect_info
s ARRAYREF
of ARRAYREF
for slave.
# In your MyApp::Schema
__PACKAGE__->slave_connect_info( [
[ 'dbi:mysql:database:hostname=host', 'username', 'passsword', { ... } ],
[ 'dbi:mysql:database:hostname=host', 'username', 'passsword', { ... } ],
[ 'dbi:mysql:database:hostname=host', 'username', 'passsword', { ... } ],
...,
] );
slave_connection
Connection for slave stored. You can get this by "slave".
METHODS
load_classes
No @classes
provided, this method registers all result_source
classes for master and slave. If you provide @classes
, registers them for master and slave.
# You have MyApp::Schema::Artist, MyApp::Schema::Album, MyApp::Schema::Track
# In your MyApp::Schema
__PACKAGE__->load_classes;
Then, this method re-maps class_mappings
and source_registrations
.
# Re-mapped class_mappings
class_mappings => {
MyApp::Schema::Artist => 'Artist',
MyApp::Schema::Artist::Slave => 'Artist::Slave',
MyApp::Schema::Album => 'Album',
MyApp::Schema::Album::Slave => 'Album::Slave',
MyApp::Schema::Track => 'Track',
MyApp::Schema::Track::Slave => 'Track::Slave',
}
# Re-mapped source_registrations
source_registrations => {
MyApp::Schema::Artist => {
bless( {
...,
...,
...,
}, DBIx::Class::ResultSource::Table )
},
MyApp::Schema::Artist::Slave => {
bless( {
...,
...,
...,
}, DBIx::Class::ResultSource::Table )
},
...,
...,
...,
MyApp::Schema::Track::Slave => {
bless( {
...,
...,
...,
}, DBIx::Class::ResultSource::Table )
},
}
See "load_classes" in DBIx::Class::Schema.
resultset
If $moniker
is slave moniker, this method returns $result_set
for slave. See "resultset" in DBIx::Class::Schema.
sources
This method returns the sorted alphabetically source monikers of all source registrations on this schema. See "sources" in DBIx::Class::Schema.
# Returns all sources including slave sources
my @all_sources = $schema->sources;
master_sources
This method returns the sorted alphabetically master source monikers of all source registrations on this schema.
my @master_sources = $schema->master_sources;
slave_sources
This method returns the sorted alphabetically slave source monikers of all source registrations on this schema.
my @slave_sources = $schema->slave_sources;
connect_slave
This method creates slave connection, and store it in slave_connection
. You can get this by "slave". Usualy, you don't have to call it directry.
slave
Getter for "slave_connection". You can get schema for slave if it stored in "slave_connection".
my $slave_schema = $schema->slave;
select_connect_info
You can define this method in your schema class as you like. This method has to return $connect_info
as ARRAYREF
. If "select_connect_info" returns undef
or undef value or not ARRAYREF
, "_select_connect_info" will be called, and return $connect_info
at random from "slave_connect_info".
# In your MyApp::Schame
sub select_connect_info {
my $self = shift;
my @connect_info = @{$self->slave_connect_info};
my $connect_info;
# Some algorithm to select connect_info here
return $connect_info;
}
INTERNAL METHOD
_select_connect_info
Internal method. This method returns $connect_info
for slave as ARRAYREF
. Usually, you don't have to call it directry. If you select $connect_info
as you like, define "select_connect_info" in your schema class. See "select_connect_info" for more information.
AUTHOR
travail <travail@cabane.no-ip.org>
COPYRIGHT
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
The full text of the license can be found in the LICENSE file included with this module.