File Coverage

lib/Decl/Semantics/Repeat.pm
Criterion Covered Total %
statement 13 42 30.9
branch 0 6 0.0
condition n/a
subroutine 5 11 45.4
pod 7 7 100.0
total 25 66 37.8


line stmt bran cond sub pod time code
1             package Decl::Semantics::Repeat;
2            
3 12     12   77 use warnings;
  12         27  
  12         473  
4 12     12   75 use strict;
  12         29  
  12         1067  
5            
6 12     12   74 use base qw(Decl::Node);
  12         24  
  12         1219  
7 12     12   78 use Decl::Semantics::Code;
  12         25  
  12         6506  
8            
9             =head1 NAME
10            
11             Decl::Semantics::Repeat - implements a repeated node
12            
13             =head1 VERSION
14            
15             Version 0.01
16            
17             =cut
18            
19             our $VERSION = '0.01';
20            
21            
22             =head1 SYNOPSIS
23            
24             The "repeat" node repeats its children at its own hierarchical level. It's essentially a loop at build time, a quick way to build structure
25             based on data retrieved. The C/C
26             node has separate children for its query and repetition text and thus has a place to put parameters, code, and other things to refine the
27             repetition process, the C/C
28            
29             =head2 defines(), tags_defined()
30            
31             Called by Decl::Semantics during import, to find out what xmlapi tags this plugin claims to implement.
32            
33             =cut
34 0     0 1 0 sub defines { ('repeat', 'select', 'foreach'); }
35             #our %build_handlers = ( select => { node => sub { Decl::Semantics::Repeat->new (@_) }, body => 'none' },
36             # foreach => { node => sub { Decl::Semantics::Repeat->new (@_) }, body => 'none' }, );
37 12     12 1 85 sub tags_defined { Decl->new_data(<
38             repeat
39             select
40             foreach
41             EOF
42            
43             =head2 decode_line
44            
45             The select/foreach node is the first to parse its line differently from the standard. It treats its entire line as an SQL query (or
46             a data query, depending) - it uses the same syntax as the ^foreach/^select command in embedded Perl.
47            
48             The only exception is that to make the expression of the body easier, it I uses C to retrieve the values from each
49             row. The hash keys are then used to determine what should be replaced in the body for each child built.
50            
51             =cut
52            
53             sub decode_line {
54 0     0 1   my ($self) = @_;
55 0 0         return $self->SUPER::decode_line if $self->is('repeat');
56 0           $self->{query} = "select " . $self->{line};
57             }
58            
59             =head2 parse_body
60            
61             Same thing. The select/foreach node doesn't want to parse its body. Normally, we'd just mark that in build_handlers, but if we do that,
62             we can't macroinsert the results (because there wouldn't be any body parser there, either... Yes, this was a confusing couple of hours.)
63            
64             =cut
65            
66             sub parse_body {
67 0     0 1   my ($self) = @_;
68 0 0         return $self->SUPER::parse_body if $self->is('repeat');
69             }
70            
71             =head2 post_build
72            
73             Here is where we actually do the work of instantiating our true children, based on the body given us and repeating over the results of the
74             query passed in. The repeat body is either the direct body of this tag, or the body of the "text" tag below it, depending on whether this
75             is a "repeat" or a "foreach"/"select" construct.
76            
77             =cut
78            
79             sub post_build {
80 0     0 1   my ($self) = @_;
81            
82 0           my $body = $self->{body}; # TODO: or the text body
83            
84 0           my $d = $self->find_context('database');
85 0           my $dbh = $self->find_context('database')->dbh;
86 0           my $sth = $dbh->prepare($self->{query});
87 0           $sth->execute();
88 0           my @children = ();
89 0           $self->{group} = 1;
90 0           while (my $row = $sth->fetchrow_hashref) {
91 0           my $child = $body;
92 0           foreach my $field (keys %$row) {
93 0           $child =~ s/\$$field/$$row{$field}/gmx;
94             }
95 0           push @children, $self->macroinsert ($child);
96             }
97 0           $self->{children} = \@children;
98             }
99            
100             =head2 go
101            
102             Finally, at runtime, we just execute by calling each of our macroinserted children. Et voila!
103            
104             =cut
105            
106             sub go {
107 0     0 1   my $self = shift;
108 0           my $return;
109            
110 0           foreach (@{$self->{children}}) {
  0            
111 0           $return = $_->go (@_);
112             }
113 0           return $return;
114             }
115            
116             =head2 nodes
117            
118             We override C to permit group shenanigans.
119            
120             =cut
121            
122 0 0   0 1   sub nodes { grep { (defined $_[1] ? $_->is($_[1]) : 1) } @{$_[0]->{children}} }
  0            
  0            
123            
124             =head1 AUTHOR
125            
126             Michael Roberts, C<< >>
127            
128             =head1 BUGS
129            
130             Please report any bugs or feature requests to C, or through
131             the web interface at L. I will be notified, and then you'll
132             automatically be notified of progress on your bug as I make changes.
133            
134             =head1 LICENSE AND COPYRIGHT
135            
136             Copyright 2010 Michael Roberts.
137            
138             This program is free software; you can redistribute it and/or modify it
139             under the terms of either: the GNU General Public License as published
140             by the Free Software Foundation; or the Artistic License.
141            
142             See http://dev.perl.org/licenses/ for more information.
143            
144             =cut
145            
146             1; # End of Decl::Semantics::Repeat