# 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::<yourDBD>->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::<yourDBD>`
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::<yourDBD>->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 <abeltje@cpan.org>
# 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.