File Coverage

blib/lib/Class/DBI/Loader/SQLite.pm
Criterion Covered Total %
statement 59 59 100.0
branch 9 12 75.0
condition 3 6 50.0
subroutine 9 9 100.0
pod n/a
total 80 86 93.0


line stmt bran cond sub pod time code
1             package Class::DBI::Loader::SQLite;
2              
3 1     1   9 use strict;
  1         3  
  1         61  
4 1     1   6 use base 'Class::DBI::Loader::Generic';
  1         2  
  1         2405  
5 1     1   7 use vars '$VERSION';
  1         2  
  1         212  
6 1     1   7 use Text::Balanced qw( extract_bracketed );
  1         3  
  1         103  
7 1     1   5 use DBI;
  1         2  
  1         106  
8 1     1   6 use Carp;
  1         1  
  1         1438  
9             require Class::DBI::SQLite;
10             require Class::DBI::Loader::Generic;
11              
12             $VERSION = '0.30';
13              
14             =head1 NAME
15              
16             Class::DBI::Loader::SQLite - Class::DBI::Loader SQLite Implementation.
17              
18             =head1 SYNOPSIS
19              
20             use Class::DBI::Loader;
21              
22             # $loader is a Class::DBI::Loader::SQLite
23             my $loader = Class::DBI::Loader->new(
24             dsn => "dbi:SQLite:dbname=/path/to/dbfile",
25             namespace => "Data",
26             );
27             my $class = $loader->find_class('film'); # $class => Data::Film
28             my $obj = $class->retrieve(1);
29              
30             =head1 DESCRIPTION
31              
32             Multi-column primary keys are supported. It's also fine to define multi-column
33             foreign keys, but they will be ignored because L does not support them.
34              
35             See L, L.
36              
37             =cut
38              
39 1     1   3 sub _db_class { return 'Class::DBI::SQLite' }
40              
41             sub _relationships {
42 1     1   3 my $self = shift;
43 1         17 foreach my $table ( $self->tables ) {
44              
45 4         30 my $dbh = $self->find_class($table)->db_Main;
46 4         380 my $sth = $dbh->prepare(<<"");
47             SELECT sql FROM sqlite_master WHERE tbl_name = ?
48              
49 4         673 $sth->execute($table);
50 4         2096 my ($sql) = $sth->fetchrow_array;
51 4         31 $sth->finish;
52              
53             # Cut "CREATE TABLE ( )" blabla...
54 4         32 $sql =~ /^[\w\s]+\((.*)\)$/si;
55 4         14 my $cols = $1;
56              
57             # strip single-line comments
58 4         15 $cols =~ s/\-\-.*\n/\n/g;
59              
60             # temporarily replace any commas inside parens,
61             # so we don't incorrectly split on them below
62 4         8 my $cols_no_bracketed_commas = $cols;
63 4         24 while ( my $extracted =
64             ( extract_bracketed( $cols, "()", "[^(]*" ) )[0] )
65             {
66 3         1184 my $replacement = $extracted;
67 3         13 $replacement =~ s/,/--comma--/g;
68 3         11 $replacement =~ s/^\(//;
69 3         9 $replacement =~ s/\)$//;
70 3         99 $cols_no_bracketed_commas =~ s/$extracted/$replacement/m;
71             }
72              
73             # Split column definitions
74 4         2354 for my $col ( split /,/, $cols_no_bracketed_commas ) {
75              
76             # put the paren-bracketed commas back, to help
77             # find multi-col fks below
78 13         36 $col =~ s/\-\-comma\-\-/,/g;
79              
80             # CDBI doesn't have built-in support multi-col fks, so ignore them
81 13 100 66     115 next if $col =~ s/^\s*FOREIGN\s+KEY\s*//i && $col =~ /^\([^,)]+,/;
82              
83             # Strip punctuations around key and table names
84 12         28 $col =~ s/[()\[\]'"]/ /g;
85 12         51 $col =~ s/^\s+//gs;
86              
87             # Grab reference
88 12 100       124 if ( $col =~ /^(\w+).*REFERENCES\s+(\w+)/i ) {
89 1         4 chomp $col;
90 1 50       13 warn qq/\# Found foreign key definition "$col"\n\n/
91             if $self->debug;
92 1         122 eval { $self->_has_a_many( $table, $1, $2 ) };
  1         20  
93 1 50 33     10290 warn qq/\# has_a_many failed "$@"\n\n/ if $@ && $self->debug;
94             }
95             }
96             }
97             }
98              
99             sub _tables {
100 1     1   1 my $self = shift;
101 1 50       2 my $dbh = DBI->connect( @{ $self->{_datasource} } ) or croak($DBI::errstr);
  1         14  
102 1         1378 my $sth = $dbh->prepare("SELECT * FROM sqlite_master");
103 1         425 $sth->execute;
104 1         10 my @tables;
105 1         241 while ( my $row = $sth->fetchrow_hashref ) {
106 5 100       110 next unless lc( $row->{type} ) eq 'table';
107 4         81 push @tables, $row->{tbl_name};
108             }
109 1         6 $sth->finish;
110 1         65 $dbh->disconnect;
111 1         67 return @tables;
112             }
113              
114             =head1 SEE ALSO
115              
116             L, L
117              
118             =cut
119              
120             1;