view pkg/models/sr.go @ 1224:bc4b642c8d04

Started with an upload sounding result to temp upload area.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 19 Nov 2018 17:14:42 +0100
parents
children 1c0c9190fcf2
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"
	"time"
)

const (
	SoundingResultDateFormat = "2006-01-02"
	WGS84                    = 4326
)

type (
	SoundingResultDate struct{ time.Time }

	SoundingResultMeta struct {
		Date           SoundingResultDate `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`
)

func (srd *SoundingResultDate) UnmarshalJSON(data []byte) error {
	var s string
	if err := json.Unmarshal(data, &s); err != nil {
		return err
	}
	d, err := time.Parse(SoundingResultDateFormat, s)
	if err == nil {
		*srd = SoundingResultDate{d}
	}
	return err
}

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(conn *sql.Conn, ctx context.Context) []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'\n", m.DepthReference))
	case err != nil:
		errs = append(errs, err)
	case !b:
		errs = append(errs, errors.New("Unexpected depth reference"))
	}

	err = conn.QueryRowContext(context.Background(),
		checkBottleneckSQL,
		m.Bottleneck).Scan(&b)
	switch {
	case err == sql.ErrNoRows:
		errs = append(errs, fmt.Errorf("Unknown bottleneck '%s'\n", m.Bottleneck))
	case err != nil:
		errs = append(errs, err)
	case !b:
		errs = append(errs, errors.New("Unexpected bottleneck"))
	}

	return errs
}