view pkg/imports/dsr.go @ 4798:ca6a5f722471

Added Description method to most imports. Only for imports where information relevant to the administrator is relevant.
author Sascha Wilde <wilde@intevation.de>
date Fri, 25 Oct 2019 18:25:38 +0200
parents 911b1349a9bd
children f32d086b5dbf
line wrap: on
line source

// This is Free Software under GNU Affero General Public License v >= 3.0
// without warranty, see README.md and license for details.
//
// SPDX-License-Identifier: AGPL-3.0-or-later
// License-Filename: LICENSES/AGPL-3.0.txt
//
// Copyright (C) 2019 by via donau
//   – Österreichische Wasserstraßen-Gesellschaft mbH
// Software engineering by Intevation GmbH
//
// Author(s):
//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
//  * Sascha Wilde <wilde@intevation.de>

package imports

import (
	"context"
	"database/sql"
	"errors"
	"strings"

	"gemma.intevation.de/gemma/pkg/common"
	"gemma.intevation.de/gemma/pkg/models"
)

// DeleteSoundingResult is a Job to delete a sounding result from the database.
type DeleteSoundingResult struct {
	BottleneckId string      `json:"bottleneck-id"`
	Date         models.Date `json:"date-info"`
}

func (dsr *DeleteSoundingResult) Description() (string, error) {

	var descs []string

	descs = append(descs, dsr.BottleneckId)
	descs = append(descs, dsr.Date.Format(common.DateFormat))
	return strings.Join(descs, "|"), nil
}

// DSRJobKind is the import queue type identifier.
const DSRJobKind JobKind = "dsr"

type dsrJobCreator struct{}

func init() { RegisterJobCreator(DSRJobKind, dsrJobCreator{}) }

func (dsrJobCreator) Description() string { return "delete sounding result" }

func (dsrJobCreator) AutoAccept() bool { return false }

func (dsrJobCreator) Create() Job { return new(DeleteSoundingResult) }

func (dsrJobCreator) Depends() [2][]string {
	// Same as import.
	return srJobCreator{}.Depends()
}

const (
	dsrFindSQL = `
SELECT id FROM waterway.sounding_results
  WHERE bottleneck_id = $1
  AND date_info = $2
  AND staging_done
`
	dsrStageDoneSQL = `
DELETE FROM waterway.sounding_results
WHERE id IN (
  SELECT key from import.track_imports
  WHERE import_id = $1 AND
        deletion AND
        relation = 'waterway.sounding_results'::regclass)`
)

// StageDone finally removes the sounding result from the database.
func (dsrJobCreator) StageDone(
	ctx context.Context,
	tx *sql.Tx,
	id int64,
) error {
	result, err := tx.ExecContext(ctx, dsrStageDoneSQL, id)
	if err != nil {
		return err
	}
	rows, err := result.RowsAffected()
	if err != nil {
		return err
	}
	if rows == 0 {
		return errors.New("Deletion failed.  " +
			"Propably Data outside the area of responsibility." +
			"Or the data was already deleted by another user.")
	}
	return err
}

// CleanUp of a sounding result delete import is a NOP.
func (*DeleteSoundingResult) CleanUp() error { return nil }

// Do prepares the deletion of the sounding result.
func (dsr *DeleteSoundingResult) Do(
	ctx context.Context,
	importID int64,
	conn *sql.Conn,
	feedback Feedback,
) (interface{}, error) {

	tx, err := conn.BeginTx(ctx, nil)
	if err != nil {
		return nil, err
	}
	defer tx.Rollback()

	feedback.Info("SR: bottleneck-id: %v, date-info: %v",
		dsr.BottleneckId, dsr.Date.Time)

	var id int64
	if err := tx.QueryRowContext(ctx, dsrFindSQL,
		dsr.BottleneckId, dsr.Date.Time).Scan(&id); err != nil {
		return nil, err
	}

	feedback.Info("Prepare deletion of sounding result with id %d", id)

	if _, err := tx.ExecContext(
		ctx,
		trackImportDeletionSQL,
		importID,
		"waterway.sounding_results",
		id,
		true,
	); err != nil {
		return nil, err
	}

	if err := tx.Commit(); err != nil {
		return nil, err
	}

	return dsr, nil
}