The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Mango - Pure-Perl non-blocking I/O MongoDB driver

SYNOPSIS

  use Mango;
  my $mango = Mango->new('mongodb://localhost:27017');

  # Insert document
  my $oid = $mango->db('test')->collection('foo')->insert({bar => 'baz'});

  # Find document
  my $doc = $mango->db('test')->collection('foo')->find_one({bar => 'baz'});
  say $doc->{bar};

  # Update document
  $mango->db('test')->collection('foo')
    ->update({bar => 'baz'}, {bar => 'yada'});

  # Remove document
  $mango->db('test')->collection('foo')->remove({bar => 'yada'});

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

  # Blocking parallel find (does not work inside a running event loop)
  my $delay = Mojo::IOLoop->delay;
  for my $name (qw(sri marty)) {
    my $end = $delay->begin(0);
    $mango->db('test')->collection('users')->find({name => $name})->all(sub {
      my ($cursor, $err, $docs) = @_;
      $end->(@$docs);
    });
  }
  my @docs = $delay->wait;

  # Non-blocking parallel find (does work inside a running event loop)
  my $delay = Mojo::IOLoop->delay(sub {
    my ($delay, @docs) = @_;
    ...
  });
  for my $name (qw(sri marty)) {
    my $end = $delay->begin(0);
    $mango->db('test')->collection('users')->find({name => $name})->all(sub {
      my ($cursor, $err, $docs) = @_;
      $end->(@$docs);
    });
  }
  $delay->wait unless Mojo::IOLoop->is_running;

DESCRIPTION

Mango is a pure-Perl non-blocking I/O MongoDB driver, optimized for use with the Mojolicious real-time web framework, and with multiple event loop support.

To learn more about MongoDB you should take a look at the official documentation.

Note that this whole distribution is EXPERIMENTAL and will change without warning!

Most of the API is not changing much anymore, but you should wait for a stable 1.0 release before using any of the modules in this distribution in a production environment. Unsafe operations are not supported, so far this is considered a feature.

Many arguments passed to methods as well as values of attributes get serialized to BSON with Mango::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 Mango object safely.

For better scalability (epoll, kqueue) and to provide IPv6 as well as TLS support, the optional modules EV (4.0+), IO::Socket::IP (0.16+) and IO::Socket::SSL (1.75+) will be used automatically by Mojo::IOLoop if they are installed. Individual features can also be disabled with the MOJO_NO_IPV6 and MOJO_NO_TLS environment variables.

EVENTS

Mango inherits all events from Mojo::EventEmitter and can emit the following new ones.

connection

  $mango->on(connection => sub {
    my ($mango, $id) = @_;
    ...
  });

Emitted when a new connection has been established.

error

  $mango->on(error => sub {
    my ($mango, $err) = @_;
    ...
  });

Emitted if an error occurs that can't be associated with an operation.

  $mango->on(error => sub {
    my ($mango, $err) = @_;
    say "This looks bad: $err";
  });

ATTRIBUTES

Mango implements the following attributes.

credentials

  my $credentials = $mango->credentials;
  $mango          = $mango->credentials([['test', 'sri', 's3cret']]);

Authentication credentials that will be used on every reconnect.

default_db

  my $name = $mango->default_db;
  $mango   = $mango->default_db('test');

Default database, defaults to admin.

hosts

  my $hosts = $mango->hosts;
  $mango    = $mango->hosts([['localhost', 3000]]);

Server to connect to, defaults to localhost and port 27017.

ioloop

  my $loop = $mango->ioloop;
  $mango   = $mango->ioloop(Mojo::IOLoop->new);

Event loop object to use for blocking I/O operations, defaults to a Mojo::IOLoop object.

j

  my $j  = $mango->j;
  $mango = $mango->j(1);

Wait for all operations to have reached the journal, defaults to 0.

max_connections

  my $max = $mango->max_connections;
  $mango  = $mango->max_connections(5);

Maximum number of connections to use for non-blocking operations, defaults to 5.

protocol

  my $protocol = $mango->protocol;
  $mango       = $mango->protocol(Mango::Protocol->new);

Protocol handler, defaults to a Mango::Protocol object.

w

  my $w  = $mango->w;
  $mango = $mango->w(2);

Wait for all operations to have reached at least this many servers, 1 indicates just primary, 2 indicates primary and at least one secondary, defaults to 1.

wtimeout

  my $timeout = $mango->wtimeout;
  $mango      = $mango->wtimeout(1);

Timeout for write propagation in milliseconds, defaults to 1000.

METHODS

Mango inherits all methods from Mojo::Base and implements the following new ones.

new

  my $mango = Mango->new;
  my $mango = Mango->new('mongodb://sri:s3cret@localhost:3000/test?w=2');

Construct a new Mango object.

backlog

  my $num = $mango->backlog;

Number of queued operations that have not yet been assigned to a connection.

db

  my $db = $mango->db;
  my $db = $mango->db('test');

Get Mango::Database object for database, uses default_db if no name is provided.

delete

  my $reply = $mango->delete($name, $flags, $query);

Perform low level delete operation followed by getLastError command. You can also append a callback to perform operation non-blocking.

  $mango->delete(($name, $flags, $query) => sub {
    my ($mango, $err, $reply) = @_;
    ...
  });
  Mojo::IOLoop->start unless Mojo::IOLoop->is_running;

get_more

  my $reply = $mango->get_more($name, $return, $cursor);

Perform low level get_more operation. You can also append a callback to perform operation non-blocking.

  $mango->get_more(($name, $return, $cursor) => sub {
    my ($mango, $err, $reply) = @_;
    ...
  });
  Mojo::IOLoop->start unless Mojo::IOLoop->is_running;

insert

  my $reply = $mango->insert($name, $flags, @docs);

Perform low level insert operation followed by getLastError command. You can also append a callback to perform operation non-blocking.

  $mango->insert(($name, $flags, @docs) => sub {
    my ($mango, $err, $reply) = @_;
    ...
  });
  Mojo::IOLoop->start unless Mojo::IOLoop->is_running;

kill_cursors

  $mango->kill_cursors(@ids);

Perform low level kill_cursors operation. You can also append a callback to perform operation non-blocking.

    $mango->kill_cursors(@ids => sub {
      my ($mango, $err) = @_;
      ...
    });
    Mojo::IOLoop->start unless Mojo::IOLoop->is_running;

query

  my $reply = $mango->query($name, $flags, $skip, $return, $query, $fields);

Perform low level query operation. You can also append a callback to perform operation non-blocking.

  $mango->query(($name, $flags, $skip, $return, $query, $fields) => sub {
    my ($mango, $err, $reply) = @_;
    ...
  });
  Mojo::IOLoop->start unless Mojo::IOLoop->is_running;

update

  my $reply = $mango->update($name, $flags, $query, $update);

Perform low level update operation followed by getLastError command. You can also append a callback to perform operation non-blocking.

  $mango->update(($name, $flags, $query, $update) => sub {
    my ($mango, $err, $reply) = @_;
    ...
  });
  Mojo::IOLoop->start unless Mojo::IOLoop->is_running;

DEBUGGING

You can set the MANGO_DEBUG environment variable to get some advanced diagnostics information printed to STDERR.

  MANGO_DEBUG=1

SPONSORS

Some of the work on this distribution has been sponsored by Drip Depot, thank you!

AUTHOR

Sebastian Riedel, sri@cpan.org.

CREDITS

In alphabetical order:

    Andrey Khozov

COPYRIGHT AND LICENSE

Copyright (C) 2013, Sebastian Riedel.

This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0.

SEE ALSO

Mojolicious::Guides, http://mojolicio.us.