# HG changeset patch # User Sascha L. Teichmann # Date 1542366526 -3600 # Node ID 3d50f558870c7336db1d9880ecc24147f763395c # Parent f7131eeb2a534085b35d39a4af0f3a16fb9bd257 REST GET call to /imports now has the ability to be filtered by kinds or states. Something like &states=queued,running,failed,pending,accepted&kinds=sr Note: The states are not the current states of the import queue, yet. The import queue will be adjusted soon. diff -r f7131eeb2a53 -r 3d50f558870c pkg/controllers/importqueue.go --- a/pkg/controllers/importqueue.go Thu Nov 15 19:06:53 2018 +0100 +++ b/pkg/controllers/importqueue.go Fri Nov 16 12:08:46 2018 +0100 @@ -14,17 +14,22 @@ package controllers import ( + "context" "database/sql" "fmt" + "log" "net/http" "strconv" + "strings" + "gemma.intevation.de/gemma/pkg/imports" "gemma.intevation.de/gemma/pkg/models" "github.com/gorilla/mux" + "github.com/jackc/pgx/pgtype" ) const ( - selectImportsUnpagedSQL = ` + selectImportsSQL = ` SELECT id, state::varchar, @@ -32,10 +37,7 @@ kind, username FROM waterway.imports -ORDER BY id` - - selectImportPagedSQL = selectImportsUnpagedSQL + ` -LIMIT $1 OFFSET $2` +` selectHasImportSQL = ` SELECT true FROM Waterway.imports WHERE id = $1` @@ -60,27 +62,96 @@ DELETE FROM waterway.imports WHERE id = $1` ) +func toTextArray(txt string, allowed []string) *pgtype.TextArray { + parts := strings.Split(txt, ",") + var accepted []string + for _, part := range parts { + if part = strings.ToLower(strings.TrimSpace(part)); len(part) == 0 { + continue + } + for _, a := range allowed { + if part == a { + accepted = append(accepted, part) + break + } + } + } + if len(accepted) == 0 { + return nil + } + var ta pgtype.TextArray + if err := ta.Set(accepted); err != nil { + log.Printf("warn: %v\n", err) + return nil + } + return &ta +} + +func queryImportListStmt( + conn *sql.Conn, + ctx context.Context, + vars map[string]string, +) (*sql.Rows, error) { + + var ( + stmt strings.Builder + args []interface{} + states *pgtype.TextArray + kinds *pgtype.TextArray + ) + + if st, found := vars["states"]; found { + states = toTextArray(st, imports.ImportStateNames) + } + + if ks, found := vars["kinds"]; found { + kinds = toTextArray(ks, imports.ImportKindNames) + } + + stmt.WriteString(selectImportsSQL) + if states != nil || kinds != nil { + stmt.WriteString(" WHERE ") + } + + if states != nil { + fmt.Fprintf(&stmt, " states = ANY($%d) ", len(args)+1) + args = append(args, states) + } + + if states != nil && kinds != nil { + stmt.WriteString("AND") + } + + if kinds != nil { + fmt.Fprintf(&stmt, " kind = ANY($%d) ", len(args)+1) + args = append(args, kinds) + } + + stmt.WriteString(" ORDER BY enqueued DESC ") + + if lim, found := vars["limit"]; found { + fmt.Fprintf(&stmt, " LIMIT $%d ", len(args)+1) + limit, _ := strconv.ParseInt(lim, 10, 64) + args = append(args, limit) + } + + if ofs, found := vars["offset"]; found { + fmt.Fprintf(&stmt, " OFFSET $%d ", len(args)+1) + offset, _ := strconv.ParseInt(ofs, 10, 64) + args = append(args, offset) + } + + return conn.QueryContext(ctx, stmt.String(), args...) +} + func listImports( _ interface{}, req *http.Request, conn *sql.Conn, ) (jr JSONResult, err error) { - vars := mux.Vars(req) - - off, of := vars["offset"] - lim, lf := vars["limit"] var rows *sql.Rows - - if of && lf { - offset, _ := strconv.ParseInt(off, 10, 64) - limit, _ := strconv.ParseInt(lim, 10, 64) - rows, err = conn.QueryContext( - req.Context(), selectImportPagedSQL, limit, offset) - } else { - rows, err = conn.QueryContext( - req.Context(), selectImportsUnpagedSQL) - } + rows, err = queryImportListStmt(conn, req.Context(), mux.Vars(req)) if err != nil { return } diff -r f7131eeb2a53 -r 3d50f558870c pkg/controllers/routes.go --- a/pkg/controllers/routes.go Thu Nov 15 19:06:53 2018 +0100 +++ b/pkg/controllers/routes.go Fri Nov 16 12:08:46 2018 +0100 @@ -172,7 +172,9 @@ Methods(http.MethodGet). Queries( "offset", "{offset:[0-9]+}", - "limit", "{limit:[0-9]+}") + "limit", "{limit:[0-9]+}", + "states", "", + "kinds", "") api.Handle("/imports", lsImports).Methods(http.MethodGet) diff -r f7131eeb2a53 -r 3d50f558870c pkg/imports/kinds.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkg/imports/kinds.go Fri Nov 16 12:08:46 2018 +0100 @@ -0,0 +1,18 @@ +package imports + +// 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 + +var ImportKindNames = []string{ + string(SRJobKind), +} diff -r f7131eeb2a53 -r 3d50f558870c pkg/imports/queue.go --- a/pkg/imports/queue.go Thu Nov 15 19:06:53 2018 +0100 +++ b/pkg/imports/queue.go Fri Nov 16 12:08:46 2018 +0100 @@ -70,6 +70,17 @@ usedDeps: map[string]struct{}{}, } +var ( + ImportStateNames = []string{ + "queued", + "running", + "failed", + "pending", + "accepted", + "declined", + } +) + const ( queueUser = "sys_admin"