Mango

 view release on metacpan or  search on metacpan

lib/Mango/Collection.pm  view on Meta::CPAN

  $self->_command($cmd, $cb, sub { shift->{cursor}->{firstBatch}->[0] });
}

sub remove {
  my $self  = shift;
  my $cb    = ref $_[-1] eq 'CODE' ? pop : undef;
  my $query = shift // {};
  my $flags = shift // {};

  ($query, $flags) = ({_id => $query}, {single => 1})
    if ref $query eq 'Mango::BSON::ObjectID';
  my $command = bson_doc
    delete       => $self->name,
    deletes      => [{q => $query, limit => $flags->{single} ? 1 : 0}],
    ordered      => \1,
    writeConcern => $self->db->build_write_concern;

  return $self->_command($command, $cb);
}

sub rename {
  my ($self, $name, $cb) = @_;

  my $admin = $self->db->mango->db('admin');
  my $dbname = $self->db->name;
  my $oldname = join '.', $dbname, $self->name;
  my $newname = join '.', $dbname, $name;

  my $cmd = bson_doc renameCollection => $oldname, to => $newname;

  # Non-blocking
  return $admin->command($cmd, sub {
    my ($admin_db, $err, $doc) = @_;
    my $newcol = $doc->{ok} ? $self->db->collection($name) : undef;
    return $cb->($self, $err, $newcol);
  }) if $cb;

  # Blocking
  my $doc = $admin->command($cmd);
  return $doc->{ok} ? $self->db->collection($name) : undef;
}

sub save {
  my ($self, $doc, $cb) = @_;

  # New document
  return $self->insert($doc, $cb) unless $doc->{_id};

  # Update non-blocking
  my @update = ({_id => $doc->{_id}}, $doc, {upsert => 1});
  return $self->update(@update => sub { shift->$cb(shift, $doc->{_id}) })
    if $cb;

  # Update blocking
  $self->update(@update);
  return $doc->{_id};
}

sub stats { $_[0]->_command(bson_doc(collstats => $_[0]->name), $_[1]) }

sub update {
  my ($self, $query, $update) = (shift, shift, shift);
  my $cb = ref $_[-1] eq 'CODE' ? pop : undef;
  my $flags = shift // {};

  $update = {
    q => ref $query eq 'Mango::BSON::ObjectID' ? {_id => $query} : $query,
    u => $update,
    upsert => $flags->{upsert} ? \1 : \0,
    multi  => $flags->{multi}  ? \1 : \0
  };
  my $command = bson_doc
    update       => $self->name,
    updates      => [$update],
    ordered      => \1,
    writeConcern => $self->db->build_write_concern;

  return $self->_command($command, $cb);
}

sub _aggregate {
  my ($self, $command, $doc) = @_;

  # Document (explain)
  return $doc if $command->{explain};

  # Collection
  my $out = $command->{pipeline}[-1]{'$out'};
  return $self->db->collection($out) if defined $out;

  # Cursor
  my $cursor = $doc->{cursor};
  return Mango::Cursor->new(collection => $self, id => $cursor->{id})
    ->add_batch($cursor->{firstBatch});
}

sub _command {
  my ($self, $command, $cb, $return) = @_;
  $return ||= sub {shift};

  # Non-blocking
  my $db       = $self->db;
  my $protocol = $db->mango->protocol;
  return $db->command(
    $command => sub {
      my ($db, $err, $doc) = @_;
      $err ||= $protocol->write_error($doc);
      $self->$cb($err, $return->($doc));
    }
  ) if $cb;

  # Blocking
  my $doc = $db->command($command);
  if (my $err = $protocol->write_error($doc)) { croak $err }
  return $return->($doc);
}

sub _map_reduce {
  my ($self, $doc) = @_;
  return $doc->{results} unless $doc->{result};
  return $self->db->collection($doc->{result});



( run in 0.919 second using v1.01-cache-2.11-cpan-39bf76dae61 )