Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 7dce1e6b

Von Sven Schöling vor etwa 13 Jahren hinzugefügt

  • ID 7dce1e6b79376cb9fd7966051210b0e099f97c9c
  • Vorgänger f4194b70
  • Nachfolger 2438dd57

rose_auto_create_model.pl überarbeitet.

- nocommit option
- farbige ausgabe
- verbose
- login aus config laden
- bessere doku

Unterschiede anzeigen:

scripts/rose_auto_create_model.pl
10 10
use CGI qw( -no_xhtml);
11 11
use Config::Std;
12 12
use Data::Dumper;
13
use Digest::MD5 qw(md5_hex);
13 14
use English qw( -no_match_vars );
15
use Getopt::Long;
14 16
use List::MoreUtils qw(any);
17
use Pod::Usage;
18
use Term::ANSIColor;
15 19

  
16 20
use SL::Auth;
17 21
use SL::DBUtils;
......
23 27
use SL::DB::Helper::ALL;
24 28
use SL::DB::Helper::Mappings;
25 29

  
30
my %blacklist     = SL::DB::Helper::Mappings->get_blacklist;
31
my %package_names = SL::DB::Helper::Mappings->get_package_names;
32

  
26 33
our $form;
27 34
our $cgi;
28 35
our $auth;
......
36 43

  
37 44
our $meta_path = "SL/DB/MetaSetup";
38 45

  
46
my %config;
47

  
39 48
sub setup {
40
  if (@ARGV < 2) {
41
    print "Usage: $PROGRAM_NAME login table1[=package1] [table2[=package2] ...]\n";
42
    print "   or  $PROGRAM_NAME login [--all|-a] [--sugar|-s]\n";
43
    exit 1;
44
  }
45 49

  
46 50
  SL::LxOfficeConf->read;
47 51

  
48
  my $login     = shift @ARGV;
52
  my $login     = $config{login} || $::lx_office_conf{devel}{login};
49 53

  
50
  $::lxdebug    = LXDebug->new();
54
  if (!$login) {
55
    error("No login found in config. Please provide a login:");
56
    usage();
57
  }
51 58

  
52
  # locale messages
59
  $::lxdebug    = LXDebug->new();
53 60
  $::locale       = Locale->new("de");
54 61
  $::form         = new Form;
55 62
  $::cgi          = new CGI('');
56 63
  $::auth         = SL::Auth->new();
57

  
58 64
  $::user         = User->new($login);
59

  
60 65
  %::myconfig     = $auth->read_user($login);
61 66
  $form->{script} = 'rose_meta_data.pl';
62 67
  $form->{login}  = $login;
......
93 98
CODE
94 99

  
95 100
  if ($EVAL_ERROR) {
96
    print STDERR "Error in execution for table '$table': $EVAL_ERROR";
101
    error("Error in execution for table '$table'");
102
    error("'$EVAL_ERROR'") if $config{verbose};
97 103
    return;
98 104
  }
99 105

  
100 106
  $definition =~ s/::AUTO::/::/g;
101

  
102
  my $file_exists = -f $meta_file;
103

  
104
  open(OUT, ">$meta_file") || die;
105
  print OUT <<CODE;
107
  my $full_definition = <<CODE;
106 108
# This file has been auto-generated. Do not modify it; it will be overwritten
107 109
# by $::script automatically.
108 110
$definition;
109 111
CODE
110
  close OUT;
111 112

  
112
  print "File '$meta_file' " . ($file_exists ? 'updated' : 'created') . " for table '$table'\n";
113

  
114
  if (! -f $file) {
115
    open(OUT, ">$file") || die;
116
    print OUT <<CODE;
113
  my $meta_definition = <<CODE;
117 114
# This file has been auto-generated only because it didn't exist.
118 115
# Feel free to modify it at will; it will not be overwritten automatically.
119 116

  
......
128 125

  
129 126
1;
130 127
CODE
131
    close OUT;
132 128

  
133
    print "File '$file' created as well.\n";
129
  my $file_exists = -f $meta_file;
130
  if ($file_exists) {
131
    my $old_size    = -s $meta_file;
132
    my $old_md5     = md5_hex(do { local(@ARGV, $/) = ($meta_file); <> });
133
    my $new_size    = length $full_definition;
134
    my $new_md5     = md5_hex($full_definition);
135
    if ($old_size == $new_size && $old_md5 == $new_md5) {
136
      notice("No changes in $meta_file, skipping.") if $config{verbose};
137
      return;
138
    }
139
  }
140

  
141
  if (!$config{nocommit}) {
142
    open my $out, ">", $meta_file || die;
143
    print $out $full_definition;
144
  }
145

  
146
  notice("File '$meta_file' " . ($file_exists ? 'updated' : 'created') . " for table '$table'");
147

  
148
  if (! -f $file) {
149
    if (!$config{nocommit}) {
150
      open my $out, ">", $file || die;
151
      print $out $meta_definition;
152
    }
153

  
154
    notice("File '$file' created as well.");
134 155
  }
135 156
}
136 157

  
137
setup();
158
sub parse_args {
159
  my ($options) = @_;
160
  GetOptions(
161
    'login|user=s'  => \ my $login,
162
    all             => \ my $all,
163
    sugar           => \ my $sugar,
164
    'no-commit'     => \ my $nocommit,
165
    help            => sub { pod2usage(verbose => 99, sections => 'NAME|SYNOPSIS|OPTIONS') },
166
    verbose         => \ my $verbose,
167
  );
168

  
169
  $options->{login}    = $login if $login;
170
  $options->{sugar}    = $sugar;
171
  $options->{all}      = $all;
172
  $options->{nocommit} = $nocommit;
173
  $options->{verbose}  = $verbose;
174
}
138 175

  
139
my %blacklist     = SL::DB::Helper::Mappings->get_blacklist;
140
my %package_names = SL::DB::Helper::Mappings->get_package_names;
176
sub usage {
177
  pod2usage(verbose => 99, sections => 'SYNOPSIS');
178
}
141 179

  
142
my @tables = ();
143
if (($ARGV[0] eq '--all') || ($ARGV[0] eq '-a') || ($ARGV[0] eq '--sugar') || ($ARGV[0] eq '-s')) {
144
  my ($type, $prefix) = ($ARGV[0] eq '--sugar') || ($ARGV[0] eq '-s') ? ('SUGAR', 'sugar_') : ('LXOFFICE', '');
145
  my $db              = SL::DB::create(undef, $type);
146
  @tables             = map  { $package_names{$type}->{$_} ? "${_}=" . $package_names{$type}->{$_} : $prefix ? "${_}=${prefix}${_}" : $_ }
147
                        grep { my $table = $_; !any { $_ eq $table } @{ $blacklist{$type} } }
148
                        $db->list_tables;
180
sub make_tables {
181
  my @tables;
182
  if ($config{all} || $config{sugar}) {
183
    my ($type, $prefix) = $config{sugar} ? ('SUGAR', 'sugar_') : ('LXOFFICE', '');
184
    my $db              = SL::DB::create(undef, $type);
185
    @tables             =
186
      map { $package_names{$type}->{$_} ? "$_=" . $package_names{$type}->{$_} : $prefix ? "$_=$prefix$_" : $_ }
187
      grep { my $table = $_; !any { $_ eq $table } @{ $blacklist{$type} } }
188
      $db->list_tables;
189
  } elsif (@ARGV) {
190
    @tables = @ARGV;
191
  } else {
192
    error("You specified neither --sugar nor --all nor any specific tables.");
193
    usage();
194
  }
149 195

  
150
} else {
151
  @tables = @ARGV;
196
  @tables;
152 197
}
153 198

  
154
foreach my $table (@tables) {
199
sub error {
200
  print STDERR colored(shift, 'red'), $/;
201
}
202

  
203
sub notice {
204
  print @_, $/;
205
}
206

  
207
parse_args(\%config);
208
setup();
209
my @tables = make_tables();
210

  
211
for my $table (@tables) {
155 212
  # add default model name unless model name is given or no defaults exists
156 213
  $table .= '=' . $package_names{LXOFFICE}->{lc $table} if $table !~ /=/ && $package_names{LXOFFICE}->{lc $table};
157 214

  
158 215
  process_table($table);
159 216
}
217

  
218
1;
219

  
220
__END__
221

  
222
=encoding utf-8
223

  
224
=head1 NAME
225

  
226
rose_auto_create_model - mana Rose::DB::Object classes for Lx-Office
227

  
228
=head1 SYNOPSIS
229

  
230
  scripts/rose_create_model.pl --login login table1[=package1] [table2[=package2] ...]
231
  scripts/rose_create_model.pl --login login [--all|-a] [--sugar|-s]
232

  
233
  # updates all models
234
  scripts/rose_create_model.pl --login login --all
235

  
236
  # updates only customer table, login taken from config
237
  scripts/rose_create_model.pl customer
238

  
239
  # updates only parts table, package will be Part
240
  scripts/rose_create_model.pl parts=Part
241

  
242
  # try to update parts, but don't do it. tell what would happen in detail
243
  scripts/rose_create_model.pl --no-commit --verbose parts
244

  
245
=head1 DESCRIPTION
246

  
247
Rose::DB::Object comes with a nice function named auto initialization with code
248
generation. The documentation of Rose describes it like this:
249

  
250
I<[...] auto-initializing metadata at runtime by querying the database has many
251
caveats. An alternate approach is to query the database for metadata just once,
252
and then generate the equivalent Perl code which can be pasted directly into
253
the class definition in place of the call to auto_initialize.>
254

  
255
I<Like the auto-initialization process itself, perl code generation has a
256
convenient wrapper method as well as separate methods for the individual parts.
257
All of the perl code generation methods begin with "perl_", and they support
258
some rudimentary code formatting options to help the code conform to you
259
preferred style. Examples can be found with the documentation for each perl_*
260
method.>
261

  
262
I<This hybrid approach to metadata population strikes a good balance between
263
upfront effort and ongoing maintenance. Auto-generating the Perl code for the
264
initial class definition saves a lot of tedious typing. From that point on,
265
manually correcting and maintaining the definition is a small price to pay for
266
the decreased start-up cost, the ability to use the class in the absence of a
267
database connection, and the piece of mind that comes from knowing that your
268
class is stable, and won't change behind your back in response to an "action at
269
a distance" (i.e., a database schema update).>
270

  
271
Unfortunately this ready easier than it is, since classes need to get in the
272
right package and directory, certain stuff need to be adjusted and table names
273
need to be translated into their class names. This script will wrap all that
274
behind a few simple options.
275

  
276
In the most basic version, just give it a login and
277

  
278
=head1 OPTIONS
279

  
280
=over 4
281

  
282
=item C<--login, -l LOGIN>
283

  
284
=item C<--user, -u LOGIN>
285

  
286
Provide a login. If not present the login is loaded from the config key
287
C<devel/login>. If that too is not found, an error is thrown.
288

  
289
=item C<--all, -a>
290

  
291
Process all tables from the database. Only those that are blacklistes in
292
L<SL::DB::Helper::Mappings> are excluded.
293

  
294
=item C<--sugar, -s>
295

  
296
Process tables in sugar schema instead of standard schema. Rarely useful unless
297
you debug schema awareness of the RDBO layer.
298

  
299
=item C<--no-commit, -n>
300

  
301
Do not write back generated files. This will do everything as usual but not
302
actually modify any files.
303

  
304
=item C<--help, -h>
305

  
306
Print this help.
307

  
308
=item C<--verbose, -v>
309

  
310
Prints extra information, such as skipped files that were not changed and
311
errors where the auto initialization failed.
312

  
313
=back
314

  
315
=head1 BUGS
316

  
317
None yet.
318

  
319
=head1 AUTHOR
320

  
321
Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
322

  
323
=cut

Auch abrufbar als: Unified diff