Perl: ORM с помощью DBIx::Class (DBIC)

в 16:32, , рубрики: database, orm, perl, sql, sqlite, метки: , , , ,

Доброго времени суток уважаемые Хабрецы!
Здесь я расскажу вам об использовании DBIx::Class, с помощью которого вы сможете реализовать Object Relation Mapping (ORM) на языке Perl. опросы о том, полезен или бесполезен ORM как таковой и другие
риторические размышления в стиле «жили же раньше люди как-то без компьютеров, и зачем они нужны сейчас?!», я обошел стороной. Обо всем об этом прошу в кОменты.
А теперь собственно об использовании DBIx::Class.

DBIx::Class — перл модуль, реализующий ORM подход, позволяющий использовать объекты(классы) вместо традиционного SQL. Для объяснения некоторых принципов нам потребуется тестовая (SQLite) база данных, самая баянистая бд — книги/авторы.

create table authors (
id integer primary key autoincrement,
name text not null,
);
create table books (
id integer primary key autoincrement,
title text not null,
author integer,
foreign key (author) references authors(id),
)

Теперь пару слов об аббревиатуре CRUD.
C — create, R — retrieve, U — update, D — delete (создать, искать, обновить, удалить).
Это основные операции, которые применяются в отношении бд.

СОЗДАТЬ

my $book = $model_book->create({
title => 'Twilight: New Moon',
author => $id_author,
});
для книг
my $steph = $author_model->create({
name => 'Stephenie Meyer',
});

для авторов

Чтобы добавить еще одну книгу данного автора, пишем:

my $book = $steph->add_to_books({
title => 'Twilight: Eclipse',
});

или так:

my $book = $steph->create_related(
'books', {
title => 'Twilight: Eclipse',
});

ИСКАТЬ
my $book = $model_book->find($id_book);
my $book = $model_book->search({
title => 'Twilight: New Moon',
})->single();
my @books = $model_book->search({
author => $id_author,
})->all();
ОБНОВИТЬ
$book->update({
title => 'Censure',
});
УДАЛИТЬ (наконец-то)

$book->delete();
Создаем модели(классы) для наших таблиц

Существует два способа сделать это, ручками и автоматически. Как перл программист, я опишу второй способ, который создаст результирующие классы автоматически (ручной способ отличается только тем, что вы эти классы создаете сами, и для каждого атрибута в sql таблице прописываете его характеристики).
Для наших целей, нам потребуется так называемый Loader (DBIx::Class::Schema::Loader), вспомогательный класс который фиксирует все изменения в базе данных и автоматически применяет их к соотвествующим классам.

package Library::DBIC;
use base qw/DBIx::Class::Schema::Loader/;
use strict;
use warnings;
my @connection_args = (
"dbi:SQLite:books.db",
{ loader_options => {
debug => $ENV{DBIC_TRACE} || 0,
use_namespaces => 1,
}
});
__PACKAGE__->connection(@connection_args);
__PACKAGE__->load_namespaces;
1;

Для предоставления результатов работы с бд (кортеж или набор результатов) используют *::DBIC::Result::[TableName] и *::DBIC::ResultSet::[TableName] соответственно.

Используем в приложении

use strict;
use warnings;
my $model_author = Library::DBIC->resultset('Authors');
my $author = $model_author->create( { name => 'William Gibson' } );
my $book = $author->add_to_books( { title => 'Neuromancer' } );

Благодарю за внимание.

p.s. Книги, упомянутые в 1й половине статьи прочитаны и просмотрены не были, честное пионерское.

Автор: edem

* - обязательные к заполнению поля