view pkg/imports/dst.go @ 5670:b75d0b303328

Various fixes and improvements of gauges import: - Allow update of erased data (and thereby set erased to false) - Fix source_organization to work with ERDMS2 - Give ISRS of new and updated gauges in summary - Fixed reference of null pointers if revlevels are missing - Fixed reference of null pointer on update errors - Added ISRS to reference_code warning
author Sascha Wilde <wilde@sha-bang.de>
date Fri, 08 Dec 2023 17:29:56 +0100
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>
//  * Sascha Wilde <wilde@intevation.de>

package imports

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

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

// DSTJobKind is the import queue type identifier.
const DSTJobKind JobKind = "dst"

type dstJobCreator struct{}

func init() { RegisterJobCreator(DSTJobKind, dstJobCreator{}) }

func (dstJobCreator) Description() string { return "delete stretch" }

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

func (dstJobCreator) Create() Job { return new(DeleteStretch) }

func (dstJobCreator) Depends() [2][]string {
	return [2][]string{{"stretches"}}
}

const (
	dstExistsSQL = `
SELECT EXISTS (
  SELECT 1 FROM users.stretches
  WHERE id = $1 AND staging_done)
`
	dstStageDoneSQL = `
DELETE FROM users.stretches
WHERE id IN (
  SELECT key from import.track_imports
  WHERE import_id = $1 AND
        deletion AND
        relation = 'users.stretches'::regclass)`
)

// StageDone finally removes the stretch from the database.
func (dstJobCreator) StageDone(
	ctx context.Context,
	tx *sql.Tx,
	id int64,
	_ Feedback,
) error {
	_, err := tx.ExecContext(ctx, dstStageDoneSQL, id)
	return err
}

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

// Do prepares the deletion of the stretch.
func (dst *DeleteStretch) 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, dstExistsSQL, dst.ID).Scan(&found); err != nil {
		return nil, err
	}

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

	feedback.Info("Prepare deletion of stretch with id %d", dst.ID)

	if _, err := tx.ExecContext(
		ctx,
		trackImportDeletionSQL,
		importID,
		"users.stretches",
		dst.ID,
		true,
	); err != nil {
		return nil, err
	}

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

	return dst, nil
}