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

NAME

MongoDBI::Document::Storage::Operation - Standard MongoDBI Document/Collection Operations

VERSION

version 0.0.12

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

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.