view pkg/models/sr.go @ 2672:b997e1fd1d3d import-overview-rework

Fixed warning SQL prefix for selection.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 14 Mar 2019 17:29:36 +0100
parents df6383831ad3
children 5bc941d9ec43
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) 2018 by via donau
//   – Österreichische Wasserstraßen-Gesellschaft mbH
// Software engineering by Intevation GmbH
//
// Author(s):
//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
//  * Bernhard E. Reiter <bernhard.reiter@intevation.de>

package models

import (
	"context"
	"database/sql"
	"encoding/json"
	"errors"
	"fmt"
	"io"

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

type (
	SoundingResultMeta struct {
		Date           Date   `json:"date"`
		Bottleneck     string `json:"bottleneck"`
		EPSG           uint   `json:"epsg"`
		DepthReference string `json:"depth-reference"`
	}
)

const (
	checkDepthReferenceSQL = `
SELECT true FROM depth_references WHERE depth_reference = $1`

	checkBottleneckSQL = `
SELECT true FROM waterway.bottlenecks WHERE objnam = $1`

	checkBottleneckDateUniqueSQL = `
SELECT true FROM waterway.sounding_results sr JOIN
  waterway.bottlenecks bn ON sr.bottleneck_id = bn.id
WHERE bn.objnam = $1 AND sr.date_info = $2`
)

func (m *SoundingResultMeta) Decode(r io.Reader) error {
	err := json.NewDecoder(r).Decode(m)
	if err == nil && m.EPSG == 0 {
		m.EPSG = WGS84
	}
	return err
}

func (m *SoundingResultMeta) Validate(ctx context.Context, conn *sql.Conn) []error {

	var errs []error

	var b bool
	err := conn.QueryRowContext(ctx,
		checkDepthReferenceSQL,
		m.DepthReference).Scan(&b)
	switch {
	case err == sql.ErrNoRows:
		errs = append(errs, fmt.Errorf("unknown depth reference '%s'", m.DepthReference))
	case err != nil:
		errs = append(errs, err)
	case !b:
		errs = append(errs, errors.New("unexpected depth reference"))
	}

	err = conn.QueryRowContext(ctx,
		checkBottleneckSQL,
		m.Bottleneck).Scan(&b)
	switch {
	case err == sql.ErrNoRows:
		errs = append(errs, fmt.Errorf("unknown bottleneck '%s'", m.Bottleneck))
	case err != nil:
		errs = append(errs, err)
	case !b:
		errs = append(errs, errors.New("unexpected bottleneck"))
	}

	err = conn.QueryRowContext(ctx,
		checkBottleneckDateUniqueSQL,
		m.Bottleneck, m.Date.Time).Scan(&b)
	switch {
	case err == sql.ErrNoRows: // good! -> unique.
	case err != nil:
		errs = append(errs, err)
	case b:
		errs = append(errs,
			fmt.Errorf("sounding result for date %s already exists at bottleneck '%s'",
				m.Date.Time.Format(common.DateFormat),
				m.Bottleneck))
	}

	return errs
}