File Coverage

blib/lib/Anego/Task/SchemaLoader.pm
Criterion Covered Total %
statement 24 76 31.5
branch 0 14 0.0
condition 0 8 0.0
subroutine 8 14 57.1
pod 0 4 0.0
total 32 116 27.5


line stmt bran cond sub pod time code
1             package Anego::Task::SchemaLoader;
2 1     1   6 use strict;
  1         2  
  1         24  
3 1     1   4 use warnings;
  1         2  
  1         19  
4 1     1   4 use utf8;
  1         2  
  1         8  
5 1     1   22 use Digest::MD5 qw/ md5_hex /;
  1         2  
  1         55  
6 1     1   315 use SQL::Translator;
  1         207326  
  1         30  
7              
8 1     1   7 use Anego::Config;
  1         2  
  1         18  
9 1     1   246 use Anego::Git;
  1         2  
  1         45  
10 1     1   5 use Anego::Logger;
  1         2  
  1         549  
11              
12             sub from {
13 0     0 0   my $class = shift;
14 0   0       my $method = lc(shift || 'latest');
15 0           my @args = @_;
16              
17 0 0         unless ($class->can($method)) {
18 0           errorf("Could not use method: %s\n", $method);
19             }
20              
21 0           return $class->$method(@args);
22             }
23              
24             sub revision {
25 0     0 0   my ($class, $revision) = @_;
26 0           my $config = Anego::Config->load;
27              
28 0           my $schema_class = $config->schema_class;
29 0           my $schema_str = git_cat_file(sprintf('%s:%s', $revision, $config->schema_path));
30              
31 0           my $ddl = _load_ddl_from_schema_string($schema_class, $schema_str);
32              
33 0           my $tr = SQL::Translator->new(
34             parser => $config->rdbms,
35             data => \$ddl,
36             );
37 0           $tr->translate;
38 0           return _filter($tr);
39             }
40              
41             sub latest {
42 0     0 0   my ($class) = @_;
43 0           my $config = Anego::Config->load;
44              
45 0           my $schema_class = $config->schema_class;
46 0           my $schema_path = $config->schema_path;
47              
48 0 0         errorf("Could not find schema class file: $schema_path") unless -f $schema_path;
49              
50 0 0         open my $fh, '<', $schema_path or errorf("Failed to open: $!");
51 0           my $schema_str = do { local $/; <$fh> };
  0            
  0            
52 0           close $fh;
53              
54 0           my $ddl = _load_ddl_from_schema_string($schema_class, $schema_str);
55              
56 0           my $tr = SQL::Translator->new(
57             parser => $config->rdbms,
58             data => \$ddl,
59             );
60 0           $tr->translate;
61 0           return _filter($tr);
62             }
63              
64             sub database {
65 0     0 0   my ($class) = @_;
66 0           my $config = Anego::Config->load;
67              
68 0           my $tr = SQL::Translator->new(
69             parser => 'DBI',
70             parser_args => { dbh => $config->dbh },
71             );
72 0           $tr->translate;
73 0           return _filter($tr);
74             }
75              
76             sub _load_ddl_from_schema_string {
77 0     0     my ($schema_class, $schema_str) = @_;
78              
79 0           $schema_str =~ s/package\s+$schema_class;?//;
80              
81 0           my $klass = sprintf('Anego::Task::SchemaLoader::__ANON__::%s', md5_hex(int rand 65535));
82 0           eval sprintf <<'__SRC__', $klass, $schema_str;
83             package %s;
84              
85             %s
86             __SRC__
87              
88 0           return $klass->output;
89             }
90              
91              
92             sub _filter {
93 0     0     my ($tr) = @_;
94 0 0         return $tr unless $tr;
95              
96 0           my $config = Anego::Config->load;
97 0 0         if ($config->rdbms eq 'MySQL') {
98 0           for my $table ($tr->schema->get_tables) {
99 0           my $options = $table->options;
100 0 0         if (my ($idx) = grep { $options->[$_]->{AUTO_INCREMENT} } 0..$#{$options}) {
  0            
  0            
101 0           splice @{ $options }, $idx, 1;
  0            
102             }
103 0           for my $field ($table->get_fields) {
104 0 0 0       delete $field->{default_value} if $field->{is_nullable} && exists $field->{default_value} && $field->{default_value} eq 'NULL';
      0        
105             }
106             }
107             }
108 0           return $tr;
109             }
110              
111             1;