File Coverage

blib/lib/DBIx/Class/Schema/Versioned.pm
Criterion Covered Total %
statement 54 201 26.8
branch 0 50 0.0
condition 0 26 0.0
subroutine 18 41 43.9
pod 12 12 100.0
total 84 330 25.4


line stmt bran cond sub pod time code
1             package # Hide from PAUSE
2             DBIx::Class::Version::Table;
3 3     3   29210 use base 'DBIx::Class::Core';
  3         10  
  3         352  
4 3     3   18 use strict;
  3         6  
  3         74  
5 3     3   13 use warnings;
  3         5  
  3         331  
6              
7             __PACKAGE__->table('dbix_class_schema_versions');
8              
9             __PACKAGE__->add_columns
10             ( 'version' => {
11             'data_type' => 'VARCHAR',
12             'is_auto_increment' => 0,
13             'default_value' => undef,
14             'is_foreign_key' => 0,
15             'name' => 'version',
16             'is_nullable' => 0,
17             'size' => '10'
18             },
19             'installed' => {
20             'data_type' => 'VARCHAR',
21             'is_auto_increment' => 0,
22             'default_value' => undef,
23             'is_foreign_key' => 0,
24             'name' => 'installed',
25             'is_nullable' => 0,
26             'size' => '20'
27             },
28             );
29             __PACKAGE__->set_primary_key('version');
30              
31             package # Hide from PAUSE
32             DBIx::Class::Version::TableCompat;
33 3     3   19 use base 'DBIx::Class::Core';
  3         3  
  3         360  
34             __PACKAGE__->table('SchemaVersions');
35              
36             __PACKAGE__->add_columns
37             ( 'Version' => {
38             'data_type' => 'VARCHAR',
39             },
40             'Installed' => {
41             'data_type' => 'VARCHAR',
42             },
43             );
44             __PACKAGE__->set_primary_key('Version');
45              
46             package # Hide from PAUSE
47             DBIx::Class::Version;
48 3     3   16 use base 'DBIx::Class::Schema';
  3         7  
  3         221  
49 3     3   15 use strict;
  3         5  
  3         57  
50 3     3   12 use warnings;
  3         3  
  3         163  
51              
52             __PACKAGE__->register_class('Table', 'DBIx::Class::Version::Table');
53              
54             package # Hide from PAUSE
55             DBIx::Class::VersionCompat;
56 3     3   14 use base 'DBIx::Class::Schema';
  3         6  
  3         192  
57 3     3   16 use strict;
  3         5  
  3         60  
58 3     3   13 use warnings;
  3         4  
  3         194  
59              
60             __PACKAGE__->register_class('TableCompat', 'DBIx::Class::Version::TableCompat');
61              
62              
63             # ---------------------------------------------------------------------------
64              
65             =head1 NAME
66              
67             DBIx::Class::Schema::Versioned - DBIx::Class::Schema plugin for Schema upgrades
68              
69             =head1 SYNOPSIS
70              
71             package MyApp::Schema;
72             use base qw/DBIx::Class::Schema/;
73              
74             our $VERSION = 0.001;
75              
76             # load MyApp::Schema::CD, MyApp::Schema::Book, MyApp::Schema::DVD
77             __PACKAGE__->load_classes(qw/CD Book DVD/);
78              
79             __PACKAGE__->load_components(qw/Schema::Versioned/);
80             __PACKAGE__->upgrade_directory('/path/to/upgrades/');
81              
82              
83             =head1 DESCRIPTION
84              
85             This module provides methods to apply DDL changes to your database using SQL
86             diff files. Normally these diff files would be created using
87             L.
88              
89             A table called I is created and maintained by the
90             module. This is used to determine which version your database is currently at.
91             Similarly the $VERSION in your DBIC schema class is used to determine the
92             current DBIC schema version.
93              
94             The upgrade is initiated manually by calling C on your schema object,
95             this will attempt to upgrade the database from its current version to the current
96             schema version using a diff from your I. If a suitable diff is
97             not found then no upgrade is possible.
98              
99             =head1 SEE ALSO
100              
101             L is a much more powerful alternative to this
102             module. Examples of things it can do that this module cannot do include
103              
104             =over
105              
106             =item *
107              
108             Downgrades in addition to upgrades
109              
110             =item *
111              
112             Multiple sql files per upgrade/downgrade/install
113              
114             =item *
115              
116             Perl scripts allowed for upgrade/downgrade/install
117              
118             =item *
119              
120             Just one set of files needed for upgrade, unlike this module where one might
121             need to generate C
122              
123             =back
124              
125             =head1 GETTING STARTED
126              
127             Firstly you need to setup your schema class as per the L, make sure
128             you have specified an upgrade_directory and an initial $VERSION.
129              
130             Then you'll need two scripts, one to create DDL files and diffs and another to perform
131             upgrades. Your creation script might look like a bit like this:
132              
133             use strict;
134             use Pod::Usage;
135             use Getopt::Long;
136             use MyApp::Schema;
137              
138             my ( $preversion, $help );
139             GetOptions(
140             'p|preversion:s' => \$preversion,
141             ) or die pod2usage;
142              
143             my $schema = MyApp::Schema->connect(
144             $dsn,
145             $user,
146             $password,
147             );
148             my $sql_dir = './sql';
149             my $version = $schema->schema_version();
150             $schema->create_ddl_dir( 'MySQL', $version, $sql_dir, $preversion );
151              
152             Then your upgrade script might look like so:
153              
154             use strict;
155             use MyApp::Schema;
156              
157             my $schema = MyApp::Schema->connect(
158             $dsn,
159             $user,
160             $password,
161             );
162              
163             if (!$schema->get_db_version()) {
164             # schema is unversioned
165             $schema->deploy();
166             } else {
167             $schema->upgrade();
168             }
169              
170             The script above assumes that if the database is unversioned then it is empty
171             and we can safely deploy the DDL to it. However things are not always so simple.
172              
173             if you want to initialise a pre-existing database where the DDL is not the same
174             as the DDL for your current schema version then you will need a diff which
175             converts the database's DDL to the current DDL. The best way to do this is
176             to get a dump of the database schema (without data) and save that in your
177             SQL directory as version 0.000 (the filename must be as with
178             L) then create a diff using your create DDL
179             script given above from version 0.000 to the current version. Then hand check
180             and if necessary edit the resulting diff to ensure that it will apply. Once you have
181             done all that you can do this:
182              
183             if (!$schema->get_db_version()) {
184             # schema is unversioned
185             $schema->install("0.000");
186             }
187              
188             # this will now apply the 0.000 to current version diff
189             $schema->upgrade();
190              
191             In the case of an unversioned database the above code will create the
192             dbix_class_schema_versions table and write version 0.000 to it, then
193             upgrade will then apply the diff we talked about creating in the previous paragraph
194             and then you're good to go.
195              
196             =cut
197              
198             package DBIx::Class::Schema::Versioned;
199              
200 3     3   37 use strict;
  3         5  
  3         61  
201 3     3   14 use warnings;
  3         5  
  3         80  
202 3     3   14 use base 'DBIx::Class::Schema';
  3         4  
  3         195  
203              
204 3     3   17 use DBIx::Class::Carp;
  3         5  
  3         29  
205 3     3   838 use Time::HiRes qw/gettimeofday/;
  3         1797  
  3         23  
206 3     3   488 use Try::Tiny;
  3         5  
  3         270  
207 3     3   18 use Scalar::Util 'weaken';
  3         6  
  3         162  
208 3     3   15 use namespace::clean;
  3         12  
  3         28  
209              
210             __PACKAGE__->mk_classdata('_filedata');
211             __PACKAGE__->mk_classdata('upgrade_directory');
212             __PACKAGE__->mk_classdata('backup_directory');
213             __PACKAGE__->mk_classdata('do_backup');
214             __PACKAGE__->mk_classdata('do_diff_on_init');
215              
216              
217             =head1 METHODS
218              
219             =head2 upgrade_directory
220              
221             Use this to set the directory your upgrade files are stored in.
222              
223             =head2 backup_directory
224              
225             Use this to set the directory you want your backups stored in (note that backups
226             are disabled by default).
227              
228             =cut
229              
230             =head2 install
231              
232             =over 4
233              
234             =item Arguments: $db_version
235              
236             =back
237              
238             Call this to initialise a previously unversioned database. The table 'dbix_class_schema_versions' will be created which will be used to store the database version.
239              
240             Takes one argument which should be the version that the database is currently at. Defaults to the return value of L.
241              
242             See L for more details.
243              
244             =cut
245              
246             sub install
247             {
248 0     0 1   my ($self, $new_version) = @_;
249              
250             # must be called on a fresh database
251 0 0         if ($self->get_db_version()) {
252 0           $self->throw_exception("A versioned schema has already been deployed, try upgrade instead.\n");
253             }
254              
255             # default to current version if none passed
256 0   0       $new_version ||= $self->schema_version();
257              
258 0 0         if ($new_version) {
259             # create versions table and version row
260 0           $self->{vschema}->deploy;
261 0           $self->_set_db_version({ version => $new_version });
262             }
263             }
264              
265             =head2 deploy
266              
267             Same as L but also calls C.
268              
269             =cut
270              
271             sub deploy {
272 0     0 1   my $self = shift;
273 0           $self->next::method(@_);
274 0           $self->install();
275             }
276              
277             =head2 create_upgrade_path
278              
279             =over 4
280              
281             =item Arguments: { upgrade_file => $file }
282              
283             =back
284              
285             Virtual method that should be overridden to create an upgrade file.
286             This is useful in the case of upgrading across multiple versions
287             to concatenate several files to create one upgrade file.
288              
289             You'll probably want the db_version retrieved via $self->get_db_version
290             and the schema_version which is retrieved via $self->schema_version
291              
292             =cut
293              
294       0 1   sub create_upgrade_path {
295             ## override this method
296             }
297              
298             =head2 ordered_schema_versions
299              
300             =over 4
301              
302             =item Return Value: a list of version numbers, ordered from lowest to highest
303              
304             =back
305              
306             Virtual method that should be overridden to return an ordered list
307             of schema versions. This is then used to produce a set of steps to
308             upgrade through to achieve the required schema version.
309              
310             You may want the db_version retrieved via $self->get_db_version
311             and the schema_version which is retrieved via $self->schema_version
312              
313             =cut
314              
315       0 1   sub ordered_schema_versions {
316             ## override this method
317             }
318              
319             =head2 upgrade
320              
321             Call this to attempt to upgrade your database from the version it
322             is at to the version this DBIC schema is at. If they are the same
323             it does nothing.
324              
325             It will call L to retrieve an ordered
326             list of schema versions (if ordered_schema_versions returns nothing
327             then it is assumed you can do the upgrade as a single step). It
328             then iterates through the list of versions between the current db
329             version and the schema version applying one update at a time until
330             all relevant updates are applied.
331              
332             The individual update steps are performed by using
333             L, which will apply the update and also
334             update the dbix_class_schema_versions table.
335              
336             =cut
337              
338             sub upgrade {
339 0     0 1   my ($self) = @_;
340 0           my $db_version = $self->get_db_version();
341              
342             # db unversioned
343 0 0         unless ($db_version) {
344 0           carp 'Upgrade not possible as database is unversioned. Please call install first.';
345 0           return;
346             }
347              
348             # db and schema at same version. do nothing
349 0 0         if ( $db_version eq $self->schema_version ) {
350 0           carp 'Upgrade not necessary';
351 0           return;
352             }
353              
354 0           my @version_list = $self->ordered_schema_versions;
355              
356             # if nothing returned then we preload with min/max
357 0 0         @version_list = ( $db_version, $self->schema_version )
358             unless ( scalar(@version_list) );
359              
360             # catch the case of someone returning an arrayref
361 0 0         @version_list = @{ $version_list[0] }
  0            
362             if ( ref( $version_list[0] ) eq 'ARRAY' );
363              
364             # remove all versions in list above the required version
365 0   0       while ( scalar(@version_list)
366             && ( $version_list[-1] ne $self->schema_version ) )
367             {
368 0           pop @version_list;
369             }
370              
371             # remove all versions in list below the current version
372 0   0       while ( scalar(@version_list) && ( $version_list[0] ne $db_version ) ) {
373 0           shift @version_list;
374             }
375              
376             # check we have an appropriate list of versions
377 0 0         if ( scalar(@version_list) < 2 ) {
378 0           die;
379             }
380              
381             # do sets of upgrade
382 0           while ( scalar(@version_list) >= 2 ) {
383 0           $self->upgrade_single_step( $version_list[0], $version_list[1] );
384 0           shift @version_list;
385             }
386             }
387              
388             =head2 upgrade_single_step
389              
390             =over 4
391              
392             =item Arguments: db_version - the version currently within the db
393              
394             =item Arguments: target_version - the version to upgrade to
395              
396             =back
397              
398             Call this to attempt to upgrade your database from the
399             I to the I. If they are the same it
400             does nothing.
401              
402             It requires an SQL diff file to exist in your I,
403             normally you will have created this using L.
404              
405             If successful the dbix_class_schema_versions table is updated with
406             the I.
407              
408             This method may be called repeatedly by the upgrade method to
409             upgrade through a series of updates.
410              
411             =cut
412              
413             sub upgrade_single_step
414             {
415 0     0 1   my ($self,
416             $db_version,
417             $target_version) = @_;
418              
419             # db and schema at same version. do nothing
420 0 0         if ($db_version eq $target_version) {
421 0           carp 'Upgrade not necessary';
422 0           return;
423             }
424              
425             # strangely the first time this is called can
426             # differ to subsequent times. so we call it
427             # here to be sure.
428             # XXX - just fix it
429 0           $self->storage->sqlt_type;
430              
431 0           my $upgrade_file = $self->ddl_filename(
432             $self->storage->sqlt_type,
433             $target_version,
434             $self->upgrade_directory,
435             $db_version,
436             );
437              
438 0           $self->create_upgrade_path({ upgrade_file => $upgrade_file });
439              
440 0 0         unless (-f $upgrade_file) {
441 0           carp "Upgrade not possible, no upgrade file found ($upgrade_file), please create one";
442 0           return;
443             }
444              
445 0           carp "DB version ($db_version) is lower than the schema version (".$self->schema_version."). Attempting upgrade.\n";
446              
447             # backup if necessary then apply upgrade
448 0           $self->_filedata($self->_read_sql_file($upgrade_file));
449 0 0         $self->backup() if($self->do_backup);
450 0     0     $self->txn_do(sub { $self->do_upgrade() });
  0            
451              
452             # set row in dbix_class_schema_versions table
453 0           $self->_set_db_version({version => $target_version});
454             }
455              
456             =head2 do_upgrade
457              
458             This is an overwritable method used to run your upgrade. The freeform method
459             allows you to run your upgrade any way you please, you can call C
460             any number of times to run the actual SQL commands, and in between you can
461             sandwich your data upgrading. For example, first run all the B
462             commands, then migrate your data from old to new tables/formats, then
463             issue the DROP commands when you are finished. Will run the whole file as it is by default.
464              
465             =cut
466              
467             sub do_upgrade
468             {
469 0     0 1   my ($self) = @_;
470              
471             # just run all the commands (including inserts) in order
472 0           $self->run_upgrade(qr/.*?/);
473             }
474              
475             =head2 run_upgrade
476              
477             $self->run_upgrade(qr/create/i);
478              
479             Runs a set of SQL statements matching a passed in regular expression. The
480             idea is that this method can be called any number of times from your
481             C method, running whichever commands you specify via the
482             regex in the parameter. Probably won't work unless called from the overridable
483             do_upgrade method.
484              
485             =cut
486              
487             sub run_upgrade
488             {
489 0     0 1   my ($self, $stm) = @_;
490              
491 0 0         return unless ($self->_filedata);
492 0           my @statements = grep { $_ =~ $stm } @{$self->_filedata};
  0            
  0            
493 0           $self->_filedata([ grep { $_ !~ /$stm/i } @{$self->_filedata} ]);
  0            
  0            
494              
495 0           for (@statements)
496             {
497 0 0         $self->storage->debugobj->query_start($_) if $self->storage->debug;
498 0           $self->apply_statement($_);
499 0 0         $self->storage->debugobj->query_end($_) if $self->storage->debug;
500             }
501              
502 0           return 1;
503             }
504              
505             =head2 apply_statement
506              
507             Takes an SQL statement and runs it. Override this if you want to handle errors
508             differently.
509              
510             =cut
511              
512             sub apply_statement {
513 0     0 1   my ($self, $statement) = @_;
514              
515 0 0         $self->storage->dbh->do($_) or carp "SQL was: $_";
516             }
517              
518             =head2 get_db_version
519              
520             Returns the version that your database is currently at. This is determined by the values in the
521             dbix_class_schema_versions table that C and C write to.
522              
523             =cut
524              
525             sub get_db_version
526             {
527 0     0 1   my ($self, $rs) = @_;
528              
529 0           my $vtable = $self->{vschema}->resultset('Table');
530             my $version = try {
531 0     0     $vtable->search({}, { order_by => { -desc => 'installed' }, rows => 1 } )
532             ->get_column ('version')
533             ->next;
534 0           };
535 0   0       return $version || 0;
536             }
537              
538             =head2 schema_version
539              
540             Returns the current schema class' $VERSION
541              
542             =cut
543              
544             =head2 backup
545              
546             This is an overwritable method which is called just before the upgrade, to
547             allow you to make a backup of the database. Per default this method attempts
548             to call C<< $self->storage->backup >>, to run the standard backup on each
549             database type.
550              
551             This method should return the name of the backup file, if appropriate..
552              
553             This method is disabled by default. Set $schema->do_backup(1) to enable it.
554              
555             =cut
556              
557             sub backup
558             {
559 0     0 1   my ($self) = @_;
560             ## Make each ::DBI::Foo do this
561 0           $self->storage->backup($self->backup_directory());
562             }
563              
564             =head2 connection
565              
566             Overloaded method. This checks the DBIC schema version against the DB version and
567             warns if they are not the same or if the DB is unversioned. It also provides
568             compatibility between the old versions table (SchemaVersions) and the new one
569             (dbix_class_schema_versions).
570              
571             To avoid the checks on connect, set the environment var DBIC_NO_VERSION_CHECK or alternatively you can set the ignore_version attr in the forth argument like so:
572              
573             my $schema = MyApp::Schema->connect(
574             $dsn,
575             $user,
576             $password,
577             { ignore_version => 1 },
578             );
579              
580             =cut
581              
582             sub connection {
583 0     0 1   my $self = shift;
584 0           $self->next::method(@_);
585 0           $self->_on_connect();
586 0           return $self;
587             }
588              
589             sub _on_connect
590             {
591 0     0     my ($self) = @_;
592              
593 0           weaken (my $w_storage = $self->storage );
594              
595             $self->{vschema} = DBIx::Class::Version->connect(
596 0     0     sub { $w_storage->dbh },
597              
598             # proxy some flags from the main storage
599 0           { map { $_ => $w_storage->$_ } qw( unsafe ) },
  0            
600             );
601 0   0       my $conn_attrs = $w_storage->_dbic_connect_attributes || {};
602              
603 0           my $vtable = $self->{vschema}->resultset('Table');
604              
605             # useful when connecting from scripts etc
606 0 0 0       return if ($conn_attrs->{ignore_version} || ($ENV{DBIC_NO_VERSION_CHECK} && !exists $conn_attrs->{ignore_version}));
      0        
607              
608             # check for legacy versions table and move to new if exists
609 0 0         unless ($self->_source_exists($vtable)) {
610 0     0     my $vtable_compat = DBIx::Class::VersionCompat->connect(sub { $w_storage->dbh })->resultset('TableCompat');
  0            
611 0 0         if ($self->_source_exists($vtable_compat)) {
612 0           $self->{vschema}->deploy;
613 0           map { $vtable->new_result({ installed => $_->Installed, version => $_->Version })->insert } $vtable_compat->all;
  0            
614 0           $self->storage->_get_dbh->do("DROP TABLE " . $vtable_compat->result_source->from);
615             }
616             }
617              
618 0           my $pversion = $self->get_db_version();
619              
620 0 0         if($pversion eq $self->schema_version)
621             {
622             #carp "This version is already installed";
623 0           return 1;
624             }
625              
626 0 0         if(!$pversion)
627             {
628 0           carp "Your DB is currently unversioned. Please call upgrade on your schema to sync the DB.";
629 0           return 1;
630             }
631              
632 0           carp "Versions out of sync. This is " . $self->schema_version .
633             ", your database contains version $pversion, please call upgrade on your Schema.";
634             }
635              
636             # is this just a waste of time? if not then merge with DBI.pm
637             sub _create_db_to_schema_diff {
638 0     0     my $self = shift;
639              
640 0           my %driver_to_db_map = (
641             'mysql' => 'MySQL'
642             );
643              
644 0           my $db = $driver_to_db_map{$self->storage->dbh->{Driver}->{Name}};
645 0 0         unless ($db) {
646 0           print "Sorry, this is an unsupported DB\n";
647 0           return;
648             }
649              
650 0 0         unless (DBIx::Class::Optional::Dependencies->req_ok_for ('deploy')) {
651 0           $self->throw_exception("Unable to proceed without " . DBIx::Class::Optional::Dependencies->req_missing_for ('deploy') );
652             }
653              
654 0           my $db_tr = SQL::Translator->new({
655             add_drop_table => 1,
656             parser => 'DBI',
657             parser_args => { dbh => $self->storage->dbh }
658             });
659              
660 0           $db_tr->producer($db);
661 0           my $dbic_tr = SQL::Translator->new;
662 0           $dbic_tr->parser('SQL::Translator::Parser::DBIx::Class');
663 0           $dbic_tr->data($self);
664 0           $dbic_tr->producer($db);
665              
666 0           $db_tr->schema->name('db_schema');
667 0           $dbic_tr->schema->name('dbic_schema');
668              
669             # is this really necessary?
670 0           foreach my $tr ($db_tr, $dbic_tr) {
671 0           my $data = $tr->data;
672 0           $tr->parser->($tr, $$data);
673             }
674              
675 0           my $diff = SQL::Translator::Diff::schema_diff($db_tr->schema, $db,
676             $dbic_tr->schema, $db,
677             { ignore_constraint_names => 1, ignore_index_names => 1, caseopt => 1 });
678              
679 0           my $filename = $self->ddl_filename(
680             $db,
681             $self->schema_version,
682             $self->upgrade_directory,
683             'PRE',
684             );
685 0           my $file;
686 0 0         if(!open($file, ">$filename"))
687             {
688 0           $self->throw_exception("Can't open $filename for writing ($!)");
689 0           next;
690             }
691 0           print $file $diff;
692 0           close($file);
693              
694 0           carp "WARNING: There may be differences between your DB and your DBIC schema. Please review and if necessary run the SQL in $filename to sync your DB.";
695             }
696              
697              
698             sub _set_db_version {
699 0     0     my $self = shift;
700 0           my ($params) = @_;
701 0   0       $params ||= {};
702              
703 0 0         my $version = $params->{version} ? $params->{version} : $self->schema_version;
704 0           my $vtable = $self->{vschema}->resultset('Table');
705              
706             ##############################################################################
707             # !!! NOTE !!!
708             ##############################################################################
709             #
710             # The travesty below replaces the old nice timestamp format of %Y-%m-%d %H:%M:%S
711             # This is necessary since there are legitimate cases when upgrades can happen
712             # back to back within the same second. This breaks things since we relay on the
713             # ability to sort by the 'installed' value. The logical choice of an autoinc
714             # is not possible, as it will break multiple legacy installations. Also it is
715             # not possible to format the string sanely, as the column is a varchar(20).
716             # The 'v' character is added to the front of the string, so that any version
717             # formatted by this new function will sort _after_ any existing 200... strings.
718 0           my @tm = gettimeofday();
719 0           my @dt = gmtime ($tm[0]);
720 0           my $o = $vtable->new_result({
721             version => $version,
722             installed => sprintf("v%04d%02d%02d_%02d%02d%02d.%03.0f",
723             $dt[5] + 1900,
724             $dt[4] + 1,
725             $dt[3],
726             $dt[2],
727             $dt[1],
728             $dt[0],
729             int($tm[1] / 1000), # convert to millisecs
730             ),
731             })->insert;
732             }
733              
734             sub _read_sql_file {
735 0     0     my $self = shift;
736 0   0       my $file = shift || return;
737              
738 0 0         open my $fh, '<', $file or carp("Can't open upgrade file, $file ($!)");
739 0           my @data = split /\n/, join '', <$fh>;
740 0           close $fh;
741              
742             @data = split /;/,
743             join '',
744 0 0 0       grep { $_ &&
  0            
745             !/^--/ &&
746             !/^(BEGIN|BEGIN TRANSACTION|COMMIT)/mi }
747             @data;
748              
749 0           return \@data;
750             }
751              
752             sub _source_exists
753             {
754 0     0     my ($self, $rs) = @_;
755              
756             return try {
757 0     0     $rs->search(\'1=0')->cursor->next;
758 0           1;
759             } catch {
760 0     0     0;
761 0           };
762             }
763              
764             =head1 FURTHER QUESTIONS?
765              
766             Check the list of L.
767              
768             =head1 COPYRIGHT AND LICENSE
769              
770             This module is free software L
771             by the L. You can
772             redistribute it and/or modify it under the same terms as the
773             L.
774              
775             =cut
776              
777             1;