NAME
MongoDBI::Document::Storage::Operation - Standard MongoDBI Document/Collection Operations
VERSION
version 0.0.10
SYNOPSIS
package main;
my $cds = CDDB::Album;
my @cds = $cds->all; # returns all records (as hashes not instances)
foreach my $cd (@cds) {
my $this_cd = $cds->new(%{ $cd });
my $that_cd = $this_cd->clone;
$this_cd->rating(5);
$that_cd->rating(1);
$this_cd->save; # save changes to existing cd
$that_cd->insert; # new cd record
}
1;
DESCRIPTION
MongoDBI::Document::Storage::Operation is a role that provides collection-specific functionality to your MongoDBI document classes.
METHODS
all
The all method, called on the class or instance, returns an arrayref of hashrefs corresponding to the documents in the document class collection which match the criteria specified.
my @cds = CDDB::Album->all;
... db.albums.find();
my @cds = CDDB::Album->all(title => 'Thriller');
... db.albums.find({ "title" : "thriller" });
# using M::D::S::Criterion query syntax
my @cds = CDDB::Album->all('rating$gt' => 10);
... db.albums.find({ "rating" : { "$gt" : 10 } });
clone
The clone method, can only be called on a class instance which has been previously inserted thus having a valid ID, returns a cloned instance of itself including set attributes and configuration minus its ID.
my $cd1 = CDDB::Album->first; # get the first record as an instance
my $cd2 = $cd1->clone;
$cd2->insert; # insert not save, can't save without an id
collection
The collection method, called on a class or instance, simply returns the MongoDB::Collection object set in the current document class configuration.
my $mongo_col = CDDB::Album->collection;
connection
The connection method, called on a class or instance, simply returns the MongoDB::Connection object set in the current document class configuration.
my $mongo_con = CDDB::Album->connection;
count
The count method, called on a class or instance, simply returns the total number of documents matching the specified criteria.
my $count = CDDB::Album->count;
... db.albums.find().count();
my $count = CDDB::Album->all(title => 'Thriller');
... db.albums.find({ "title" : "thriller" }).count();
create
The create method, called on a class or instance, inserts a new document into the database and returns the newly create class instance.
my $cd = CDDB::Album->create(title => 'Greatest HITS', released => ...);
$cd->title('Greatest Hits');
$cd->save;
execute_on
The execute_on method, called on a class or instance, is designed to allow the execution of specific database commands against alternate database servers. While it was certainly the goal for this method to be instrumental in providing support for MongoDB clustered environments (master/slave, replicasets, etc), this method has many applications.
my $cds = CDDB::Album;
my @cds = $cds->all; # returns all records (from 127.0.0.1, default)
$cds->execute_on('192.168.1.101' => sub {
foreach my $cd (@cds) {
# save changes to cd on the master server
$cd->rating(5);
$cd->save;
}
});
# or ...
$cds->execute_on(name => 'alt_dbname', host => '192.168.1.101', sub {
foreach my $cd (@cds) {
# save changes to cd on the master server
$cd->rating(5);
$cd->save;
}
});
# or ...
# if using MongoDBI::Application with connection pooling
my @cds = $cds->execute_on('slave' => sub {
return shift->all
});
$cds->execute_on('master' => sub {
foreach my $cd (@cds) {
# save changes to cd on the master server
$cd->rating(5);
$cd->save;
}
});
find
The find method, called on a class or instance, not to be confused with the find method available via the MongoDB driver, allows you to quickly query a resultset using the syntax described in MongoDBI::Document::Storage::Criterion.
The find method always returns a MongoDB::Cursor object, it accepts a single argument (just the document ID, not MongoDB::OID) or key/value query syntax. If you would like to pass in a MongoDB::OID object to reference the document ID, please use the following syntax:
my $cd = CDDB::Album->find('4df7a599005ec15814000000')->next;
my $cd = CDDB::Album->find(_id => $mongo_oid)->next;
my $search = CDDB::Album->find(title => qr/Hits/);
while (my $cd = $search->next) {
...
}
find_one
The find_one method, called on a class or instance, not to be confused with the find_one method available via the MongoDB driver, allows you to quickly query a resultset using the MongoDBI::Document::Storage::Criterion syntax.
The find_one method tries to return an instance of the current class based on the result of the query. The find_one method accepts a single argument (just the document ID, not MongoDB::OID) or key/value query syntax. If you would like to pass in a MongoDB::OID object to reference the document ID, please use the following syntax:
my $cd = CDDB::Album->find_one('4df7a599005ec15814000000');
my $cd = CDDB::Album->find_one(_id => $mongo_oid);
my $search = CDDB::Album->find_one(title => qr/Hits/);
find_or_create
The find_or_create method, called on a class or instance, attempts to find a single document based on the passed-in criteria, returning a class instance based on the returned document, if no matching documents can be found inserts a new document into the database and returns the newly create class instance.
my $cd = CDDB::Album->find_or_create(title => 'Greatest HITS');
$cd->save;
find_or_new
The find_or_new method, called on a class or instance, attempts to find a single document based on the passed-in criteria, returning a class instance based on the returned document, if no matching documents can be found instantiates and returns a new class object.
my $cd = CDDB::Album->find_or_new(title => 'Greatest HITS');
$cd->id ? $cd->save : $cd->insert;
full_name
The full_name method, called on a class or instance, simply returns the fully-qualified database collection name based on the collection and connection configuration.
CDDB::Album->config->set_database('test');
my $col_name = CDDB::Album->full_name;
print $col_name; # prints test.albums
first
The first method, called on a class or instance, allows you to quickly query a resultset using the MongoDBI::Document::Storage::Criterion syntax returning an instance of the current class based on the first result of the query automatically sorted by ID in ascending order. The first method accepts key/value query syntax.
my $cd = CDDB::Album->first;
my $cd = CDDB::Album->first(title => qr/Hits/);
insert
The insert method, can only be called on a class instance which has NOT been previously inserted thus not having an ID set, collapses the dirty attributes/fields and inserts the instance into the defined collection returning itself.
my $cd1 = CDDB::Album->new(...);
$cd1->insert;
last
The last method, called on a class or instance, allows you to quickly query a resultset using the MongoDBI::Document::Storage::Criterion syntax returning an instance of the current class based on the last result of the query automatically sorted by ID in descending order. The last method accepts key/value query syntax.
my $cd = CDDB::Album->last;
my $cd = CDDB::Album->last(title => qr/Hits/);
name
The name method, called on a class or instance, simply returns the name of the database collection based on the collection configuration.
my $col_name = CDDB::Album->name;
print $col_name; # prints albums
query
The query method, called on a class or instance, is shorthand (an alias) for calling the search method and eventually calling the query method within MongoDBI::Document::Storage::Criterion package executing pre-defined filters and returning the resulting MongoDB::Cursor object.
package CDDB::Album;
use MongoDBI::Document;
filter 'w_quantity' => sub {
my ($filter, $self, $cond, $value) = @_;
$filter->and_where("quantity$cond" => $value);
};
package main;
# note: any arg not recognized as an pre-defined filter is passed to the
# filter preceding it
my $cursor = CDDB::Album->query('w_quantity', '$gte', 1000);
# is the equivalent of ...
my $search = CDDB::Album->search->where('w_quantity', '$gte', 1000);
my $cursor = $search->query;
while (my $document = $cursor->next) {
...
}
reload
The reload method, can only be called on a class instance which has been previously inserted thus having an ID set, uses the ID to poll the database returning a new instance object based on the query result if any.
This method is useful in stateless applications or applications where the instance may remain in-use for an inordinate amount of time allowing someone else the possibility to update that exact same record with information that differs from your own unsaved object thus having your eventual save overwrite their changes.
my $cd1 = CDDB::Album->first;
... 10 mins later ...
# i should probably reload this object before making changes
$cd1->reload;
$cd1->title(...); # change it
$cd1->save;
remove
The remove method, can only be called on a class instance which has been previously inserted thus having an ID set, uses the ID to poll the database for the corresponding document and removes it (both on the object and in the collection) returning a copy of the original before deletion.
my $cd1 = CDDB::Album->first;
# $cd1 = $cd1->remove; if you're a stickler for convention
$cd1->remove;
$cd1->title(...); # completely new title
$cd1->insert; # new document based on the deleted
save
The save method, can only be called on a class instance which has been previously inserted thus having an ID set, uses the ID to poll the database for the corresponding document updating the "dirty fields only" while saving it to the database.
my $cd1 = CDDB::Album->first;
$cd1->save; # saves nothing
$cd1->title(...); # completely new title
$cd1->save; # save, updating the title only, not the entire document
search
The search method, called on a class or instance, simply returns a MongoDBI::Document::Storage::Criterion object allowing you to build complex queries.
my $search = CDDB::Album->search;
my $search = CDDB::Album->search->where('title$in' => ['Bad', 'Thriller']);
# call query to return a MongoDB::Cursor object for further usage
my $cursor = $search->query;
while (my $document = $cursor->next) {
...
}
The search method also supports another syntax for chaining stored queries/filters.
package CDDB::Album;
use MongoDBI::Document;
filter 'filter_a' => sub {
my ($filter, $self, @
) = @_;
$filter->and_where(...)
};
filter 'filter_b' => sub {
my ($filter, $self, @args) = @_;
$filter->and_where(...)
};
package main;
my $search = CDDB::Album->search('filter_a', 'filter_b');
# experimental syntax (pass args to filters)
# my $search = CDDB::Album->search('filter_a', 'filter_b' => (1..9));
# my $search = CDDB::Album->search('filter_a' => (1..9), 'filter_b');
my $cursor = $search->query;
while (my $document = $cursor->next) {
...
}
update
The update method, unlike the MongoDB driver update method, can only be called on a class instance which has been previously inserted thus having an ID set, uses the ID to poll the database for the corresponding document updating the "dirty fields only" while saving it to the database. The main difference between the update method and the save method is that the update method can change the entire structure of the document by discarding fields that haven't been set.
You can safely use the save option where the update function might sound like the right choice, and only use the update option when needed (knowing exactly what it does). The following is an example:
my $cd1 = CDDB::Album->first;
$cd1->update; # updates nothing
$cd1->title(...); # completely new title
$cd1->update; # update, updating the title only, not the entire document
$cd1->update(set => 0); # update, replacing the document with title and ID
AUTHOR
Al Newkirk <awncorp@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2011 by awncorp.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.