diff --git a/README.docker.md b/README.docker.md index d064d68b..7e46e152 100644 --- a/README.docker.md +++ b/README.docker.md @@ -12,16 +12,18 @@ used for production instances. 1. Install [docker compose](https://docs.docker.com/compose/install/) 1. run `docker build -t gcis .` - Go get some tea. + 1. run `mkdir -p files/assets-back` 1. Setup postgres *alone* first + 1. If you have an existing postgres container, run `docker rm gcis_postgres_1` 1. Download the latest [public content release](https://github.com/USGCRP/gcis/releases) 1. Untar the files 1. the `schema` file should be moved to `./db/docker/2_schema.sql` 1. the `content_1` file should be moved to `./db/docker/3_content_1.sql` 1. the `content_2` file should be moved to `./db/docker/4_content_2.sql` - if you want an empty GCIS instance, only copy the schema & content 1. - 1. run `docker-compose up postgres` + 1. run `docker-compose up postgres &` - Refresh your tea. - 1. after the previous command finishes loading, exit the command + 1. after the previous command finishes loading, run `docker-compose stop` 1. Start the full docker set 1. run `docker-compose up` 1. GCIS should be available at `127.0.0.1` with all content available diff --git a/docker-compose.yml b/docker-compose.yml index 9c2e35c1..46a5aaf6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -version: '2' +version: '3' services: nginx: image: nginx:latest @@ -18,6 +18,8 @@ services: - PGHOST=postgres - PGUSER=gcisops - MOJO_MODE=development + volumes: + - ./files:/var/local/www postgres: image: postgres:9.6 diff --git a/lib/Tuba/Activity.pm b/lib/Tuba/Activity.pm index 8914a605..c46d1376 100644 --- a/lib/Tuba/Activity.pm +++ b/lib/Tuba/Activity.pm @@ -132,8 +132,8 @@ sub update_rel { for my $id ($c->param('delete_publication')) { next unless $id; Tuba::DB::Object::Methodology::Manager->delete_objects( - { activity_identifier => $activity->identifier, - publication_id => $id }); + where => [{activity_identifier => $activity->identifier, publication_id => $id}], + audit_user => $c->audit_user, audit_note => $c->audit_note); $c->flash(message => 'Saved changes'); } diff --git a/lib/Tuba/Array.pm b/lib/Tuba/Array.pm index 0adbd5fd..3d5ae743 100644 --- a/lib/Tuba/Array.pm +++ b/lib/Tuba/Array.pm @@ -64,7 +64,9 @@ sub update_rel { } for my $id ($c->param('delete_table')) { - ArrayTableMaps->delete_objects({ table_identifier => $id, array_identifier => $object->identifier }); + ArrayTableMaps->delete_objects( + where => [{table_identifier => $id, array_identifier => $object->identifier}], + audit_user => $c->audit_user, audit_note => $c->audit_note); $c->flash(message => 'Saved changes'); } diff --git a/lib/Tuba/Controller.pm b/lib/Tuba/Controller.pm index 55e70a77..63c12258 100644 --- a/lib/Tuba/Controller.pm +++ b/lib/Tuba/Controller.pm @@ -974,11 +974,13 @@ PUT files. sub put_files { my $c = shift; + my $file = Mojo::Upload->new(asset => Mojo::Asset::File->new->add_chunk($c->req->body)); $file->filename($c->stash("filename") || 'asset'); my $obj = $c->_this_object or return $c->reply->not_found; my $pub = $obj->get_publication(autocreate => 1); - my $tfile = $pub->upload_file(c => $c, upload => $file) or do { + + my $tfile = $pub->upload_file(c => $c, upload => $file, audit_user => $c->user, audit_note => $c->audit_note) or do { return $c->render(status => 500, text => $pub->error); }; $tfile->generate_thumbnail(); @@ -1219,8 +1221,8 @@ sub update_rel { for my $id ($c->param("delete_$dwhat")) { next unless $id; $mwhat->delete_objects( - { "${dwhat}_identifier" => $id, - publication_id => $pub->id }); + where => [{"${dwhat}_identifier" => $id, publication_id => $pub->id}], + audit_user => $c->user, audit_note => $c->audit_note); $c->flash(message => 'Saved changes'); } } @@ -1404,7 +1406,7 @@ sub remove { or return $c->redirect_with_error('update_form',"couldn't find $json->{replacement}"); @replacement = (replacement => $rpl); } - $object->delete(audit_user => $c->user, @replacement) + $object->delete(audit_user => $c->user, audit_note => $c->audit_note, @replacement) or return $c->redirect_with_error('update_form', $object->error); return $c->render(text => 'ok'); } diff --git a/lib/Tuba/DB/Mixin/Object/Publication.pm b/lib/Tuba/DB/Mixin/Object/Publication.pm index b65bbf8b..6a37a5d1 100644 --- a/lib/Tuba/DB/Mixin/Object/Publication.pm +++ b/lib/Tuba/DB/Mixin/Object/Publication.pm @@ -219,9 +219,9 @@ sub upload_file { }; $tfile->size($file->size); $pub->add_files($tfile); - $pub->save(audit_user => $c->user); + $pub->save(audit_user => $c->user, audit_note => $c->audit_note); $tfile->meta->error_mode('return'); - $tfile->save(audit_user => $c->user) or do { + $tfile->save(audit_user => $c->user, audit_note => $c->audit_note) or do { $pub->error($tfile->error); return; }; diff --git a/lib/Tuba/DB/Object/Manager.pm b/lib/Tuba/DB/Object/Manager.pm index c9ea1289..d1fe8483 100644 --- a/lib/Tuba/DB/Object/Manager.pm +++ b/lib/Tuba/DB/Object/Manager.pm @@ -69,5 +69,53 @@ sub dbgrep { } +sub delete_objects +{ + # Get the arguments. + # + my $object = shift; + my %args = @_; + + # Get the database and database handle objects. + # + my $db = $object->object_class->init_db; + my $dbh = $db->retain_dbh; + + # Add the database and database handle to the args. + # + $args{db} = $db; + $args{dbh} = $dbh; + + # Remove the audit user and audit note arguments. Throw an error if there is + # no audit user argument. + # + my $audit_user = delete $args{audit_user} or die "missing audit_user for $object"; + my $audit_note = delete $args{audit_note}; + + # Do the database transaction. + # + my $count= 0; + + $db->do_transaction( sub { + # Add the audit user and audit note. + # + $dbh->do("set local audit.username = ?",{},$audit_user); + $dbh->do("set local audit.note = ?",{},$audit_note) if $audit_note; + + # Call the super-class delete_objects method with the arguments. + # + $count = $object->SUPER::delete_objects(%args); + } + ) or do { + # Record an error if the transaction didn't succeed. + # + $object->error($db->error) unless $object->error; + }; + + # Return the object count result from the parent delete_objects method. + # + return $count; +} + 1; diff --git a/lib/Tuba/Figure.pm b/lib/Tuba/Figure.pm index 4fdf6eb4..a433ab75 100644 --- a/lib/Tuba/Figure.pm +++ b/lib/Tuba/Figure.pm @@ -207,13 +207,23 @@ sub update_rel { } my $report_identifier = $c->stash('report_identifier'); - my @delete_images = $c->param('delete_image'); + + my @delete_images; + + @delete_images = $c->param('delete_image') if $c->param('delete_image'); + if (my $nother = $json->{delete_image_identifier}) { push @delete_images, $nother; } - for my $id (@delete_images) { - ImageFigureMaps->delete_objects({ image_identifier => $id, figure_identifier => $object->identifier, report_identifier => $report_identifier }); - $c->flash(message => 'Saved changes'); + + if (0 < scalar @delete_images) { + for my $id (@delete_images) { + ImageFigureMaps->delete_objects( + where => [{figure_identifier => $object->identifier, + report_identifier => $report_identifier}], + audit_user => $c->audit_user, audit_note => $c->audit_note); + $c->flash(message => 'Saved changes'); + } } return $c->SUPER::update_rel(@_); diff --git a/lib/Tuba/Image.pm b/lib/Tuba/Image.pm index b189d41d..861459a4 100644 --- a/lib/Tuba/Image.pm +++ b/lib/Tuba/Image.pm @@ -63,7 +63,9 @@ sub update_rel { } for my $id ($c->param('delete_figure')) { - ImageFigureMaps->delete_objects({ figure_identifier => $id, image_identifier => $object->identifier }); + ImageFigureMaps->delete_objects( + where => [{figure_identifier => $id, image_identifier => $object->identifier}], + audit_user => $c->audit_user, audit_note => $c->audit_note); $c->flash(message => 'Saved changes'); } diff --git a/lib/Tuba/Methodology.pm b/lib/Tuba/Methodology.pm index 789cddc2..b2d8566e 100644 --- a/lib/Tuba/Methodology.pm +++ b/lib/Tuba/Methodology.pm @@ -79,8 +79,8 @@ sub update_rel { for my $id ($c->param('delete_publication')) { next unless $id; Methodology->delete_objects( - { activity_identifier => $activity->identifier, - publication_id => $id }); + where => [{activity_identifier => $activity->identifier, publication_id => $id}], + audit_user => $c->audit_user, audit_note => $c->audit_note); $c->flash(message => 'Saved changes'); } diff --git a/lib/Tuba/Organization.pm b/lib/Tuba/Organization.pm index 8dba07bd..2fbdad00 100644 --- a/lib/Tuba/Organization.pm +++ b/lib/Tuba/Organization.pm @@ -47,14 +47,16 @@ sub update_rel { if (my $pub_id = $json->{delete_publication} || $c->param('delete_publication')) { my $con_id = $json->{contributor_id} || $c->param('contributor_id'); die "person does not match contributor" unless Contributor->new(id => $con_id)->load->organization_identifier eq $org->identifier; - PublicationContributorMaps->delete_objects({ - contributor_id => $con_id, - publication_id => $pub_id, - }) or return $c->update_error("Failed to remove publication"); + PublicationContributorMaps->delete_objects( + where => [{ contributor_id => $con_id, publication_id => $pub_id }], + audit_user => $c->audit_user, audit_note => $c->audit_note) + or return $c->update_error("Failed to remove publication"); } elsif (my $id = $json->{delete_contributor} || $c->param('delete_contributor')) { die "person does not match contributor" unless Contributor->new(id => $id)->load->organization_identifier eq $org->identifier; - Contributors->delete_objects({ id => $id }) - or return $c->update_error("Failed to remove contributor"); + Contributors->delete_objects( + where => [{ id => $id }], + audit_user => $c->audit_user, audit_note => $c->audit_note) + or return $c->update_error("Failed to remove contributor"); $c->flash(info => "Saved changes."); } diff --git a/lib/Tuba/Person.pm b/lib/Tuba/Person.pm index 538dc5a5..23ea2862 100644 --- a/lib/Tuba/Person.pm +++ b/lib/Tuba/Person.pm @@ -143,14 +143,16 @@ sub update_rel { if (my $pub_id = $json->{delete_publication} || $c->param('delete_publication')) { my $con_id = $json->{contributor_id} || $c->param('contributor_id'); die "person does not match contributor" unless Contributor->new(id => $con_id)->load->person_id == $person->id; - PublicationContributorMaps->delete_objects({ - contributor_id => $con_id, - publication_id => $pub_id, - }) or return $c->update_error("Failed to remove publication"); + PublicationContributorMaps->delete_objects( + where => [{contributor_id => $con_id, publication_id => $pub_id}], + audit_user => $c->audit_user, audit_note => $c->audit_note) + or return $c->update_error("Failed to remove publication"); } elsif (my $id = $json->{delete_contributor} || $c->param('delete_contributor')) { die "person does not match contributor" unless Contributor->new(id => $id)->load->person_id == $person->id; - Contributors->delete_objects({ id => $id }) - or return $c->update_error("Failed to remove contributor"); + Contributors->delete_objects( + where => [{ id => $id }], + audit_user => $c->audit_user, audit_note => $c->audit_note) + or return $c->update_error("Failed to remove contributor"); $c->flash(info => "Saved changes."); } diff --git a/lib/Tuba/Table.pm b/lib/Tuba/Table.pm index 3f56a064..d84c7660 100644 --- a/lib/Tuba/Table.pm +++ b/lib/Tuba/Table.pm @@ -138,7 +138,11 @@ sub update_rel { my $report_identifier = $c->stash('report_identifier'); for my $id (grep { defined && length } $c->param('delete_array')) { - ArrayTableMaps->delete_objects({ array_identifier => $id, table_identifier => $object->identifier, report_identifier => $report_identifier }); + ArrayTableMaps->delete_objects( + where => [{array_identifier => $id, + table_identifier => $object->identifier, + report_identifier => $report_identifier}], + audit_user => $c->audit_user, audit_note => $c->audit_note); my $array = Array->new(identifier => $id); $array->load; if (!@{ $array->tables }) {