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__ |