From Code to Community: Sponsoring The Perl and Raku Conference 2025 Learn more

NAME

ObjectDB - usable ORM

SYNOPSIS

package MyDB;
use base 'ObjectDB';
sub init_db {
...
return $dbh;
}
package MyAuthor;
use base 'MyDB';
__PACKAGE__->meta(
table => 'author',
auto_increment => 'id',
discover_schema => 1,
generate_columns_methods => 1,
generate_related_methods => 1,
relationships => {
books => {
type => 'one to many',
class => 'MyBook',
map => { id => 'author_id' }
}
}
);
package MyBook;
use base 'MyDB';
__PACKAGE__->meta(
table => 'book',
auto_increment => 'id',
discover_schema => 1,
generate_columns_methods => 1,
generate_related_methods => 1,
relationships => {
author => {
type => 'many to one',
class => 'MyAuthor',
map => { author_id => 'id' }
}
}
);
my $book_by_id = MyBook->new(id => 1)->load(with => 'author');
my @books_authored_by_Pushkin = MyBook->table->find(where => [ 'author.name' => 'Pushkin' ]);
$author->create_related('books', title => 'New Book');

DESCRIPTION

ObjectDB is a lightweight and flexible object-relational mapper. While being light it stays usable. ObjectDB borrows many things from Rose::DB::Object, but unlike in the last one columns are not objects, everything is pretty much straightforward and flat.

Supported servers: SQLite, MySQL, PostgreSQL.

STABILITY

This module is used in several productions, under heavy load and big volumes.

PERFORMANCE

When performance is a must but you don't want to switch back to DBI take a look at find_by_compose, find_by_sql methods and at rows_as_hashes option in ObjectDB::Table.

Latest benchmarks

# Create
Rate create DBI
create 10204/s -- -73%
DBI 37975/s 272% --
# Select 1
Rate find find_by_compose find_by_sql DBI
find 4478/s -- -36% -80% -91%
find_by_compose 7042/s 57% -- -69% -86%
find_by_sql 22556/s 404% 220% -- -56%
DBI 51724/s 1055% 634% 129% --
# Select many
Rate find find_by_compose find_by_sql DBI
find 5618/s -- -21% -76% -89%
find_by_compose 7109/s 27% -- -69% -86%
find_by_sql 23077/s 311% 225% -- -53%
DBI 49180/s 775% 592% 113% --
# Select many with iterator
Rate find_by_sql find_by_compose find
find_by_sql 25.8/s -- -18% -19%
find_by_compose 31.5/s 22% -- -2%
find 32.1/s 24% 2% --
find_by_compose (hash) 201/s 677% 537% 526%
find (hash) 202/s 680% 539% 528%
find_by_sql (hash) 415/s 1505% 1215% 1193%
DBI 1351/s 5128% 4184% 4109%
find_by_compose (hash) find (hash) find_by_sql (hash) DBI
find_by_sql -87% -87% -94% -98%
find_by_compose -84% -84% -92% -98%
find -84% -84% -92% -98%
find_by_compose (hash) -- -0% -52% -85%
find (hash) 0% -- -51% -85%
find_by_sql (hash) 107% 106% -- -69%
DBI 573% 570% 226% --

Meta auto discovery and method generation

When you have DBIx::Inspector installed meta can be automatically discovered without the need to specify columns. And special methods for columns and relationships are automatically generated.

Actions on columns

Methods

set_columns

Set columns.

$book->set_columns(title => 'New Book', pages => 140);
set_column

Set column.

$book->set_column(title => 'New Book');
get_column
my $title = $book->get_column('title');
column

A shortcut for set_column/get_column.

$book->column(title => 'New Book');
my $title = $book->column('title');

Actions on rows

Main ObjectDB instance represents a row object. All actions performed on this instance are performed on one row. For performing actions on several rows see ObjectDB::Table.

Methods

create

Creates a new row. If meta has an auto_increment column then it is properly set.

my $author = MyAuthor->new(name => 'Me')->create;

It is possible to create related objects automatically:

my $author = MyAuthor->new(
name => 'Me',
books => [{title => 'Book1'}, {title => 'Book2'}]
)->create;

Which is a convenient way of calling C <create_related> manually .

load

Loads an object by primary or unique key.

my $author = MyAuthor->new(id => 1)->load;

It is possible to load an object with related objects.

my $book = MyBook->new(title => 'New Book')->load(with => 'author');
update

Updates an object.

$book->set_column(title => 'Old Title');
$book->update;
delete

Deletes an object. Related objects are NOT deleted.

$book->delete;

Actions on tables

In order to perform an action on table a ObjectDB::Table object must be obtained via table method (see ObjectDB::Table for all available actions). The only exception is find, it is available on a row object for convenience.

MyBook->table->delete; # deletes ALL records from MyBook

Methods

Returns preloaded related objects or loads them on demand.

# same as find_related but with caching
my $description = $book->related('book_description');
# returns from cache
my $description = $book->related('book_description');

Creates related object, setting appropriate foreign keys. Accepts a list, a hash reference, an object.

$author->create_related('books', title => 'New Book');
$author->create_related('books', MyBook->new(title => 'New Book'));

Finds related object.

my $books = $author->find_related('books', where => [title => 'New Book']);

Updates related object.

$author->update_related(
'books',
set => {title => 'Old Book'},
where => [title => 'New Book']
);

Deletes related object.

$author->delete_related('books', where => [title => 'New Book']);

Transactions

All the exceptions will be catched, a rollback will be run and exceptions will be rethrown. It is safe to use rollback or commit inside of a transaction when you want to do custom exception handling.

MyDB->txn(
sub {
... do smth that can throw ...
}
);

txn's return value is preserved, so it is safe to do something like:

my $result = MyDB->txn(
sub {
return 'my result';
}
);

Methods

txn

Accepts a subroutine reference, wraps code into eval and runs it rethrowing all exceptions.

commit

Commit transaction.

rollback

Rollback transaction.

Utility methods

Methods

meta

Returns meta object. See ObjectDB::Meta.

init_db

Returns current DBI instance.

is_modified

Returns 1 if object is modified.

is_in_db

Returns 1 if object is in database.

Checks if related objects are loaded.

clone

Clones object preserving all columns except primary or unique keys.

to_hash

Converts object into a hash reference, including all preloaded objects.

CREDITS

kitt-vl (github/kitt-vl)

AUTHOR

Viacheslav Tykhanovskyi

COPYRIGHT AND LICENSE

Copyright 2013-2017, Viacheslav Tykhanovskyi.

This module is free software, you may distribute it under the same terms as Perl.