schema-loader now uses Class::C3, and ::Pg uses that to override ::Generic->new(...
[dbsrgits/DBIx-Class-Schema-Loader.git] / lib / DBIx / Class / Schema / Loader / mysql.pm
1 package DBIx::Class::Schema::Loader::mysql;
2
3 use strict;
4 use warnings;
5 use Class::C3;
6 use base 'DBIx::Class::Schema::Loader::Generic';
7
8 =head1 NAME
9
10 DBIx::Class::Schema::Loader::mysql - DBIx::Schema::Class::Loader mysql Implementation.
11
12 =head1 SYNOPSIS
13
14   use DBIx::Class::Schema::Loader;
15
16   # $loader is a DBIx::Class::Schema::Loader::mysql
17   my $loader = DBIx::Class::Schema::Loader->new(
18     dsn       => "dbi:mysql:dbname",
19     user      => "root",
20     password  => "",
21   );
22
23 =head1 DESCRIPTION
24
25 See L<DBIx::Class::Schema::Loader>.
26
27 =cut
28
29 sub _db_classes {
30     return qw/DBIx::Class::PK::Auto::MySQL/;
31 }
32
33 sub _load_relationships {
34     my $self   = shift;
35     my @tables = $self->tables;
36     my $dbh    = $self->schema->storage->dbh;
37     my $dsn    = $self->dsn;
38     my %conn   =
39       $dsn =~ m/\Adbi:\w+(?:\(.*?\))?:(.+)\z/i
40       && index( $1, '=' ) >= 0
41       ? split( /[=;]/, $1 )
42       : ( database => $1 );
43     my $dbname = $conn{database} || $conn{dbname} || $conn{db};
44     die("Can't figure out the table name automatically.") if !$dbname;
45
46     my $quoter = $dbh->get_info(29) || q{`};
47
48     foreach my $table (@tables) {
49         my $query = "SHOW CREATE TABLE ${dbname}.${table}";
50         my $sth   = $dbh->prepare($query)
51           or die("Cannot get table definition: $table");
52         $sth->execute;
53         my $table_def = $sth->fetchrow_arrayref->[1] || '';
54         
55         my (@reldata) = ($table_def =~ /CONSTRAINT `.*` FOREIGN KEY \(`(.*)`\) REFERENCES `(.*)` \(`(.*)`\)/ig);
56
57         while (scalar @reldata > 0) {
58             my $cols = shift @reldata;
59             my $f_table = shift @reldata;
60             my $f_cols = shift @reldata;
61
62             my @cols = map { s/$quoter//; $_ } split(/\s*,\s*/,$cols);
63             my @f_cols = map { s/$quoter//; $_ } split(/\s*,\s*/,$f_cols);
64             die "Mismatched column count in rel for $table => $f_table"
65               if @cols != @f_cols;
66             
67             my $cond = {};
68             for(my $i = 0; $i < @cols; $i++) {
69                 $cond->{$f_cols[$i]} = $cols[$i];
70             }
71
72             eval { $self->_make_cond_rel( $table, $f_table, $cond) };
73             warn qq/\# belongs_to_many failed "$@"\n\n/ if $@ && $self->debug;
74         }
75         
76         $sth->finish;
77     }
78 }
79
80 sub _tables {
81     my $self = shift;
82     my $dbh    = $self->schema->storage->dbh;
83     my @tables;
84     my $quoter = $dbh->get_info(29) || q{`};
85     foreach my $table ( $dbh->tables ) {
86         $table =~ s/$quoter//g;
87         push @tables, $1
88           if $table =~ /\A(\w+)\z/;
89     }
90     return @tables;
91 }
92
93 sub _table_info {
94     my ( $self, $table ) = @_;
95     my $dbh    = $self->schema->storage->dbh;
96
97     # MySQL 4.x doesn't support quoted tables
98     my $query = "DESCRIBE $table";
99     my $sth = $dbh->prepare($query) or die("Cannot get table status: $table");
100     $sth->execute;
101     my ( @cols, @pri );
102     while ( my $hash = $sth->fetchrow_hashref ) {
103         my ($col) = $hash->{Field} =~ /(\w+)/;
104         push @cols, $col;
105         push @pri, $col if $hash->{Key} eq "PRI";
106     }
107
108     return ( \@cols, \@pri );
109 }
110
111 =head1 SEE ALSO
112
113 L<DBIx::Class::Schema::Loader>
114
115 =cut
116
117 1;