File Coverage

blib/lib/SQL/DB/Schema.pm
Criterion Covered Total %
statement 90 100 90.0
branch 9 12 75.0
condition n/a
subroutine 20 23 86.9
pod 5 5 100.0
total 124 140 88.5


line stmt bran cond sub pod time code
1             package SQL::DB::Schema;
2 5     5   20448 use strict;
  5         10  
  5         188  
3 5     5   27 use warnings;
  5         8  
  5         125  
4 5     5   932 use Moo;
  5         16402  
  5         37  
5 5     5   12580 use Log::Any qw/$log/;
  5         2699  
  5         40  
6 5     5   450 use Carp qw/confess/;
  5         10  
  5         330  
7 5     5   3341 use SQL::DB::Expr qw/_bval/;
  5         18  
  5         35  
8 5     5   1589 use Sub::Install qw/install_sub/;
  5         9  
  5         40  
9              
10             our $VERSION = '0.971.0';
11              
12             # Ordinals for DBI->column_info() results
13             use constant {
14 5         1488 TABLE_CAT => 0,
15             TABLE_SCHEM => 1,
16             TABLE_NAME => 2,
17             COLUMN_NAME => 3,
18             DATA_TYPE => 4,
19             TYPE_NAME => 5,
20             COLUMN_SIZE => 6,
21             BUFFER_LENGTH => 7,
22             DECIMAL_DIGITS => 8,
23             NUM_PREC_RADIX => 9,
24             NULLABLE => 10,
25             REMARKS => 11,
26             COLUMN_DEF => 12,
27             SQL_DATA_TYPE => 13,
28             SQL_DATETIME_SUB => 14,
29             CHAR_OCTET_LENGTH => 15,
30             ORDINAL_POSITION => 16,
31             IS_NULLABLE => 17,
32 5     5   709 };
  5         12  
33              
34             # Object definition
35              
36             has 'name' => (
37             is => 'ro',
38             required => 1,
39             );
40              
41             has 'package_root' => (
42             is => 'ro',
43             required => 1,
44             );
45              
46             has '_tables' => (
47             is => 'ro',
48             init_arg => undef,
49             default => sub { {} },
50             );
51              
52 5     5   29 sub _getglob { no strict 'refs'; \*{ $_[0] } }
  5     0   8  
  5         2315  
  0         0  
  0         0  
53              
54             around BUILDARGS => sub {
55             my $orig = shift;
56             my $class = shift;
57             my %args = @_;
58              
59             ( $args{package_root} = $args{name} ) =~ tr/a-zA-Z0-9/_/cs;
60             $args{package_root} = __PACKAGE__ . '::' . $args{package_root};
61              
62             return $class->$orig(%args);
63             };
64              
65             sub define {
66 3     3 1 412 my $self = shift;
67 3         8 my $data = shift;
68              
69 3         23 my $package_root = $self->package_root;
70 3         16 my $tables = $self->_tables;
71              
72 3         18 foreach my $colref (@$data) {
73 7         178 my $table = $colref->[TABLE_NAME];
74 7         18 my $srow = $package_root . '::Srow::' . $table;
75 7         19 my $urow = $package_root . '::Urow::' . $table;
76              
77 7 100       28 if ( !exists $tables->{$table} ) {
78              
79 3     3   31 eval "package $srow; use Moo; extends 'SQL::DB::Expr'";
  3         7  
  3         52  
  3         307  
80 3     3   19 eval "package $urow; use Moo; extends 'SQL::DB::Expr'";
  3         5  
  3         40  
  3         717  
81              
82             # @{ *{ _getglob( $srow . '::ISA' ) }{ARRAY} } = ('SQL::DB::Expr');
83             # @{ *{ _getglob( $urow . '::ISA' ) }{ARRAY} } = ('SQL::DB::Expr');
84              
85             install_sub(
86             {
87             code => sub {
88 0     0   0 my $table_expr = shift;
89 0         0 return $table_expr . '.*';
90             },
91 3         417 into => $urow,
92             as => '_columns',
93             }
94             );
95             install_sub(
96             {
97             code => sub {
98 0     0   0 my $table_expr = shift;
99 0         0 return SQL::DB::Expr->new(
100             _txt => [ $table_expr->_alias . '.*' ] );
101             },
102 3         367 into => $srow,
103             as => '_columns',
104             }
105             );
106             }
107 7         143 $tables->{$table}++;
108              
109 7         22 my $col = lc $colref->[COLUMN_NAME];
110              
111 7 50       25 if ( $col eq 'new' ) {
112 0         0 confess "Column name 'new' (table/view '$table') clashes with "
113             . __PACKAGE__ . '!!!';
114             }
115              
116 5     5   4999 use bytes;
  5         46  
  5         32  
117 7         18 my $type = lc $colref->[TYPE_NAME];
118              
119             install_sub(
120             {
121             code => sub {
122 40     40   1160 my $table_expr = shift;
123 40         1160 SQL::DB::Expr->new(
124             _txt => [ $table_expr->_alias . '.' . $col ],
125             _type => $type,
126             );
127             },
128 7         54 into => $srow,
129             as => $col,
130             }
131             );
132              
133             install_sub(
134             {
135             code => sub {
136 8     8   1276 my $table_expr = shift;
137              
138 8 50       23 if (@_) {
139 0         0 my $val = shift;
140 0         0 return SQL::DB::Expr->new(
141             _txt => [ $col . ' = ', _bval( $val, $type ) ],
142             _type => $type,
143             );
144             }
145              
146 8         200 return SQL::DB::Expr->new(
147             _txt => [$col],
148             _type => $type,
149             );
150             },
151 7         338 into => $urow,
152             as => $col,
153             }
154             );
155             }
156              
157 3         265 return;
158             }
159              
160             sub not_known {
161 6     6 1 484 my $self = shift;
162 6         29 my $tables = $self->_tables;
163 6         18 return grep { !exists $tables->{$_} } @_;
  6         58  
164             }
165              
166             sub irows {
167 3     3 1 5 my $self = shift;
168              
169 3         8 my @ret;
170 3         10 foreach my $name (@_) {
171 3 100       26 if ( !exists $self->_tables->{$name} ) {
172 1         20 die "Table not defined in schema: $name";
173             }
174 2     2   16 push( @ret, sub { $name . '(' . join( ',', @_ ) . ')' } );
  2         288  
175             }
176 2         10 return @ret;
177             }
178              
179             sub srows {
180 7     7 1 15 my $self = shift;
181              
182 7         14 my @ret;
183 7         27 foreach my $name (@_) {
184 7 100       55 if ( !exists $self->_tables->{$name} ) {
185 2         31 die "Table not defined in schema: $name";
186             }
187 5         36 my $class = $self->package_root . '::Srow::' . $name;
188 5         155 my $srow = $class->new( _txt => [$name], _alias => $name );
189 5         167 push( @ret, $srow );
190             }
191 5         30 return @ret;
192             }
193              
194             sub urows {
195 4     4 1 8 my $self = shift;
196              
197 4         10 my @ret;
198 4         14 foreach my $name (@_) {
199 4 50       33 if ( !exists $self->_tables->{$name} ) {
200 0         0 die "Table not defined in schema: $name";
201             }
202 4         24 my $class = $self->package_root . '::Urow::' . $name;
203 4         223 my $urow = $class->new( _txt => [$name] );
204 4         30 push( @ret, $urow );
205             }
206 4         23 return @ret;
207             }
208              
209             1;
210              
211             # vim: set tabstop=4 expandtab: