diff options
Diffstat (limited to 'install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info')
6 files changed, 0 insertions, 2003 deletions
diff --git a/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/Handler.pm b/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/Handler.pm deleted file mode 100644 index 65416a8..0000000 --- a/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/Handler.pm +++ /dev/null @@ -1,305 +0,0 @@ -package App::Info::Handler; - -# $Id: Handler.pm,v 1.1 2004-04-29 09:21:28 ivan Exp $ - -=head1 NAME - -App::Info::Handler - App::Info event handler base class - -=head1 SYNOPSIS - - use App::Info::Category::FooApp; - use App::Info::Handler; - - my $app = App::Info::Category::FooApp->new( on_info => ['default'] ); - -=head1 DESCRIPTION - -This class defines the interface for subclasses that wish to handle events -triggered by App::Info concrete subclasses. The different types of events -triggered by App::Info can all be handled by App::Info::Handler (indeed, by -default they're all handled by a single App::Info::Handler object), and -App::Info::Handler subclasses may be designed to handle whatever events they -wish. - -If you're interested in I<using> an App::Info event handler, this is probably -not the class you should look at, since all it does is define a simple handler -that does nothing with an event. Look to the L<App::Info::Handler -subclasses|"SEE ALSO"> included in this distribution to do more interesting -things with App::Info events. - -If, on the other hand, you're interested in implementing your own event -handlers, read on! - -=cut - -use strict; -use vars qw($VERSION); -$VERSION = '0.22'; - -my %handlers; - -=head1 INTERFACE - -This section documents the public interface of App::Info::Handler. - -=head2 Class Method - -=head3 register_handler - - App::Info::Handler->register_handler( $key => $code_ref ); - -This class method may be used by App::Info::Handler subclasses to register -themselves with App::Info::Handler. Multiple registrations are supported. The -idea is that a subclass can define different functionality by specifying -different strings that represent different modes of constructing an -App::Info::Handler subclass object. The keys are case-sensitve, and should be -unique across App::Info::Handler subclasses so that many subclasses can be -loaded and used separately. If the C<$key> is already registered, -C<register_handler()> will throw an exception. The values are code references -that, when executed, return the appropriate App::Info::Handler subclass -object. - -=cut - -sub register_handler { - my ($pkg, $key, $code) = @_; - Carp::croak("Handler '$key' already exists") - if $handlers{$key}; - $handlers{$key} = $code; -} - -# Register ourself. -__PACKAGE__->register_handler('default', sub { __PACKAGE__->new } ); - -############################################################################## - -=head2 Constructor - -=head3 new - - my $handler = App::Info::Handler->new; - $handler = App::Info::Handler->new( key => $key); - -Constructs an App::Info::Handler object and returns it. If the key parameter -is provided and has been registered by an App::Info::Handler subclass via the -C<register_handler()> class method, then the relevant code reference will be -executed and the resulting App::Info::Handler subclass object returned. This -approach provides a handy shortcut for having C<new()> behave as an abstract -factory method, returning an object of the subclass appropriate to the key -parameter. - -=cut - -sub new { - my ($pkg, %p) = @_; - my $class = ref $pkg || $pkg; - $p{key} ||= 'default'; - if ($class eq __PACKAGE__ && $p{key} ne 'default') { - # We were called directly! Handle it. - Carp::croak("No such handler '$p{key}'") unless $handlers{$p{key}}; - return $handlers{$p{key}}->(); - } else { - # A subclass called us -- just instantiate and return. - return bless \%p, $class; - } -} - -=head2 Instance Method - -=head3 handler - - $handler->handler($req); - -App::Info::Handler defines a single instance method that must be defined by -its subclasses, C<handler()>. This is the method that will be executed by an -event triggered by an App::Info concrete subclass. It takes as its single -argument an App::Info::Request object, and returns a true value if it has -handled the event request. Returning a false value declines the request, and -App::Info will then move on to the next handler in the chain. - -The C<handler()> method implemented in App::Info::Handler itself does nothing -more than return a true value. It thus acts as a very simple default event -handler. See the App::Info::Handler subclasses for more interesting handling -of events, or create your own! - -=cut - -sub handler { 1 } - -1; -__END__ - -=head1 SUBCLASSING - -I hatched the idea of the App::Info event model with its subclassable handlers -as a way of separating the aggregation of application metadata from writing a -user interface for handling certain conditions. I felt it a better idea to -allow people to create their own user interfaces, and instead to provide only -a few examples. The App::Info::Handler class defines the API interface for -handling these conditions, which App::Info refers to as "events". - -There are various types of events defined by App::Info ("info", "error", -"unknown", and "confirm"), but the App::Info::Handler interface is designed to -be flexible enough to handle any and all of them. If you're interested in -creating your own App::Info event handler, this is the place to learn how. - -=head2 The Interface - -To create an App::Info event handler, all one need do is subclass -App::Info::Handler and then implement the C<new()> constructor and the -C<handler()> method. The C<new()> constructor can do anything you like, and -take any arguments you like. However, I do recommend that the first thing -you do in your implementation is to call the super constructor: - - sub new { - my $pkg = shift; - my $self = $pkg->SUPER::new(@_); - # ... other stuff. - return $self; - } - -Although the default C<new()> constructor currently doesn't do much, that may -change in the future, so this call will keep you covered. What it does do is -take the parameterized arguments and assign them to the App::Info::Handler -object. Thus if you've specified a "mode" argument, where clients can -construct objects of you class like this: - - my $handler = FooHandler->new( mode => 'foo' ); - -You can access the mode parameter directly from the object, like so: - - sub new { - my $pkg = shift; - my $self = $pkg->SUPER::new(@_); - if ($self->{mode} eq 'foo') { - # ... - } - return $self; - } - -Just be sure not to use a parameter key name required by App::Info::Handler -itself. At the moment, the only parameter accepted by App::Info::Handler is -"key", so in general you'll be pretty safe. - -Next, I recommend that you take advantage of the C<register_handler()> method -to create some shortcuts for creating handlers of your class. For example, say -we're creating a handler subclass FooHandler. It has two modes, a default -"foo" mode and an advanced "bar" mode. To allow both to be constructed by -stringified shortcuts, the FooHandler class implementation might start like -this: - - package FooHandler; - - use strict; - use App::Info::Handler; - use vars qw(@ISA); - @ISA = qw(App::Info::Handler); - - foreach my $c (qw(foo bar)) { - App::Info::Handler->register_handler - ( $c => sub { __PACKAGE__->new( mode => $c) } ); - } - -The strings "foo" and "bar" can then be used by clients as shortcuts to have -App::Info objects automatically create and use handlers for certain events. -For example, if a client wanted to use a "bar" event handler for its info -events, it might do this: - - use App::Info::Category::FooApp; - use FooHandler; - - my $app = App::Info::Category::FooApp->new(on_info => ['bar']); - -Take a look at App::Info::Handler::Print and App::Info::Handler::Carp to see -concrete examples of C<register_handler()> usage. - -The final step in creating a new App::Info event handler is to implement the -C<handler()> method itself. This method takes a single argument, an -App::Info::Request object, and is expected to return true if it handled the -request, and false if it did not. The App::Info::Request object contains all -the metadata relevant to a request, including the type of event that triggered -it; see L<App::Info::Request|App::Info::Request> for its documentation. - -Use the App::Info::Request object however you like to handle the request -however you like. You are, however, expected to abide by a a few guidelines: - -=over 4 - -=item * - -For error and info events, you are expected (but not required) to somehow -display the info or error message for the user. How your handler chooses to do -so is up to you and the handler. - -=item * - -For unknown and confirm events, you are expected to prompt the user for a -value. If it's a confirm event, offer the known value (found in -C<$req-E<gt>value>) as a default. - -=item * - -For unknown and confirm events, you are expected to call C<$req-E<gt>callback> -and pass in the new value. If C<$req-E<gt>callback> returns a false value, you -are expected to display the error message in C<$req-E<gt>error> and prompt the -user again. Note that C<$req-E<gt>value> calls C<$req-E<gt>callback> -internally, and thus assigns the value and returns true if -C<$req-E<gt>callback> returns true, and does not assign the value and returns -false if C<$req-E<gt>callback> returns false. - -=item * - -For unknown and confirm events, if you've collected a new value and -C<$req-E<gt>callback> returns true for that value, you are expected to assign -the value by passing it to C<$req-E<gt>value>. This allows App::Info to give -the value back to the calling App::Info concrete subclass. - -=back - -Probably the easiest way to get started creating new App::Info event handlers -is to check out the simple handlers provided with the distribution and follow -their logical examples. Consult the App::Info documentation of the L<event -methods|App::Info/"Events"> for details on how App::Info constructs the -App::Info::Request object for each event type. - -=head1 BUGS - -Report all bugs via the CPAN Request Tracker at -L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=App-Info>. - -=head1 AUTHOR - -David Wheeler <L<david@wheeler.net|"david@wheeler.net">> - -=head1 SEE ALSO - -L<App::Info|App::Info> thoroughly documents the client interface for setting -event handlers, as well as the event triggering interface for App::Info -concrete subclasses. - -L<App::Info::Request|App::Info::Request> documents the interface for the -request objects passed to App::Info::Handler C<handler()> methods. - -The following App::Info::Handler subclasses offer examples for event handler -authors, and, of course, provide actual event handling functionality for -App::Info clients. - -=over 4 - -=item L<App::Info::Handler::Carp|App::Info::Handler::Carp> - -=item L<App::Info::Handler::Print|App::Info::Handler::Print> - -=item L<App::Info::Handler::Prompt|App::Info::Handler::Prompt> - -=back - -=head1 COPYRIGHT AND LICENSE - -Copyright (c) 2002, David Wheeler. All Rights Reserved. - -This module is free software; you can redistribute it and/or modify it under the -same terms as Perl itself. - -=cut diff --git a/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/Handler/Prompt.pm b/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/Handler/Prompt.pm deleted file mode 100644 index 47edd78..0000000 --- a/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/Handler/Prompt.pm +++ /dev/null @@ -1,170 +0,0 @@ -package App::Info::Handler::Prompt; - -# $Id: Prompt.pm,v 1.1 2004-04-29 09:21:29 ivan Exp $ - -=head1 NAME - -App::Info::Handler::Prompt - Prompting App::Info event handler - -=head1 SYNOPSIS - - use App::Info::Category::FooApp; - use App::Info::Handler::Print; - - my $prompter = App::Info::Handler::Print->new; - my $app = App::Info::Category::FooApp->new( on_unknown => $prompter ); - - # Or... - my $app = App::Info::Category::FooApp->new( on_confirm => 'prompt' ); - -=head1 DESCRIPTION - -App::Info::Handler::Prompt objects handle App::Info events by printing their -messages to C<STDOUT> and then accepting a new value from C<STDIN>. The new -value is validated by any callback supplied by the App::Info concrete subclass -that triggered the event. If the value is valid, App::Info::Handler::Prompt -assigns the new value to the event request. If it isn't it prints the error -message associated with the event request, and then prompts for the data -again. - -Although designed with unknown and confirm events in mind, -App::Info::Handler::Prompt handles info and error events as well. It will -simply print info event messages to C<STDOUT> and print error event messages -to C<STDERR>. For more interesting info and error event handling, see -L<App::Info::Handler::Print|App::Info::Handler::Print> and -L<App::Info::Handler::Carp|App::Info::Handler::Carp>. - -Upon loading, App::Info::Handler::Print registers itself with -App::Info::Handler, setting up a single string, "prompt", that can be passed -to an App::Info concrete subclass constructor. This string is a shortcut that -tells App::Info how to create an App::Info::Handler::Print object for handling -events. - -=cut - -use strict; -use App::Info::Handler; -use vars qw($VERSION @ISA); -$VERSION = '0.22'; -@ISA = qw(App::Info::Handler); - -# Register ourselves. -App::Info::Handler->register_handler - ('prompt' => sub { __PACKAGE__->new('prompt') } ); - -=head1 INTERFACE - -=head2 Constructor - -=head3 new - - my $prompter = App::Info::Handler::Prompt->new; - -Constructs a new App::Info::Handler::Prompt object and returns it. No special -arguments are required. - -=cut - -sub new { - my $pkg = shift; - my $self = $pkg->SUPER::new(@_); - $self->{tty} = -t STDIN && ( -t STDOUT || !( -f STDOUT || -c STDOUT ) ); - # We're done! - return $self; -} - -my $get_ans = sub { - my ($prompt, $tty, $def) = @_; - # Print the message. - local $| = 1; - local $\; - print $prompt; - - # Collect the answer. - my $ans; - if ($tty) { - $ans = <STDIN>; - if (defined $ans ) { - chomp $ans; - } else { # user hit ctrl-D - print "\n"; - } - } else { - print "$def\n" if defined $def; - } - return $ans; -}; - -sub handler { - my ($self, $req) = @_; - my $ans; - my $type = $req->type; - if ($type eq 'unknown' || $type eq 'confirm') { - # We'll want to prompt for a new value. - my $val = $req->value; - my ($def, $dispdef) = defined $val ? ($val, " [$val] ") : ('', ' '); - my $msg = $req->message or Carp::croak("No message in request"); - $msg .= $dispdef; - - # Get the answer. - $ans = $get_ans->($msg, $self->{tty}, $def); - # Just return if they entered an empty string or we couldnt' get an - # answer. - return 1 unless defined $ans && $ans ne ''; - - # Validate the answer. - my $err = $req->error; - while (!$req->value($ans)) { - print "$err: '$ans'\n"; - $ans = $get_ans->($msg, $self->{tty}, $def); - return 1 unless defined $ans && $ans ne ''; - } - - } elsif ($type eq 'info') { - # Just print the message. - print STDOUT $req->message, "\n"; - } elsif ($type eq 'error') { - # Just print the message. - print STDERR $req->message, "\n"; - } else { - # This shouldn't happen. - Carp::croak("Invalid request type '$type'"); - } - - # Return true to indicate that we've handled the request. - return 1; -} - -1; -__END__ - -=head1 BUGS - -Report all bugs via the CPAN Request Tracker at -L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=App-Info>. - -=head1 AUTHOR - -David Wheeler <L<david@wheeler.net|"david@wheeler.net">> - -=head1 SEE ALSO - -L<App::Info|App::Info> documents the event handling interface. - -L<App::Info::Handler::Carp|App::Info::Handler::Carp> handles events by -passing their messages Carp module functions. - -L<App::Info::Handler::Print|App::Info::Handler::Print> handles events by -printing their messages to a file handle. - -L<App::Info::Handler|App::Info::Handler> describes how to implement custom -App::Info event handlers. - -=head1 COPYRIGHT AND LICENSE - -Copyright (c) 2002, David Wheeler. All Rights Reserved. - -This module is free software; you can redistribute it and/or modify it under the -same terms as Perl itself. - -=cut diff --git a/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/RDBMS.pm b/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/RDBMS.pm deleted file mode 100644 index 504d570..0000000 --- a/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/RDBMS.pm +++ /dev/null @@ -1,55 +0,0 @@ -package App::Info::RDBMS; - -# $Id: RDBMS.pm,v 1.1 2004-04-29 09:21:28 ivan Exp $ - -use strict; -use App::Info; -use vars qw(@ISA $VERSION); -@ISA = qw(App::Info); -$VERSION = '0.22'; - -1; -__END__ - -=head1 NAME - -App::Info::RDBMS - Information about databases on a system - -=head1 DESCRIPTION - -This class is an abstract base class for App::Info subclasses that provide -information about relational databases. Its subclasses are required to -implement its interface. See L<App::Info|App::Info> for a complete description -and L<App::Info::RDBMS::PostgreSQL|App::Info::RDBMS::PostgreSQL> for an example -implementation. - -=head1 INTERFACE - -Currently, App::Info::RDBMS adds no more methods than those from its parent -class, App::Info. - -=head1 BUGS - -Report all bugs via the CPAN Request Tracker at -L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=App-Info>. - -=head1 AUTHOR - -David Wheeler <L<david@wheeler.net|"david@wheeler.net">> - -=head1 SEE ALSO - -L<App::Info|App::Info>, -L<App::Info::RDBMS::PostgreSQL|App::Info::RDBMS::PostgreSQL> - -=head1 COPYRIGHT AND LICENSE - -Copyright (c) 2002, David Wheeler. All Rights Reserved. - -This module is free software; you can redistribute it and/or modify it under the -same terms as Perl itself. - -=cut - - - diff --git a/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/RDBMS/PostgreSQL.pm b/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/RDBMS/PostgreSQL.pm deleted file mode 100644 index aef326c..0000000 --- a/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/RDBMS/PostgreSQL.pm +++ /dev/null @@ -1,730 +0,0 @@ -package App::Info::RDBMS::PostgreSQL; - -# $Id: PostgreSQL.pm,v 1.1 2004-04-29 09:21:29 ivan Exp $ - -=head1 NAME - -App::Info::RDBMS::PostgreSQL - Information about PostgreSQL - -=head1 SYNOPSIS - - use App::Info::RDBMS::PostgreSQL; - - my $pg = App::Info::RDBMS::PostgreSQL->new; - - if ($pg->installed) { - print "App name: ", $pg->name, "\n"; - print "Version: ", $pg->version, "\n"; - print "Bin dir: ", $pg->bin_dir, "\n"; - } else { - print "PostgreSQL is not installed. :-(\n"; - } - -=head1 DESCRIPTION - -App::Info::RDBMS::PostgreSQL supplies information about the PostgreSQL -database server installed on the local system. It implements all of the -methods defined by App::Info::RDBMS. Methods that trigger events will trigger -them only the first time they're called (See L<App::Info|App::Info> for -documentation on handling events). To start over (after, say, someone has -installed PostgreSQL) construct a new App::Info::RDBMS::PostgreSQL object to -aggregate new metadata. - -Some of the methods trigger the same events. This is due to cross-calling of -shared subroutines. However, any one event should be triggered no more than -once. For example, although the info event "Executing `pg_config --version`" -is documented for the methods C<name()>, C<version()>, C<major_version()>, -C<minor_version()>, and C<patch_version()>, rest assured that it will only be -triggered once, by whichever of those four methods is called first. - -=cut - -use strict; -use App::Info::RDBMS; -use App::Info::Util; -use vars qw(@ISA $VERSION); -@ISA = qw(App::Info::RDBMS); -$VERSION = '0.22'; - -my $u = App::Info::Util->new; - -=head1 INTERFACE - -=head2 Constructor - -=head3 new - - my $pg = App::Info::RDBMS::PostgreSQL->new(@params); - -Returns an App::Info::RDBMS::PostgreSQL object. See L<App::Info|App::Info> for -a complete description of argument parameters. - -When it called, C<new()> searches the file system for the F<pg_config> -application. If found, F<pg_config> will be called by the object methods below -to gather the data necessary for each. If F<pg_config> cannot be found, then -PostgreSQL is assumed not to be installed, and each of the object methods will -return C<undef>. - -App::Info::RDBMS::PostgreSQL searches for F<pg_config> along your path, as -defined by C<File::Spec-E<gt>path>. Failing that, it searches the following -directories: - -=over 4 - -=item /usr/local/pgsql/bin - -=item /usr/local/postgres/bin - -=item /opt/pgsql/bin - -=item /usr/local/bin - -=item /usr/local/sbin - -=item /usr/bin - -=item /usr/sbin - -=item /bin - -=back - -B<Events:> - -=over 4 - -=item info - -Looking for pg_config - -=item confirm - -Path to pg_config? - -=item unknown - -Path to pg_config? - -=back - -=cut - -sub new { - # Construct the object. - my $self = shift->SUPER::new(@_); - - # Find pg_config. - $self->info("Looking for pg_config"); - my @paths = ($u->path, - qw(/usr/local/pgsql/bin - /usr/local/postgres/bin - /opt/pgsql/bin - /usr/local/bin - /usr/local/sbin - /usr/bin - /usr/sbin - /bin)); - - if (my $cfg = $u->first_cat_exe('pg_config', @paths)) { - # We found it. Confirm. - $self->{pg_config} = $self->confirm( key => 'pg_config', - prompt => 'Path to pg_config?', - value => $cfg, - callback => sub { -x }, - error => 'Not an executable'); - } else { - # Handle an unknown value. - $self->{pg_config} = $self->unknown( key => 'pg_config', - prompt => 'Path to pg_config?', - callback => sub { -x }, - error => 'Not an executable'); - } - - return $self; -} - -# We'll use this code reference as a common way of collecting data. -my $get_data = sub { - return unless $_[0]->{pg_config}; - $_[0]->info("Executing `$_[0]->{pg_config} $_[1]`"); - my $info = `$_[0]->{pg_config} $_[1]`; - chomp $info; - return $info; -}; - -############################################################################## - -=head2 Class Method - -=head3 key_name - - my $key_name = App::Info::RDBMS::PostgreSQL->key_name; - -Returns the unique key name that describes this class. The value returned is -the string "PostgreSQL". - -=cut - -sub key_name { 'PostgreSQL' } - -############################################################################## - -=head2 Object Methods - -=head3 installed - - print "PostgreSQL is ", ($pg->installed ? '' : 'not '), "installed.\n"; - -Returns true if PostgreSQL is installed, and false if it is not. -App::Info::RDBMS::PostgreSQL determines whether PostgreSQL is installed based -on the presence or absence of the F<pg_config> application on the file system -as found when C<new()> constructed the object. If PostgreSQL does not appear -to be installed, then all of the other object methods will return empty -values. - -=cut - -sub installed { return $_[0]->{pg_config} ? 1 : undef } - -############################################################################## - -=head3 name - - my $name = $pg->name; - -Returns the name of the application. App::Info::RDBMS::PostgreSQL parses the -name from the system call C<`pg_config --version`>. - -B<Events:> - -=over 4 - -=item info - -Executing `pg_config --version` - -=item error - -Failed to find PostgreSQL version with `pg_config --version` - -Unable to parse name from string - -Unable to parse version from string - -Failed to parse PostgreSQL version parts from string - -=item unknown - -Enter a valid PostgreSQL name - -=back - -=cut - -# This code reference is used by name(), version(), major_version(), -# minor_version(), and patch_version() to aggregate the data they need. -my $get_version = sub { - my $self = shift; - $self->{'--version'} = 1; - my $data = $get_data->($self, '--version'); - unless ($data) { - $self->error("Failed to find PostgreSQL version with ". - "`$self->{pg_config} --version"); - return; - } - - chomp $data; - my ($name, $version) = split /\s+/, $data, 2; - - # Check for and assign the name. - $name ? - $self->{name} = $name : - $self->error("Unable to parse name from string '$data'"); - - # Parse the version number. - if ($version) { - my ($x, $y, $z) = $version =~ /(\d+)\.(\d+).(\d+)/; - if (defined $x and defined $y and defined $z) { - @{$self}{qw(version major minor patch)} = - ($version, $x, $y, $z); - } else { - $self->error("Failed to parse PostgreSQL version parts from " . - "string '$version'"); - } - } else { - $self->error("Unable to parse version from string '$data'"); - } -}; - -sub name { - my $self = shift; - return unless $self->{pg_config}; - - # Load data. - $get_version->($self) unless $self->{'--version'}; - - # Handle an unknown name. - $self->{name} ||= $self->unknown( key => 'name' ); - - # Return the name. - return $self->{name}; -} - -############################################################################## - -=head3 version - - my $version = $pg->version; - -Returns the PostgreSQL version number. App::Info::RDBMS::PostgreSQL parses the -version number from the system call C<`pg_config --version`>. - -B<Events:> - -=over 4 - -=item info - -Executing `pg_config --version` - -=item error - -Failed to find PostgreSQL version with `pg_config --version` - -Unable to parse name from string - -Unable to parse version from string - -Failed to parse PostgreSQL version parts from string - -=item unknown - -Enter a valid PostgreSQL version number - -=back - -=cut - -sub version { - my $self = shift; - return unless $self->{pg_config}; - - # Load data. - $get_version->($self) unless $self->{'--version'}; - - # Handle an unknown value. - unless ($self->{version}) { - # Create a validation code reference. - my $chk_version = sub { - # Try to get the version number parts. - my ($x, $y, $z) = /^(\d+)\.(\d+).(\d+)$/; - # Return false if we didn't get all three. - return unless $x and defined $y and defined $z; - # Save all three parts. - @{$self}{qw(major minor patch)} = ($x, $y, $z); - # Return true. - return 1; - }; - $self->{version} = $self->unknown( key => 'version number', - callback => $chk_version); - } - - return $self->{version}; -} - -############################################################################## - -=head3 major version - - my $major_version = $pg->major_version; - -Returns the PostgreSQL major version number. App::Info::RDBMS::PostgreSQL -parses the major version number from the system call C<`pg_config --version`>. -For example, C<version()> returns "7.1.2", then this method returns "7". - -B<Events:> - -=over 4 - -=item info - -Executing `pg_config --version` - -=item error - -Failed to find PostgreSQL version with `pg_config --version` - -Unable to parse name from string - -Unable to parse version from string - -Failed to parse PostgreSQL version parts from string - -=item unknown - -Enter a valid PostgreSQL major version number - -=back - -=cut - -# This code reference is used by major_version(), minor_version(), and -# patch_version() to validate a version number entered by a user. -my $is_int = sub { /^\d+$/ }; - -sub major_version { - my $self = shift; - return unless $self->{pg_config}; - # Load data. - $get_version->($self) unless exists $self->{'--version'}; - # Handle an unknown value. - $self->{major} = $self->unknown( key => 'major version number', - callback => $is_int) - unless $self->{major}; - return $self->{major}; -} - -############################################################################## - -=head3 minor version - - my $minor_version = $pg->minor_version; - -Returns the PostgreSQL minor version number. App::Info::RDBMS::PostgreSQL -parses the minor version number from the system call C<`pg_config --version`>. -For example, if C<version()> returns "7.1.2", then this method returns "2". - -B<Events:> - -=over 4 - -=item info - -Executing `pg_config --version` - -=item error - -Failed to find PostgreSQL version with `pg_config --version` - -Unable to parse name from string - -Unable to parse version from string - -Failed to parse PostgreSQL version parts from string - -=item unknown - -Enter a valid PostgreSQL minor version number - -=back - -=cut - -sub minor_version { - my $self = shift; - return unless $self->{pg_config}; - # Load data. - $get_version->($self) unless exists $self->{'--version'}; - # Handle an unknown value. - $self->{minor} = $self->unknown( key => 'minor version number', - callback => $is_int) - unless defined $self->{minor}; - return $self->{minor}; -} - -############################################################################## - -=head3 patch version - - my $patch_version = $pg->patch_version; - -Returns the PostgreSQL patch version number. App::Info::RDBMS::PostgreSQL -parses the patch version number from the system call C<`pg_config --version`>. -For example, if C<version()> returns "7.1.2", then this method returns "1". - -B<Events:> - -=over 4 - -=item info - -Executing `pg_config --version` - -=item error - -Failed to find PostgreSQL version with `pg_config --version` - -Unable to parse name from string - -Unable to parse version from string - -Failed to parse PostgreSQL version parts from string - -=item unknown - -Enter a valid PostgreSQL minor version number - -=back - -=cut - -sub patch_version { - my $self = shift; - return unless $self->{pg_config}; - # Load data. - $get_version->($self) unless exists $self->{'--version'}; - # Handle an unknown value. - $self->{patch} = $self->unknown( key => 'patch version number', - callback => $is_int) - unless defined $self->{patch}; - return $self->{patch}; -} - -############################################################################## - -=head3 bin_dir - - my $bin_dir = $pg->bin_dir; - -Returns the PostgreSQL binary directory path. App::Info::RDBMS::PostgreSQL -gathers the path from the system call C<`pg_config --bindir`>. - -B<Events:> - -=over 4 - -=item info - -Executing `pg_config --bindir` - -=item error - -Cannot find bin directory - -=item unknown - -Enter a valid PostgreSQL bin directory - -=back - -=cut - -# This code reference is used by bin_dir(), lib_dir(), and so_lib_dir() to -# validate a directory entered by the user. -my $is_dir = sub { -d }; - -sub bin_dir { - my $self = shift; - return unless $self->{pg_config}; - unless (exists $self->{bin_dir} ) { - if (my $dir = $get_data->($self, '--bindir')) { - $self->{bin_dir} = $dir; - } else { - # Handle an unknown value. - $self->error("Cannot find bin directory"); - $self->{bin_dir} = $self->unknown( key => 'bin directory', - callback => $is_dir) - } - } - - return $self->{bin_dir}; -} - -############################################################################## - -=head3 inc_dir - - my $inc_dir = $pg->inc_dir; - -Returns the PostgreSQL include directory path. App::Info::RDBMS::PostgreSQL -gathers the path from the system call C<`pg_config --includedir`>. - -B<Events:> - -=over 4 - -=item info - -Executing `pg_config --includedir` - -=item error - -Cannot find include directory - -=item unknown - -Enter a valid PostgreSQL include directory - -=back - -=cut - -sub inc_dir { - my $self = shift; - return unless $self->{pg_config}; - unless (exists $self->{inc_dir} ) { - if (my $dir = $get_data->($self, '--includedir')) { - $self->{inc_dir} = $dir; - } else { - # Handle an unknown value. - $self->error("Cannot find include directory"); - $self->{inc_dir} = $self->unknown( key => 'include directory', - callback => $is_dir) - } - } - - return $self->{inc_dir}; -} - -############################################################################## - -=head3 lib_dir - - my $lib_dir = $pg->lib_dir; - -Returns the PostgreSQL library directory path. App::Info::RDBMS::PostgreSQL -gathers the path from the system call C<`pg_config --libdir`>. - -B<Events:> - -=over 4 - -=item info - -Executing `pg_config --libdir` - -=item error - -Cannot find library directory - -=item unknown - -Enter a valid PostgreSQL library directory - -=back - -=cut - -sub lib_dir { - my $self = shift; - return unless $self->{pg_config}; - unless (exists $self->{lib_dir} ) { - if (my $dir = $get_data->($self, '--libdir')) { - $self->{lib_dir} = $dir; - } else { - # Handle an unknown value. - $self->error("Cannot find library directory"); - $self->{lib_dir} = $self->unknown( key => 'library directory', - callback => $is_dir) - } - } - - return $self->{lib_dir}; -} - -############################################################################## - -=head3 so_lib_dir - - my $so_lib_dir = $pg->so_lib_dir; - -Returns the PostgreSQL shared object library directory path. -App::Info::RDBMS::PostgreSQL gathers the path from the system call -C<`pg_config --pkglibdir`>. - -B<Events:> - -=over 4 - -=item info - -Executing `pg_config --pkglibdir` - -=item error - -Cannot find shared object library directory - -=item unknown - -Enter a valid PostgreSQL shared object library directory - -=back - -=cut - -# Location of dynamically loadable modules. -sub so_lib_dir { - my $self = shift; - return unless $self->{pg_config}; - unless (exists $self->{so_lib_dir} ) { - if (my $dir = $get_data->($self, '--pkglibdir')) { - $self->{so_lib_dir} = $dir; - } else { - # Handle an unknown value. - $self->error("Cannot find shared object library directory"); - $self->{so_lib_dir} = - $self->unknown( key => 'shared object library directory', - callback => $is_dir) - } - } - - return $self->{so_lib_dir}; -} - -############################################################################## - -=head3 home_url - - my $home_url = $pg->home_url; - -Returns the PostgreSQL home page URL. - -=cut - -sub home_url { "http://www.postgresql.org/" } - -############################################################################## - -=head3 download_url - - my $download_url = $pg->download_url; - -Returns the PostgreSQL download URL. - -=cut - -sub download_url { "http://www.ca.postgresql.org/sitess.html" } - -1; -__END__ - -=head1 BUGS - -Report all bugs via the CPAN Request Tracker at -L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=App-Info>. - -=head1 AUTHOR - -David Wheeler <L<david@wheeler.net|"david@wheeler.net">> based on code by Sam -Tregar <L<sam@tregar.com|"sam@tregar.com">>. - -=head1 SEE ALSO - -L<App::Info|App::Info> documents the event handling interface. - -L<App::Info::RDBMS|App::Info::RDBMS> is the App::Info::RDBMS::PostgreSQL -parent class. - -L<DBD::Pg|DBD::Pg> is the L<DBI|DBI> driver for connecting to PostgreSQL -databases. - -L<http://www.postgresql.org/> is the PostgreSQL home page. - -=head1 COPYRIGHT AND LICENSE - -Copyright (c) 2002, David Wheeler. All Rights Reserved. - -This module is free software; you can redistribute it and/or modify it under the -same terms as Perl itself. - -=cut diff --git a/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/Request.pm b/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/Request.pm deleted file mode 100644 index c02c97b..0000000 --- a/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/Request.pm +++ /dev/null @@ -1,287 +0,0 @@ -package App::Info::Request; - -# $Id: Request.pm,v 1.1 2004-04-29 09:21:28 ivan Exp $ - -=head1 NAME - -App::Info::Request - App::Info event handler request object - -=head1 SYNOPSIS - - # In an App::Info::Handler subclass: - sub handler { - my ($self, $req) = @_; - print "Event Type: ", $req->type; - print "Message: ", $req->message; - print "Error: ", $req->error; - print "Value: ", $req->value; - } - -=head1 DESCRIPTION - -Objects of this class are passed to the C<handler()> method of App::Info event -handlers. Generally, this class will be of most interest to App::Info::Handler -subclass implementers. - -The L<event triggering methods|App::Info/"Events"> in App::Info each construct -a new App::Info::Request object and initialize it with their arguments. The -App::Info::Request object is then the sole argument passed to the C<handler()> -method of any and all App::Info::Handler objects in the event handling chain. -Thus, if you'd like to create your own App::Info event handler, this is the -object you need to be familiar with. Consult the -L<App::Info::Handler|App::Info::Handler> documentation for details on creating -custom event handlers. - -Each of the App::Info event triggering methods constructs an -App::Info::Request object with different attribute values. Be sure to consult -the documentation for the L<event triggering methods|App::Info/"Events"> in -App::Info, where the values assigned to the App::Info::Request object are -documented. Then, in your event handler subclass, check the value returned by -the C<type()> method to determine what type of event request you're handling -to handle the request appropriately. - -=cut - -use strict; -use vars qw($VERSION); -$VERSION = '0.23'; - -############################################################################## - -=head1 INTERFACE - -The following sections document the App::Info::Request interface. - -=head2 Constructor - -=head3 new - - my $req = App::Info::Request->new(%params); - -This method is used internally by App::Info to construct new -App::Info::Request objects to pass to event handler objects. Generally, you -won't need to use it, other than perhaps for testing custom App::Info::Handler -classes. - -The parameters to C<new()> are passed as a hash of named parameters that -correspond to their like-named methods. The supported parameters are: - -=over 4 - -=item type - -=item message - -=item error - -=item value - -=item callback - -=back - -See the object methods documentation below for details on these object -attributes. - -=cut - -sub new { - my $pkg = shift; - - # Make sure we've got a hash of arguments. - Carp::croak("Odd number of parameters in call to " . __PACKAGE__ . - "->new() when named parameters expected" ) if @_ % 2; - my %params = @_; - - # Validate the callback. - if ($params{callback}) { - Carp::croak("Callback parameter '$params{callback}' is not a code ", - "reference") - unless UNIVERSAL::isa($params{callback}, 'CODE'); - } else { - # Otherwise just assign a default approve callback. - $params{callback} = sub { 1 }; - } - - # Validate type parameter. - if (my $t = $params{type}) { - Carp::croak("Invalid handler type '$t'") - unless $t eq 'error' or $t eq 'info' or $t eq 'unknown' - or $t eq 'confirm'; - } else { - $params{type} = 'info'; - } - - # Return the request object. - bless \%params, ref $pkg || $pkg; -} - -############################################################################## - -=head2 Object Methods - -=head3 message - - my $message = $req->message; - -Returns the message stored in the App::Info::Request object. The message is -typically informational, or an error message, or a prompt message. - -=cut - -sub message { $_[0]->{message} } - -############################################################################## - -=head3 error - - my $error = $req->error; - -Returns any error message associated with the App::Info::Request object. The -error message is typically there to display for users when C<callback()> -returns false. - -=cut - -sub error { $_[0]->{error} } - -############################################################################## - -=head3 type - - my $type = $req->type; - -Returns a string representing the type of event that triggered this request. -The types are the same as the event triggering methods defined in App::Info. -As of this writing, the supported types are: - -=over - -=item info - -=item error - -=item unknown - -=item confirm - -=back - -Be sure to consult the App::Info documentation for more details on the event -types. - -=cut - -sub type { $_[0]->{type} } - -############################################################################## - -=head3 callback - - if ($req->callback($value)) { - print "Value '$value' is valid.\n"; - } else { - print "Value '$value' is not valid.\n"; - } - -Executes the callback anonymous subroutine supplied by the App::Info concrete -base class that triggered the event. If the callback returns false, then -C<$value> is invalid. If the callback returns true, then C<$value> is valid -and can be assigned via the C<value()> method. - -Note that the C<value()> method itself calls C<callback()> if it was passed a -value to assign. See its documentation below for more information. - -=cut - -sub callback { - my $self = shift; - my $code = $self->{callback}; - local $_ = $_[0]; - $code->(@_); -} - -############################################################################## - -=head3 value - - my $value = $req->value; - if ($req->value($value)) { - print "Value '$value' successfully assigned.\n"; - } else { - print "Value '$value' not successfully assigned.\n"; - } - -When called without an argument, C<value()> simply returns the value currently -stored by the App::Info::Request object. Typically, the value is the default -value for a confirm event, or a value assigned to an unknown event. - -When passed an argument, C<value()> attempts to store the the argument as a -new value. However, C<value()> calls C<callback()> on the new value, and if -C<callback()> returns false, then C<value()> returns false and does not store -the new value. If C<callback()> returns true, on the other hand, then -C<value()> goes ahead and stores the new value and returns true. - -=cut - -sub value { - my $self = shift; - if ($#_ >= 0) { - # grab the value. - my $value = shift; - # Validate the value. - if ($self->callback($value)) { - # The value is good. Assign it and return true. - $self->{value} = $value; - return 1; - } else { - # Invalid value. Return false. - return; - } - } - # Just return the value. - return $self->{value}; -} - -1; -__END__ - -=head1 BUGS - -Report all bugs via the CPAN Request Tracker at -L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=App-Info>. - -=head1 AUTHOR - -David Wheeler <L<david@wheeler.net|"david@wheeler.net">> - -=head1 SEE ALSO - -L<App::Info|App::Info> documents the event triggering methods and how they -construct App::Info::Request objects to pass to event handlers. - -L<App::Info::Handler:|App::Info::Handler> documents how to create custom event -handlers, which must make use of the App::Info::Request object passed to their -C<handler()> object methods. - -The following classes subclass App::Info::Handler, and thus offer good -exemplars for using App::Info::Request objects when handling events. - -=over 4 - -=item L<App::Info::Handler::Carp|App::Info::Handler::Carp> - -=item L<App::Info::Handler::Print|App::Info::Handler::Print> - -=item L<App::Info::Handler::Prompt|App::Info::Handler::Prompt> - -=back - -=head1 COPYRIGHT AND LICENSE - -Copyright (c) 2002, David Wheeler. All Rights Reserved. - -This module is free software; you can redistribute it and/or modify it under the -same terms as Perl itself. - -=cut diff --git a/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/Util.pm b/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/Util.pm deleted file mode 100644 index 55bb333..0000000 --- a/install/5.005/DBD-Pg-1.22-fixvercmp/t/lib/App/Info/Util.pm +++ /dev/null @@ -1,456 +0,0 @@ -package App::Info::Util; - -# $Id: Util.pm,v 1.1 2004-04-29 09:21:28 ivan Exp $ - -=head1 NAME - -App::Info::Util - Utility class for App::Info subclasses - -=head1 SYNOPSIS - - use App::Info::Util; - - my $util = App::Info::Util->new; - - # Subclasses File::Spec. - my @paths = $util->paths; - - # First directory that exists in a list. - my $dir = $util->first_dir(@paths); - - # First directory that exists in a path. - $dir = $util->first_path($ENV{PATH}); - - # First file that exists in a list. - my $file = $util->first_file('this.txt', '/that.txt', 'C:\\foo.txt'); - - # First file found among file base names and directories. - my $files = ['this.txt', 'that.txt']; - $file = $util->first_cat_file($files, @paths); - -=head1 DESCRIPTION - -This class subclasses L<File::Spec|File::Spec> and adds its own methods in -order to offer utility methods to L<App::Info|App::Info> classes. Although -intended to be used by App::Info subclasses, in truth App::Info::Util's -utility may be considered more general, so feel free to use it elsewhere. - -The methods added in addition to the usual File::Spec suspects are designed to -facilitate locating files and directories on the file system, as well as -searching those files. The assumption is that, in order to provide useful -metadata about a given software package, an App::Info subclass must find -relevant files and directories and parse them with regular expressions. This -class offers methods that simplify those tasks. - -=cut - -use strict; -use File::Spec (); -use vars qw(@ISA $VERSION); -@ISA = qw(File::Spec); -$VERSION = '0.22'; - -my %path_dems = (MacOS => qr',', - MSWin32 => qr';', - os2 => qr';', - VMS => undef, - epoc => undef); - -my $path_dem = exists $path_dems{$^O} ? $path_dems{$^O} : qr':'; - -=head1 CONSTRUCTOR - -=head2 new - - my $util = App::Info::Util->new; - -This is a very simple constructor that merely returns an App::Info::Util -object. Since, like its File::Spec super class, App::Info::Util manages no -internal data itself, all methods may be used as class methods, if one prefers -to. The constructor here is provided merely as a convenience. - -=cut - -sub new { bless {}, ref $_[0] || $_[0] } - -=head1 OBJECT METHODS - -In addition to all of the methods offered by its super class, -L<File::Spec|File::Spec>, App::Info::Util offers the following methods. - -=head2 first_dir - - my @paths = $util->paths; - my $dir = $util->first_dir(@dirs); - -Returns the first file system directory in @paths that exists on the local -file system. Only the first item in @paths that exists as a directory will be -returned; any other paths leading to non-directories will be ignored. - -=cut - -sub first_dir { - shift; - foreach (@_) { return $_ if -d } - return; -} - -=head2 first_path - - my $path = $ENV{PATH}; - $dir = $util->first_path($path); - -Takes the $path string and splits it into a list of directory paths, based on -the path demarcator on the local file system. Then calls C<first_dir()> to -return the first directoy in the path list that exists on the local file -system. The path demarcator is specified for the following file systems: - -=over 4 - -=item MacOS: "," - -=item MSWin32: ";" - -=item os2: ";" - -=item VMS: undef - -This method always returns undef on VMS. Patches welcome. - -=item epoc: undef - -This method always returns undef on epoch. Patches welcome. - -=item Unix: ":" - -All other operating systems are assumed to be Unix-based. - -=back - -=cut - -sub first_path { - return unless $path_dem; - shift->first_dir(split /$path_dem/, shift) -} - -=head2 first_file - - my $file = $util->first_file(@filelist); - -Examines each of the files in @filelist and returns the first one that exists -on the file system. The file must be a regular file -- directories will be -ignored. - -=cut - -sub first_file { - shift; - foreach (@_) { return $_ if -f } - return; -} - -=head2 first_exe - - my $exe = $util->first_exe(@exelist); - -Examines each of the files in @exelist and returns the first one that exists -on the file system as an executable file. Directories will be ignored. - -=cut - -sub first_exe { - shift; - foreach (@_) { return $_ if -f && -x } - return; -} - -=head2 first_cat_path - - my $file = $util->first_cat_path('ick.txt', @paths); - $file = $util->first_cat_path(['this.txt', 'that.txt'], @paths); - -The first argument to this method may be either a file or directory base name -(that is, a file or directory name without a full path specification), or a -reference to an array of file or directory base names. The remaining arguments -constitute a list of directory paths. C<first_cat_path()> processes each of -these directory paths, concatenates (by the method native to the local -operating system) each of the file or directory base names, and returns the -first one that exists on the file system. - -For example, let us say that we were looking for a file called either F<httpd> -or F<apache>, and it could be in any of the following paths: -F</usr/local/bin>, F</usr/bin/>, F</bin>. The method call looks like this: - - my $httpd = $util->first_cat_path(['httpd', 'apache'], '/usr/local/bin', - '/usr/bin/', '/bin'); - -If the OS is a Unix variant, C<first_cat_path()> will then look for the first -file that exists in this order: - -=over 4 - -=item /usr/local/bin/httpd - -=item /usr/local/bin/apache - -=item /usr/bin/httpd - -=item /usr/bin/apache - -=item /bin/httpd - -=item /bin/apache - -=back - -The first of these complete paths to be found will be returned. If none are -found, then undef will be returned. - -=cut - -sub first_cat_path { - my $self = shift; - my $files = ref $_[0] ? shift() : [shift()]; - foreach my $p (@_) { - foreach my $f (@$files) { - my $path = $self->catfile($p, $f); - return $path if -e $path; - } - } - return; -} - -=head2 first_cat_dir - - my $dir = $util->first_cat_dir('ick.txt', @paths); - $dir = $util->first_cat_dir(['this.txt', 'that.txt'], @paths); - -Funtionally identical to C<first_cat_path()>, except that it returns the -directory path in which the first file was found, rather than the full -concatenated path. Thus, in the above example, if the file found was -F</usr/bin/httpd>, while C<first_cat_path()> would return that value, -C<first_cat_dir()> would return F</usr/bin> instead. - -=cut - -sub first_cat_dir { - my $self = shift; - my $files = ref $_[0] ? shift() : [shift()]; - foreach my $p (@_) { - foreach my $f (@$files) { - my $path = $self->catfile($p, $f); - return $p if -e $path; - } - } - return; -} - -=head2 first_cat_exe - - my $exe = $util->first_cat_exe('ick.txt', @paths); - $exe = $util->first_cat_exe(['this.txt', 'that.txt'], @paths); - -Funtionally identical to C<first_cat_path()>, except that it returns the full -path to the first executable file found, rather than simply the first file -found. - -=cut - -sub first_cat_exe { - my $self = shift; - my $files = ref $_[0] ? shift() : [shift()]; - foreach my $p (@_) { - foreach my $f (@$files) { - my $path = $self->catfile($p, $f); - return $path if -f $path && -x $path; - } - } - return; -} - -=head2 search_file - - my $file = 'foo.txt'; - my $regex = qr/(text\s+to\s+find)/; - my $value = $util->search_file($file, $regex); - -Opens C<$file> and executes the C<$regex> regular expression against each line -in the file. Once the line matches and one or more values is returned by the -match, the file is closed and the value or values returned. - -For example, say F<foo.txt> contains the line "Version 6.5, patch level 8", -and you need to grab each of the three version parts. All three parts can -be grabbed like this: - - my $regex = qr/Version\s+(\d+)\.(\d+),[^\d]*(\d+)/; - my @nums = $util->search_file($file, $regex); - -Now C<@nums> will contain the values C<(6, 5, 8)>. Note that in a scalar -context, the above search would yeild an array reference: - - my $regex = qr/Version\s+(\d+)\.(\d+),[^\d]*(\d+)/; - my $nums = $util->search_file($file, $regex); - -So now C<$nums> contains C<[6, 5, 8]>. The same does not hold true if the -match returns only one value, however. Say F<foo.txt> contains the line -"king of the who?", and you wish to know who the king is king of. Either -of the following two calls would get you the data you need: - - my $minions = $util->search_file($file, qr/King\s+of\s+(.*)/); - my @minions = $util->search_file($file, qr/King\s+of\s+(.*)/); - -In the first case, because the regular expression contains only one set of -parentheses, C<search_file()> will simply return that value: C<$minions> -contains the string "the who?". In the latter case, C<@minions> of course -contains a single element: C<("the who?")>. - -Note that a regular expression without parentheses -- that is, one that -doesn't grab values and put them into $1, $2, etc., will never successfully -match a line in this method. You must include something to parentetically -match. If you just want to know the value of what was matched, parenthesize -the whole thing and if the value returns, you have a match. Also, if you need -to match patterns across lines, try using multiple regular expressions with -C<multi_search_file()>, instead. - -=cut - -sub search_file { - my ($self, $file, $regex) = @_; - return unless $file && $regex; - open F, "<$file" or Carp::croak "Cannot open $file: $!\n"; - my @ret; - while (<F>) { - # If we find a match, we're done. - (@ret) = /$regex/ and last; - } - close F; - # If the match returned an more than one value, always return the full - # array. Otherwise, return just the first value in a scalar context. - return unless @ret; - return wantarray ? @ret : $#ret <= 0 ? $ret[0] : \@ret; -} - -=head2 multi_search_file - - my @regexen = (qr/(one)/, qr/(two)\s+(three)/); - my @matches = $util->multi_search_file($file, @regexen); - -Like C<search_file()>, this mehod opens C<$file> and parses it for regular -expresion matches. This method, however, can take a list of regular -expressions to look for, and will return the values found for all of them. -Regular expressions that match and return multiple values will be returned as -array referernces, while those that match and return a single value will -return just that single value. - -For example, say you are parsing a file with lines like the following: - - #define XML_MAJOR_VERSION 1 - #define XML_MINOR_VERSION 95 - #define XML_MICRO_VERSION 2 - -You need to get each of these numbers, but calling C<search_file()> for each -of them would be wasteful, as each call to C<search_file()> opens the file and -parses it. With C<multi_search_file()>, on the other hand, the file will be -opened only once, and, once all of the regular expressions have returned -matches, the file will be closed and the matches returned. - -Thus the above values can be collected like this: - - my @regexen = ( qr/XML_MAJOR_VERSION\s+(\d+)$/, - qr/XML_MINOR_VERSION\s+(\d+)$/, - qr/XML_MICRO_VERSION\s+(\d+)$/ ); - - my @nums = $file->multi_search_file($file, @regexen); - -The result will be that C<@nums> contains C<(1, 95, 2)>. Note that -C<multi_file_search()> tries to do the right thing by only parsing the file -until all of the regular expressions have been matched. Thus, a large file -with the values you need near the top can be parsed very quickly. - -As with C<search_file()>, C<multi_search_file()> can take regular expressions -that match multiple values. These will be returned as array references. For -example, say the file you're parsing has files like this: - - FooApp Version 4 - Subversion 2, Microversion 6 - -To get all of the version numbers, you can either use three regular -expressions, as in the previous example: - - my @regexen = ( qr/FooApp\s+Version\s+(\d+)$/, - qr/Subversion\s+(\d+),/, - qr/Microversion\s+(\d$)$/ ); - - my @nums = $file->multi_search_file($file, @regexen); - -In which case C<@nums> will contain C<(4, 2, 6)>. Or, you can use just two -regular expressions: - - my @regexen = ( qr/FooApp\s+Version\s+(\d+)$/, - qr/Subversion\s+(\d+),\s+Microversion\s+(\d$)$/ ); - - my @nums = $file->multi_search_file($file, @regexen); - -In which case C<@nums> will contain C<(4, [2, 6])>. Note that the two -parentheses that return values in the second regular expression cause the -matches to be returned as an array reference. - -=cut - -sub multi_search_file { - my ($self, $file, @regexen) = @_; - return unless $file && @regexen; - my @each = @regexen; - open F, "<$file" or Carp::croak "Cannot open $file: $!\n"; - my %ret; - while (my $line = <F>) { - my @splice; - # Process each of the regular expresssions. - for (my $i = 0; $i < @each; $i++) { - if ((my @ret) = $line =~ /$each[$i]/) { - # We have a match! If there's one match returned, just grab - # it. If there's more than one, keep it as an array ref. - $ret{$each[$i]} = $#ret > 0 ? \@ret : $ret[0]; - # We got values for this regex, so not its place in the @each - # array. - push @splice, $i; - } - } - # Remove any regexen that have already found a match. - for (@splice) { splice @each, $_, 1 } - # If there are no more regexes, we're done -- no need to keep - # processing lines in the file! - last unless @each; - } - close F; - return unless %ret; - return wantarray ? @ret{@regexen} : \@ret{@regexen}; -} - -1; -__END__ - -=head1 BUGS - -Report all bugs via the CPAN Request Tracker at -L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=App-Info>. - -=head1 AUTHOR - -David Wheeler <L<david@wheeler.net|"david@wheeler.net">> - -=head1 SEE ALSO - -L<App::Info|App::Info>, L<File::Spec|File::Spec>, -L<App::Info::HTTPD::Apache|App::Info::HTTPD::Apache> -L<App::Info::RDBMS::PostgreSQL|App::Info::RDBMS::PostgreSQL> - -=head1 COPYRIGHT AND LICENSE - -Copyright (c) 2002, David Wheeler. All Rights Reserved. - -This module is free software; you can redistribute it and/or modify it under the -same terms as Perl itself. - -=cut |