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