File Coverage

lib/Cheater/AST.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Cheater::AST;
2              
3 11     11   323 use 5.010000;
  11         87  
  11         425  
4 11     11   4647 use Moose;
  0            
  0            
5             use Clone qw(clone);
6              
7             sub process_table ($$$$$$$);
8              
9             has 'goals' => (is => 'ro', isa => 'HashRef');
10             has 'cols' => (is => 'ro', isa => 'HashRef');
11             has 'deps' => (is => 'ro', isa => 'HashRef');
12             has 'types' => (is => 'ro', isa => 'HashRef');
13             has 'tables' => (is => 'ro', isa => 'HashRef');
14             has 'col_clones' => (is => 'ro', isa => 'HashRef');
15              
16             around BUILDARGS => sub {
17             my $orig = shift;
18             my $class = shift;
19              
20             my $parse_tree = shift;
21              
22             #warn "BUILDARGS";
23              
24             my (%tables, %cols, %deps, %goals, %types, %col_clones);
25              
26             my %cols_visited;
27              
28             %types = (
29             integer => 1,
30             text => 1,
31             serial => 1,
32             real => 1,
33             date => 1,
34             time => 1,
35             datetime => 1,
36             );
37              
38             my $n;
39             do {{
40             $n = @$parse_tree;
41             @$parse_tree = map {
42             $_->[0] eq 'include' ? @{ $_->[1] } : $_
43             } @$parse_tree;
44             }} while (@$parse_tree > $n);
45              
46             for my $stmt (@$parse_tree) {
47             #say $stmt->[0];
48             my $typ = $stmt->[0];
49              
50             given ($typ) {
51             when ('type') {
52             my $typname = $stmt->[1];
53             my $def = $stmt->[2];
54             $types{$typname} = $def;
55             }
56             when ('rows') {
57             my $table = $stmt->[2];
58             my $rows = $goals{$table};
59             if ($rows) {
60             die "table $table was configured to generate $rows rows.\n";
61             }
62             $rows = $stmt->[1];
63             $goals{$table} = $rows;
64             }
65             when ('table') {
66             my $table_name = $stmt->[1];
67             my $table = $stmt->[2];
68             process_table($table_name, $table, \%tables, \%deps, \%cols, \%types, \%col_clones);
69             }
70             when ('table_assign') {
71             my $lhs = $stmt->[1];
72             my $rhs = $stmt->[2];
73              
74             my $table = $tables{$rhs};
75              
76             if (!defined $table) {
77             die "ERROR: $lhs = $rhs: Table $rhs not defined yet.\n";
78             }
79              
80             my $new_table = clone($table);
81              
82             process_table($lhs, $new_table, \%tables, \%deps, \%cols, \%types, \%col_clones);
83             }
84             default {
85             warn "WARN: Unknown statement type: $typ\n";
86             }
87             }
88             }
89              
90             return {
91             tables => \%tables,
92             cols => \%cols,
93             deps => \%deps,
94             goals => \%goals,
95             types => \%types,
96             col_clones => \%col_clones,
97             };
98             };
99              
100             sub process_table ($$$$$$$) {
101             my ($table_name, $table, $tables, $deps, $cols, $types, $col_clones) = @_;
102              
103             $tables->{$table_name} = $table;
104             for my $col (@$table) {
105             #say "col: ", $col->[0];
106             my $name = $col->[0];
107             my $type = $col->[1];
108              
109             my ($domain, $attrs);
110              
111             if ($type eq 'refs') {
112             my $target = $col->[2];
113             $deps->{"$table_name.$name"} =
114             $target->[0] . '.' . $target->[1];
115             $attrs = $col->[3];
116             } elsif ($type eq '=') {
117             my $target = $col->[2];
118             $deps->{"$table_name.$name"} =
119             "$table_name.$target";
120             $col_clones->{"$table_name.$name"} = "$table_name.$target";
121             } else {
122             if (! $types->{$type}) {
123             die "column type $type not defined.\n";
124             }
125              
126             $domain = $col->[2];
127             if (@$domain == 0) {
128             $domain = undef;
129             } else {
130             $domain = $domain->[0];
131             }
132              
133             $attrs = $col->[3];
134             }
135              
136             $cols->{"$table_name.$name"} = {
137             type => $type,
138             domain => $domain,
139             attrs => $attrs,
140             };
141             }
142             }
143              
144             1;