package PITA::Guest::Storage::Simple; =pod =head1 NAME PITA::Guest::Storage::Simple - A (relatively) simple Guest Storage object =head1 DESCRIPTION The L class provides an API for cataloguing and retrieving Guest images, with all the data stored on the filesystem using the native XML file formats. Guest image location and searching is done the long way, with no indexing. =head1 METHODS =cut use strict; use Carp (); use File::Spec (); use File::Path (); use base 'PITA::Guest::Storage'; use vars qw{$VERSION $LOCKFILE}; BEGIN { $VERSION = '0.40'; $LOCKFILE = 'PITA-Guest-Storage-Simple.lock'; } ##################################################################### # Constructor and Accessors =pod =head2 new my $store = PITA::Guest::Storage::Simple->new( storage_dir => '/var/pita/storage', ); The C method creates a new simple storage object. It takes a single named param Returns a C object, or throws an exception on error. =cut sub new { my $class = shift; my $self = $class->SUPER::new(@_); # Check params unless ( $self->storage_dir and -d $self->storage_dir and -w _ ) { Carp::croak('The storage_dir is not a writable directory'); } $self; } =pod =head2 storage_dir The C accessor returns the location of the directory that serves as the root of the data store. =cut sub storage_dir { $_[0]->{storage_dir}; } ##################################################################### # PITA::Guest::Storage::Simple Methods =pod =head2 create my $store = PITA::Guest::Storage::Simple->new( storage_dir => ); The C constructor creates a new C repository. =cut sub create { my $class = shift; my $self = bless { @_ }, $class; # The storage_dir should not exist, we will create it my $storage_dir = $self->storage_dir; unless ( $storage_dir ) { Carp::croak("The storage_dir param was not provided"); } if ( -d $storage_dir ) { Carp::croak("The storage_dir '$storage_dir' already exists"); } eval { File::Path::mkpath( $storage_dir, 1, 0711 ) }; if ( $@ ) { Carp::croak("Failed to create the storage_dir '$storage_dir': $@"); } # Create the lock file and take it unless ( $self->storage_lock_take ) { # In create, a false return is a bigger problem Carp::croak('Failed to create and take the lock file'); } $self; } =pod =head2 storage_lock The C method returns the location of the storage lock file. The lock file is taken by a C object at constructor-time, and hold for the duration of the object's existance. Returns a file path string. =cut sub storage_lock { File::Spec->catfile( $_[0]->storage_dir, $LOCKFILE ); } =pod =head2 storage_lock_take The C method takes a lock on the C file, creating it if needed (in the C method case). It does not wait to take the lock, failing immediately if the lock cannot be taken. Returns true if the lock is taken, false if the lock cannot be taken, or throws an exception on error. =cut sub storage_lock_take { my $self = shift; my $lock = $self->storage_lock; # Take the lock # Create the file if needed unless ( -f $lock ) { local *LOCKFILE; open( LOCKFILE, ">$lock" ) or Carp::croak("open: $!" ); print LOCKFILE "A lockfile" or Carp::croak("print: $!"); close LOCKFILE or Carp::croak("close: $!"); } # Store the lock in the object $self->{storage_lock_object} = 1; ### Temporary object 1; } =pod =head2 storage_lock_object If we have a lock on the storage, returns the lock object for the lock. Returns a C object or false if we do not have a lock =cut sub storage_lock_object { $_[0]->{storage_lock_object}; } =pod =head2 storage_lock_release If we have a lock on the storage, release the lock. Returns true once the lock is released, or throws an exception on error or if the object does not hold the lock. =cut sub storage_lock_delete { my $self = shift; unless ( $self->storage_lock_object ) { Carp::croak('Cannot release a lock that we do not hold'); } delete $self->{storage_lock_object}; 1; } ##################################################################### # PITA::Guest::Storage Methods sub add_guest { my $self = shift; die 'CODE INCOMPLETE'; } sub guest { my $self = shift; die 'CODE INCOMPLETE'; } sub guests { my $self = shift; die 'CODE INCOMPLETE'; } sub platform { my $self = shift; die 'CODE INCOMPLETE'; } sub platforms { my $self = shift; die 'CODE INCOMPLETE'; } 1; =pod =head1 SUPPORT Bugs should be reported via the CPAN bug tracker at L For other issues, contact the author. =head1 AUTHOR Adam Kennedy Eadamk@cpan.orgE =head1 SEE ALSO L, L, L =head1 COPYRIGHT Copyright 2005, 2006 Adam Kennedy. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. The full text of the license can be found in the LICENSE file included with this module. =cut