# HG changeset patch # User Sascha L. Teichmann # Date 1588866629 -7200 # Node ID c352dbbf2778d308be2d8b41ab92310ae97a987c # Parent 5bc8daa986d957913fd7a2571096dcfba0a04758 Started with loading limiting factors and validities. diff -r 5bc8daa986d9 -r c352dbbf2778 pkg/controllers/fwa.go --- a/pkg/controllers/fwa.go Thu May 07 16:25:58 2020 +0200 +++ b/pkg/controllers/fwa.go Thu May 07 17:50:29 2020 +0200 @@ -14,14 +14,99 @@ package controllers import ( + "context" + "database/sql" "log" "net/http" "time" + "github.com/gorilla/mux" + "gemma.intevation.de/gemma/pkg/common" - "github.com/gorilla/mux" + "gemma.intevation.de/gemma/pkg/middleware" +) + +const ( + selectBottlenecksLimitingSQL = ` +SELECT + lower(validity), + upper(validity), + limiting +FROM + waterway.bottlenecks +WHERE + bottleneck_id = $1 AND + validity && tstzrange($2, $3)` +) + +type ( + limitingValidity struct { + limiting string + lower time.Time + upper time.Time + } + + limitingValidities []limitingValidity ) +func (lv *limitingValidity) intersects(from, to time.Time) bool { + return !(to.Before(lv.lower) || from.After(lv.upper)) +} + +func (lvs limitingValidities) find() func(from, to time.Time) *limitingValidity { + + var last *limitingValidity + + return func(from, to time.Time) *limitingValidity { + if last != nil && last.intersects(from, to) { + return last + } + for i := range lvs { + if lv := &lvs[i]; lv.intersects(from, to) { + last = lv + return lv + } + } + return nil + } +} + +func loadLimitingValidities( + ctx context.Context, + conn *sql.Conn, + bottleneckID string, + from, to time.Time, +) (limitingValidities, error) { + + var lvs limitingValidities + + rows, err := conn.QueryContext( + ctx, + selectLimitingSQL, + from, to) + + if err != nil { + return nil, err + } + defer rows.Close() + + for rows.Next() { + var lv limitingValidity + if err := rows.Scan( + &lv.limiting, + &lv.lower, + &lv.upper, + ); err != nil { + return nil, err + } + lv.lower = lv.lower.UTC() + lv.upper = lv.upper.UTC() + lvs = append(lvs, lv) + } + + return lvs, rows.Err() +} + func fairwayAvailability(rw http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) @@ -29,14 +114,12 @@ switch vars["kind"] { case "bottleneck": fairwayAvailabilityBottleneck(rw, req) - case "stretch": - case "section": + case "stretch": // TODO: Implement me! + case "section": // TODO: Implement me! default: http.Error(rw, "Invalid kind type.", http.StatusBadRequest) return } - - // TODO: Implement me! } func parseFromTo( @@ -77,8 +160,21 @@ return } + ctx := req.Context() + conn := middleware.GetDBConn(req) + + lvs, err := loadLimitingValidities( + ctx, + conn, + bottleneckID, + from, to) + if err != nil { + log.Printf("error: %v\n", err) + http.Error(rw, "Loading validities failed", http.StatusInternalServerError) + return + } + // TODO: Implement me! - _ = from - _ = to _ = los + _ = lvs }