File Coverage

blib/lib/Teng/Schema/Dumper.pm
Criterion Covered Total %
statement 53 55 96.3
branch 14 18 77.7
condition 0 3 0.0
subroutine 7 7 100.0
pod 1 1 100.0
total 75 84 89.2


line stmt bran cond sub pod time code
1             package Teng::Schema::Dumper;
2 1     1   484 use strict;
  1         2  
  1         33  
3 1     1   5 use warnings;
  1         2  
  1         34  
4 1     1   429 use DBIx::Inspector 0.06;
  1         5694  
  1         25  
5 1     1   6 use Carp ();
  1         2  
  1         14  
6 1     1   5 use DBI ();
  1         2  
  1         662  
7              
8             my %SQLTYPE2NAME = map { &{$DBI::{$_}} => $_ } @{$DBI::EXPORT_TAGS{sql_types}};
9              
10             sub dump {
11 5     5 1 38201 my $class = shift;
12 5 50       28 my %args = @_==1 ? %{$_[0]} : @_;
  0         0  
13              
14 5 50       18 my $dbh = $args{dbh} or Carp::croak("missing mandatory parameter 'dbh'");
15 5 50       15 my $namespace = $args{namespace} or Carp::croak("missing mandatory parameter 'namespace'");
16              
17 5         21 my $inspector = DBIx::Inspector->new(dbh => $dbh);
18              
19 5         3466 my $ret = "";
20              
21 5 100       20 if ( ref $args{tables} eq "ARRAY" ) {
    100          
22 1         2 for my $table_name (@{ $args{tables} }) {
  1         4  
23 2         8 $ret .= _render_table($inspector->table($table_name), \%args);
24             }
25             }
26             elsif ( $args{tables} ) {
27 1         13 $ret .= _render_table($inspector->table($args{tables}), \%args);
28             }
29             else {
30 3         9 $ret .= "package ${namespace}::Schema;\n";
31 3         8 $ret .= "use strict;\n";
32 3         5 $ret .= "use warnings;\n";
33 3         5 $ret .= "use DBI qw/:sql_types/;\n";
34 3         6 $ret .= "use Teng::Schema::Declare;\n";
35 3 100       10 $ret .= "base_row_class '$args{base_row_class}';\n" if $args{base_row_class};
36 3 100       9 $ret .= "default_row_class_prefix '$args{default_row_class_prefix}';\n" if $args{default_row_class_prefix};
37 3         16 for my $table_info (sort { $a->name cmp $b->name } $inspector->tables) {
  9         1965  
38 9         38 $ret .= _render_table($table_info, \%args);
39             }
40 3         19 $ret .= "1;\n";
41             }
42              
43 5         41 return $ret;
44             }
45              
46             sub _render_table {
47 12     12   1498 my ($table_info, $args) = @_;
48              
49 12         18 my $ret = "";
50              
51 12         27 $ret .= "table {\n";
52 12         30 $ret .= sprintf(" name '%s';\n", $table_info->name);
53 12         78 $ret .= sprintf(" pk %s;\n", join ',' , map { q{'}.$_->name.q{'} } $table_info->primary_key);
  12         17059  
54 12         133 $ret .= " columns (\n";
55 12         37 for my $col ($table_info->columns) {
56 48 50       14267 if ($col->data_type) {
57 0   0     0 $ret .= sprintf(" {name => '%s', type => %s},\n", $col->name, $SQLTYPE2NAME{$col->data_type} || $col->data_type);
58             } else {
59 48         196 $ret .= sprintf(" '%s',\n", $col->name);
60             }
61             }
62 12         132 $ret .= " );\n";
63              
64 12 100       39 if (my $rule = $args->{inflate}->{$table_info->name}) {
65 1         41 $ret .= $rule;
66             }
67              
68 12         79 $ret .= "};\n\n";
69              
70 12         86 return $ret;
71             }
72              
73             1;
74             __END__
75              
76             =head1 NAME
77              
78             Teng::Schema::Dumper - Schema code generator
79              
80             =head1 SYNOPSIS
81              
82             use DBI;
83             use Teng::Schema::Dumper;
84              
85             my $dbh = DBI->connect(@dsn) or die;
86             print Teng::Schema::Dumper->dump(
87             dbh => $dbh,
88             namespace => 'Mock::DB',
89             inflate => +{
90             user => q|
91             use Mock::Inflate::Name;
92             inflate 'name' => sub {
93             my ($col_value) = @_;
94             return Mock::Inflate::Name->new(name => $col_value);
95             };
96             deflate 'name' => sub {
97             my ($col_value) = @_;
98             return ref $col_value ? $col_value->name : $col_value . '_deflate';
99             };
100             inflate qr/.+oo/ => sub {
101             my ($col_value) = @_;
102             return Mock::Inflate::Name->new(name => $col_value);
103             };
104             deflate qr/.+oo/ => sub {
105             my ($col_value) = @_;
106             return ref $col_value ? $col_value->name : $col_value . '_deflate';
107             };
108             |,
109             },
110             );
111              
112             =head1 DESCRIPTION
113              
114             This module generates the Perl code to generate L<Teng::Schema> instance.
115              
116             You can use it by C<do "my/schema.pl"> or embed it to the package.
117              
118             =head1 METHODS
119              
120             =over 4
121              
122             =item C<Teng::Schema::Dumper-E<gt>dump(dbh =E<gt> $dbh, namespace =E<gt> $namespace)>
123              
124             This is the method to generate code from DB. It returns the Perl5 code in string.
125              
126             The arguments are:
127              
128             =over 4
129              
130             =item C<dbh>
131              
132             Database handle from DBI.
133              
134             =item C<namespace>
135              
136             your project Teng namespace.
137              
138             =item C<base_row_class>
139              
140             Specify the default base row class for L<Teng::Schema::Declare>.
141              
142             =item C<default_row_class_prefix>
143              
144             Specify the default row class prefix for L<Teng::Schema::Declare>.
145              
146             =back
147              
148             =back
149