# 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](https://metacpan.org/pod/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](https://metacpan.org/pod/DBI) take a look at `find_by_compose`, `find_by_sql` methods and at `rows_as_hashes` option in [ObjectDB::Table](https://metacpan.org/pod/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](https://metacpan.org/pod/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](https://metacpan.org/pod/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](https://metacpan.org/pod/ObjectDB::Table) object must be obtained via `table` method (see [ObjectDB::Table](https://metacpan.org/pod/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 ## Actions on related objects ### Methods - `related` 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'); - `create_related` 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')); - `find_related` Finds related object. my $books = $author->find_related('books', where => [title => 'New Book']); - `update_related` Updates related object. $author->update_related( 'books', set => {title => 'Old Book'}, where => [title => 'New Book'] ); - `delete_related` 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. - `is_related_loaded` 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.