Создание классов схемы
В части 1 мы заложили основу нашего проекта, а в этой части мы сосредоточимся на создании базы данных и схемы классов. Схема классов относится к классам, основанным на базе данных и ее таблицах.
После того, как мы сгенерируем классы, мы создадим средство доступа для возврата данных особым образом, а затем метод для выполнения настраиваемого поиска. После каждого этапа мы можем запускать тесты, чтобы проверить, что отсутствует, а что работает.
Генерация схемы
Теперь мы воспользуемся функцией make_schema_at, которая экспортируется DBIx :: Class :: Schema :: Loader, для создания классов схемы. make_schema_at просто считывает схему СУБД, в нашем случае app.db, и создает классы на основе своих таблиц.
Создать сценарий схемы
Откройте файл scripts / make_schema.pl и введите следующие строки.
#!/usr/bin/env perl use strict; use warnings; use DBIx::Class::Schema::Loader qw(make_schema_at); my @dsn = 'dbi:SQLite:dbname=app.db'; my %options = ( dump_directory => './lib' ); make_schema_at('App::Schema' => \%options, \@dsn);
Краткое объяснение этого файла - @dsn определяет, как устанавливается соединение с базой данных, а % options содержит информацию, которая может использоваться для создания классов. В этом случае dump_directory указывает, в каком каталоге будут созданы классы. Наконец, вызывается make_schema_at для генерации классов в пространстве имен App :: Schema.
Теперь запустим наш скрипт генерации:
perl scripts/make_schema.pl
Теперь содержимое каталога lib должно выглядеть следующим образом:
lib/ └── App ├── Schema │ └── Result │ └── User.pm └── Schema.pm
Запустите тест с помощью verify -lv t / basic.t, и результат должен быть похож на следующий.
ok 1 — use App::Schema; not ok 2 — App::Schema::Result::User->can('fullname') …
Первый тест должен пройти, поскольку App :: Schema теперь существует. Однако остальные четыре завершатся ошибкой, потому что ни метод доступа fullname, ни метод age_less_than еще не реализованы. Это рассматривается в следующих разделах.
Настраиваемые поля и поисковые запросы
Хорошо, теперь, когда схема класса сгенерирована, пора добавить к ней некоторые настраиваемые функции. Мы начнем с определения настраиваемого средства доступа, возвращающего полное имя пользователя. Это более короткий способ, чем необходимость вручную связывать имя и фамилию везде, где требуется полное имя пользователя.
Добавление метода доступа полного имени
Откройте файл lib / App / Schema / Result / User.pm и добавьте следующий метод.
sub fullname { my $self = shift; return $self->firstname . ' ' . $self->lastname; }
Примечание. Вышеупомянутая подпрограмма должна быть определена под строкой следующего содержания:
# Created by DBIx::Class::Schema::Loader v0.07045 @ 2016–08–07 10:02:31 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:
Если вы вносите изменения в свою базу данных, например добавляете новый столбец в таблицу пользователей, повторный запуск make_schema.pl обновит модуль User.pm, чтобы отразить изменения. Однако он не удаляет код, написанный под указанной строкой. Внесение любых изменений выше этой строки может привести к сбою создания схемы класса.
Протестируйте аксессор
Запустите тест еще раз, и результаты должны выглядеть так:
ok 1 — use App::Schema; ok 2 — App::Schema::Result::User->can('fullname') ok 3 — Should read from set using a custom accessor not ok 4 — App::Schema::ResultSet::User->can('age_less_than')
Второй и третий тесты теперь пройдены, поскольку fullname определено и работает правильно.
Как видите, метод доступа fullname действует как виртуальный столбец в SQL. Поле полное имя считается виртуальным, поскольку оно не является столбцом в таблице пользователей, но выглядит так. Вместо этого полное имя вычисляется с использованием полей имени и фамилии.
Определите метод пользовательского поиска
Теперь мы определим метод для выполнения пользовательского поиска по пользователям. Этот метод будет определен в классе ResultSet, который можно создать следующим образом:
mkdir -p lib/App/Schema/ResultSet && \ touch lib/App/Schema/ResultSet/User.pm
Теперь откройте файл lib / App / Schema / ResultSet / User.pm и введите следующий код:
package App::Schema::ResultSet::User; use base 'DBIx::Class::ResultSet'; sub age_less_than { my $self = shift; my $age = shift; return $self->find({ age => { '<' => $age }}); } 1;
Протестируйте собственный метод
Запустите тест еще раз, и результат должен быть следующим.
t/basic.t .. ok 1 — use App::Schema; ok 2 — App::Schema::Result::User->can('fullname') ok 3 — should read from set using a custom accessor ok 4 — App::Schema::ResultSet::User->can('age_less_than') ok 5 — should perform search using a custom method 1..5 ok All tests successful.
Вывод выше показывает, что все работает так, как мы и планировали. То есть мы можем получить полное имя пользователя с помощью специального средства доступа и найти всех пользователей младше указанного возраста.
Резюме
Этот пост завершает краткое введение в ORM на Perl из двух частей с помощью DBIx :: Class. Создание схемы класса было достигнуто с помощью одного вызова make_schema_at. Для добавления настраиваемого средства доступа и метода требовалось лишь добавить подпрограмму к модулям Result :: User и ResultSet :: User соответственно. Мы также доказали свою функциональность с помощью Test Driven Development.
Спасибо за чтение, и вы можете порекомендовать эту серию публикаций, нажав кнопку 💚.
Код для обеих частей этой статьи можно найти здесь.