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

NAME

Ormlette - Light and fluffy object persistence

VERSION

version 0.005

SYNOPSIS

  my $dbh = DBI->connect(...);
  Ormlette->init($dbh, tables => [ 'my_table' ], namespace => Test);

  my $obj = Test::MyTable->create(foo => 1, bar => 3);
  print Test::MyTable->load(foo => 1)->bar; # 3

DESCRIPTION

Ormlette is a simple object persistence mechanism which is specifically designed to avoid imposing any requirements on how your code is organized or what base classes you use.

Rather than requiring your classes to inherit from it, Ormlette is initialized by passing an open database handle to Ormlette->init, at which point Ormlette will identify the tables in that database and, for each one, derive a package name by camel-casing the table name using _ in the table name as a word break (e.g., foo_bar becomes FooBar) and prepending the current package's name. It will then inject its methods (see below) into the resulting package. It will also create accessors corresponding to each of the table's fields unless these accessors already exist.

Note that, if you want to define your own methods within a package which will have methods injected by Ormlette, you should load the corresponding module (with use or require) before doing any Ormlette initializations affecting that package so that Ormlette will know what methods you've defined yourself and avoid interfering with them.

Ormlette Core Methods

init ($dbh, %params)

Attaches Ormlette methods to classes corresponding to tables in the database connected to $dbh. Recognized parameters:

debug

The debug option will cause additional debugging information to be printed to STDERR as Ormlette does its initialization. At this point, this consists solely of the generated source code for each package affected by Ormlette.

isa

Specifies that all Ormlette-generated classes should be made subclasses of the isa package. This is done by directly setting @ISA, not via use base or use parent, so you are responsible for ensuring that the specified class is available to use as a parent.

If Ormlette is adding to a class which already exists and already has a parent in @ISA, the existing parent will be untouched and the isa option will have no effect on that class.

ignore_root

Ormlette will normally inject a dbh method into the base namespace of its generated code, providing access to the source database. This is not always desirable. In such cases, setting ignore_root will prevent Ormlette from making any modifications to that package.

ignore_tables

Ormlette will normally generate classes corresponding to all tables found in the database. If there are tables which should be skipped over, a reference to an array of table names to skip can be passed in the ignore_tables parameter.

If you prefer to list the tables to include rather than the tables to exclude, use tables. There should never be a reason to specify both tables and ignore_tables, but, if this is done, tables will take precedence and ignore_tables will be silently ignored.

namespace

By default, Ormlette will use the name of the package which calls init as the base namespace for its generated code. If you want the code to be placed into a different namespace, use the namespace parameter to override this default.

readonly

If readonly is set to a true value, no constructors or database-altering methods will be created and generated accessors will be read-only.

tables

If you only require Ormlette code to be generated for some of the tables in your database, providing a reference to an array of table names in the tables parameter will cause all other tables to be ignored.

If you prefer to list the tables to exclude rather than those to include, use ignore_tables.

dbh

Returns the internal database handle used for database interaction. Can be called on the core Ormlette object, the root namespace of its generated code (unless the ignore_root option is set when calling init), or any of the persistent classes generated in that namespace.

Root Namespace Methods

If the ignore_root option is set when calling init, no methods will be generated in the root namespace.

dbh

Returns the database handle attached by Ormlette to the root namespace. If multiple Ormlette objects have been instantiated with the same namespace, this will return the handle corresponding to the first Ormlette initialized there.

Table Class Methods

In addition to the methods listed below, accessors will be generated for each field found in the table unless an accessor for that field already exists, providing the convenience of not having to create all the accessors yourself while also allowing for custom accessors to be used where needed. Generated accessors will be read-only if readonly is set or writable using the $obj->attr('new value') convention otherwise.

Note that the generated accessors are extremely simple and make no attempt at performing any form of data validation, so you may wish to use another fine CPAN module to generate accessors before initializing Ormlette.

create

Constructs an object by calling new, then uses insert to immediately store it to the database.

