File Coverage

blib/lib/Test/Mojo/Pg.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Test::Mojo::Pg;
2 2     2   39532 use Mojo::Base -base;
  2         15154  
  2         17  
3 2     2   375 use File::Basename;
  2         2  
  2         153  
4 2     2   1871 use Mojo::Pg;
  0            
  0            
5             use Mojo::Pg::Migrations;
6              
7             our $VERSION = '0.31';
8              
9             has host => undef;
10             has port => undef;
11             has db => 'testdb';
12             has username => undef;
13             has password => undef;
14             has migsql => undef;
15             has verbose => 0;
16              
17             sub construct {
18             my ($self) = @_;
19             $self->drop_database;
20             $self->create_database;
21             }
22              
23             sub deconstruct {
24             my ($self) = @_;
25             $self->drop_database;
26             }
27              
28             sub get_version {
29             my ($self, $p) = @_;
30             my $q_v = 'SELECT version()';
31             my $q_sv = 'SHOW server_version';
32             my $q_svn = 'SHOW server_version_num';
33              
34             my $full_version = $p->db->query($q_v)->array->[0];
35             my $server_version = $p->db->query($q_sv)->array->[0];
36             my $server_version_num = $p->db->query($q_svn)->array->[0];
37             say '-> Pg full version is ' . $full_version
38             if $self->verbose;
39             say '-> Pg server_version is ' . $server_version
40             if $self->verbose;
41             say '-> Pg server_version_num is ' . $server_version_num
42             if $self->verbose;
43             return $server_version_num;
44             }
45              
46             sub connstring {
47             my ($self, $dbms) = @_;
48             my $prefix = 'postgresql://';
49             my $result = $prefix
50             . $self->_connstring_user
51             . $self->_connstring_server;
52             return $result if defined $dbms;
53              
54             $result .= '/' . $self->db;
55              
56             return $result;
57             }
58              
59             sub _connstring_server {
60             my ($self) = @_;
61             return $self->host . ':' . $self->port
62             if defined $self->host and defined $self->port;
63             return $self->host if defined $self->host;
64             return '';
65             }
66              
67             sub _connstring_user {
68             my ($self) = @_;
69             return $self->username . '@' if defined $self->username;
70             return '';
71             }
72              
73             sub drop_database {
74             my ($self) = @_;
75             # Connect to the DBMS
76             my $c = $self->connstring(1);
77             say "Dropping database " . $self->db . " as $c" if $self->verbose;
78             my $p = Mojo::Pg->new($c);
79             $self->remove_connections($p);
80             $p->db->query('drop database if exists ' . $self->db . ';');
81             $p->db->disconnect;
82             }
83              
84             sub create_database {
85             my ($self) = @_;
86             my $c = $self->connstring(1);
87             say "Creating database defined as $c" if $self->verbose;
88             my $p = Mojo::Pg->new($c);
89             $p->db->query('create database '. $self->db .';');
90              
91             if (not defined $self->migsql) {
92             warn 'No migration script - empty database created.';
93             $p->db->disconnect;
94             return 1;
95             }
96              
97             my $db = Mojo::Pg->new($self->connstring);
98             my $migrations = Mojo::Pg::Migrations->new(pg => $db);
99             $migrations->from_file($self->migsql);
100             $migrations->migrate(0)->migrate;
101             $db->db->disconnect;
102             return 1;
103             }
104              
105             sub remove_connections {
106             my ($self, $p) = @_;
107             say 'Removing existing connections' if $self->verbose;
108             my $pf = $self->get_version($p) < 90200 ? 'procpid' : 'pid';
109             my $q = q|SELECT pg_terminate_backend(pg_stat_activity.| . $pf . q|) |
110             . q|FROM pg_stat_activity |
111             . q|WHERE pg_stat_activity.datname='| . $self->db . q|' |
112             . q|AND | . $pf . q| <> pg_backend_pid();|;
113             $p->db->query($q);
114             }
115              
116             =head1 NAME
117              
118             Test::Mojo::Pg - a helper for dealing with Pg during tests
119              
120             =head1 SYNOPSIS
121              
122             use Test::Mojo::Pg;
123             my $db;
124              
125             # Bring up database to prepare for tests
126             BEGIN {
127             $db = Test::Mojo::Pg->new(host => 'ananke', db => 'mydb'), 'Test::Mojo::Pg';
128             $db->construct;
129             }
130              
131             # Tear down the database to clean the environment
132             END {
133             $db->deconstruct;
134             }
135              
136             =head1 DESCRIPTION
137              
138             Test::Mojo::Pg makes the creation and removal of a transitory database during
139             testing when using Mojo::Pg. This is useful when every test should work from a 'clean' database.
140              
141             =head1 CONSTRUCTOR
142              
143             You can either pass options in when calling the constructor or set the attributes later.
144              
145             my $p1 = Test::Mojo::Pg->new();
146             my $p2 = Test::Mojo::Pg->new(host=>'myhost', db => 'db1');
147              
148             Option keys match the attribute names.
149              
150             =head1 ATTRIBUTES
151              
152             The following are the attributes for this module.
153              
154             =head2 host
155              
156             Sets the Postgres server hostname. If omitted, no hostname (or port, if defined)
157             will be configured for the connection string (which effectively means use localhost).
158              
159             =head2 port
160              
161             Sets the Postgres server port. If omitted, no port will be configured for the
162             connection string.
163              
164             =head2 db
165              
166             Sets the test database name.
167              
168             default: testdb
169              
170             =head2 username
171              
172             Sets the login username. If omitted, no username will be provided to the server.
173              
174             =head2 password
175              
176             Sets the login password. If omitted, no password will be provided to the server.
177              
178             =head2 migsql
179              
180             Sets the file to use for Mojo::Pg::Migrations. If no sql file is provided, a
181             warning will be emitted that only an empty database has been provided.
182              
183             =head2 verbose
184              
185             Enables verbose output of operations such as the server's version string.
186              
187             # get the verbose level - 0|1
188             $p->verbose;
189              
190             # set the verbose level to 'on'
191             $p->verbose(1);
192              
193              
194             =head1 METHODS
195              
196             The following are the methods for this module.
197              
198             =head2 connstring
199              
200             Returns the connection string for the database. Returns the connection string
201             for the dbms by passing in '1'.
202              
203             my $testdb_connstring = $testdb->connstring;
204              
205             my $testdb_dbms = $testdb->connstring(1);
206              
207             =head2 construct
208              
209             The construct method removes current connections to the database and
210             the database itself if it exists, creates a new database, and loads the
211             migrations file if it's defined. This normally gets called from the BEGIN block.
212              
213             $testdb->construct;
214              
215             =head2 deconstruct
216              
217             The deconstruct method removes current connections to the database and the
218             database itself if it exists. This normally gets called from the END block.
219              
220             $testdb->desconstruct;
221              
222             =head2 create_database
223              
224             Creates the database as defined by the connection string.
225              
226             $testdb->create_database;
227              
228             =head2 drop_database
229              
230             Drops the database as defined by the connection string.
231              
232             $testdb->drop_database;
233              
234             =head2 get_version
235              
236             my $version = $testdb->get_version;
237              
238             Retrieve the database version.
239              
240             =head2 remove_connections
241              
242             Force removal of connection related data in the dbms. Many times required in
243             order to drop the database.
244              
245             $testdb->remove_connections;
246              
247             =head1 AUTHORS
248              
249             Richard A. Elberger Eriche@cpan.orgE.
250              
251             =head1 MAINTAINERS
252              
253             =over 4
254              
255             =item Richard A. Elberger Eriche@cpan.orgE
256              
257             =back
258              
259              
260             =head1 BUGS
261              
262             See F to report and view bugs.
263              
264              
265             =head1 SOURCE
266              
267             The source code repository for Test::More can be found at
268             F.
269              
270             =head1 COPYRIGHT
271              
272             Copyright 2015 by Richard A. Elberger Eriche@cpan.orgE.
273              
274             This program is free software; you can redistribute it and/or
275             modify it under the same terms as Perl itself.
276              
277             See F
278              
279             =cut
280              
281             1;