docs and reqs update for 0.01000 release
[dbsrgits/DBIx-Class-Schema-Loader.git] / lib / DBIx / Class / Schema / Loader / SQLite.pm
CommitLineData
18fca96a 1package DBIx::Class::Schema::Loader::SQLite;
a78e3fed 2
3use strict;
3980d69c 4use warnings;
2a4b8262 5use Class::C3;
a4a19f3c 6use base qw/DBIx::Class::Schema::Loader::Generic/;
3980d69c 7
a78e3fed 8use Text::Balanced qw( extract_bracketed );
a78e3fed 9
10=head1 NAME
11
18fca96a 12DBIx::Class::Schema::Loader::SQLite - DBIx::Class::Schema::Loader SQLite Implementation.
a78e3fed 13
14=head1 SYNOPSIS
15
18fca96a 16 use DBIx::Class::Schema::Loader;
a78e3fed 17
18fca96a 18 # $loader is a DBIx::Class::Schema::Loader::SQLite
19 my $loader = DBIx::Class::Schema::Loader->new(
a78e3fed 20 dsn => "dbi:SQLite:dbname=/path/to/dbfile",
a78e3fed 21 );
a78e3fed 22
23=head1 DESCRIPTION
24
18fca96a 25See L<DBIx::Class::Schema::Loader>.
a78e3fed 26
27=cut
28
3980d69c 29sub _db_classes {
a78e3fed 30 return qw/DBIx::Class::PK::Auto::SQLite/;
31}
32
708c0939 33# XXX this really needs a re-factor
3980d69c 34sub _load_relationships {
35 my $self = shift;
36 foreach my $table ( $self->tables ) {
a78e3fed 37
3980d69c 38 my $dbh = $self->schema->storage->dbh;
a78e3fed 39 my $sth = $dbh->prepare(<<"");
40SELECT sql FROM sqlite_master WHERE tbl_name = ?
41
42 $sth->execute($table);
43 my ($sql) = $sth->fetchrow_array;
44 $sth->finish;
45
46 # Cut "CREATE TABLE ( )" blabla...
47 $sql =~ /^[\w\s]+\((.*)\)$/si;
48 my $cols = $1;
49
50 # strip single-line comments
51 $cols =~ s/\-\-.*\n/\n/g;
52
53 # temporarily replace any commas inside parens,
54 # so we don't incorrectly split on them below
55 my $cols_no_bracketed_commas = $cols;
56 while ( my $extracted =
57 ( extract_bracketed( $cols, "()", "[^(]*" ) )[0] )
58 {
59 my $replacement = $extracted;
60 $replacement =~ s/,/--comma--/g;
61 $replacement =~ s/^\(//;
62 $replacement =~ s/\)$//;
63 $cols_no_bracketed_commas =~ s/$extracted/$replacement/m;
64 }
65
66 # Split column definitions
67 for my $col ( split /,/, $cols_no_bracketed_commas ) {
68
69 # put the paren-bracketed commas back, to help
70 # find multi-col fks below
71 $col =~ s/\-\-comma\-\-/,/g;
72
708c0939 73 $col =~ s/^\s*FOREIGN\s+KEY\s*//i;
a78e3fed 74
75 # Strip punctuations around key and table names
708c0939 76 $col =~ s/[\[\]'"]/ /g;
a78e3fed 77 $col =~ s/^\s+//gs;
78
79 # Grab reference
4ce22656 80 chomp $col;
16f6b6ac 81 next if $col !~ /^(.*)\s+REFERENCES\s+(\w+) (?: \s* \( (.*) \) )? /ix;
708c0939 82
16f6b6ac 83 my ($cols, $f_table, $f_cols) = ($1, $2, $3);
132694df 84
16f6b6ac 85 if($cols =~ /^\(/) { # Table-level
86 $cols =~ s/^\(\s*//;
87 $cols =~ s/\s*\)$//;
88 }
89 else { # Inline
90 $cols =~ s/\s+.*$//;
91 }
132694df 92
16f6b6ac 93 my $cond;
708c0939 94
16f6b6ac 95 if($f_cols) {
96 my @cols = map { s/\s*//g; $_ } split(/\s*,\s*/,$cols);
97 my @f_cols = map { s/\s*//g; $_ } split(/\s*,\s*/,$f_cols);
98 die "Mismatched column count in rel for $table => $f_table"
99 if @cols != @f_cols;
100 $cond = {};
101 for(my $i = 0 ; $i < @cols; $i++) {
102 $cond->{$f_cols[$i]} = $cols[$i];
103 }
3980d69c 104 eval { $self->_make_cond_rel( $table, $f_table, $cond ) };
a78e3fed 105 }
16f6b6ac 106 else {
3980d69c 107 eval { $self->_make_simple_rel( $table, $f_table, $cols ) };
16f6b6ac 108 }
109
110 warn qq/\# belongs_to_many failed "$@"\n\n/
3980d69c 111 if $@ && $self->debug;
a78e3fed 112 }
113 }
114}
115
3980d69c 116sub _tables {
117 my $self = shift;
118 my $dbh = $self->schema->storage->dbh;
a78e3fed 119 my $sth = $dbh->prepare("SELECT * FROM sqlite_master");
120 $sth->execute;
121 my @tables;
122 while ( my $row = $sth->fetchrow_hashref ) {
123 next unless lc( $row->{type} ) eq 'table';
124 push @tables, $row->{tbl_name};
125 }
a78e3fed 126 return @tables;
127}
128
3980d69c 129sub _table_info {
130 my ( $self, $table ) = @_;
a78e3fed 131
132 # find all columns.
3980d69c 133 my $dbh = $self->schema->storage->dbh;
a78e3fed 134 my $sth = $dbh->prepare("PRAGMA table_info('$table')");
135 $sth->execute();
136 my @columns;
137 while ( my $row = $sth->fetchrow_hashref ) {
138 push @columns, $row->{name};
139 }
140 $sth->finish;
141
142 # find primary key. so complex ;-(
143 $sth = $dbh->prepare(<<'SQL');
144SELECT sql FROM sqlite_master WHERE tbl_name = ?
145SQL
146 $sth->execute($table);
147 my ($sql) = $sth->fetchrow_array;
148 $sth->finish;
a78e3fed 149 my ($primary) = $sql =~ m/
150 (?:\(|\,) # either a ( to start the definition or a , for next
151 \s* # maybe some whitespace
152 (\w+) # the col name
153 [^,]* # anything but the end or a ',' for next column
154 PRIMARY\sKEY/sxi;
155 my @pks;
156
157 if ($primary) {
158 @pks = ($primary);
159 }
160 else {
9a69e859 161 my ($pks) = $sql =~ m/PRIMARY\s+KEY\s*\(\s*([^)]+)\s*\)/i;
a78e3fed 162 @pks = split( m/\s*\,\s*/, $pks ) if $pks;
163 }
164 return ( \@columns, \@pks );
165}
166
167=head1 SEE ALSO
168
18fca96a 169L<DBIx::Schema::Class::Loader>
a78e3fed 170
171=cut
172
1731;