Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
2.0
- Promises support for all non-blocking methods
- Fix Mojolicious 8.x compatibility
- Use official MongoDB BSON parser

1.31
- Fix typo in the synopsis (#33)

Expand Down
5 changes: 4 additions & 1 deletion Makefile.PL
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ WriteMakefile(
},
no_index => {directory => ['t']}
},
PREREQ_PM => {Mojolicious => '5.40'},
PREREQ_PM => {
Mojolicious => '8.40',
BSON => '1.12.2',
},
test => {TESTS => 't/*.t t/*/*.t'}
);
23 changes: 10 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@

Pure-Perl non-blocking I/O MongoDB driver, optimized for use with the
[Mojolicious](http://mojolicio.us) real-time web framework.
It also supports [BSON::XS](https://metacpan.org/pod/BSON::XS) parser

```perl
use Mojolicious::Lite;
use Mango;
use Mango::BSON ':bson';
use BSON:Types ':all';

my $uri = 'mongodb://<user>:<pass>@<server>/<database>';
helper mango => sub { state $mango = Mango->new($uri) };
Expand All @@ -18,21 +19,17 @@ get '/' => sub {
my $ip = $c->tx->remote_address;

# Store information about current visitor
$collection->insert({when => bson_time, from => $ip} => sub {
my ($collection, $err, $oid) = @_;

return $c->reply->exception($err) if $err;

$collection->insert_p({when => bson_time, from => $ip})->then(sub {
my ($oid) = @_;
# Retrieve information about previous visitors
$collection->find->sort({when => -1})->fields({_id => 0})->all(sub {
my ($collection, $err, $docs) = @_;

return $c->reply->exception($err) if $err;

$collection->find->sort({when => -1})->fields({_id => 0})->all_p->then(sub {
my ($docs) = @_;
# And show it to current visitor
$c->render(json => $docs);
});
});
})
})->catch(sub {
return $c->reply->exception(@_)
})
};

app->start;
Expand Down
12 changes: 6 additions & 6 deletions lib/Mango.pm
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use Mojo::Base 'Mojo::EventEmitter';

use Carp 'croak';
use Hash::Util::FieldHash;
use Mango::BSON 'bson_doc';
use BSON::Types 'bson_doc';
use Mango::Database;
use Mango::Protocol;
use Mojo::IOLoop;
Expand All @@ -29,7 +29,7 @@ has w => 1;
# is good for security.
Hash::Util::FieldHash::fieldhash my %AUTH;

our $VERSION = '1.30';
our $VERSION = '2.0.1';

sub DESTROY { shift->_cleanup }

Expand Down Expand Up @@ -330,7 +330,7 @@ sub _write {

=head1 NAME

Mango - Pure-Perl non-blocking I/O MongoDB driver
Mango - Pure-Perl non-blocking I/O MongoDB driver. Supports BSON::XS parser if it's available.

=head1 SYNOPSIS

Expand All @@ -357,9 +357,9 @@ Mango - Pure-Perl non-blocking I/O MongoDB driver
mango->db('test')->collection('foo')->remove({bar => 'yada'});

# Insert document with special BSON types
use Mango::BSON ':bson';
use BSON::Types ':all';
my $oid = mango->db('test')->collection('foo')
->insert({data => bson_bin("\x00\x01"), now => bson_time});
->insert({data => bson_bytes("\x00\x01"), now => bson_time});

# Non-blocking concurrent find
my $delay = Mojo::IOLoop->delay(sub {
Expand Down Expand Up @@ -401,7 +401,7 @@ in this distribution is no replacement for it.
Look at L<Mango::Collection> for CRUD operations.

Many arguments passed to methods as well as values of attributes get
serialized to BSON with L<Mango::BSON>, which provides many helper functions
serialized to BSON with L<BSON>, which provides many helper functions
you can use to generate data types that are not available natively in Perl.
All connections will be reset automatically if a new process has been forked,
this allows multiple processes to share the same L<Mango> object safely.
Expand Down
84 changes: 39 additions & 45 deletions lib/Mango/Auth/SCRAM.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package Mango::Auth::SCRAM;

use Mojo::Base 'Mango::Auth';
use Mojo::Util qw(dumper md5_sum encode b64_encode b64_decode);
use Mango::BSON 'bson_doc';
use BSON::Types 'bson_doc';

EVAL: {
local $@;
Expand All @@ -20,50 +20,44 @@ sub _credentials {
}

sub _authenticate {
my ($self, $id) = @_;

my $mango = $self->mango;
my $cnx = $self->mango->{connections}{$id};
my $creds = $self->{credentials};

my ($db, $user, $pass) = @$creds;

my $scram_client = Authen::SCRAM::Client->new(
skip_saslprep => 1,
username => $user,
password => $pass
);

my $delay = Mojo::IOLoop::Delay->new;
my $conv_id;

$delay->steps(
sub {
my ($d, $mango, $err, $doc) = @_;
$conv_id = $doc->{conversationId};
my $final_msg = $scram_client->final_msg(b64_decode $doc->{payload});

my $command = $self->_cmd_sasl_continue($conv_id, $final_msg);
$mango->_fast($id, $db, $command, $d->begin(0));
},
sub {
my ($d, $mango, $err, $doc) = @_;
$scram_client->validate(b64_decode $doc->{payload});

my $command = $self->_cmd_sasl_continue($conv_id, '');
$mango->_fast($id, $db, $command, $d->begin(0));
},
sub {
my ($d, $mango, $err, $doc) = @_;
$mango->emit(connection => $id)->_next;
}
);

my $command = $self->_cmd_sasl_start($scram_client->first_msg);
$mango->_fast($id, $db, $command, $delay->begin(0));

$delay->wait;
$delay->ioloop->one_tick unless $delay->ioloop->is_running;
my ($self, $id) = @_;

my $mango = $self->mango;
my $cnx = $self->mango->{connections}{$id};
my $creds = $self->{credentials};

my ($db, $user, $pass) = @$creds;

my $scram_client = Authen::SCRAM::Client->new(
skip_saslprep => 1,
username => $user,
password => $pass
);

my $loop = Mojo::IOLoop->new;
my $conv_id;

my $command = $self->_cmd_sasl_start($scram_client->first_msg);
$mango->_fast($id, $db, $command, sub {
my ($mango, $err, $doc) = @_;
$conv_id = $doc->{conversationId};
my $final_msg = $scram_client->final_msg(b64_decode $doc->{payload});

my $command = $self->_cmd_sasl_continue($conv_id, $final_msg);
$mango->_fast($id, $db, $command, sub {
my ($mango, $err, $doc) = @_;
$scram_client->validate(b64_decode $doc->{payload});

my $command = $self->_cmd_sasl_continue($conv_id, '');
$mango->_fast($id, $db, $command, sub {
my ($mango, $err, $doc) = @_;
$mango->emit(connection => $id)->_next;
$loop->stop;
})
})
});

$loop->start;
}

sub _cmd_sasl_start {
Expand Down
Loading