changeset 4332:8080007d3c06

shape upload stretch import: Finished implementation (staging, summary).
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 05 Sep 2019 10:32:45 +0200
parents 98497ac4af3c
children 3f0422751cb4
files pkg/imports/stsh.go pkg/models/common.go
diffstat 2 files changed, 105 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/imports/stsh.go	Thu Sep 05 09:29:15 2019 +0200
+++ b/pkg/imports/stsh.go	Thu Sep 05 10:32:45 2019 +0200
@@ -19,7 +19,6 @@
 	"database/sql"
 	"errors"
 	"fmt"
-	"log"
 	"os"
 	"path"
 	"path/filepath"
@@ -29,6 +28,7 @@
 	shp "github.com/jonas-p/go-shp"
 
 	"gemma.intevation.de/gemma/pkg/common"
+	"gemma.intevation.de/gemma/pkg/models"
 )
 
 type StretchShape struct {
@@ -75,13 +75,13 @@
 RETURNING id`
 )
 
+// StageDone is merely the same as for the normal stretch import.
 func (stshJobCreator) StageDone(
 	ctx context.Context,
 	tx *sql.Tx,
 	id int64,
 ) error {
-	// TODO: Implement me!
-	return nil
+	return stJobCreator{}.StageDone(ctx, tx, id)
 }
 
 func (stsh *StretchShape) CleanUp() error {
@@ -92,6 +92,37 @@
 	return strings.TrimRight(s, "\x00")
 }
 
+type stretchSummary struct {
+	ID        int64                  `json:"id"`
+	Name      string                 `json:"name"`
+	From      string                 `json:"from"`
+	To        string                 `json:"to"`
+	ObjNam    string                 `json:"objnam"`
+	NObjNam   *string                `json:"nobjnam"`
+	Date      models.Date            `json:"date-info"`
+	Countries models.UniqueCountries `json:"countries"`
+}
+
+func parseUniqueCountries(s string) (models.UniqueCountries, error) {
+	unique := map[models.Country]struct{}{}
+	var countries models.UniqueCountries
+	for _, c := range strings.Split(s, ",") {
+		if c = strings.ToUpper(strings.TrimSpace(c)); c == "" {
+			continue
+		}
+		n := models.Country(c)
+		if !n.Valid() {
+			return nil, fmt.Errorf("'%s' is not a valid country code", c)
+		}
+		if _, found := unique[n]; found {
+			return nil, fmt.Errorf("'%s' is not a unique country code", c)
+		}
+		countries = append(countries, n)
+		unique[n] = struct{}{}
+	}
+	return countries, nil
+}
+
 func (stsh *StretchShape) Do(
 	ctx context.Context,
 	importID int64,
@@ -213,6 +244,14 @@
 	}
 	defer insCountryStmt.Close()
 
+	trackStmt, err := tx.PrepareContext(ctx, trackImportSQL)
+	if err != nil {
+		return nil, err
+	}
+	defer trackStmt.Close()
+
+	var stretches []*stretchSummary
+
 	for sr.Next() {
 
 		_, p := sr.Shape()
@@ -227,24 +266,18 @@
 		}
 
 		var (
-			name      = fixAttribute(sr.Attribute(nameIdx))
-			objnam    = fixAttribute(sr.Attribute(objnamIdx))
-			nobjnam   = fixAttribute(sr.Attribute(nobjnamIdx))
-			lower     = fixAttribute(sr.Attribute(lowerIdx))
-			upper     = fixAttribute(sr.Attribute(upperIdx))
-			dateInfo  = fixAttribute(sr.Attribute(dateInfoIdx))
-			source    = fixAttribute(sr.Attribute(sourceIdx))
-			countries = fixAttribute(sr.Attribute(countriesIdx))
+			name     = fixAttribute(sr.Attribute(nameIdx))
+			objnam   = fixAttribute(sr.Attribute(objnamIdx))
+			nobjnam  = fixAttribute(sr.Attribute(nobjnamIdx))
+			lower    = fixAttribute(sr.Attribute(lowerIdx))
+			upper    = fixAttribute(sr.Attribute(upperIdx))
+			dateInfo = fixAttribute(sr.Attribute(dateInfoIdx))
+			source   = fixAttribute(sr.Attribute(sourceIdx))
+			cnts     = fixAttribute(sr.Attribute(countriesIdx))
 		)
 
-		log.Printf("name     : %+q\n", name)
-		log.Printf("objnam   : %+q\n", objnam)
-		log.Printf("nobjnam  : %+q\n", nobjnam)
-		log.Printf("lower    : %+q\n", lower)
-		log.Printf("upper    : %+q\n", upper)
-		log.Printf("dateinfo : %+q\n", dateInfo)
-		log.Printf("source   : %+q\n", source)
-		log.Printf("countries: %+q\n", countries)
+		feedback.Info("Importing stretch %s (%s - %s).",
+			name, lower, upper)
 
 		date, err := common.ParseTime(dateInfo)
 		if err != nil {
@@ -252,6 +285,12 @@
 			continue
 		}
 
+		countries, err := parseUniqueCountries(cnts)
+		if err != nil {
+			feedback.Warn("Countries: %v.", err)
+			continue
+		}
+
 		var nobjnamNull sql.NullString
 		if nobjnam != "" {
 			nobjnamNull = sql.NullString{
@@ -263,8 +302,6 @@
 		// Convert to a multi polygon.
 		area := poly.MultiPolygonGeom().AsWKB()
 
-		log.Printf("len geom: %d\n", len(area))
-
 		var id int64
 
 		if err := insStmt.QueryRowContext(
@@ -280,23 +317,52 @@
 			return nil, err
 		}
 
-		log.Println("after insert")
-
-		for _, country := range strings.Split(countries, ",") {
-			if country = strings.TrimSpace(country); country == "" {
-				continue
-			}
+		// Store the countries
+		for _, country := range countries {
 			if _, err := insCountryStmt.ExecContext(ctx, country); err != nil {
 				return nil, err
 			}
 		}
 
-		// TODO: Implement me!
+		// Finally track the stretch
+
+		if _, err := trackStmt.ExecContext(
+			ctx,
+			importID,
+			"waterway.stretches",
+			id,
+		); err != nil {
+			return nil, err
+		}
+
+		stretch := &stretchSummary{
+			ID:        id,
+			Name:      name,
+			From:      lower,
+			To:        upper,
+			ObjNam:    objnam,
+			Date:      models.Date{date},
+			Countries: countries,
+		}
+
+		if nobjnamNull.Valid {
+			stretch.NObjNam = &nobjnamNull.String
+		}
+
+		stretches = append(stretches, stretch)
 	}
 
 	if err := sr.Err(); err != nil {
 		return nil, err
 	}
 
-	return nil, errors.New("Not implemented, yet!")
+	if len(stretches) == 0 {
+		return nil, UnchangedError("No stretches written.")
+	}
+
+	if err := tx.Commit(); err != nil {
+		return nil, err
+	}
+
+	return stretches, nil
 }
--- a/pkg/models/common.go	Thu Sep 05 09:29:15 2019 +0200
+++ b/pkg/models/common.go	Thu Sep 05 10:32:45 2019 +0200
@@ -81,6 +81,16 @@
 	}
 )
 
+// Valid checks if the given country is a known one.
+func (c Country) Valid() bool {
+	for _, v := range validCountries {
+		if string(c) == v {
+			return true
+		}
+	}
+	return false
+}
+
 // UnmarshalJSON ensures that the given string forms a valid
 // two letter country code.
 func (c *Country) UnmarshalJSON(data []byte) error {