Guillaume Aubert > DBIx-NinjaORM > DBIx::NinjaORM

Download:
DBIx-NinjaORM-3.0.1.tar.gz

Dependencies

Annotate this POD

Website

View/Report Bugs
Module Version: v3.0.1   Source  

NAME ^

DBIx::NinjaORM - Flexible Perl ORM for easy transitions from inline SQL to objects.

VERSION ^

Version 3.0.1

DESCRIPTION ^

DBIx::NinjaORM was designed with a few goals in mind:

SYNOPSIS ^

Simple example

Let's take the example of a My::Model::Book class that represents a book. You would start My::Model::Book with the following code:

        package My::Model::Book;
        
        use strict;
        use warnings;
        
        use base 'DBIx::NinjaORM';
        
        use DBI;
        
        
        sub static_class_info
        {
                my ( $class ) = @_;
                
                # Retrieve defaults from DBIx::Ninja->static_class_info().
                my $info = $class->SUPER::static_class_info();
                
                $info->set(
                        {
                                # Set mandatory defaults.
                                table_name       => 'books',
                                primary_key_name => 'book_id',
                                default_dbh      => DBI->connect(
                                        "dbi:mysql:[database_name]:localhost:3306",
                                        "[user]",
                                        "[password]",
                                ),
                                
                                # Add optional information.
                                # Allow filtering SELECTs on books.name.
                                filtering_fields => [ 'name' ],
                        }
                );
                
                return $info;
        }
        
        1;

Inheriting with use base 'DBIx::NinjaORM' and creating sub static_class_info (with a default database handle and a table name) are the only two requirements to have a working model.

A more complex model

If you have more than one Model class to create, for example My::Model::Book and My::Model::Library, you probably want to create a single class My::Model to hold the defaults and then inherits from that main class.

        package My::Model;
        
        use strict;
        use warnings;
        
        use base 'DBIx::NinjaORM';
        
        use DBI;
        use Cache::Memcached::Fast;
        
        
        sub static_class_info
        {
                my ( $class ) = @_;
                
                # Retrieve defaults from DBIx::Ninja->static_class_info().
                my $info = $class->SUPER::static_class_info();
                
                # Set defaults common to all your objects.
                $info->set(
                        {
                                default_dbh => DBI->connect(
                                        "dbi:mysql:[database_name]:localhost:3306",
                                        "[user]",
                                        "[password]",
                                ),
                                memcache    => Cache::Memcached::Fast->new(
                                        {
                                                servers =>
                                                [
                                                        'localhost:11211',
                                                ],
                                        }
                                ),
                        }
                );
                
                return $info;
        }
        
        1;

The various classes will then inherit from My::Model, and the inherited defaults will make static_class_info() shorter in the other classes:

        package My::Model::Book;
        
        use strict;
        use warnings;
        
        # Inherit from your base model class, not from DBIx::NinjaORM.
        use base 'My::Model';
        
        sub static_class_info
        {
                my ( $class ) = @_;
                
                # Retrieve defaults from My::Model.
                my $info = $class->SUPER::static_class_info();
                
                $info->set(
                        {
                                # Set mandatory defaults for this class.
                                table_name       => 'books',
                                primary_key_name => 'book_id',
                                
                                # Add optional information.
                                # Allow filtering SELECTs on books.name.
                                filtering_fields => [ 'name' ],
                        }
                );
                
                return $info;
        }
        
        1;

SUPPORTED DATABASES ^

This distribution currently supports:

Please contact me if you need support for another database type, I'm always glad to add extensions if you can help me with testing.

SUBCLASSABLE METHODS ^

DBIx::NinjaORM is designed with inheritance in mind, and you can subclass most of its public methods to extend or alter its behavior.

This group of method covers the most commonly subclassed methods, with examples and use cases.

clone()

Clone the current object and return the clone.

        my $cloned_book = $book->clone();

commit()

Convenience function to insert or update the object.

If the object has a primary key set, update() is called, otherwise insert() is called. If there's an error, the method with croak with relevant error information.

        $book->commit();

