1 package SL::DBUpgrade2::Base;
5 use parent qw(Rose::Object);
9 use English qw(-no_match_vars);
10 use File::Basename ();
13 use List::MoreUtils qw(uniq);
15 use Rose::Object::MakeMethods::Generic (
16 scalar => [ qw(dbh myconfig) ],
24 my $file_name = delete $params{file_name};
26 if (!eval { require $file_name }) {
27 delete $INC{$file_name};
31 my $package = delete $params{tag};
32 $package =~ s/[^a-zA-Z0-9_]+/_/g;
33 $package = "SL::DBUpgrade2::${package}";
35 $package->new(%params)->run;
39 my ($self, $msg) = @_;
41 die $::locale->text("Database update error:") . "<br>$msg<br>" . $self->db_errstr('DBI');
45 my ($self, $query, %params) = @_;
47 my $dbh = $params{dbh} || $self->dbh;
49 return if $dbh->do($query, undef, @{ $params{bind} || [] });
51 $self->db_error($query) unless $params{may_fail};
58 my ($self, $handle) = @_;
60 my $error = $handle ? $handle->errstr : $self->dbh->errstr;
62 return $::locale->is_utf8 ? Encode::decode('utf-8', $error) : $error;
66 my ($self, $wanted_coa) = @_;
68 my ($have_coa) = selectrow_query($::form, $self->dbh, q{ SELECT count(*) FROM defaults WHERE coa = ? }, $wanted_coa);
76 my $query = q{ SELECT count(*)
77 FROM ar, ap, gl, invoice, acc_trans, customer, vendor, parts
79 my ($empty) = selectrow_query($::form, $self->dbh, $query);
84 sub add_print_templates {
85 my ($self, $src_dir, @files) = @_;
87 $::lxdebug->message(LXDebug::DEBUG1(), "add_print_templates: src_dir $src_dir files " . join(' ', @files));
90 croak "File '${src_dir}/$_' does not exist" unless -f "${src_dir}/$_";
93 my %users = $::auth->read_all_users;
94 my @template_dirs = uniq map { $_ = $_->{templates}; s:/+$::; $_ } values %users;
96 $::lxdebug->message(LXDebug::DEBUG1(), "add_print_templates: template_dirs " . join(' ', @template_dirs));
98 foreach my $src_file (@files) {
99 foreach my $template_dir (@template_dirs) {
100 my $dest_file = $template_dir . '/' . $src_file;
103 $::lxdebug->message(LXDebug::DEBUG1(), "add_print_templates: dest_file exists, skipping: ${dest_file}");
107 my $dest_dir = File::Basename::dirname($dest_file);
109 if ($dest_dir && !-d $dest_dir) {
110 File::Path::make_path($dest_dir) or die "Cannot create directory '${dest_dir}': $!";
113 File::Copy::copy($src_dir . '/' . $src_file, $dest_file) or die "Cannot copy '${src_dir}/${src_file}' to '${dest_file}': $!";
115 $::lxdebug->message(LXDebug::DEBUG1(), "add_print_templates: copied '${src_dir}/${src_file}' to '${dest_file}'");
131 SL::DBUpgrade2::Base - Base class for Perl-based database upgrade files
135 Database scripts written in Perl must be derived from this class and
136 provide a method called C<run>.
138 The functions in this base class offer functionality for the upgrade
143 The following properties (which can be accessed with
144 C<$self-E<gt>property_name>) are available to the database upgrade
151 The database handle; an Instance of L<DBI>. It is connected, and a
152 transaction has been started right before the script (the method
153 L</run>)) was executed.
157 The stripped-down version of the C<%::myconfig> hash: this hash
158 reference only contains the database connection parameters applying to
159 the current database.
167 =item C<add_print_templates $source_dir, @files>
169 Adds (copies) new print templates to existing users. All existing
170 users in the authentication database are read. The listed C<@files>
171 are copied to each user's configured templates directory preserving
172 sub-directory structure (non-existing sub-directories will be
173 created). If a template with the same name exists it will be skipped.
175 The source file names must all be relative to the source directory
176 C<$source_dir>. This way only the desired sub-directories are created
177 in the users' template directories. Example:
179 $self->add_print_templates(
180 'templates/print/Standard',
181 qw(receipt.tex common.sty images/background.png)
184 Let's assume a user's template directory is
185 C<templates/big-money-inc>. The call above would trigger five actions:
189 =item 1. Create the directory C<templates/big-money-inc> if it doesn't
192 =item 2. Copy C<templates/print/Standard/receipt.tex> to
193 C<templates/big-money-inc/receipt.tex> if there's no such file in that
196 =item 3. Copy C<templates/print/Standard/common.sty> to
197 C<templates/big-money-inc/common.sty> if there's no such file in that
200 =item 4. Create the directory C<templates/big-money-inc/images> if it
203 =item 5. Copy C<templates/print/Standard/images/background.png> to
204 C<templates/big-money-inc/images/background.png> if there's no such
205 file in that directory.
209 =item C<check_coa $coa_name>
211 Returns trueish if the database uses the chart of accounts named
214 =item C<db_error $message>
216 Outputs an error message C<$message> to the user and aborts execution.
218 =item C<db_query $query, %params>
220 Executes an SQL query. The following parameters are supported:
226 What the method does if the query fails depends on this parameter. If
227 it is falsish (the default) then the method will simply die outputting
228 the error message via L</db_error>. If C<may_fail> is trueish then the
229 current transaction will be rolled back, a new one will be started.
233 An optional array reference containing bind parameter for the query.
237 The database handle to use. If undefined then C<$self-E<gt>dbh> will
242 =item C<db_errstr [$handle]>
244 Returns the last database from C<$handle> error message encoded in
245 Perl's internal encoding. The PostgreSQL DBD leaves the UTF-8 flag off
246 for error messages even if the C<pg_enable_utf8> attribute is set.
248 C<$handle> is optional and can be one of three things:
252 =item 1. A database or statement handle. In that case
253 C<$handle-E<gt>errstr> is used.
255 =item 2. The string 'DBI'. In that case C<$DBI::errstr> is used.
257 =item 3. If it is undefined then C<$self-E<gt>dbh-E<gt>errstr> is
262 =item C<execute_script>
264 Executes a named database upgrade script. This function is not
265 supposed to be called from an upgrade script. Instead, the upgrade
266 manager L<SL::DBUpgrade2> uses it in order to execute the actual
267 database upgrade scripts.
269 =item C<is_coa_empty>
271 Returns trueish if no transactions have been recorded in the table
276 This method is the entry point for the actual upgrade. Each upgrade
277 script must provide this method.
287 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>