1 package CXGN
::FileRepository
;
2 use namespace
::autoclean
;
4 use Moose
::Util
::TypeConstraints
;
11 use CXGN
::FileRepository
::VersionedFile
;
15 CXGN::FileRepository - versioned file repository
19 # open a repository that contains versioned files
20 my $repos = CXGN::FileRepository
21 ->new( '/some/directory/somewhere/' );
24 # get a certain CXGN::FileRepository::VersionedFile for the file in
25 # FileClass 'MyFoo' that has metadata bar => 'baz', boo => 'blorg'
26 # DIES if the given attributes are not specific enough
27 my $versionedfile = $repos->get_vf( class => 'MyFoo',
32 # same as get_vf, but returns a Path::Class::File object for the
33 # current version of the specified file, or nothing if there is no
35 my $file = $repos->get_file( metadata... )
37 # function to search for VersionedFiles matching some attributes
38 my @versionedfiles = $repos->search_vfs( class => 'MyBar',
39 something => 'something',
42 # same as above, but returns Path::Class::File objects for current
44 my @files = $repos->search_vfs( same... )
46 # publish a new version of the MyFoo in $versionedfile, and
47 # remove/unpublish all the files in @versionedfiles, all in one
48 # CXGN::Publish transaction
50 $repos->publish( $versionedfile->publish_new_version( '/foo/bar.txt' ),
51 map $_->publish_remove, @versionedfiles
57 Representation of a file repository of clone sequences, annotations,
74 Attributes are read only unless otherwise noted.
76 basedir - (Path::Class::Dir) base directory for this file repository.
78 create - boolean, whether this repos is set to create its own base
81 publisher - CXGN::Publish object to use for publishing files to this
86 # and define the basedir attribute
89 isa
=> 'Path::Class::Dir',
99 isa
=> 'CXGN::Publish',
102 my $p = CXGN
::Publish
->new;
106 handles
=> ['publish'],
115 ->new( '/data/prod/public/foo' )
116 Desc : open an existing file repository, dies if does
117 not exist and create => 1 not passed
118 Args : basedir => string dirname or Path::Class::Dir,
119 create => 1, #< will create dir and parent dirs if not
122 string dirname or Path::Class::Dir, interpreted
123 as the basedir you want
124 Ret : FileRepository object
131 my %args = @_ == 1 ?
(basedir
=> @_) : @_;
133 # check required basedir
134 defined $args{basedir
}
135 or croak
"no 'basedir' argument passed, and it is required";
137 # coerce basedir to Path::Class::Dir
138 unless( ref $args{basedir
} && $args{basedir
}->can('stringify') ) {
139 $args{basedir
} = Path
::Class
::Dir
->new( "$args{basedir}" );
142 # create our basedir if create was passed
143 my $d = $args{basedir
}->stringify;
146 or croak
"basedir '$d' does not exist, maybe you want to specify create => 1 to create it?\n";
148 or croak
"$! creating '$d'";
149 -d
$d or die 'sanity check failed';
152 return $class->SUPER::BUILDARGS
( %args );
158 Usage: $repos->publish( [op], [op] )
159 Desc : do a publish operation using this repo's publisher object
160 Args : publish operation arrayrefs,
161 same as L<CXGN::Publish> publish()
162 Ret : nothing meaningful
163 Side Effects: does publish operations
167 # this method created by 'handles' delegation on publisher attribute
171 Usage: my @files = $repo->search_files( %args );
172 Desc : search for files present in their current versions in the
174 Args : search criteria as a hash-list
175 Ret : list of matching files as Path::Class::File objects (possibly
176 empty), in no particular order
180 # get a list of files in the current version of the repo that are
181 # CloneSequence files, of type fasta, belonging to the given
183 my @files = $repo->search_files( class => 'CloneSequence',
194 # return the current_file, for those VFs that have them
195 map $_->current_file || (), $self->search_vfs( @_ );
200 Same as search_files, but returns CXGN::FileRepository::VersionedFile
201 objects for all matching files that have already been published.
206 my ($self, %conditions) = @_;
208 my $fileclass_condition = delete $conditions{class};
209 my @classes = $fileclass_condition
210 ?
($self->_find_class_or_die($fileclass_condition))
211 : $self->file_classes;
213 return map { $_->search_vfs( %conditions ) }
220 Same as search_files, but returns just one Path::Class::File, or
221 nothing if no such file currently exists. Dies if the search
222 conditions are not specific enough to specify exactly one file.
229 my $r = $self->get_vf(@_);
231 return $r->current_file if $r;
238 Same as search_files, but returns just one VersionedFile, regardless
239 of whether a file currently exists for it.
248 my $class = delete $conditions{class}
249 or croak
"must specify a class in call to get_vf";
251 my $fileclass_obj = $self->_find_class_or_die($class);
253 return $fileclass_obj->get_vf( %conditions );
257 sub _find_class_or_die
{
258 my ( $self, $classname ) = @_;
260 my $class = ref $self;
263 "${class}::FileClass::$classname",
266 foreach my $class ( @search_classes ) {
267 unless( Class
::MOP
::is_class_loaded
($class) ) {
268 #it is not loaded, try to load it
269 eval { Class
::MOP
::load_class
( $class ) };
273 return $class->new( repository
=> $self );
276 confess
"could not find file class matching '$classname', searched for ".join(',',@search_classes);
282 Usage: my @classes = $repos->file_classes
283 Desc : list all the file classes present in the repos
285 Ret : list of file class objects for this repos
289 # makes a method _fileslots() that instantiates a list of all FileSlot
290 # objects in this namespace, except those which end with Base
291 use Module
::Pluggable
::Object
();
292 use Devel
::InnerPackage
();
296 my $class = ref $self;
298 my $exclude_pat = qr/Base$/; #< exclude all packages ending in Base
299 my $fileclass_base = $class."::FileClass";
302 Module
::Pluggable
::Object
303 ->new( exclude
=> $exclude_pat,
304 search_path
=> $fileclass_base,
311 grep {$_ !~ $exclude_pat}
312 Devel
::InnerPackage
::list_packages
($fileclass_base);
314 #warn "$class got file classes: ".join ', ', @fileclasses;
316 return sort map {$_->new( repository
=> $self ) } @fileclasses;
322 Robert Buels, E<lt>rmb32@cornell.eduE<gt>
326 Robert Buels, E<lt>rmb32@cornell.eduE<gt>
328 =head1 COPYRIGHT & LICENSE
330 Copyright 2009 Boyce Thompson Institute for Plant Research
332 This program is free software; you can redistribute it and/or modify
333 it under the same terms as Perl itself.
338 __PACKAGE__
->meta->make_immutable;