Arguments: (none).

get()

Get the value corresponding to an object's field.

        my $book_name = $book->get('name');

This method will croak if you attempt to retrieve a private field. It also detects if the object was retrieved from the database, in which case it has an exhaustive list of the fields that actually exist in the database and it will croak if you attempt to retrieve a field that doesn't exist in the database.

get_current_time()

Return the current time, to use in SQL statements.

        my $current_time = $class->get_current_time( $field_name );

By default, DBIx::NinjaORM assumes that time is stored as unixtime (integer) in the database. If you are using a different field type for created and modified, you can subclass this method to return the current time in a different format.

Arguments:

Notes:

insert()

Insert a row corresponding to the data passed as first parameter, and fill the object accordingly upon success.

        my $book = My::Model::Book->new();
        $book->insert(
                {
                        name => 'Learning Perl',
                }
        );

If you don't need the object afterwards, you can simply do:

        My::Model::Book->insert(
                {
                        name => 'Learning Perl',
                }
        );

This method supports the following optional arguments:

        $book->insert(
                \%data,
                overwrite_created           => $unixtime,
                generated_primary_key_value => $value,
                dbh                         => $dbh,
                ignore                      => $boolean,
        );

new()

new() has two possible uses:

When retrieving a single object from the database, the first argument should be a hashref containing the following information to select a single row:

This method also supports the following optional arguments, passed in a hash after the filtering criteria above-mentioned:

remove()

Delete in the database the row corresponding to the current object.

        $book->remove();

This method accepts the following arguments:

retrieve_list_nocache()

Dispatch of retrieve_list() when objects should not be retrieved from the cache.

See retrieve_list() for the parameters this method accepts.

set()

Set fields and values on an object.

        $book->set(
                {
                        name => 'Learning Perl',
                        isbn => '9781449303587',
                },
        );

This method supports the following arguments:

static_class_info()

This methods sets defaults as well as general information for a specific class.

It allows for example indicating what table the objects will be related to, or what database handle to use. See DBIx::NinjaORM::StaticClassInfo for the full list of options that can be set or overridden.

Here's what a typical subclassed static_class_info() would look like:

        sub static_class_info
        {
                my ( $class ) = @_;
                
                # Retrieve defaults coming from higher in the inheritance chain, up
                # to DBIx::NinjaORM->static_class_info().
                my $info = $class->SUPER::static_class_info();
                
                # Set or override information.
                $info->set(
                        {
                                table_name       => 'books',
                                primary_key_name => 'book_id',
                                default_dbh      => DBI->connect(
                                        "dbi:mysql:[database_name]:localhost:3306",
                                        "[user]",
                                        "[password]",
                                ),
                        }
                );
                
                # Return the updated information hashref.
                return $info;
        }

update()

Update the row in the database corresponding to the current object, using the primary key and its value on the object.

        $book->update(
                {
                        name => 'Learning Perl',
                }
        );

This method supports the following optional arguments:

validate_data()

Validate the hashref of data passed as first argument. This is used both by insert() and update to check the data before performing databse operations.

        my $validated_data = $object->validate_data(
                \%data,
        );

If there is invalid data, the method will croak with a detail of the error.

UTILITY METHODS ^

dump()

Return a Dumper( ) of the current object.

        my $string = $book->dump();

flatten_object()

Return a hash with the requested key/value pairs based on the list of fields provided.

Note that non-native fields (starting with an underscore) are not allowed. It also protects sensitive fields.

#TODO: allow defining sensitive fields.

        my $book_data = $book->flatten_object(
                [ 'name', 'isbn' ]
        );

reload()

Reload the content of the current object. This always skips the cache.

        $book->reload();

retrieve_list()

Return an arrayref of objects matching all the criteria passed.

This method supports the following filtering criteria in a hashref passed as first argument:

