Mercurial > gemma
diff pkg/controllers/importqueue.go @ 1189:3d50f558870c
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.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Fri, 16 Nov 2018 12:08:46 +0100 |
parents | a04126989d91 |
children | 3afa71405b87 |
line wrap: on
line diff
--- 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 }