File Coverage

blib/lib/Geoffrey/Changelog/Database.pm
Criterion Covered Total %
statement 17 116 14.6
branch 0 52 0.0
condition 0 25 0.0
subroutine 6 24 25.0
pod 11 11 100.0
total 34 228 14.9


line stmt bran cond sub pod time code
1             package Geoffrey::Changelog::Database;
2              
3 1     1   70363 use utf8;
  1         17  
  1         5  
4 1     1   47 use 5.024;
  1         4  
5 1     1   5 use strict;
  1         2  
  1         19  
6 1     1   4 use warnings;
  1         2  
  1         26  
7 1     1   504 use Geoffrey::Exception::Database;
  1         13216  
  1         44  
8              
9             $Geoffrey::Changelog::Database::VERSION = '0.000202';
10              
11 1     1   483 use parent 'Geoffrey::Role::Changelog';
  1         282  
  1         6  
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             return $self->dbh->selectall_arrayref(
77             $s_changeset_sql,
78             {Slice => {}},
79 0   0       ($hr_params->{changeset_id} ? ($hr_params->{changeset_id}) : ())
80             ) || Geoffrey::Exception::Database::throw_sql_handle($!, $s_changeset_sql);
81             }
82              
83             sub _prepare_tables {
84 0     0     my ($self) = @_;
85 0           require Geoffrey::Action::Table;
86 0           my $o_action_able = Geoffrey::Action::Table->new(dbh => $self->dbh, converter => $self->converter);
87 0           my $hr_params = $self->converter->get_changelog_table_hashref($self->dbh, $self->schema);
88 0 0         if ($hr_params) {
89 0           $hr_params->{schema} = $self->schema;
90 0           Geoffrey::Action::Table->new(dbh => $self->dbh, converter => $self->converter)->add($hr_params);
91             }
92              
93 0           my $o_statement_handle = $self->dbh->prepare($self->converter->select_get_table);
94 0 0         if ($self->schema) {
95 0 0         $o_statement_handle->execute($self->schema, $self->_changlog_entries_table_name) or Carp::confess $!;
96             }
97             else {
98 0 0         $o_statement_handle->execute($self->_changlog_entries_table_name) or Carp::confess $!;
99             }
100 0           $hr_params = $o_statement_handle->fetchrow_hashref;
101 0 0         return $hr_params ? undef : $o_action_able->add({
102             name => $self->_changlog_entries_table_name,
103             columns => $self->_changlog_entries_table,
104             schema => $self->schema,
105             });
106             }
107              
108 0     0 1   sub file_extension { return $_[0]->{file_extension}; }
109              
110             sub _get_changeset_entries {
111 0     0     my ($self, $hr_unhandeled_changelog) = @_;
112 0 0         my $s_table_name = ($self->schema ? $self->schema . q/./ : q//) . $self->_changlog_entries_table_name;
113 0           my $s_entries_sql = $self->_sql_abstract->select($s_table_name, qw/*/, {geoffrey_changelog => {'=', '?'}});
114              
115 0   0       my $ar_entries = $self->dbh->selectall_arrayref($s_entries_sql, {Slice => {}}, ($hr_unhandeled_changelog->{ID}))
116             || Geoffrey::Exception::Database::throw_sql_handle($!, $s_entries_sql);
117 0           return $ar_entries;
118             }
119              
120             sub load {
121 0     0 1   my ($self, $s_changeset_id) = @_;
122 0 0         my $ar_changesets = $self->_get_changesets($s_changeset_id ? ({changeset_id => $s_changeset_id}) : ());
123 0           $_->{entries} = $self->_get_changeset_entries($_) for @{$ar_changesets};
  0            
124 0           require Geoffrey::Utils;
125 0           Geoffrey::Utils::to_lowercase($_) for @{$ar_changesets};
  0            
126 0 0 0       return ($s_changeset_id && scalar @{$ar_changesets} == 1) ? $ar_changesets->[0] : $ar_changesets;
127             }
128              
129              
130             sub load_changeset {
131 0     0 1   my ($self, $s_changeset_id) = @_;
132 0           my $ar_changesets = $self->_get_changesets({changeset_id => $s_changeset_id});
133 0           $_->{entries} = $self->_get_changeset_entries($_) for @{$ar_changesets};
  0            
134 0           require Geoffrey::Utils;
135 0           Geoffrey::Utils::to_lowercase($_) for @{$ar_changesets};
  0            
136 0 0 0       return ($s_changeset_id && scalar @{$ar_changesets} == 1) ? $ar_changesets->[0] : $ar_changesets;
137             }
138              
139             sub write {
140 0     0 1   my ($self, $s_file, $ur_data) = @_;
141 0           return shift->insert(@_);
142             }
143              
144             sub delete {
145 0     0 1   my ($self, $s_changeset_id) = @_;
146 0           my $ar_changesets = $self->_get_changesets({changeset_id => $s_changeset_id, not_executed => 1});
147 0 0         return unless scalar @{$ar_changesets};
  0            
148 0           my @a_statements = ();
149 0           push @a_statements,
150             $self->_action_entry->drop({
151             schema => $self->schema,
152             table => $self->_changlog_entries_table_name,
153             conditions => {geoffrey_changelog => $s_changeset_id,}});
154 0           push @a_statements,
155             $self->_action_entry->drop(
156             {schema => $self->schema, table => $self->geoffrey_changelogs, conditions => {id => $s_changeset_id,}});
157 0           return \@a_statements;
158             }
159              
160             sub insert {
161 0     0 1   my ($self, $s_file, $ur_data) = @_;
162 0           $self->_prepare_tables;
163 0           require Ref::Util;
164 0 0         return $self->{generated_sql} if Ref::Util::is_hashref($ur_data);
165 0           for my $hr_changeset (@{$ur_data}) {
  0            
166 0 0         next unless (exists $hr_changeset->{id});
167 0 0         next unless scalar @{$hr_changeset->{entries}};
  0            
168              
169             push(
170 0           @{$self->{generated_sql}},
171             $self->_action_entry->add({
172             schema => $self->schema,
173             table => $self->geoffrey_changelogs,
174             values => [{
175             id => $hr_changeset->{id},
176             filename => __PACKAGE__ . '::' . __LINE__,
177             created_by => $hr_changeset->{created_by} ? $hr_changeset->{created_by}
178             : $hr_changeset->{author} ? $hr_changeset->{author}
179             : undef,
180             geoffrey_version => $Geoffrey::Changelog::Database::VERSION,
181 0 0         ($hr_changeset->{comment} ? (comment => $hr_changeset->{comment}) : ()),
    0          
    0          
182             }]}));
183              
184 0           for my $hr_entry (@{$hr_changeset->{entries}}) {
  0            
185             push(
186 0           @{$self->{generated_sql}},
187             $self->_action_entry->add({
188             schema => $self->schema,
189             table => $self->_changlog_entries_table_name,
190             values => [{
191             geoffrey_changelog => $hr_changeset->{id},
192             action => $hr_entry->{action},
193             name => $hr_entry->{entry_name},
194 0 0         (exists $hr_entry->{as} ? (plain_sql => $hr_entry->{as}) : ()),
195             }]}));
196             }
197             }
198 0           return $self->{generated_sql};
199             }
200              
201             ## GETTER / SETTER
202              
203             sub schema {
204 0     0 1   my ($self, $s_schema) = @_;
205 0 0         $self->{schema} = $s_schema if $s_schema;
206 0           return $self->{schema};
207             }
208              
209             sub converter {
210 0     0 1   my ($self, $o_converter) = @_;
211 0 0         $self->{converter} = $o_converter if $o_converter;
212 0           return $self->{converter};
213             }
214              
215             sub dbh {
216 0     0 1   my ($self, $o_dbh) = @_;
217 0 0         $self->{dbh} = $o_dbh if $o_dbh;
218 0           return $self->{dbh};
219             }
220              
221             sub geoffrey_changelogs {
222 0     0 1   my ($self, $s_geoffrey_changelogs) = @_;
223 0 0         $self->{geoffrey_changelogs} = $s_geoffrey_changelogs if $s_geoffrey_changelogs;
224 0   0       $self->{geoffrey_changelogs} //= 'geoffrey_changelogs';
225 0           return $self->{geoffrey_changelogs};
226             }
227              
228             ## END GETTER / SETTER
229              
230             1; # End of Geoffrey::Changelog
231              
232             __END__