view pkg/imports/dsec.go @ 5490:5f47eeea988d logging

Use own logging package.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 20 Sep 2021 17:45:39 +0200
parents 59a99655f34d
children 6270951dda28
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>

package imports

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

	"gemma.intevation.de/gemma/pkg/log"
)

// DeleteSection is a Job to delete a section from the database.
type DeleteSection struct {
	ID int64 `json:"id"`
}

// DSECJobKind is the import queue type identifier.
const DSECJobKind JobKind = "dsec"

type dsecJobCreator struct{}

func init() { RegisterJobCreator(DSECJobKind, dsecJobCreator{}) }

func (dsecJobCreator) Description() string { return "delete section" }

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

func (dsecJobCreator) Create() Job { return new(DeleteSection) }

func (dsecJobCreator) Depends() [2][]string {
	return [2][]string{{"sections"}}
}

const (
	dsecExistsSQL = `
SELECT EXISTS (
  SELECT 1 FROM waterway.sections
  WHERE id = $1 AND staging_done)
`
	dsecStageDoneSQL = `
DELETE FROM waterway.sections
WHERE id IN (
  SELECT key from import.track_imports
  WHERE import_id = $1 AND
        deletion AND
        relation = 'waterway.sections'::regclass)`
)

// StageDone finally removes the section from the database.
func (dsecJobCreator) StageDone(
	ctx context.Context,
	tx *sql.Tx,
	id int64,
	_ Feedback,
) error {
	res, err := tx.ExecContext(ctx, dsecStageDoneSQL, id)
	if err != nil {
		return err
	}
	n, err := res.RowsAffected()
	if err != nil {
		log.Errorf(
			"RowsAffected returned an error. Missing driver support?")
		return nil
	}
	if n == 0 {
		return errors.New(
			"nothing deleted. Probably due to missing access rights")
	}
	return err
}

// CleanUp of a section delete import is a NOP.
func (*DeleteSection) CleanUp() error { return nil }

// Do prepares the deletion of the section.
func (dsec *DeleteSection) 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()

	var found bool
	if err := tx.QueryRowContext(ctx, dsecExistsSQL, dsec.ID).Scan(&found); err != nil {
		return nil, err
	}

	if !found {
		return nil, fmt.Errorf("no section with id %d found", dsec.ID)
	}

	feedback.Info("Prepare deletion of section with id %d", dsec.ID)

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

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

	return dsec, nil
}