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