File Coverage

blib/lib/Geoffrey/Changelog/Database.pm
Criterion Covered Total %
statement 17 108 15.7
branch 0 48 0.0
condition 0 22 0.0
subroutine 6 23 26.0
pod 10 10 100.0
total 33 211 15.6


line stmt bran cond sub pod time code
1             package Geoffrey::Changelog::Database;
2              
3 1     1   68042 use utf8;
  1         15  
  1         5  
4 1     1   47 use 5.024;
  1         4  
5 1     1   5 use strict;
  1         2  
  1         18  
6 1     1   4 use warnings;
  1         2  
  1         24  
7 1     1   465 use Geoffrey::Exception::Database;
  1         12893  
  1         40  
8              
9             $Geoffrey::Changelog::Database::VERSION = '0.000201';
10              
11 1     1   445 use parent 'Geoffrey::Role::Changelog';
  1         286  
  1         5  
12              
13             sub new {
14 0     0 1   my $class = shift;
15 0           my $self = $class->SUPER::new(@_);
16 0           $self->{needs_converter} = 1;
17 0           $self->{needs_dbh} = 1;
18 0           $self->{generated_sql} = [];
19 0           $self = bless $self, $class;
20 0 0 0       $self->_prepare_tables if ( $self->converter && $self->dbh );
21 0           return $self;
22             }
23              
24             sub _action_entry {
25 0     0     my ( $self, $o_action_entry ) = @_;
26 0 0         $self->{action_entry} = $o_action_entry if $o_action_entry;
27 0           require Geoffrey::Action::Entry;
28 0   0       $self->{action_entry} //= Geoffrey::Action::Entry->new( dbh => $self->dbh, converter => $self->converter );
29 0           return $self->{action_entry};
30             }
31              
32             sub _sql_abstract {
33 0     0     my ($self) = @_;
34 0           require SQL::Abstract;
35 0   0       $self->{sql_abstract} //= SQL::Abstract->new;
36 0           return $self->{sql_abstract};
37             }
38              
39             sub _changlog_entries_table_name {
40 0   0 0     $_[0]->{changlog_entries_table} //= 'geoffrey_changlog_entries';
41 0           return $_[0]->{changlog_entries_table};
42             }
43              
44             sub _changlog_entries_table {
45 0     0     my ($self) = @_;
46             return [
47 0           { name => 'id', type => 'integer', primarykey => 1, notnull => 1, default => 'autoincrement', },
48             { name => 'action', type => 'varchar', lenght => 64, },
49             { name => 'name', type => 'varchar', lenght => 64, },
50             { name => 'template', type => 'varchar', lenght => 64, },
51             { name => 'type', type => 'varchar', lenght => 64, },
52             { name => 'plain_sql', type => 'text' },
53             { name => 'refcolumn', type => 'varchar', lenght => 64, },
54             { name => 'reftable', type => 'varchar', lenght => 64, },
55             { name => 'columns', type => 'varchar', lenght => 64, },
56             {
57             name => 'geoffrey_changelog',
58             type => 'varchar',
59             lenght => 64,
60             notnull => 1,
61             foreignkey => { reftable => $self->geoffrey_changelogs, refcolumn => 'id' },
62             },
63             ];
64             }
65              
66             sub _get_changesets {
67 0     0     my ( $self, $hr_params ) = @_;
68 0           $self->_prepare_tables;
69             my $s_changeset_sql = $self->_sql_abstract->select(
70             ( $self->schema ? $self->schema . q/./ : q// ) . $self->geoffrey_changelogs,
71             qw/*/,
72             {
73             ( $hr_params->{changeset_id} ? ( id => $hr_params->{changeset_id} ) : () ),
74 0 0         ( $hr_params->{not_executed} ? ( md5sum => undef ) : () ),
    0          
    0          
75             }
76             );
77             return $self->dbh->selectall_arrayref(
78             $s_changeset_sql,
79             { Slice => {} },
80 0   0       ( $hr_params->{changeset_id} ? ( $hr_params->{changeset_id} ) : () )
81             ) || Geoffrey::Exception::Database::throw_sql_handle( $!, $s_changeset_sql );
82             }
83              
84             sub _prepare_tables {
85 0     0     my ($self) = @_;
86 0           require Geoffrey::Action::Table;
87 0           my $o_action_able = Geoffrey::Action::Table->new( dbh => $self->dbh, converter => $self->converter );
88 0           my $hr_params = $self->converter->get_changelog_table_hashref( $self->dbh, $self->schema );
89 0 0         if ($hr_params) {
90 0           $hr_params->{schema} = $self->schema;
91 0           Geoffrey::Action::Table->new( dbh => $self->dbh, converter => $self->converter )->add($hr_params);
92             }
93              
94 0           my $o_statement_handle = $self->dbh->prepare( $self->converter->select_get_table );
95 0 0         if ( $self->schema ) {
96 0 0         $o_statement_handle->execute( $self->schema, $self->_changlog_entries_table_name ) or Carp::confess $!;
97             }
98             else {
99 0 0         $o_statement_handle->execute( $self->_changlog_entries_table_name ) or Carp::confess $!;
100             }
101 0           $hr_params = $o_statement_handle->fetchrow_hashref;
102 0 0         return $hr_params ? undef : $o_action_able->add(
103             {
104             name => $self->_changlog_entries_table_name,
105             columns => $self->_changlog_entries_table,
106             schema => $self->schema,
107             }
108             );
109             }
110              
111 0     0 1   sub file_extension { return $_[0]->{file_extension}; }
112              
113             sub _get_changeset_entries {
114 0     0     my ( $self, $hr_unhandeled_changelog ) = @_;
115 0 0         my $s_table_name = ( $self->schema ? $self->schema . q/./ : q// ) . $self->_changlog_entries_table_name;
116 0           my $s_entries_sql = $self->_sql_abstract->select( $s_table_name, qw/*/, { geoffrey_changelog => { '=', '?' } } );
117              
118             my $ar_entries =
119 0   0       $self->dbh->selectall_arrayref( $s_entries_sql, { Slice => {} }, ( $hr_unhandeled_changelog->{ID} ) )
120             || Geoffrey::Exception::Database::throw_sql_handle( $!, $s_entries_sql );
121 0           return $ar_entries;
122             }
123              
124             sub load {
125 0     0 1   my ( $self, $s_changeset_id ) = @_;
126 0           my $ar_changesets = $self->_get_changesets( { changeset_id => $s_changeset_id } );
127 0           $_->{entries} = $self->_get_changeset_entries($_) for @{$ar_changesets};
  0            
128 0           require Geoffrey::Utils;
129 0           Geoffrey::Utils::to_lowercase($_) for @{$ar_changesets};
  0            
130 0 0 0       return ( $s_changeset_id && scalar @{$ar_changesets} == 1 ) ? $ar_changesets->[0] : $ar_changesets;
131             }
132              
133             sub write {
134 0     0 1   my ( $self, $s_file, $ur_data ) = @_;
135 0           return shift->insert(@_);
136             }
137              
138             sub delete {
139 0     0 1   my ( $self, $s_changeset_id ) = @_;
140 0           my $ar_changesets = $self->_get_changesets( { changeset_id => $s_changeset_id, not_executed => 1 } );
141 0 0         return unless scalar @{$ar_changesets};
  0            
142 0           my @a_statements = ();
143 0           push @a_statements,
144             $self->_action_entry->drop(
145             {
146             schema => $self->schema,
147             table => $self->_changlog_entries_table_name,
148             conditions => {
149             geoffrey_changelog => $s_changeset_id,
150             }
151             }
152             );
153 0           push @a_statements,
154             $self->_action_entry->drop(
155             {
156             schema => $self->schema,
157             table => $self->geoffrey_changelogs,
158             conditions => {
159             id => $s_changeset_id,
160             }
161             }
162             );
163 0           return \@a_statements;
164             }
165              
166             sub insert {
167 0     0 1   my ( $self, $s_file, $ur_data ) = @_;
168 0           $self->_prepare_tables;
169 0           require Ref::Util;
170 0 0         return $self->{generated_sql} if Ref::Util::is_hashref($ur_data);
171 0           for my $hr_changeset ( @{$ur_data} ) {
  0            
172 0 0         next unless ( exists $hr_changeset->{id} );
173 0 0         next unless scalar @{ $hr_changeset->{entries} };
  0            
174              
175             push(
176 0           @{ $self->{generated_sql} },
177             $self->_action_entry->add(
178             {
179             schema => $self->schema,
180             table => $self->geoffrey_changelogs,
181             values => [
182             {
183             id => $hr_changeset->{id},
184             filename => __PACKAGE__ . '::' . __LINE__,
185             created_by => $hr_changeset->{created_by} ? $hr_changeset->{created_by}
186             : $hr_changeset->{author} ? $hr_changeset->{author}
187             : undef,
188             geoffrey_version => $Geoffrey::Changelog::Database::VERSION,
189 0 0         ( $hr_changeset->{comment} ? ( comment => $hr_changeset->{comment} ) : () ),
    0          
    0          
190             }
191             ]
192             }
193             )
194             );
195              
196 0           for my $hr_entry ( @{ $hr_changeset->{entries} } ) {
  0            
197             push(
198 0           @{ $self->{generated_sql} },
199             $self->_action_entry->add(
200             {
201             schema => $self->schema,
202             table => $self->_changlog_entries_table_name,
203             values => [
204             {
205             geoffrey_changelog => $hr_changeset->{id},
206             action => $hr_entry->{action},
207             name => $hr_entry->{entry_name},
208 0 0         ( exists $hr_entry->{as} ? ( plain_sql => $hr_entry->{as} ) : () ),
209             }
210             ]
211             }
212             )
213             );
214             }
215             }
216 0           return $self->{generated_sql};
217             }
218              
219             ## GETTER / SETTER
220              
221             sub schema {
222 0     0 1   my ( $self, $s_schema ) = @_;
223 0 0         $self->{schema} = $s_schema if $s_schema;
224 0           return $self->{schema};
225             }
226              
227             sub converter {
228 0     0 1   my ( $self, $o_converter ) = @_;
229 0 0         $self->{converter} = $o_converter if $o_converter;
230 0           return $self->{converter};
231             }
232              
233             sub dbh {
234 0     0 1   my ( $self, $o_dbh ) = @_;
235 0 0         $self->{dbh} = $o_dbh if $o_dbh;
236 0           return $self->{dbh};
237             }
238              
239             sub geoffrey_changelogs {
240 0     0 1   my ( $self, $s_geoffrey_changelogs ) = @_;
241 0 0         $self->{geoffrey_changelogs} = $s_geoffrey_changelogs if $s_geoffrey_changelogs;
242 0   0       $self->{geoffrey_changelogs} //= 'geoffrey_changelogs';
243 0           return $self->{geoffrey_changelogs};
244             }
245              
246             ## END GETTER / SETTER
247              
248             1; # End of Geoffrey::Changelog
249              
250             __END__