Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

INI::Library

by DamnDirtyApe (Curate)
on Jul 29, 2002 at 08:54 UTC ( #185917=sourcecode: print w/ replies, xml ) Need Help??

Category: Text Processing
Author/Contact Info DamnDirtyApe <douggorley@shaw.ca>
Description: I wrote this module because I wanted a super-simple way to separate my SQL queries from my application code.
package INI::Library ;

=head1 NAME

INI::Library - A module for managing simple libraries
stored in INI-like files.

=head1 SYNOPSIS

  use INI::Library ;
    
  my $sql = new INI::Library { lib => 'sql.lib' } ;

  ## Ask for a library entry by name...
  my $query = $sql->retr( 'some_sql_query' ) ;

  ## Add or update an entry...
  $sql->set( 'yet_another_query', <<'END' ) ;
  SELECT foo
  FROM   bar
  WHERE  zoot = 1
  END

  ## Remove an entry from the library...
  $sql->drop( 'one_more_query' ) ;

  ## List the entries in the library...
  print join( ' : ', $sql->elements ), "\n" ;

  ## Dump the contents of the library to a string...
  my $lib_str = $sql->ini_out ;

  ## Write the INI library to disk...
  $sql->write ;

=head1 LIBRARY FILE FORMAT

The format for the library files looks a little like an INI file (henc
+e
the name.)  However, unlike an INI file, it does not handle key=value 
+pairs
which are divided into sections.  Library entry names are on a line by
themselves, enclosed in square brackets.  Whatever occurs until the
next title tag is the value of the library entry.  Blank lines, pound
signs (#) and C++ style comments (//) are all discarded.

A sample library file might look like this:

  ## A sample library file

  [get_survey_questions]
  select   question_no,
           question_text
  from     question
  where    survey_id = ?
  order by question_no

  [get_survey_info]
  select title,
         date_format( open_date, '%Y%m%d' ) as open_date, 
         date_format( close_date, '%Y%m%d' ) as close_date, 
         template_file
  from   survey
  where  survey_id = ?


=cut

use strict ;
use warnings ;

=head1 OBJECT METHODS

=over 4

=item PACKAGE-E<gt>new( HASHREF )

Create a new library handle.  Currently, the only argument supported i
+n
the hashref is C<lib>, which refers to the file containing the INI
library.

=cut

sub new
{
    my $proto = shift ;
    my $options = shift ;
    my $self = {
                 'options'  => $options,
                 'contents' => undef
               } ;
    {
        my $curr_name = '' ;
        open INI, $self->{'options'}->{'lib'}
          or die "Cannot open $self->{'options'}->{'lib'}: $!" ;
        while ( <INI> )
        {
            next if m{^\s*$} ;
            next if m{^\s*#} ;
            next if m{^\s*//} ;
            if ( m{^\[([^\]]+)\]} )
            {
                $curr_name = $1 ;
                next ;
            }
            if ( $curr_name )
            {
                $self->{'contents'}->{$curr_name} .= $_ ;
            }
        }
    }
    bless $self, $proto ;
    return $self ;
}

=item $OBJ-E<gt>retr( NAME )

Returns the library entry referenced by NAME.

=cut 

sub retr
{
    my ( $self, $entity_name ) = @_ ;
    return $self->{'contents'}->{$entity_name} ;
}

=item $OBJ-E<gt>set( NAME, VALUE )

Sets the library entry NAME to VALUE.  This is used both to create new
library entries and to update existing ones.

=cut

sub set
{
    my ( $self, $entity_name, $entity ) = @_ ;
    $self->{'contents'}->{$entity_name} = $entity ;
    return $self ;
}

=item $OBJ-E<gt>drop( NAME )

Drops entry NAME form the library.

=cut

sub drop
{
    my ( $self, $entity_name ) = @_ ;
    delete $self->{'contents'}->{$entity_name} ;
    return $self ;
}

=item $OBJ-E<gt>elements

Returns a list of all entry names in the library.

=cut 

sub elements
{
    my $self = shift ;
    return sort keys %{$self->{'contents'}} ;
}

=item $OBJ-E<gt>ini_out

Returns a string containing the library contents in the same
INI format that the module reads from.

=cut 

sub ini_out
{
    my $self   = shift ;
    my $output = '' ;
    foreach ( sort keys %{$self->{'contents'}} )
    {
        $output .= sprintf "[%s]\n%s\n", $_, $self->{'contents'}->{$_}
+ ;
    }
    return $output ;
}

=item $OBJ-E<gt>write

Writes the library to the file named in C<lib>.

=cut

sub write
{
    my $self = shift ;
    open OUT, ">$self->{'options'}->{'lib'}"
      or die "Cannot open $self->{'options'}->{'lib'}: $!" ;
    print OUT $self->ini_out ;
    close OUT ;
}

=back

=head1 AUTHOR

Doug Gorley E<lt>douggorley@shaw.caE<gt>

=cut

1 ;

__END__

Comment on INI::Library
Download Code
Re: INI::Library
by simon.proctor (Vicar) on Jul 29, 2002 at 11:24 UTC
    Hi,

    I was thinking about your package name and was wondering whether you would consider Library::INI or Library::Config::Ini. Because then you have the kind of namespace you could add to if need be (as your project grows for example). You could also call it Config::Ini and pair it up with Config::IniFiles (where that uses name=value pairs) though I personally wouldn't :P. Nice snippet though :)
Re: INI::Library
by gav^ (Curate) on Jul 29, 2002 at 17:46 UTC
    I quite like your idea, it's nice and lightweight. One suggestion might be to change the name to be in the SQL:: namespace so it is easier to find.

    Other other interesting modules that try to solve this problem (not embedding SQL in your perl scripts) include SQL::Catalog, SQL::Snippet, DBIx::Librarian, and Ima::DBI.

    gav^

Back to Code Catacombs

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://185917]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (10)
As of 2015-07-07 06:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (87 votes), past polls