File Coverage

blib/lib/DBIx/Model.pm
Criterion Covered Total %
statement 9 71 12.6
branch 0 14 0.0
condition 0 6 0.0
subroutine 3 5 60.0
pod 0 1 0.0
total 12 97 12.3


line stmt bran cond sub pod time code
1             package DBIx::Model;
2 1     1   20511 use strict;
  1         3  
  1         30  
3 1     1   5 use warnings;
  1         2  
  1         30  
4 1     1   466 use DBIx::Model::DB;
  1         6  
  1         948  
5              
6             our $VERSION = '0.0.1_2';
7              
8             my %columns;
9             my %forward;
10             my %backward;
11              
12             sub DBI::db::model {
13 0     0     my $dbh = shift;
14 0           my $catalog = shift;
15 0           my $schema = shift;
16 0   0       my $names = shift // '%';
17 0   0       my $type = shift // 'TABLE,VIEW';
18              
19             my $db = DBIx::Model::DB->new(
20             name => $dbh->{Name},
21 0           catalog => $catalog,
22             schema => $schema,
23             table_types => $type,
24             );
25 0           my @raw_fk;
26              
27 0           my $t_sth =
28             $dbh->table_info( $db->catalog, $db->schema, $names, $db->table_types );
29              
30 0           my $trefs = $t_sth->fetchall_hashref('TABLE_NAME');
31 0           foreach my $tname ( sort keys %$trefs ) {
32             my $table = $db->add_table(
33             name => $tname,
34             type => $trefs->{$tname}->{TABLE_TYPE}
35 0           );
36              
37 0           my @primary = $dbh->primary_key( $db->catalog, $db->schema, $tname );
38 0           my $c_sth = $dbh->column_info( $db->catalog, $db->schema, $tname, '%' );
39              
40 0           while ( my $c_ref = $c_sth->fetchrow_hashref ) {
41 0           my $pri = grep { $c_ref->{COLUMN_NAME} eq $_ } @primary;
  0            
42             $table->add_column(
43             name => $c_ref->{COLUMN_NAME},
44             nullable => $c_ref->{NULLABLE},
45             size => $c_ref->{COLUMN_SIZE},
46 0 0 0       type => $c_ref->{TYPE_NAME} || '*UNKNOWN*',
47             primary => $pri ? 1 : 0,
48             );
49             }
50              
51 0           my $fk_sth =
52             $dbh->foreign_key_info( $db->catalog, $db->schema, undef,
53             $db->catalog, $db->schema, $tname );
54              
55 0           my @x;
56 0           while ( my $fk_ref = $fk_sth->fetchrow_hashref ) {
57 0 0         next unless defined $fk_ref->{PKCOLUMN_NAME}; # mysql?
58              
59 0 0         if ( $fk_ref->{KEY_SEQ} == 1 ) {
60 0 0         if (@x) {
61 0           push( @raw_fk, [@x] );
62             }
63             @x = (
64             lc $tname,
65             lc $fk_ref->{PKTABLE_NAME},
66             [
67             lc $fk_ref->{FKCOLUMN_NAME}, lc $fk_ref->{PKCOLUMN_NAME}
68 0           ]
69             );
70             }
71             else {
72             push(
73             @x,
74             [
75             lc $fk_ref->{FKCOLUMN_NAME}, lc $fk_ref->{PKCOLUMN_NAME}
76 0           ]
77             );
78             }
79             }
80              
81 0 0         if (@x) {
82 0           push( @raw_fk, [@x] );
83             }
84             }
85              
86 0           foreach my $fk (@raw_fk) {
87             my ($from) =
88 0           grep { $_->name_lc eq $fk->[0] } $db->tables;
  0            
89 0           my ($to) = grep { $_->name_lc eq $fk->[1] } $db->tables;
  0            
90 0           shift @$fk;
91 0           shift @$fk;
92              
93 0           my @from;
94             my @to;
95              
96 0           foreach my $pair (@$fk) {
97 0           push( @from, grep { $_->name_lc eq $pair->[0] } $from->columns );
  0            
98 0           push( @to, grep { $_->name_lc eq $pair->[1] } $to->columns );
  0            
99             }
100              
101             $from->add_foreign_key(
102 0           to_table => $to,
103             columns => \@from,
104             to_columns => \@to,
105             );
106              
107 0           map { $columns{ $_->full_name_lc } = $_ } @from, @to;
  0            
108             map {
109 0           $forward{ $to[$_]->full_name_lc }->{ $from[$_]->full_name_lc }++;
  0            
110 0           $backward{ $from[$_]->full_name_lc }->{ $to[$_]->full_name_lc }++;
111             } 0 .. ( ( scalar @from ) - 1 );
112             }
113              
114 0           my $chain = 1;
115 0           while ( my $key = ( sort keys %forward, keys %backward )[0] ) {
116 0           chainer( $key, $chain++ );
117             }
118              
119 0           $db->chains( $chain - 1 );
120 0           %columns = %forward = %backward = ();
121 0           return $db;
122             }
123              
124             sub chainer {
125 0     0 0   my $key = shift;
126 0           my $chain = shift;
127              
128 0           $columns{$key}->chain($chain);
129              
130 0 0         if ( my $val = delete $forward{$key} ) {
131 0           foreach my $new ( sort keys %$val ) {
132 0           chainer( $new, $chain );
133             }
134             }
135              
136 0 0         if ( my $val = delete $backward{$key} ) {
137 0           foreach my $new ( sort keys %$val ) {
138 0           chainer( $new, $chain );
139             }
140             }
141             }
142              
143             1;
144              
145             __END__