Note that you can combine filters (which is the equivalent of AND in SQL) in that hashref:

        # Retrieve books by ISBN for a specific author.
        my $books = My::Model::Book->retrieve_list(
                {
                        isbn      =>
                        [
                                '9781449313142',
                                '9781449393090',
                        ],
                        author_id => 12,
                }
        );

Filters as discussed above, imply an equality between the field and the values. For instance, in the last example, the request could be written as "Please provide a list of books with author_id equal to 12, which also have an ISBN equal to 9781449313142 or an ISBN equal to 9781449393090".

If you wish to request records using some other operator than equals, you can create a request similar to the following:

        # Retrieve books for a specific author with ISBNs starting with a certain pattern.
        my $books = My::Model::Book->retrieve_list(
                {
                        isbn      =>
                        {
                                operator => 'like',
                                value => [ '9781%' ],
                        },
                        author_id => 12,
                }
        );

The above example could be written as "Please provide a list of books with author_id equal to 12, which also have an ISBN starting with 9781".

Valid operators include:

        * =
        * not
        * <=
        * >=
        * <
        * >
        * between
        * null
        * not_null
        * like
        * not_like

This method also supports the following optional arguments, passed in a hash after the filtering criteria above-mentioned:

ACCESSORS ^

get_cache_key_field()

Return the name of the field that should be used in the cache key.

        my $cache_time = $class->cache_key_field();
        my $cache_time = $object->cache_key_field();

get_default_dbh()

WARNING: this method will be removed soon. Use get_info('default_dbh') instead.

Return the default database handle to use with this class.

        my $default_dbh = $class->get_default_dbh();
        my $default_dbh = $object->get_default_dbh();

get_filtering_fields()

Returns the fields that can be used as filtering criteria in retrieve_list().

Notes:

get_info()

Return cached static class information for the current object or class.

        my $info = $class->get_info();
        my $info = $object->get_info();

get_list_cache_time()

WARNING: this method will be removed soon. Use get_info('list_cache_time') instead.

Return the duration for which a list of objects of the current class can be cached.

        my $list_cache_time = $class->list_cache_time();
        my $list_cache_time = $object->list_cache_time();

get_memcache()

WARNING: this method will be removed soon. Use get_info('memcache') instead.

Return the memcache object to use with this class.

        my $memcache = $class->get_memcache();
        my $memcache = $object->get_memcache();

get_object_cache_time()

WARNING: this method will be removed soon. Use get_info('object_cache_time') instead.

Return the duration for which an object of the current class can be cached.

        my $object_cache_time = $class->get_object_cache_time();
        my $object_cache_time = $object->get_object_cache_time();

get_primary_key_name()

WARNING: this method will be removed soon. Use get_info('primary_key_name') instead.

Return the underlying primary key name for the current class or object.

        my $primary_key_name = $class->get_primary_key_name();
        my $primary_key_name = $object->get_primary_key_name();

get_readonly_fields()

WARNING: this method will be removed soon. Use get_info('readonly_fields') instead.

Return an arrayref of fields that cannot be modified via set(), update(), or insert().

        my $readonly_fields = $class->get_readonly_fields();
        my $readonly_fields = $object->get_readonly_fields();

get_table_name()

WARNING: this method will be removed soon. Use get_info('table_name') instead.

Returns the underlying table name for the current class or object.

        my $table_name = $class->get_table_name();
        my $table_name = $object->get_table_name();

get_unique_fields()

WARNING: this method will be removed soon. Use get_info('unique_fields') instead.

Return an arrayref of fields that are unique for the underlying table.

Important: this doesn't include the primary key name. To retrieve the name of the primary key, use $class-primary_key_name()>

        my $unique_fields = $class->get_unique_fields();
        my $unique_fields = $object->get_unique_fields();

has_created_field()

WARNING: this method will be removed soon. Use get_info('has_created_field') instead.

Return a boolean to indicate whether the underlying table has a 'created' field.

        my $has_created_field = $class->has_created_field();
        my $has_created_field = $object->has_created_field();

has_modified_field()

WARNING: this method will be removed soon. Use get_info('has_modified_field') instead.

