Bio-JBrowse-Store-NCList
view release on metacpan or search on metacpan
lib/Bio/JBrowse/Store/NCList/JSONFileStorage.pm view on Meta::CPAN
use strict;
use warnings;
use File::Spec ();
use File::Path ();
use JSON 2 ();
use IO::File;
use Fcntl ":flock";
use PerlIO::gzip;
use constant DEFAULT_MAX_JSON_DEPTH => 2048;
sub new {
my ($class, $outDir, $compress, $opts) = @_;
# create JSON object
my $json = JSON->new->relaxed->max_depth( DEFAULT_MAX_JSON_DEPTH );
# set opts
if (defined($opts) and ref($opts) eq 'HASH') {
for my $method (keys %$opts) {
$json->$method( $opts->{$method} );
}
}
my $self = {
outDir => $outDir,
ext => $compress ? ".jsonz" : ".json",
compress => $compress,
json => $json
};
bless $self, $class;
File::Path::mkpath( $outDir ) unless (-d $outDir);
return $self;
}
sub _write_htaccess {
my ( $self ) = @_;
if( $self->{compress} && ! $self->{htaccess_written} ) {
my $hn = File::Spec->catfile( $self->{outDir}, '.htaccess' );
return if -e $hn;
open my $h, '>', $hn or die "$! writing $hn";
my @extensions = qw( .jsonz .txtz .txt.gz );
my $re = '('.join('|',@extensions).')$';
$re =~ s/\./\\./g;
print $h <<EOA;
# This Apache .htaccess file is for
# serving precompressed files (@extensions) with the proper
# Content-Encoding HTTP headers. In order for Apache to pay attention
# to this, its AllowOverride configuration directive for this
# filesystem location must allow FileInfo overrides.
<IfModule mod_gzip.c>
mod_gzip_item_exclude "$re"
</IfModule>
<IfModule setenvif.c>
SetEnvIf Request_URI "$re" no-gzip dont-vary
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "$re">
Header onsuccess set Content-Encoding gzip
</FilesMatch>
</IfModule>
EOA
$self->{htaccess_written} = 1;
}
}
sub fullPath {
my ($self, $path) = @_;
return File::Spec->join($self->{outDir}, $path);
}
sub ext {
return shift->{ext};
}
sub encodedSize {
my ($self, $obj) = @_;
return length($self->{json}->encode($obj));
}
sub put {
my ($self, $path, $toWrite) = @_;
$self->_write_htaccess;
my $file = $self->fullPath($path);
my $fh = IO::File->new( $file, O_WRONLY | O_CREAT )
or die "couldn't open $file: $!";
flock $fh, LOCK_EX;
$fh->seek(0, SEEK_SET);
$fh->truncate(0);
if ($self->{compress}) {
binmode($fh, ":gzip")
or die "couldn't set binmode: $!";
}
$fh->print($self->{json}->encode($toWrite))
or die "couldn't write to $file: $!";
$fh->close()
or die "couldn't close $file: $!";
}
sub get {
my ($self, $path, $default) = @_;
my $file = $self->fullPath($path);
if (-s $file) {
my $OLDSEP = $/;
my $fh = IO::File->new( $file, O_RDONLY )
or die "couldn't open $file: $!";
( run in 0.691 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )