File Coverage

blib/lib/Teng/Schema/Dumper.pm
Criterion Covered Total %
statement 52 54 96.3
branch 12 16 75.0
condition 0 3 0.0
subroutine 7 7 100.0
pod 1 1 100.0
total 72 81 88.8


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