From 3a91f6b6816fa1f09f5f1bfe84db30e7020bd16e Mon Sep 17 00:00:00 2001 From: Anthony Brummett Date: Wed, 26 Nov 2014 11:50:46 -0600 Subject: [PATCH 1/3] extract function to connect to a database --- t/commands.t | 44 +++++++++++++++----------------------------- 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/t/commands.t b/t/commands.t index 55b2eb6..0c64c58 100644 --- a/t/commands.t +++ b/t/commands.t @@ -34,10 +34,7 @@ subtest 'create template from database' => sub { # Make a table in the database my $table_name = "test_table_$$"; { - my $dbi = DBI->connect(sprintf('dbi:Pg:dbname=%s;host=%s;port=%s', - $pg->name, $pg->host, $pg->port), - $pg->owner, - ''); + my $dbi = _connect_to_database($pg->name, $pg->owner); ok($dbi->do("CREATE TABLE $table_name (foo integer NOT NULL PRIMARY KEY)"), 'Create table in base database'); $dbi->disconnect; @@ -62,9 +59,7 @@ subtest 'create template from database' => sub { ok($template, 'get created template'); # connect to the template database - my $dbi = DBI->connect(sprintf('dbi:Pg:dbname=%s;host=%s;port=%s', - $template->name, $pg->host, $pg->port), - $pg->owner, ''); + my $dbi = _connect_to_database($template->name, $pg->owner); ok($dbi->do("SELECT foo FROM $table_name WHERE FALSE"), 'table exists in template database'); $dbi->disconnect; @@ -91,10 +86,7 @@ subtest 'create database with owner' => sub { # Make a table in the template my $table_name = "test_table_$$"; { - my $dbi = DBI->connect(sprintf('dbi:Pg:dbname=%s;host=%s;port=%s', - $pg->name, $pg->host, $pg->port), - $pg->owner, - ''); + my $dbi = _connect_to_database($pg->name, $pg->owner); ok($dbi->do("CREATE TABLE $table_name (foo integer NOT NULL PRIMARY KEY)"), 'Create table in base template'); $dbi->disconnect; @@ -114,9 +106,7 @@ subtest 'create database with owner' => sub { ok($database, 'execute'); # connect to the newly created database - my $dbi = DBI->connect(sprintf('dbi:Pg:dbname=%s;host=%s;port=%s', - $database->name, $config->db_host, $config->db_port), - $pg->owner, ''); + my $dbi = _connect_to_database($database->name, $pg->owner); ok($dbi->do("SELECT foo FROM $table_name WHERE FALSE"), 'table exists in template database'); $dbi->disconnect; @@ -146,10 +136,7 @@ subtest 'create database with invalid owner' => sub { # Make a table in the template my $table_name = "test_table_$$"; { - my $dbi = DBI->connect(sprintf('dbi:Pg:dbname=%s;host=%s;port=%s', - $pg->name, $pg->host, $pg->port), - $pg->owner, - ''); + my $dbi = _connect_to_database($pg->name, $pg->owner); ok($dbi->do("CREATE TABLE $table_name (foo integer NOT NULL PRIMARY KEY)"), 'Create table in base template'); $dbi->disconnect; @@ -183,10 +170,7 @@ subtest 'create database from template' => sub { # Make a table in the template my $table_name = "test_table_$$"; { - my $dbi = DBI->connect(sprintf('dbi:Pg:dbname=%s;host=%s;port=%s', - $pg->name, $pg->host, $pg->port), - $pg->owner, - ''); + my $dbi = _connect_to_database($pg->name, $pg->owner); ok($dbi->do("CREATE TABLE $table_name (foo integer NOT NULL PRIMARY KEY)"), 'Create table in base template'); $dbi->disconnect; @@ -205,9 +189,7 @@ subtest 'create database from template' => sub { ok($database, 'execute'); # connect to the newly created database - my $dbi = DBI->connect(sprintf('dbi:Pg:dbname=%s;host=%s;port=%s', - $database->name, $config->db_host, $config->db_port), - $database->owner, ''); + my $dbi = _connect_to_database($database->name, $database->owner); ok($dbi->do("SELECT foo FROM $table_name WHERE FALSE"), 'table exists in template database'); $dbi->disconnect; @@ -293,10 +275,7 @@ subtest 'delete with connections' => sub { schema => $schema, )->execute(); ok($database, 'Create database'); - my $dbh = DBI->connect(sprintf('dbi:Pg:dbname=%s;host=%s;port=%s', - $database->name, $config->db_host, $config->db_port), - $database->owner, - ''); + my $dbh = _connect_to_database($database->name, $database->owner); ok($dbh, 'connect to created database'); my $cmd = TestDbServer::Command::DeleteDatabase->new( database_id => $database->id, @@ -335,3 +314,10 @@ sub create_new_schema { return TestDbServer::Schema->connect($config->db_connect_string, $config->db_user, $config->db_password); } +sub _connect_to_database { + my($name, $owner) = @_; + + return DBI->connect(sprintf('dbi:Pg:dbname=%s;host=%s;port=%s', + $name, $config->db_host, $config->db_port), + $owner, ''); +} From da8247a286a7d18fe51a7b53ee45496e6b15b33b Mon Sep 17 00:00:00 2001 From: Anthony Brummett Date: Wed, 26 Nov 2014 12:46:12 -0600 Subject: [PATCH 2/3] Command::DeleteTemplate now removes the template database Not removing it was a bug --- lib/TestDbServer/Command/DeleteTemplate.pm | 12 ++++++++++++ lib/TestDbServer/TemplateRoutes.pm | 4 ++++ t/commands.t | 11 ++++++++--- t/template.t | 11 ++++++++++- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/lib/TestDbServer/Command/DeleteTemplate.pm b/lib/TestDbServer/Command/DeleteTemplate.pm index bcefbc5..a46b8ac 100644 --- a/lib/TestDbServer/Command/DeleteTemplate.pm +++ b/lib/TestDbServer/Command/DeleteTemplate.pm @@ -7,6 +7,9 @@ use namespace::autoclean; has template_id => ( isa => 'Str', is => 'ro', required => 1 ); has schema => (isa => 'TestDbServer::Schema', is => 'ro', required => 1 ); +has superuser => ( isa => 'Str', is => 'ro', required => 1 ); +has host => ( isa => 'Str', is => 'ro', required => 1 ); +has port => ( isa => 'Str', is => 'ro', required => 1 ); sub execute { my $self = shift; @@ -16,6 +19,15 @@ sub execute { Exception::TemplateNotFound->throw(name => $self->template_id); } + my $pg = TestDbServer::PostgresInstance->new(name => $template->name, + host => $self->host, + port => $self->port, + owner => $template->owner, + superuser => $self->superuser, + ); + + $pg->dropdb(); + $template->delete(); } diff --git a/lib/TestDbServer/TemplateRoutes.pm b/lib/TestDbServer/TemplateRoutes.pm index e85c6e9..6f1dc5e 100644 --- a/lib/TestDbServer/TemplateRoutes.pm +++ b/lib/TestDbServer/TemplateRoutes.pm @@ -151,9 +151,13 @@ sub delete { my $return_code; try { + my($host, $port) = $self->app->host_and_port_for_created_database(); my $cmd = TestDbServer::Command::DeleteTemplate->new( template_id => $id, schema => $schema, + superuser => $self->app->configuration->db_user, + host => $host, + port => $port, ); $schema->txn_do(sub { $cmd->execute(); diff --git a/t/commands.t b/t/commands.t index 0c64c58..c9ba762 100644 --- a/t/commands.t +++ b/t/commands.t @@ -207,7 +207,7 @@ subtest 'create database from template' => sub { }; subtest 'delete template' => sub { - plan tests => 3; + plan tests => 4; my $pg = new_pg_instance(); @@ -218,12 +218,17 @@ subtest 'delete template' => sub { my $cmd = TestDbServer::Command::DeleteTemplate->new( template_id => $template->template_id, - schema => $schema); + schema => $schema, + host => $config->db_host, + port => $config->db_port, + superuser => $config->db_user); ok($cmd, 'new'); ok($cmd->execute(), 'execute'); ok(! $schema->find_template($template->template_id), - 'template is deleted'); + 'template record is deleted'); + + ok(! _connect_to_database($pg->name, $pg->owner), 'cannot connect to deleted template database'); }; subtest 'delete database' => sub { diff --git a/t/template.t b/t/template.t index a955a4b..e5d9713 100644 --- a/t/template.t +++ b/t/template.t @@ -81,7 +81,16 @@ subtest 'get' => sub { subtest 'delete' => sub { plan tests => 8; - my $template_id = $templates[0]->template_id; + my $template_to_delete = $templates[0]; + my $template_id = $template_to_delete->id; + + # The template has to exist as a real database before we can delete it + my $dbh = DBI->connect(sprintf('dbi:Pg:dbname=%s;host=%s;port=%s', + $config->default_template_name, $config->db_host, $config->db_port), + $config->db_user, ''); + $dbh->do(sprintf('CREATE DATABASE "%s"', $template_to_delete->name)); + $dbh->disconnect; + $t->delete_ok("/templates/$template_id") ->status_is(204); From 2f44f4aa1810ec8d1ac6df6a670939e593e736bd Mon Sep 17 00:00:00 2001 From: Anthony Brummett Date: Wed, 26 Nov 2014 13:02:37 -0600 Subject: [PATCH 3/3] Extract common execute() from delete template and database commands --- lib/TestDbServer/Command/DeleteDatabase.pm | 33 ++----------- lib/TestDbServer/Command/DeleteTemplate.pm | 29 ++---------- .../Command/DeleteTemplateOrDatabase.pm | 47 +++++++++++++++++++ 3 files changed, 57 insertions(+), 52 deletions(-) create mode 100644 lib/TestDbServer/Command/DeleteTemplateOrDatabase.pm diff --git a/lib/TestDbServer/Command/DeleteDatabase.pm b/lib/TestDbServer/Command/DeleteDatabase.pm index 0d63867..ac9423d 100644 --- a/lib/TestDbServer/Command/DeleteDatabase.pm +++ b/lib/TestDbServer/Command/DeleteDatabase.pm @@ -1,39 +1,16 @@ package TestDbServer::Command::DeleteDatabase; -use TestDbServer::PostgresInstance; -use TestDbServer::Exceptions; +use TestDbServer::Command::DeleteTemplateOrDatabase; use Moose; use namespace::autoclean; +extends 'TestDbServer::Command::DeleteTemplateOrDatabase'; has database_id => ( isa => 'Str', is => 'ro', required => 1 ); -has schema => (isa => 'TestDbServer::Schema', is => 'ro', required => 1 ); -has superuser => ( isa => 'Str', is => 'ro', required => 1 ); -has host => ( isa => 'Str', is => 'ro', required => 1 ); -has port => ( isa => 'Str', is => 'ro', required => 1 ); -sub execute { - my $self = shift; - - my $database = $self->schema->find_database($self->database_id); - unless ($database) { - Exception::DatabaseNotFound->throw(name => $self->database_id); - } - - my $pg = TestDbServer::PostgresInstance->new( - name => $database->name, - host => $self->host, - port => $self->port, - owner => $database->owner, - superuser => $self->superuser, - ); - - $pg->dropdb(); - - $database->delete(); - - return 1; -} +sub _entity_find_method { 'find_database' } +sub _entity_id_method { 'database_id' } +sub _not_found_exception { 'Exception::DatabaseNotFound' } __PACKAGE__->meta->make_immutable; diff --git a/lib/TestDbServer/Command/DeleteTemplate.pm b/lib/TestDbServer/Command/DeleteTemplate.pm index a46b8ac..601c844 100644 --- a/lib/TestDbServer/Command/DeleteTemplate.pm +++ b/lib/TestDbServer/Command/DeleteTemplate.pm @@ -1,35 +1,16 @@ package TestDbServer::Command::DeleteTemplate; -use TestDbServer::Exceptions; +use TestDbServer::Command::DeleteTemplateOrDatabase; use Moose; use namespace::autoclean; +extends 'TestDbServer::Command::DeleteTemplateOrDatabase'; has template_id => ( isa => 'Str', is => 'ro', required => 1 ); -has schema => (isa => 'TestDbServer::Schema', is => 'ro', required => 1 ); -has superuser => ( isa => 'Str', is => 'ro', required => 1 ); -has host => ( isa => 'Str', is => 'ro', required => 1 ); -has port => ( isa => 'Str', is => 'ro', required => 1 ); -sub execute { - my $self = shift; - - my $template = $self->schema->find_template($self->template_id); - unless ($template) { - Exception::TemplateNotFound->throw(name => $self->template_id); - } - - my $pg = TestDbServer::PostgresInstance->new(name => $template->name, - host => $self->host, - port => $self->port, - owner => $template->owner, - superuser => $self->superuser, - ); - - $pg->dropdb(); - - $template->delete(); -} +sub _entity_find_method { 'find_template' } +sub _entity_id_method { 'template_id' } +sub _not_found_exception { 'Exception::TemplateNotFound' } __PACKAGE__->meta->make_immutable; diff --git a/lib/TestDbServer/Command/DeleteTemplateOrDatabase.pm b/lib/TestDbServer/Command/DeleteTemplateOrDatabase.pm new file mode 100644 index 0000000..e181d48 --- /dev/null +++ b/lib/TestDbServer/Command/DeleteTemplateOrDatabase.pm @@ -0,0 +1,47 @@ +package TestDbServer::Command::DeleteTemplateOrDatabase; + +use TestDbServer::Exceptions; + +use Moose; +use Sub::Install; +use namespace::autoclean; + +has schema => (isa => 'TestDbServer::Schema', is => 'ro', required => 1 ); +has superuser => ( isa => 'Str', is => 'ro', required => 1 ); +has host => ( isa => 'Str', is => 'ro', required => 1 ); +has port => ( isa => 'Str', is => 'ro', required => 1 ); + +foreach my $subname ( qw( _entity_find_method _entity_id_method _not_found_exception )) { + no strict 'refs'; + *$subname = sub { die "$_[0] didn't implement $subname"; } +} + +sub execute { + my $self = shift; + + my($finder, $id_getter) = ($self->_entity_find_method, $self->_entity_id_method); + + my $entity = $self->schema->$finder( $self->$id_getter ); + unless ($entity) { + my $not_found = $self->_not_found_exception; + $not_found->throw(name => $self->$id_getter); + } + + my $pg = TestDbServer::PostgresInstance->new( + name => $entity->name, + host => $self->host, + port => $self->port, + owner => $entity->owner, + superuser => $self->superuser, + ); + + $pg->dropdb(); + + $entity->delete(); + + return 1; +} + +__PACKAGE__->meta->make_immutable; + +1;