This repository has been archived by the owner on Dec 11, 2017. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
324 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package Mango::GridFS; | ||
use Mojo::Base -base; | ||
|
||
use Mango::GridFS::Reader; | ||
use Mango::GridFS::Writer; | ||
|
||
has 'db'; | ||
has prefix => 'fs'; | ||
|
||
sub chunks { $_[0]->db->collection($_[0]->prefix . '.chunks') } | ||
sub files { $_[0]->db->collection($_[0]->prefix . '.files') } | ||
|
||
sub reader { Mango::GridFS::Reader->new(gridfs => shift) } | ||
sub writer { Mango::GridFS::Writer->new(gridfs => shift) } | ||
|
||
1; | ||
|
||
=encoding utf8 | ||
=head1 NAME | ||
Mango::GridFS - GridFS | ||
=head1 SYNOPSIS | ||
use Mango::GridFS; | ||
my $gridfs = Mango::GridFS->new(db => $db); | ||
=head1 DESCRIPTION | ||
L<Mango::GridFS> is an interface for MongoDB GridFS access. | ||
=head1 ATTRIBUTES | ||
L<Mango::GridFS> implements the following attributes. | ||
=head2 db | ||
my $db = $gridfs->db; | ||
$gridfs = $gridfs->db(Mango::Database->new); | ||
L<Mango::Database> object GridFS belongs to. | ||
=head2 prefix | ||
my $db = $gridfs->prefix; | ||
$gridfs = $gridfs->prefix('foo'); | ||
Prefix for GridFS collections, defaults to C<fs>. | ||
=head1 METHODS | ||
L<Mango::GridFS> inherits all methods from L<Mojo::Base> and implements the | ||
following new ones. | ||
=head2 chunks | ||
my $chunks = $gridfs->chunks; | ||
Get L<Mango::Collection> object for C<chunks> collection. | ||
=head2 files | ||
my $files = $gridfs->files; | ||
Get L<Mango::Collection> object for C<files> collection. | ||
=head2 reader | ||
my $reader = $gridfs->reader; | ||
Get L<Mango::GridFS::Reader> object. | ||
=head2 writer | ||
my $writer = $gridfs->writer; | ||
Get L<Mango::GridFS::Writer> object. | ||
=head1 SEE ALSO | ||
L<Mango>, L<Mojolicious::Guides>, L<http://mojolicio.us>. | ||
=cut |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package Mango::GridFS::Reader; | ||
use Mojo::Base -base; | ||
|
||
has 'gridfs'; | ||
|
||
sub open { | ||
my ($self, $oid) = @_; | ||
my $file = $self->gridfs->files->find_one($oid); | ||
$self->{id} = $oid; | ||
$self->{chunk_size} = $file->{chunkSize}; | ||
$self->{len} = $file->{length}; | ||
} | ||
|
||
sub read { | ||
my $self = shift; | ||
|
||
$self->{pos} //= 0; | ||
return undef if $self->{pos} >= $self->{len}; | ||
my $n = $self->{pos} / $self->{chunk_size}; | ||
my $chunk | ||
= $self->gridfs->chunks->find_one({files_id => $self->{id}, n => $n}); | ||
my $data = $chunk->{data}; | ||
$self->{pos} += length $data; | ||
return $data; | ||
} | ||
|
||
1; | ||
|
||
=encoding utf8 | ||
=head1 NAME | ||
Mango::GridFS::Reader - GridFS reader | ||
=head1 SYNOPSIS | ||
use Mango::GridFS::Reader; | ||
my $reader = Mango::GridFS::Reader->new(gridfs => $gridfs); | ||
=head1 DESCRIPTION | ||
L<Mango::GridFS::Reader> reads files from GridFS. | ||
=head1 ATTRIBUTES | ||
L<Mango::GridFS::Reader> implements the following attributes. | ||
=head2 gridfs | ||
my $gridfs = $reader->gridfs; | ||
$reader = $reader->gridfs(Mango::GridFS->new); | ||
L<Mango::GridFS> object this reader belongs to. | ||
=head1 METHODS | ||
L<Mango::GridFS::Reader> inherits all methods from L<Mojo::Base> and | ||
implements the following new ones. | ||
=head2 open | ||
$reader->open(bson_oid '1a2b3c4e5f60718293a4b5c6'); | ||
Open file. | ||
=head2 read | ||
my $chunk = $reader->read; | ||
Read chunk. | ||
=head1 SEE ALSO | ||
L<Mango>, L<Mojolicious::Guides>, L<http://mojolicio.us>. | ||
=cut |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package Mango::GridFS::Writer; | ||
use Mojo::Base -base; | ||
|
||
use Mango::BSON qw(bson_bin bson_doc bson_oid bson_time bson_true); | ||
|
||
has chunk_size => 262144; | ||
has 'gridfs'; | ||
has id => sub {bson_oid}; | ||
|
||
sub close { | ||
my $self = shift; | ||
|
||
$self->_chunk; | ||
|
||
my $gridfs = $self->gridfs; | ||
$gridfs->files->ensure_index({filename => 1}); | ||
$gridfs->chunks->ensure_index(bson_doc(files_id => 1, n => 1), | ||
{unique => bson_true}); | ||
|
||
my $command = bson_doc | ||
filemd5 => $self->id, | ||
root => $gridfs->prefix; | ||
my $md5 = $gridfs->db->command($command)->{md5}; | ||
|
||
$gridfs->files->insert( | ||
{ | ||
_id => $self->id, | ||
length => $self->{len}, | ||
chunkSize => $self->chunk_size, | ||
uploadDate => bson_time, | ||
md5 => $md5 | ||
} | ||
); | ||
} | ||
|
||
sub write { | ||
my ($self, $chunk) = @_; | ||
$self->{buffer} .= $chunk; | ||
$self->{len} += length $chunk; | ||
$self->_chunk while length $self->{buffer} > $self->chunk_size; | ||
} | ||
|
||
sub _chunk { | ||
my $self = shift; | ||
|
||
my $chunk = substr $self->{buffer}, 0, $self->chunk_size, ''; | ||
return unless length $chunk; | ||
|
||
my $n = $self->{n}++; | ||
my $chunks = $self->gridfs->chunks; | ||
$chunks->insert({files_id => $self->id, n => $n, data => bson_bin($chunk)}); | ||
} | ||
|
||
1; | ||
|
||
=encoding utf8 | ||
=head1 NAME | ||
Mango::GridFS::Writer - GridFS writer | ||
=head1 SYNOPSIS | ||
use Mango::GridFS::Writer; | ||
my $writer = Mango::GridFS::Writer->new(gridfs => $gridfs); | ||
=head1 DESCRIPTION | ||
L<Mango::GridFS::Writer> writes files to GridFS. | ||
=head1 ATTRIBUTES | ||
L<Mango::GridFS::Writer> implements the following attributes. | ||
=head2 chunk_size | ||
my $size = $writer->chunk_size; | ||
$writer = $writer->chunk_size(1024); | ||
Chunk size in bytes, defaults to C<262144>. | ||
=head2 gridfs | ||
my $gridfs = $writer->gridfs; | ||
$writer = $writer->gridfs(Mango::GridFS->new); | ||
L<Mango::GridFS> object this writer belongs to. | ||
=head2 id | ||
my $id = $writer->id; | ||
$writer = $writer->id(bson_oid '1a2b3c4e5f60718293a4b5c6'); | ||
Object id of file, defaults to a newly generated one. | ||
=head1 METHODS | ||
L<Mango::GridFS::Writer> inherits all methods from L<Mojo::Base> and | ||
implements the following new ones. | ||
=head2 close | ||
$writer->close; | ||
Close file. | ||
=head2 write | ||
$writer->write('hello world!'); | ||
Write chunk. | ||
=head1 SEE ALSO | ||
L<Mango>, L<Mojolicious::Guides>, L<http://mojolicio.us>. | ||
=cut |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
use Mojo::Base -strict; | ||
|
||
use Test::More; | ||
use Mango; | ||
|
||
plan skip_all => 'set TEST_ONLINE to enable this test' | ||
unless $ENV{TEST_ONLINE}; | ||
|
||
# Cleanup before start | ||
my $mango = Mango->new($ENV{TEST_ONLINE}); | ||
my $gridfs = $mango->db->gridfs; | ||
$gridfs->$_->remove for qw(files chunks); | ||
|
||
# Blocking roundtrip | ||
my $writer = $gridfs->writer; | ||
my $oid = $writer->id; | ||
isa_ok $oid, 'Mango::BSON::ObjectID', 'right class'; | ||
$writer->write('hello '); | ||
$writer->write('world!'); | ||
$writer->close; | ||
my $reader = $gridfs->reader; | ||
$reader->open($oid); | ||
my $data; | ||
while (defined(my $chunk = $reader->read)) { $data .= $chunk } | ||
is $data, 'hello world!', 'right content'; | ||
$gridfs->$_->drop for qw(files chunks); | ||
|
||
done_testing(); |