dc7ff907fe289154037cff921b96bc3f1aa9ac59
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / mysql.pm
1 package DBIx::Class::Storage::DBI::mysql;
2
3 use strict;
4 use warnings;
5
6 use base qw/DBIx::Class::Storage::DBI/;
7
8 __PACKAGE__->sql_maker_class('DBIx::Class::SQLMaker::MySQL');
9 __PACKAGE__->sql_limit_dialect ('LimitXY');
10 __PACKAGE__->sql_quote_char ('`');
11
12 __PACKAGE__->_use_multicolumn_in (1);
13
14 sub with_deferred_fk_checks {
15   my ($self, $sub) = @_;
16
17   $self->_do_query('SET FOREIGN_KEY_CHECKS = 0');
18   $sub->();
19   $self->_do_query('SET FOREIGN_KEY_CHECKS = 1');
20 }
21
22 sub connect_call_set_strict_mode {
23   my $self = shift;
24
25   # the @@sql_mode puts back what was previously set on the session handle
26   $self->_do_query(q|SET SQL_MODE = CONCAT('ANSI,TRADITIONAL,ONLY_FULL_GROUP_BY,', @@sql_mode)|);
27   $self->_do_query(q|SET SQL_AUTO_IS_NULL = 0|);
28 }
29
30 sub _dbh_last_insert_id {
31   my ($self, $dbh, $source, $col) = @_;
32   $dbh->{mysql_insertid};
33 }
34
35 # here may seem like an odd place to override, but this is the first
36 # method called after we are connected *and* the driver is determined
37 # ($self is reblessed). See code flow in ::Storage::DBI::_populate_dbh
38 sub _run_connection_actions {
39   my $self = shift;
40
41   # default mysql_auto_reconnect to off unless explicitly set
42   if (
43     $self->_dbh->{mysql_auto_reconnect}
44       and
45     ! exists $self->_dbic_connect_attributes->{mysql_auto_reconnect}
46   ) {
47     $self->_dbh->{mysql_auto_reconnect} = 0;
48   }
49
50   $self->next::method(@_);
51 }
52
53 # we need to figure out what mysql version we're running
54 sub sql_maker {
55   my $self = shift;
56
57   unless ($self->_sql_maker) {
58     my $maker = $self->next::method (@_);
59
60     # mysql 3 does not understand a bare JOIN
61     my $mysql_ver = $self->_dbh_get_info('SQL_DBMS_VER');
62     $maker->{_default_jointype} = 'INNER' if $mysql_ver =~ /^3/;
63   }
64
65   return $self->_sql_maker;
66 }
67
68 sub sqlt_type {
69   return 'MySQL';
70 }
71
72 sub deployment_statements {
73   my $self = shift;
74   my ($schema, $type, $version, $dir, $sqltargs, @rest) = @_;
75
76   $sqltargs ||= {};
77
78   if (
79     ! exists $sqltargs->{producer_args}{mysql_version}
80       and
81     my $dver = $self->_server_info->{normalized_dbms_version}
82   ) {
83     $sqltargs->{producer_args}{mysql_version} = $dver;
84   }
85
86   $self->next::method($schema, $type, $version, $dir, $sqltargs, @rest);
87 }
88
89 sub _exec_svp_begin {
90     my ($self, $name) = @_;
91
92     $self->_dbh->do("SAVEPOINT $name");
93 }
94
95 sub _exec_svp_release {
96     my ($self, $name) = @_;
97
98     $self->_dbh->do("RELEASE SAVEPOINT $name");
99 }
100
101 sub _exec_svp_rollback {
102     my ($self, $name) = @_;
103
104     $self->_dbh->do("ROLLBACK TO SAVEPOINT $name")
105 }
106
107 sub is_replicating {
108     my $status = shift->_get_dbh->selectrow_hashref('show slave status');
109     return ($status->{Slave_IO_Running} eq 'Yes') && ($status->{Slave_SQL_Running} eq 'Yes');
110 }
111
112 sub lag_behind_master {
113     return shift->_get_dbh->selectrow_hashref('show slave status')->{Seconds_Behind_Master};
114 }
115
116 1;
117
118 =head1 NAME
119
120 DBIx::Class::Storage::DBI::mysql - Storage::DBI class implementing MySQL specifics
121
122 =head1 SYNOPSIS
123
124 Storage::DBI autodetects the underlying MySQL database, and re-blesses the
125 C<$storage> object into this class.
126
127   my $schema = MyDb::Schema->connect( $dsn, $user, $pass, { on_connect_call => 'set_strict_mode' } );
128
129 =head1 DESCRIPTION
130
131 This class implements MySQL specific bits of L<DBIx::Class::Storage::DBI>,
132 like AutoIncrement column support and savepoints. Also it augments the
133 SQL maker to support the MySQL-specific C<STRAIGHT_JOIN> join type, which
134 you can use by specifying C<< join_type => 'straight' >> in the
135 L<relationship attributes|DBIx::Class::Relationship::Base/join_type>
136
137
138 It also provides a one-stop on-connect macro C<set_strict_mode> which sets
139 session variables such that MySQL behaves more predictably as far as the
140 SQL standard is concerned.
141
142 =head1 STORAGE OPTIONS
143
144 =head2 set_strict_mode
145
146 Enables session-wide strict options upon connecting. Equivalent to:
147
148   ->connect ( ... , {
149     on_connect_do => [
150       q|SET SQL_MODE = CONCAT('ANSI,TRADITIONAL,ONLY_FULL_GROUP_BY,', @@sql_mode)|,
151       q|SET SQL_AUTO_IS_NULL = 0|,
152     ]
153   });
154
155 =head1 AUTHORS
156
157 See L<DBIx::Class/CONTRIBUTORS>
158
159 =head1 LICENSE
160
161 You may distribute this code under the same terms as Perl itself.
162
163 =cut