Mercurial > gemma
changeset 1908:0322bce42065 dev-pdf-generation
merge default
author | Bernhard Reiter <bernhard@intevation.de> |
---|---|
date | Fri, 18 Jan 2019 17:15:33 +0100 |
parents | 4f58bada50b8 (current diff) 32c56e6c089a (diff) |
children | e62f1d2ead9e |
files | |
diffstat | 3 files changed, 224 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/pkg/imports/bn.go Fri Jan 18 17:10:16 2019 +0100 +++ b/pkg/imports/bn.go Fri Jan 18 17:15:33 2019 +0100 @@ -257,14 +257,14 @@ } feedback.Info("Storing %d bottlenecks took %s", len(nids), time.Since(start)) - if err = tx.Commit(); err == nil { - feedback.Info("Import of bottlenecks was successful") + if err := tx.Commit(); err != nil { + return nil, err } - + feedback.Info("Import of bottlenecks was successful") summary := struct { Bottlenecks []string `json:"bottlenecks"` }{ Bottlenecks: nids, } - return &summary, err + return &summary, nil }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkg/imports/st.go Fri Jan 18 17:15:33 2019 +0100 @@ -0,0 +1,218 @@ +// 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> + +package imports + +import ( + "context" + "database/sql" + "errors" + "time" + + "gemma.intevation.de/gemma/pkg/common" + "gemma.intevation.de/gemma/pkg/models" +) + +type Stretch struct { + Name string `json:"name"` + From models.Isrs `json:"from"` + To models.Isrs `json:"to"` + ObjNam string `json:"objnam"` + NObjNam *string `json:"nobjnam"` + Source string `json:"source-organization"` + Date models.Date `json:"date-info"` + Countries models.UniqueCountries `json:"countries"` +} + +const STJobKind JobKind = "st" + +type stJobCreator struct{} + +func init() { + RegisterJobCreator(STJobKind, stJobCreator{}) +} + +func (stJobCreator) Description() string { return "stretch" } + +func (stJobCreator) AutoAccept() bool { return false } + +func (stJobCreator) Create(_ JobKind, data string) (Job, error) { + st := new(Stretch) + if err := common.FromJSONString(data, st); err != nil { + return nil, err + } + return st, nil +} + +func (stJobCreator) Depends() []string { + return []string{ + "stretches", + } +} + +const ( + stDeleteSQL = ` +DELETE FROM waterway.stretches WHERE +staging_done AND name = ( + SELECT name + FROM waterway.stretches WHERE + id = ( + SELECT key from waterway.track_imports + WHERE import_id = $1 AND + relation = 'waterway.stretches'::regclass) + AND NOT staging_done +)` + + stStageDoneSQL = ` +UPDATE waterway.stretches SET staging_done = true +WHERE id IN ( + SELECT key from waterway.track_imports + WHERE import_id = $1 AND + relation = 'waterway.stretches'::regclass)` + + stInsertSQL = ` +WITH r AS ( + SELECT isrsrange( + isrs( + $1::char(2), + $2::char(3), + $3::char(5), + $4::char(5), + $5::int), + isrs( + $6::char(2), + $7::char(3), + $8::char(5), + $9::char(5), + $10::int)) AS r +) +INSERT INTO waterway.stretches ( + name, + stretch, + geom, + objnam, + nobjnam, + date_info +) VALUES ( + $11, + (SELECT r FROM r), + ISRSrange_area( + (SELECT r FROM r), + (SELECT ST_Union(CAST(area AS geometry)) + FROM waterway.waterway_area)), + $12, + $13, + $14) +RETURNING id` + + stInsertCountrySQL = ` +INSERT INTO waterway.stretch_countries ( + stretches_id, + country_code +) VALUES ( + $1, + $2 +)` +) + +// StageDone moves the imported stretch out of the staging area. +func (stJobCreator) StageDone( + ctx context.Context, + tx *sql.Tx, + id int64, +) error { + if _, err := tx.ExecContext(ctx, stDeleteSQL, id); err != nil { + return err + } + _, err := tx.ExecContext(ctx, stStageDoneSQL, id) + return err +} + +// CleanUp of a stretch import is a NOP. +func (*Stretch) CleanUp() error { return nil } + +// Do executes the actual bottleneck import. +func (st *Stretch) Do( + ctx context.Context, + importID int64, + conn *sql.Conn, + feedback Feedback, +) (interface{}, error) { + + start := time.Now() + + feedback.Info("Storing stretch '%s'", st.Name) + + if len(st.Countries) == 0 { + return nil, errors.New("List of countries is empty") + } + + tx, err := conn.BeginTx(ctx, nil) + if err != nil { + return nil, err + } + defer tx.Rollback() + + insertCountryStmt, err := tx.PrepareContext(ctx, stInsertCountrySQL) + if err != nil { + return nil, err + } + + var nobjnm sql.NullString + if st.NObjNam != nil { + nobjnm = sql.NullString{String: *st.NObjNam, Valid: true} + } + + var id int64 + if err := tx.QueryRowContext( + ctx, + stInsertSQL, + st.From.CountryCode, + st.From.LoCode, + st.From.FairwaySection, + st.From.Orc, + st.From.Hectometre, + st.To.CountryCode, + st.To.LoCode, + st.To.FairwaySection, + st.To.Orc, + st.To.Hectometre, + st.Name, + st.ObjNam, + nobjnm, + st.Date.Time, + ).Scan(&err); err != nil { + return nil, err + } + + // store the associated countries. + for _, c := range st.Countries { + if _, err := insertCountryStmt.ExecContext(ctx, id, c); err != nil { + return nil, err + } + } + + feedback.Info("Storing stretch '%s' took %s", st.Name, time.Since(start)) + if err := tx.Commit(); err != nil { + return nil, err + } + feedback.Info("Import of stretch was successful") + + summary := struct { + Stretch string `json:"stretch"` + }{ + Stretch: st.Name, + } + + return &summary, nil +}
--- a/schema/gemma.sql Fri Jan 18 17:10:16 2019 +0100 +++ b/schema/gemma.sql Fri Jan 18 17:15:33 2019 +0100 @@ -364,7 +364,8 @@ ) CREATE TABLE stretch_countries ( - stretches_id int NOT NULL REFERENCES stretches(id), + stretches_id int NOT NULL REFERENCES stretches(id) + ON DELETE CASCADE, country_code char(2) NOT NULL REFERENCES countries(country_code), UNIQUE(stretches_id, country_code) )