Added limit_dialect info (no magic because of DBD::Multi driver).
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / Replication.pm
CommitLineData
325e3466 1package DBIx::Class::Storage::DBI::Replication;
2
3use strict;
4use warnings;
5
6use DBIx::Class::Storage::DBI;
7use DBD::Multi;
8use base qw/Class::Accessor::Fast/;
9
10__PACKAGE__->mk_accessors( qw/read_source write_source/ );
11
12=head1 NAME
13
14DBIx::Class::Storage::DBI::Replication - Replicated database support
15
16=head1 SYNOPSIS
17
18 # change storage_type in your schema class
19 $schema->storage_type( '::DBI::Replication' );
20 $schema->connect_info( [
21 [ "dbi:mysql:database=test;hostname=master", "username", "password", { AutoCommit => 1 } ], # master
22 [ "dbi:mysql:database=test;hostname=slave1", "username", "password", { priority => 10 } ], # slave1
23 [ "dbi:mysql:database=test;hostname=slave2", "username", "password", { priority => 10 } ], # slave2
24 <...>
25 ] );
30804c8a 26 # If you use LIMIT in your queries (effectively, if you use SQL::Abstract::Limit),
27 # do not forget to set up limit_dialect (see: perldoc SQL::Abstract::Limit)
28 # DBIC can not set it up automatically, since DBD::Multi could not be supported directly
29 $schema->limit_dialect( 'LimitXY' ) # For MySQL
325e3466 30
31=head1 DESCRIPTION
32
33This class implements replicated data store for DBI. Currently you can define one master and numerous slave database
34connections. All write-type queries (INSERT, UPDATE, DELETE and even LAST_INSERT_ID) are routed to master database,
35all read-type queries (SELECTs) go to the slave database.
36
37For every slave database you can define a priority value, which controls data source usage pattern. It uses
38L<DBD::Multi>, so first the lower priority data sources used (if they have the same priority, the are used
39randomized), than if all low priority data sources fail, higher ones tried in order.
40
41=cut
42
43sub new {
44 my $proto = shift;
45 my $class = ref( $proto ) || $proto;
dbc6d854 46 my $self = {};
325e3466 47
48 bless( $self, $class );
49
50 $self->write_source( DBIx::Class::Storage::DBI->new );
51 $self->read_source( DBIx::Class::Storage::DBI->new );
52
53 return $self;
54}
55
56sub all_sources {
57 my $self = shift;
58
dbc6d854 59 my @sources = ($self->read_source, $self->write_source);
325e3466 60
61 return wantarray ? @sources : \@sources;
62}
63
64sub connect_info {
65 my( $self, $source_info ) = @_;
66
67 $self->write_source->connect_info( $source_info->[0] );
68
69 my @dsns = map { ($_->[3]->{priority} || 10) => $_ } @{$source_info}[1..@$source_info-1];
70 $self->read_source->connect_info( [ 'dbi:Multi:', undef, undef, { dsns => \@dsns } ] );
71}
72
73sub select {
dbc6d854 74 shift->read_source->select( @_ );
325e3466 75}
76sub select_single {
dbc6d854 77 shift->read_source->select_single( @_ );
325e3466 78}
79sub throw_exception {
dbc6d854 80 shift->read_source->throw_exception( @_ );
325e3466 81}
82sub sql_maker {
dbc6d854 83 shift->read_source->sql_maker( @_ );
325e3466 84}
85sub columns_info_for {
dbc6d854 86 shift->read_source->columns_info_for( @_ );
325e3466 87}
88sub sqlt_type {
dbc6d854 89 shift->read_source->sqlt_type( @_ );
325e3466 90}
91sub create_ddl_dir {
dbc6d854 92 shift->read_source->create_ddl_dir( @_ );
325e3466 93}
94sub deployment_statements {
dbc6d854 95 shift->read_source->deployment_statements( @_ );
325e3466 96}
97sub datetime_parser {
dbc6d854 98 shift->read_source->datetime_parser( @_ );
325e3466 99}
100sub datetime_parser_type {
dbc6d854 101 shift->read_source->datetime_parser_type( @_ );
325e3466 102}
103sub build_datetime_parser {
dbc6d854 104 shift->read_source->build_datetime_parser( @_ );
325e3466 105}
106
107sub limit_dialect {
108 my $self = shift;
dbc6d854 109 $self->$_->limit_dialect( @_ ) for( $self->all_sources );
325e3466 110}
111sub quote_char {
112 my $self = shift;
dbc6d854 113 $self->$_->quote_char( @_ ) for( $self->all_sources );
325e3466 114}
115sub name_sep {
116 my $self = shift;
dbc6d854 117 $self->$_->quote_char( @_ ) for( $self->all_sources );
325e3466 118}
119sub disconnect {
120 my $self = shift;
dbc6d854 121 $self->$_->disconnect( @_ ) for( $self->all_sources );
325e3466 122}
123sub DESTROY {
124 my $self = shift;
125
dbc6d854 126 undef $self->{write_source};
127 undef $self->{read_sources};
325e3466 128}
129
130sub last_insert_id {
dbc6d854 131 shift->write_source->last_insert_id( @_ );
325e3466 132}
133sub insert {
dbc6d854 134 shift->write_source->insert( @_ );
325e3466 135}
136sub update {
dbc6d854 137 shift->write_source->update( @_ );
325e3466 138}
139sub update_all {
dbc6d854 140 shift->write_source->update_all( @_ );
325e3466 141}
142sub delete {
dbc6d854 143 shift->write_source->delete( @_ );
325e3466 144}
145sub delete_all {
dbc6d854 146 shift->write_source->delete_all( @_ );
325e3466 147}
148sub create {
dbc6d854 149 shift->write_source->create( @_ );
325e3466 150}
151sub find_or_create {
dbc6d854 152 shift->write_source->find_or_create( @_ );
325e3466 153}
154sub update_or_create {
dbc6d854 155 shift->write_source->update_or_create( @_ );
325e3466 156}
157sub connected {
dbc6d854 158 shift->write_source->connected( @_ );
325e3466 159}
160sub ensure_connected {
dbc6d854 161 shift->write_source->ensure_connected( @_ );
325e3466 162}
163sub dbh {
dbc6d854 164 shift->write_source->dbh( @_ );
325e3466 165}
166sub txn_begin {
dbc6d854 167 shift->write_source->txn_begin( @_ );
325e3466 168}
169sub txn_commit {
dbc6d854 170 shift->write_source->txn_commit( @_ );
325e3466 171}
172sub txn_rollback {
dbc6d854 173 shift->write_source->txn_rollback( @_ );
325e3466 174}
175sub sth {
dbc6d854 176 shift->write_source->sth( @_ );
325e3466 177}
178sub deploy {
dbc6d854 179 shift->write_source->deploy( @_ );
325e3466 180}
181
182
183sub debugfh { shift->_not_supported( 'debugfh' ) };
184sub debugcb { shift->_not_supported( 'debugcb' ) };
185
186sub _not_supported {
187 my( $self, $method ) = @_;
188
189 die "This Storage does not support $method method.";
190}
191
192=head1 SEE ALSO
193
194L<DBI::Class::Storage::DBI>, L<DBD::Multi>, L<DBI>
195
196=head1 AUTHOR
197
198Norbert Csongrádi <bert@cpan.org>
199
dbc6d854 200Peter Siklósi <einon@einon.hu>
325e3466 201
202=head1 LICENSE
203
204You may distribute this code under the same terms as Perl itself.
205
206=cut
207
2081;