# NAME `Test::DBIC::SQLite` - Connect to and deploy a [`DBIx::Class::Schema`](https://metacpan.org/pod/DBIx%3A%3AClass%3A%3ASchema) on SQLite # SYNOPSIS The preferred way: ```perl #! perl -w use Test::More; use Test::DBIC::SQLite; my $t = Test::DBIC::SQLite->new( schema_class => 'My::Schema', pre_deploy_hook => \&define_functions, ); my $schema = $t->connect_dbic_ok(); my $thing = $schema->resultset('MyTable')->search( { name => 'Anything' }, { columns => [ { ul_name => \'uc_last(name)' } ] } )->first; is( $thing->get_column('ul_name'), 'anythinG', "SELECT uc_last(name) AS ul_name FROM ...; works!" ); $schema->storage->disconnect; $t->drop_dbic_ok(); done_testing(); # select uc_last('Stupid'); -- stupiD # these functions will only exist within this database connection sub define_functions { my ($schema) = @_; my $dbh = $schema->storage->dbh; $dbh->sqlite_create_function( 'uc_last', 1, sub { my ($str) = @_; $str =~ s{(.*)(.)$}{\L$1\U$2}; return $str }, ); } ``` The compatible with `v0.01` way: ```perl #! perl -w use Test::More; use Test::DBIC::SQLite; my $schema = connect_dbic_sqlite_ok('My::Schema'); ... $schema->storage->disconnect; drop_dbic_sqlite_ok(); done_testing(); ``` # DESCRIPTION This is a re-implementation of `Test::DBIC::SQLite v0.01` that uses the [`Moo::Role`](https://metacpan.org/pod/Moo::Role): [`Test::DBIC::DBDConnector`](#testdbicdbdconnector). It will `import()` [`warnings`](https://metacpan.org/pod/warnings) and [`strict`](https://metacpan.org/pod/strict) for you. ## **`Test::DBIC::SQLite->new`** ```perl my $t = Test::DBIC::SQLite->new(%parameters); my $schema = $t->connect_dbic_ok(); ... $schema->storage->disconnect(); $t->drop_dbic_ok(); ``` ### Parameters Named, list: - **_`schema_class`_ => `$schema_class`** (_Required_) The class name of the [DBIx::Class::Schema](https://metacpan.org/pod/DBIx::Class::Schema) to use for the database connection. - **_`dbi_connect_info`_ => `$sqlite_dbname`** (_Optional_, `:memory:`) The default is **`:memory:`** which will create a temporary in-memory database. One can also pass a file name for a database on disk. See [MyDBD\_connection\_parameters](#implementation-of-mydbd_connection_parameters). - **_`pre_deploy_hook`_ => `$pre_deploy_hook`** (_Optional_) This is an optional `CodeRef` that will be executed right after the connection is established but before `$schema->deploy` is called. The CodeRef will only be called if deploy is also needed. See [MyDBD\_check\_wants\_deploy](#implementation-of-mydbd_check_wants_deploy). - **_`post_connect_hook`_ => `$post_connect_hook`** (_Optional_) This is an optional `CodeRef` that will be executed right after deploy (if any) and just before returning the schema instance. Useful for populating the database. ### Returns An initialised instance of `Test::DBIC::SQLite`. ## `$td->connect_dbic_ok` This method is inherited from [Test::DBIC::DBDConnector](https://metacpan.org/pod/Test%3A%3ADBIC%3A%3ADBDConnector). ### Returns An initialised instance of `$schema_class`. ## `$td->drop_dbic_ok` This method implements `rm $dbname`, in order not to litter your test directory with left over test databases. **NOTE**: Make sure you called `$schema->storage->disconnect()` first. **NOTE**: If the test-object goes out of scope without calling `$td->drop_dbic_ok()`, the destructor will try to remove the file. Use `$Test::DBIC::SQLite::LeaveCreatedDatabases = 1` to keep the file for debugging. ## `connect_dbic_sqlite_ok(@parameters)` Create a SQLite3 database and deploy a dbic\_schema. This function is provided for compatibility with `v0.01` of this module. See [Test::DBIC::SQLite->new](#test-dbic-sqlite-new) for further information, although only these 3 arguments are supported. ### Parameters Positional: 1. **`$schema_class`** (_Required_) The class name of the [DBIx::Class::Schema](https://metacpan.org/pod/DBIx%3A%3AClass%3A%3ASchema) to use for the database connection. 2. **`$sqlite_dbname`** (_Optional_, `:memory:`) The default is **`:memory:`** which will create a temporary in-memory database. One can also pass a file name for a database on disk. See [MyDBD\_connection\_parameters](#implementation-of-mydbd_connection_parameters). 3. **`$post_connect_hook`** (_Optional_) This is an optional `CodeRef` that will be executed right after deploy (if any) and just before returning the schema instance. Useful for populating the database. ### Returns An initialised instance of `$schema_class`. ## `drop_dbic_sqlite_ok()` This function uses the cached information of the call to `connect_dbic_sqlite_ok()` and clears it after the database is dropped, using another temporary connection to the template database. See [the `drop_dbic_ok()` method](#td-drop_dbic_ok). ## Implementation of `MyDBD_connection_parameters` The value of the `dbi_connect_info` parameter to the \`new()\` constructor, is passed to this method. For this _SQLite3_ implementation this is a single string that should contain the name of the database on disk, that can be accessed with `sqlite3 (1)`. By default we use the "special" value of **`:memory:`** to create a temporary in-memory database. This method returns a list of parameters to be passed to `DBIx::Class::Schema->connect()`. Keep in mind that the last argument (options-hash) will always be augmented with key-value pair: `ignore_version => 1`. ### Note At this moment we do not support the `uri=file:$db_file_name?mode=rwc` style of _dsn_, only the `dbname=$db_file_name` style, as we only support `$sqlite_dbname` as a single parameter. ## Implementation of `MyDBD_check_wants_deploy` For in-memory databases this will always return **true**. For databases on disk this will return **true** if the file does not exist and **false** if it does. --- --- # `Test::DBIC::DBDConnector` [`Moo::Role`](https://metacpan.org/pod/Moo::Role) for writing `Test::DBIC::yourDBD` implementations # SYNOPSIS ```perl package Test::DBIC::SQLite; use Moo; with 'Test::DBIC::DBDConnector'; sub MyDBD_connection_parameters { my $class = shift; my ($db_name) = @_; $db_name //= ':memory:'; return [ "dbi:SQLite:dbname=$db_name" ]; } sub MyDBD_check_wants_deploy { my $class = shift; my ($connection_params) = @_; my ($db_name) = $connection_params->[0] =~ m{dbname=(.+)(?:;|$)}; my $wants_deploy = $db_name eq ':memory:' ? 1 : ((not -f $db_name) ? 1 : 0); return $wants_deploy; } use namespace::autoclean 0.16; 1; ``` This could be used as: ```perl #! perl -w use Test::More; use Test::DBIC::SQLite; my $t = Test::DBIC::SQLite->new(schema_class => 'My::Schema'); my $schema = $t->connect_dbic_ok(); $t->drop_dbic_ok(); done_testing(); ``` # DESCRIPTION This `Moo::Role` is for Tester-modules that implement the connection-test function for the combination of any `DBIx::Class::Schema` and a specific database-engine (`DBD::yourDBD`). ## `Test::DBIC::->new(@parameters)` The connection test does these steps: * create connection_parameters (*`MyDBD_connection_parameters`*) * create a database connection (`DBIx::Class::AnySchema->connect()`) * check the need for a fresh deployment of the schema (`wants_deploy`) * if `wants_deploy`, run the provided pre-deploy-hook (if any) * if `wants_deploy`, run `$schema->deploy` * run the post-connect-hook (if any) Your implementation will only be able to "shape" the `dbi_connect_info` parameter (*`$dbi_connect_info`*). ### Parameters Named: * **`schema_class` => `$dbic_schema_class`** (*Required*) This is the name of the [DBIx::Class::Schema](https://metacpan.org/pod/DBIx::Class::Schema) subclass of the ORM that the user who is writing the tests must provide. * **`dbic_connect_info` => `$your_dbd_connect_info`** (*Optional*) This parameter will contain the information that your `MyDBD_connection_parameters()` method implementation needs to return an ArrayRef of parameters for `DBIx::Class::Schema->connect()`. This is the only parameter your `Test::DBIC::yourDBD` must take care of in order to provide a successful connection/deploy for the user's test databases. This is done by implementing the two required methods `MyDBD_connection_parameters` and `MyDBD_check_wants_deploy`. * **`pre_deploy_hook` => `$pre_deploy_hook`** (*Optional*) A CodeRef to execute *before* `$schema->deploy` is called if `wants_deploy`. This CodeRef might be provided by the user who is writing the tests and is called with an instantiated `$your_schema_class` object as argument. * **`post_connect_hook` => `$post_connect_hook`** (*Optional*) A CodeRef to execute *after* `$schema->deploy` (if at all) is called. This CodeRef might be provided by the user who is writing the tests and is called with an instantiated `$your_schema_class` object as argument. ## The `connect_dbic_ok` method This is the base connection test for all `Test::DBIC::` implementations and probably shouldn't be overridden. The method can serve as a *instance* method as well as a *class* method. ### Retruns In both cases it returns an instantiated `DBIx::Class::Schema` object one wants to test. ## `$instance->connect_dbic_ok` ### Parameters None. ## `Test::DBIC::->connect_dbic_ok` ### Parameters As a *class* method it takes the same parameters as the [new method](#new-parameters-). ## **Required**: `MyDBD_connection_parameters($your_dbd_connect_info)` Your class will have to implement this method in a way that is appropriate for *yourDBD*. For [`DBD::SQLite`](https://metacpan.org/pod/DBD::SQLite) one could use a single argument for the filename and choose `:memory:` when not defined. Other database drivers may need a lot more more information and you could use an ArrayRef or HashRef to make sure the correct information can be returned for the connection. ### Parameters Positional: 1. **`$your_dbd_connect_info`** (unknown type) What the exact content of this parameter is, will depend on the database driver and the interface one creates for the tester module. ### Response This method should return an ArrayRef with the 4 elements supported by `DBI->connect()` and `DBIx::Class::Schema->connect()`. 1. **`dsn`** like `dbi:yourDBD:dbname=blah;...` 2. **`username`** 3. **`password`** 4. **`options`** A HashRef with extra option. ### Note This `Moo::Role` augments this method (via `around`) in order to always make sure that the `options` HashRef gets the key-pair `ignore_version => 1`, one can examine this option from within the `DBIx::Class::Schema->connect()` method to ignore a check for software and database versions. ## **Required**: `MyDBD_check_wants_deploy($your_dbd_connection_parameters)` Your class will have to implement this method in a way that is appropriate for *yourDBD*. This method gets the result of [`MyDBD_connection_parameters`](#required-mydbd_connection_parameters-your_dbd_connect_info-) passed. You will have to define a way to determine on what criteria you're going to have the code invoke the `$schema->deploy` method. ### Parameters Positional: 1. **`$your_dbd_connection_parameters`** (ArrayRef) This is the ArrayRef that was returned by your implementation of `MyDBD_connection_parameters`. ### Response The response of this method is interpreted as a perl `boolean`. --- # COPYRIGHT © `MMXXI` - Abe Timmerman # LICENSE This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.