Return a boolean to indicate whether the underlying table has a 'modified' field.

        my $has_modified_field = $class->has_modified_field();
        my $has_modified_field = $object->has_modified_field();

id()

Return the value associated with the primary key for the current object.

        my $id = $object->id();

is_verbose()

Return if verbosity is enabled.

This method supports two types of verbosity:

CACHE RELATED METHODS ^

cached_static_class_info()

Return a cached version of the information retrieved by static_class_info().

        my $static_class_info = $class->cached_static_class_info();
        my $static_class_info = $object->cached_static_class_info();

get_table_schema()

Return the schema corresponding to the underlying table.

        my $table_schema = $class->get_table_schema();
        my $table_schema = $object->get_table_schema();

delete_cache()

Delete a key from the cache.

        my $value = $class->delete_cache( key => $key );

get_cache()

Get a value from the cache.

        my $value = $class->get_cache( key => $key );

get_object_cache_key()

Return the name of the cache key for an object or a class, given a field name on which a unique constraint exists and the corresponding value.

        my $cache_key = $object->get_object_cache_key();
        my $cache_key = $class->get_object_cache_key(
                unique_field => $unique_field,
                value        => $value,
        );

invalidate_cached_object()

Invalidate the cached copies of the current object across all the unique keys this object can be referenced with.

        $object->invalidate_cached_object();

retrieve_list_cache()

Dispatch of retrieve_list() when objects should be retrieved from the cache.

See retrieve_list() for the parameters this method accepts.

set_cache()

Set a value into the cache.

        $class->set_cache(
                key         => $key,
                value       => $value,
                expire_time => $expire_time,
        );

INTERNAL METHODS ^

Those methods are used internally by DBIx::NinjaORM, you should not subclass them.

assert_dbh()

Assert that there is a database handle, either a specific one passed as first argument to this function (if defined) or the default one specified via static_class_info(), and return it.

        my $dbh = $class->assert_dbh();
        my $dbh = $object->assert_dbh();
        
        my $dbh = $class->assert_dbh( $custom_dbh );
        my $dbh = $object->assert_dbh( $custom_dbh );

Note that this method also supports coderefs that return a DBI::db object when evaluated. That way, if no database connection is needed when running the code, no connection needs to be established.

build_filtering_clause()

Create a filtering clause using the field, operator and values passed.

        my ( $clause, $clause_values ) = $class->build_filtering_clause(
                field    => $field,
                operator => $operator,
                values   => $values,
        );

parse_filtering_criteria()

Helper function that takes a list of fields and converts them into where clauses and values that can be used by retrieve_list().

        my ( $where_clauses, $where_values, $filtering_field_keys_passed ) =
                @{
                        $class->parse_filtering_criteria(
                                \%filtering_criteria
                        )
                };

$filtering_field_keys_passed indicates whether %values had keys matching at least one element of @field. This allows detecting whether any filtering criteria was passed, even if the filtering criteria do not result in WHERE clauses being returned.

reorganize_non_native_fields()

When we retrieve fields via SELECT in retrieve_list_nocache(), by convention we use _[table_name]_[field_name] for fields that are not native to the underlying table that the object represents.

This method moves them to $object->{'_table_name'}->{'field_name'} for a cleaner organization inside the object.

        $object->reorganize_non_native_fields();

BUGS ^

Please report any bugs or feature requests through the web interface at https://github.com/guillaumeaubert/DBIx-NinjaORM/issues/new. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT ^

You can find documentation for this module with the perldoc command.

        perldoc DBIx::NinjaORM

You can also look for information at:

AUTHOR ^

Guillaume Aubert, <aubertg at cpan.org>.

CONTRIBUTORS ^

ACKNOWLEDGEMENTS ^

I originally developed this project for ThinkGeek (http://www.thinkgeek.com/). Thanks for allowing me to open-source it!

Special thanks to Kate Kirby for her help with the design of this module.

COPYRIGHT & LICENSE ^

Copyright 2009-2013 Guillaume Aubert.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3 as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/

syntax highlighting: