Mercurial > gemma
changeset 4080:af2b20d6c921 historization_ng
Merged default
author | Sascha Wilde <wilde@intevation.de> |
---|---|
date | Thu, 25 Jul 2019 16:10:28 +0200 |
parents | 21854740f433 (current diff) cb74aa69954e (diff) |
children | c9bef8c27685 |
files | pkg/imports/agm.go pkg/imports/bn.go pkg/imports/gm.go pkg/imports/wg.go pkg/misc/time.go |
diffstat | 15 files changed, 95 insertions(+), 83 deletions(-) [+] |
line wrap: on
line diff
--- a/pkg/common/time.go Thu Jul 25 15:02:19 2019 +0200 +++ b/pkg/common/time.go Thu Jul 25 16:10:28 2019 +0200 @@ -27,8 +27,26 @@ DateFormat = "2006-01-02" ) +// TimeParser is a list of time formats. +type TimeParser []string + var utc0 = time.Unix(0, 0) +// Parse tries to parse a given string by the entries of the layout +// list one after another. The first matching time is returned. +// If no layout matches the last error is returned or time zero +// if the layout list is empty. +func (tg TimeParser) Parse(s string) (time.Time, error) { + var err error + var t time.Time + for _, layout := range tg { + if t, err = time.Parse(layout, s); err == nil { + break + } + } + return t, err +} + func InterpolateTime(t1 time.Time, m1 float64, t2 time.Time, m2 float64) func(float64) time.Time { // f(m1) = t1
--- a/pkg/controllers/user.go Thu Jul 25 15:02:19 2019 +0200 +++ b/pkg/controllers/user.go Thu Jul 25 16:10:28 2019 +0200 @@ -263,7 +263,8 @@ } if err != nil { - err = pgxutils.HandleError(err) + m, c := pgxutils.ReadableError{err}.MessageAndCode() + err = JSONError{Code: c, Message: m} return }
--- a/pkg/imports/agm.go Thu Jul 25 15:02:19 2019 +0200 +++ b/pkg/imports/agm.go Thu Jul 25 16:10:28 2019 +0200 @@ -31,6 +31,7 @@ "strings" "time" + "gemma.intevation.de/gemma/pkg/common" "gemma.intevation.de/gemma/pkg/misc" "gemma.intevation.de/gemma/pkg/models" ) @@ -103,10 +104,10 @@ return os.RemoveAll(agm.Dir) } -var guessDate = misc.TimeGuesser([]string{ +var guessDate = common.TimeParser([]string{ "02.01.2006 15:04", "2006-01-02T15:04:05-07:00", -}).Guess +}).Parse type timetz struct{ time.Time }
--- a/pkg/imports/bn.go Thu Jul 25 15:02:19 2019 +0200 +++ b/pkg/imports/bn.go Thu Jul 25 16:10:28 2019 +0200 @@ -582,7 +582,7 @@ ) } if err != nil { - feedback.Warn(pgxutils.HandleError(err).Error()) + feedback.Warn(pgxutils.ReadableError{err}.Error()) return nil } defer bns.Close() @@ -594,7 +594,7 @@ bnIds = append(bnIds, nid) } if err := bns.Err(); err != nil { - feedback.Warn(pgxutils.HandleError(err).Error()) + feedback.Warn(pgxutils.ReadableError{err}.Error()) return nil } if len(bnIds) == 0 { @@ -611,7 +611,7 @@ &validity, &pgBnIds, ); err != nil { - feedback.Warn(pgxutils.HandleError(err).Error()) + feedback.Warn(pgxutils.ReadableError{err}.Error()) if err2 := tx.Rollback(); err2 != nil { return err2 } @@ -624,7 +624,7 @@ bn.Bottleneck_id, validity, ); err != nil { - feedback.Warn(pgxutils.HandleError(err).Error()) + feedback.Warn(pgxutils.ReadableError{err}.Error()) if err2 := tx.Rollback(); err2 != nil { return err2 } @@ -661,7 +661,7 @@ &pgMaterials, ); err != nil { feedback.Warn("Failed to insert riverbed materials") - feedback.Warn(pgxutils.HandleError(err).Error()) + feedback.Warn(pgxutils.ReadableError{err}.Error()) return nil } }
--- a/pkg/imports/fd.go Thu Jul 25 15:02:19 2019 +0200 +++ b/pkg/imports/fd.go Thu Jul 25 16:10:28 2019 +0200 @@ -21,7 +21,7 @@ "io" "time" - "gemma.intevation.de/gemma/pkg/misc" + "gemma.intevation.de/gemma/pkg/common" "gemma.intevation.de/gemma/pkg/pgxutils" "gemma.intevation.de/gemma/pkg/wfs" ) @@ -48,11 +48,11 @@ type fdTime struct{ time.Time } -var guessFDTime = misc.TimeGuesser([]string{ +var guessFDTime = common.TimeParser([]string{ "20060102", "2006", "", -}).Guess +}).Parse func (fdt *fdTime) UnmarshalJSON(data []byte) error { var s string @@ -311,7 +311,7 @@ // ignore -> filtered by responsibility_areas continue features case err != nil: - feedback.Warn(pgxutils.HandleError(err).Error()) + feedback.Warn(pgxutils.ReadableError{err}.Error()) continue features } // Store for potential later removal.
--- a/pkg/imports/gm.go Thu Jul 25 15:02:19 2019 +0200 +++ b/pkg/imports/gm.go Thu Jul 25 16:10:28 2019 +0200 @@ -443,7 +443,7 @@ case err == sql.ErrNoRows: // thats expected, nothing to do case err != nil: - feedback.Warn(pgxutils.HandleError(err).Error()) + feedback.Warn(pgxutils.ReadableError{err}.Error()) default: newP++ } @@ -474,7 +474,7 @@ case err == sql.ErrNoRows: // thats expected, nothing to do case err != nil: - feedback.Warn(pgxutils.HandleError(err).Error()) + feedback.Warn(pgxutils.ReadableError{err}.Error()) default: newM++ }
--- a/pkg/imports/sec.go Thu Jul 25 15:02:19 2019 +0200 +++ b/pkg/imports/sec.go Thu Jul 25 16:10:28 2019 +0200 @@ -182,7 +182,7 @@ sec.Source, sec.Tolerance, ).Scan(&id); err != nil { - return nil, pgxutils.HandleError(err) + return nil, pgxutils.ReadableError{err} } if err := track(ctx, tx, importID, "waterway.sections", id); err != nil {
--- a/pkg/imports/st.go Thu Jul 25 15:02:19 2019 +0200 +++ b/pkg/imports/st.go Thu Jul 25 16:10:28 2019 +0200 @@ -203,7 +203,7 @@ st.Source, st.Tolerance, ).Scan(&id); err != nil { - return nil, pgxutils.HandleError(err) + return nil, pgxutils.ReadableError{err} } // store the associated countries.
--- a/pkg/imports/wa.go Thu Jul 25 15:02:19 2019 +0200 +++ b/pkg/imports/wa.go Thu Jul 25 16:10:28 2019 +0200 @@ -247,7 +247,7 @@ outside++ // ignore -> filtered by responsibility_areas case err != nil: - feedback.Warn(pgxutils.HandleError(err).Error()) + feedback.Warn(pgxutils.ReadableError{err}.Error()) default: features++ }
--- a/pkg/imports/wg.go Thu Jul 25 15:02:19 2019 +0200 +++ b/pkg/imports/wg.go Thu Jul 25 16:10:28 2019 +0200 @@ -327,7 +327,7 @@ ).Scan(&isNew) switch { case err != nil: - feedback.Warn(pgxutils.HandleError(err).Error()) + feedback.Warn(pgxutils.ReadableError{err}.Error()) if err2 := tx.Rollback(); err2 != nil { return nil, err2 } @@ -352,7 +352,7 @@ source, time.Time(*dr.Lastupdate), ); err != nil { - feedback.Warn(pgxutils.HandleError(err).Error()) + feedback.Warn(pgxutils.ReadableError{err}.Error()) if err2 := tx.Rollback(); err2 != nil { return nil, err2 } @@ -389,7 +389,7 @@ unchanged++ continue case err2 != nil: - feedback.Warn(pgxutils.HandleError(err2).Error()) + feedback.Warn(pgxutils.ReadableError{err2}.Error()) if err3 := tx.Rollback(); err3 != nil { return nil, err3 } @@ -436,7 +436,7 @@ code.String(), &validity, ); err != nil { - feedback.Warn(pgxutils.HandleError(err).Error()) + feedback.Warn(pgxutils.ReadableError{err}.Error()) if err2 := tx.Rollback(); err2 != nil { return nil, err2 } @@ -484,7 +484,7 @@ string(**wl.level), int64(**wl.value), ); err != nil { - feedback.Warn(pgxutils.HandleError(err).Error()) + feedback.Warn(pgxutils.ReadableError{err}.Error()) tx.Rollback() continue }
--- a/pkg/imports/wp.go Thu Jul 25 15:02:19 2019 +0200 +++ b/pkg/imports/wp.go Thu Jul 25 16:10:28 2019 +0200 @@ -30,7 +30,7 @@ "github.com/jackc/pgx/pgtype" - "gemma.intevation.de/gemma/pkg/misc" + "gemma.intevation.de/gemma/pkg/common" "gemma.intevation.de/gemma/pkg/models" "gemma.intevation.de/gemma/pkg/wfs" ) @@ -418,7 +418,7 @@ feedback.Info( "Matching points to lines with a precision of %.4fm.", precision) - parseDate := misc.TimeGuesser([]string{"02.01.2006"}).Guess + parseDate := common.TimeParser([]string{"02.01.2006"}).Parse insertStmt, err := tx.PrepareContext(ctx, insertWaterwayProfileSQL) if err != nil {
--- a/pkg/imports/wx.go Thu Jul 25 15:02:19 2019 +0200 +++ b/pkg/imports/wx.go Thu Jul 25 16:10:28 2019 +0200 @@ -321,7 +321,7 @@ // ignore -> filtered by responsibility_areas return nil case err != nil: - feedback.Warn(pgxutils.HandleError(err).Error()) + feedback.Warn(pgxutils.ReadableError{err}.Error()) default: *features++ }
--- a/pkg/misc/time.go Thu Jul 25 15:02:19 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -// This is Free Software under GNU Affero General Public License v >= 3.0.Reader. -// 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 misc - -import "time" - -// TimeGuesser is a list of time formats. -type TimeGuesser []string - -// Guess tries to parse a given string by the entries of the layout -// list one after another. The first matching time is returned. -// If no layout matches the last error is returned or time zero -// if the layout list is empty. -func (tg TimeGuesser) Guess(s string) (time.Time, error) { - var err error - var t time.Time - for _, layout := range tg { - if t, err = time.Parse(layout, s); err == nil { - break - } - } - return t, err -}
--- a/pkg/pgxutils/errors.go Thu Jul 25 15:02:19 2019 +0200 +++ b/pkg/pgxutils/errors.go Thu Jul 25 16:10:28 2019 +0200 @@ -10,24 +10,17 @@ // // Author(s): // * Tom Gottfried <tom.gottfried@intevation.de> +// * Sascha L. Teichmann <sascha.teichmann@intevation.de> package pgxutils import ( + "net/http" "strings" "github.com/jackc/pgx" ) -// Handle PostgreSQL error codes -func HandleError(err error) error { - switch e := err.(type) { - case pgx.PgError: - return dbError(e) - } - return err -} - const ( notNullViolation = "23502" foreignKeyViolation = "23503" @@ -36,9 +29,31 @@ noDataFound = "P0002" ) -type dbError pgx.PgError +type ReadableError struct { + Err error +} + +func (re ReadableError) Error() string { + m, _ := re.MessageAndCode() + return m +} -func (err dbError) Error() string { +// MessageAndCode returns a user-readable message +// and a matching HTTP status code. +// If its not a pgx.PgError it defaults to +// calling the parent Error method and returns its +// result together with http.StatusInternalServerError. +func (re ReadableError) MessageAndCode() (string, int) { + if e, ok := re.Err.(pgx.PgError); ok { + return messageAndCode(e) + } + return re.Err.Error(), http.StatusInternalServerError +} + +func messageAndCode(err pgx.PgError) (m string, c int) { + + c = http.StatusInternalServerError + switch err.Code { case notNullViolation: switch err.SchemaName { @@ -47,11 +62,14 @@ case "gauges": switch err.ColumnName { case "objname": - return "Missing objname" + m = "Missing objname" + return case "geom": - return "Missing lat/lon" + m = "Missing lat/lon" + return case "zero_point": - return "Missing zeropoint" + m = "Missing zeropoint" + return } } } @@ -62,7 +80,8 @@ case "gauge_measurements", "gauge_predictions", "bottlenecks": switch err.ConstraintName { case "gauge_key": - return "Referenced gauge with matching temporal validity not available" + m = "Referenced gauge with matching temporal validity not available" + return } } } @@ -73,7 +92,9 @@ case "user_profiles": switch err.ConstraintName { case "user_profiles_pkey": - return "A user with that name already exists" + m = "A user with that name already exists" + c = http.StatusConflict + return } } } @@ -82,14 +103,19 @@ recent := strings.SplitN(err.Where, "\n", 1)[0] switch { case strings.Contains(recent, "isrsrange_points"): - return "No distance mark found for at least one given ISRS Location Code" + m = "No distance mark found for at least one given ISRS Location Code" + return case strings.Contains(recent, "isrsrange_axis"): - return "No contiguous axis found between given ISRS Location Codes" + m = "No contiguous axis found between given ISRS Location Codes" + return case strings.Contains(recent, "isrsrange_area"): - return "No area around axis between given ISRS Location Codes" + m = "No area around axis between given ISRS Location Codes" + return } case violatesRowLevelSecurity: - return "Could not save: Data outside the area of responsibility." + m = "Could not save: Data outside the area of responsibility." + return } - return "Unexpected database error: " + err.Message + m = "Unexpected database error: " + err.Message + return }
--- a/pkg/soap/nts/service.go Thu Jul 25 15:02:19 2019 +0200 +++ b/pkg/soap/nts/service.go Thu Jul 25 16:10:28 2019 +0200 @@ -18,14 +18,14 @@ "encoding/xml" "time" - "gemma.intevation.de/gemma/pkg/misc" + "gemma.intevation.de/gemma/pkg/common" "gemma.intevation.de/gemma/pkg/soap" ) -var guessDateTime = misc.TimeGuesser([]string{ +var guessDateTime = common.TimeParser([]string{ "2006-01-02T15:04:05", "2006-01-02T15:04:05-07:00", -}).Guess +}).Parse type DateTime struct{ time.Time }