Skip to content
This repository has been archived by the owner on Jan 31, 2020. It is now read-only.

Commit

Permalink
Merge pull request #31 from nnutter/next
Browse files Browse the repository at this point in the history
consolidate with and with-out template database creation
  • Loading branch information
nnutter committed Nov 13, 2014
2 parents 54401c0 + d0cd24d commit 16ceb34
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 110 deletions.
5 changes: 0 additions & 5 deletions bin/test-db-database-create
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ GetOptions($opts, 'owner=s', 'based-on=s','short-help','help');
print_short_help() if ($opts->{'short-help'});
print_help() if ($opts->{help});

unless ($opts->{owner} xor $opts->{'based-on'}) {
print STDERR "You must use one of --owner or --based-on, but not both\n";
exit 1;
}

my $ua = get_user_agent();
my @options = make_post_options($opts);
my $req = HTTP::Request->new(POST => url_for('databases', \@options));
Expand Down
5 changes: 4 additions & 1 deletion docs/rest-api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,11 @@ The Location header will be the URL for this entity
-----------------------------------------------------

POST /databases?based_on=<template-id>
POST /databases?based_on=<template-id>&owner=<owner-name>

Create a new database and populate it with the given database template
Create a new database and populate it with the given database template.
Optionally specifying an owner name to use instead of the owner of the
template.

Returns 201 and JSON in the body
{
Expand Down
40 changes: 0 additions & 40 deletions lib/TestDbServer/Command/CreateDatabase.pm

This file was deleted.

39 changes: 35 additions & 4 deletions lib/TestDbServer/Command/CreateDatabaseFromTemplate.pm
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,42 @@ use TestDbServer::Exceptions;
use Moose;
use namespace::autoclean;

use constant DEFAULT_TEMPLATE_NAME => 'template1';

has owner => ( isa => 'Maybe[Str]', is => 'ro', required => 1 );
has host => ( isa => 'Str', is => 'ro', required => 1 );
has port => ( isa => 'Int', is => 'ro', required => 1 );
has template_id => ( isa => 'Str', is => 'ro', required => 1 );
has template_id => ( isa => 'Maybe[Str]', is => 'ro', required => 1 );
has schema => ( isa => 'TestDbServer::Schema', is => 'ro', required => 1 );
has superuser => ( isa => 'Str', is => 'ro', required => 1 );

sub execute {
my $self = shift;

my $template = $self->schema->find_template($self->template_id);
my $default_template_id = $self->schema
->search_template(name => DEFAULT_TEMPLATE_NAME)
->next->id;
my $template_id = defined $self->template_id
? $self->template_id
: $default_template_id;

my $template = $self->schema->find_template($template_id);
unless ($template) {
Exception::TemplateNotFound->throw(template_id => $self->template_id);
Exception::TemplateNotFound->throw(template_id => $template_id);
}

my $owner = $self->owner || $template->owner;
my $pg = TestDbServer::PostgresInstance->new(
host => $self->host,
port => $self->port,
owner => $template->owner,
owner => $owner,
superuser => $self->superuser,
);

if ($owner ne $self->superuser) {
$self->grant_role_to_superuser($owner);
}

$pg->createdb_from_template($template->name);

my $database = $self->schema->create_database(
Expand All @@ -43,6 +58,22 @@ sub execute {
return $database;
}

sub grant_role_to_superuser {
my ($self, $source) = @_;

my $dbh = $self->schema->storage->dbh();
my $is_valid_role = sub {
my $row = $dbh->selectrow_arrayref(q(SELECT 1 FROM pg_roles WHERE rolname=?), undef, @_);
return $row->[0];
};
for my $role_name ($source, $self->superuser) {
unless ($is_valid_role->($role_name)) {
Exception::RoleNotFound->throw(role_name => $role_name);
}
}
$dbh->do(sprintf('GRANT %s to %s', $source, $self->superuser));
}

__PACKAGE__->meta->make_immutable;

1;
38 changes: 10 additions & 28 deletions lib/TestDbServer/DatabaseRoutes.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use Mojo::Base 'Mojolicious::Controller';
use Try::Tiny;

use TestDbServer::Utils;
use TestDbServer::Command::CreateDatabase;
use TestDbServer::Command::CreateDatabaseFromTemplate;
use TestDbServer::Command::DeleteDatabase;

Expand Down Expand Up @@ -118,42 +117,25 @@ sub _hashref_for_database_obj {
sub create {
my $self = shift;

if (my $template_id = $self->req->param('based_on')) {
my $schema = $self->app->db_storage();
my $template_id = $self->req->param('based_on');
my $owner = $self->req->param('owner');
if ($template_id) {
$self->app->log->info("create database from template $template_id");
$self->_create_database_from_template($template_id);

} elsif (my $owner = $self->req->param('owner')) {
$self->app->log->info("create database with owner $owner");
$self->_create_new_database($owner);

} else {
$self->app->log->error('create databse with bad params');
$self->render_not_found;
}
}

sub _create_new_database {
my($self, $owner) = @_;

$self->_create_database_common(sub {
my($host, $port) = $self->app->host_and_port_for_created_database();
my $cmd = TestDbServer::Command::CreateDatabase->new(
owner => $owner,
template_id => undef,
host => $host,
port => $port,
superuser => $self->app->configuration->db_user,
schema => $self->app->db_storage,
);
});
else {
$self->app->log->info("create database from default template");
}
$self->_create_database_from_template($owner, $template_id);
}

sub _create_database_from_template {
my($self, $template_id) = @_;
my($self, $owner, $template_id) = @_;

$self->_create_database_common(sub {
my($host, $port) = $self->app->host_and_port_for_created_database();
TestDbServer::Command::CreateDatabaseFromTemplate->new(
owner => $owner,
template_id => $template_id,
host => $host,
port => $port,
Expand Down
5 changes: 5 additions & 0 deletions lib/TestDbServer/Exceptions.pm
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ use Exception::Class (
isa => 'Exception::BaseException',
fields => [qw(template_id)],
},

Exception::RoleNotFound => {
isa => 'Exception::BaseException',
fields => [qw(role_name)],
},
);

package Exception::BaseException;
Expand Down
8 changes: 8 additions & 0 deletions lib/TestDbServer/Schema/Result/Database.pm
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,12 @@ __PACKAGE__->add_columns(qw(database_id host port name owner create_time expire_
__PACKAGE__->set_primary_key('database_id');
__PACKAGE__->belongs_to(template => 'TestDbServer::Schema::Result::Template', 'template_id');

sub real_owner {
my $self = shift;
my $dbh = $self->result_source->storage->dbh();
my $statement = "SELECT pg_roles.rolname FROM pg_database JOIN pg_roles ON pg_database.datdba = pg_roles.oid WHERE pg_database.datname = ?;";
my $row = $dbh->selectrow_arrayref($statement, undef, $self->name);
return $row->[0];
}

1;
Loading

0 comments on commit 16ceb34

Please sign in to comment.