This method will not be generated if readonly is set.

dbh

Returns the database handle used by Ormlette operations on this class.

delete

delete('WHERE name = ?', 'John Doe')

As a class method, deletes all objects matching the criteria specified in the parameters. In an attempt to avoid data loss from accidentally calling delete as a class method when intending to use it as an instance method, nothing will be done if no criteria are provided.

As an instance method, deletes the object from the database. In this case, any parameters will be ignored. The in-memory object is unaffected and remains available for further use, including re-saving it to the database.

This method will not be generated if readonly is set. The instance method variant will only be generated for tables which have a primary key.

dirty

Read-only flag indicating whether an object is "dirty" (i.e., has unsaved changes). This flag is not maintained automatically; code using the object must use its mark_dirty method to set the flag and mark_clean to clear it.

If an object is destroyed while dirty, a DESTROY handler will automatically call its update method to write changes to the database. If the class already has a DESTROY handler prior to Ormlette initialization, this check is instead placed into an _ormlette_DESTROY method, which the other DESTROY should call if autoupdate functionality is desired.

The dirty attribute, mark_dirty and mark_clean methods, and DESTROY handler will not be generated if readonly is set or for tables which do not have a primary key.

insert

Inserts the object into the database as a new record. This method will fail if the record cannot be inserted. If the table uses an autoincrement/serial primary key and no value for that key is set in the object, the in-memory object will be updated with the id assigned by the database.

This method will not be generated if readonly is set.

iterate(sub { print $_->id })

iterate(sub { print $_->name }, 'WHERE age > ?', 18)

Takes a sub reference as the first parameter and passes each object returned by the subsequent query to the referenced sub in $_ for processing. The primary difference between this method and select is that iterate only loads one record into memory at a time, while select loads all records at once, which may require unacceptable amounts of memory when dealing with larger data sets.

mark_clean

Clears an object's dirty flag.

mark_dirty

Sets an object's dirty flag.

new

Basic constructor which accepts a hash of values and blesses them into the class. If a ->new method has already been defined, it will not be replaced. If you wish to retain the default constructor functionality within your custom ->new method, you can call $class->_ormlette_new to do so.

This method will not be generated if readonly is set.

load(1)

load(foo => 1, bar => 2)

Retrieves a single object from the database based on the specified criteria.

If the table has a single-field primary key, passing a single argument will retrieve the record with that value as its primary key.

Lookups on non-key fields or multiple-field primary keys can be performed by passing a hash of field => value pairs. If more than one record matches the given criteria, only one will be returned; which one is returned may or may not be consistent from one call to the next.

Returns undef if no matching record exists.

select

select('WHERE id = 42');

select('WHERE id > ? ORDER BY name LIMIT 5', 3);

Returns a reference to an array containing all objects matching the query specified in the parameters, in the order returned by that query. If no parameters are provided, returns objects for all records in the database's natural sort order.

As this method simply appends its parameters to "SELECT (fields) FROM (table)", arbitrarily-complex queries can be built up in the parameters, including joins and subqueries.

table

Returns the table name in which Ormlette stores this class's data.

update

Updates the object's existing database record. This method will implicitly call insert if the object does not already exist in the database.

This method will not be generated if readonly is set or for tables which do not have a primary key.

TO DO

  • Verify functionality with DBD back-ends other than SQLite

  • Add support for multi-level package hierarchies

  • Allow all Ormlette functions to be overridden, not just new and accessors

  • Add transaction support

  • Cache loaded objects to prevent duplication

CREDITS

Although it is not intended as a drop-in replacement, Ormlette's API and general coding style are heavily influenced by Adam Kennedy's ORLite.

AUTHOR

Dave Sherohman <dsheroh@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2012 by Dave Sherohman.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.

2 POD Errors

The following errors were encountered while parsing the POD:

Around line 465:

You forgot a '=back' before '=head3'

Around line 522:

=back without =over