changeset 2671:8f3facf902dd import-overview-rework

Filter prev/next, too.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 14 Mar 2019 17:25:33 +0100
parents d7b1dd25f91f
children b997e1fd1d3d
files pkg/controllers/importqueue.go
diffstat 1 files changed, 84 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/controllers/importqueue.go	Thu Mar 14 16:20:16 2019 +0100
+++ b/pkg/controllers/importqueue.go	Thu Mar 14 17:25:33 2019 +0100
@@ -51,6 +51,7 @@
   summary IS NOT NULL AS has_summary,
   imports.id IN (SELECT id FROM warned) AS has_warnings
 FROM import.imports
+WHERE
 `
 	selectImportSummaySQL = `
 SELECT summary FROM import.imports WHERE id = $1`
@@ -76,11 +77,13 @@
 
 	selectBeforeSQL = `
 SELECT enqueued FROM import.imports
-WHERE enqueued < $1 ORDER BY enqueued LIMIT 1`
+WHERE
+`
 
 	selectAfterSQL = `
 SELECT enqueued FROM import.imports
-WHERE enqueued > $1 ORDER BY enqueued LIMIT 1`
+WHERE
+`
 )
 
 func toInt8Array(txt string) *pgtype.Int8Array {
@@ -151,75 +154,95 @@
 	fb.arg(format, v...)
 }
 
-func queryImportListStmt(
-	conn *sql.Conn,
-	req *http.Request,
-) (*sql.Rows, error) {
+func buildFilters(req *http.Request) (l, b, a *filterBuilder, err error) {
+
+	l = new(filterBuilder)
+	a = new(filterBuilder)
+	b = new(filterBuilder)
 
-	var fb filterBuilder
+	var noBefore, noAfter bool
 
-	fb.stmt.WriteString(selectImportsSQL)
-
-	fb.stmt.WriteString(" WHERE ")
+	l.stmt.WriteString(selectImportsSQL)
+	a.stmt.WriteString(selectAfterSQL)
+	b.stmt.WriteString(selectBeforeSQL)
 
 	if st := req.FormValue("states"); st != "" {
 		states := toTextArray(st, imports.ImportStateNames)
-		fb.cond(" state = ANY($%d) ", states)
+		l.cond(" state = ANY($%d) ", states)
+		a.cond(" state = ANY($%d) ", states)
+		b.cond(" state = ANY($%d) ", states)
 	}
 
 	if ks := req.FormValue("kinds"); ks != "" {
 		kinds := toTextArray(ks, imports.ImportKindNames())
-		fb.cond(" kind = ANY($%d) ", kinds)
+		l.cond(" kind = ANY($%d) ", kinds)
+		a.cond(" kind = ANY($%d) ", kinds)
+		b.cond(" kind = ANY($%d) ", kinds)
 	}
 
 	if idss := req.FormValue("ids"); idss != "" {
 		ids := toInt8Array(idss)
-		fb.cond(" id = ANY($%d) ", ids)
+		l.cond(" id = ANY($%d) ", ids)
+		a.cond(" id = ANY($%d) ", ids)
+		b.cond(" id = ANY($%d) ", ids)
 	}
 
 	if from := req.FormValue("from"); from != "" {
-		fromTime, err := time.Parse(models.ImportTimeFormat, from)
-		if err != nil {
-			return nil, err
+		var fromTime time.Time
+		if fromTime, err = time.Parse(models.ImportTimeFormat, from); err != nil {
+			return
 		}
-		fb.cond(" enqueued >= $%d ", fromTime)
+		l.cond(" enqueued >= $%d ", fromTime)
+		b.cond(" enqueued < $%d", fromTime)
+	} else {
+		noBefore = true
 	}
 
 	if to := req.FormValue("to"); to != "" {
-		toTime, err := time.Parse(models.ImportTimeFormat, to)
-		if err != nil {
-			return nil, err
+		var toTime time.Time
+		if toTime, err = time.Parse(models.ImportTimeFormat, to); err != nil {
+			return
 		}
-		fb.cond(" enqueued <= $%d ", toTime)
+		l.cond(" enqueued <= $%d ", toTime)
+		a.cond(" enqueued > $%d", toTime)
+	} else {
+		noAfter = true
 	}
 
 	switch warn := strings.ToLower(req.FormValue("warnings")); warn {
 	case "1", "t", "true":
-		fb.cond(" id IN (SELECT id FROM warned) ")
+		l.cond(" id IN (SELECT id FROM warned) ")
+		a.cond(" id IN (SELECT id FROM warned) ")
+		b.cond(" id IN (SELECT id FROM warned) ")
 	}
 
-	if !fb.hasCond {
-		fb.stmt.WriteString(" TRUE ")
+	if !l.hasCond {
+		l.stmt.WriteString(" TRUE ")
+	}
+	if !b.hasCond {
+		b.stmt.WriteString(" TRUE ")
+	}
+	if !a.hasCond {
+		a.stmt.WriteString(" TRUE ")
 	}
 
-	fb.stmt.WriteString(" ORDER BY enqueued DESC ")
+	l.stmt.WriteString(" ORDER BY enqueued DESC ")
+	a.stmt.WriteString(" ORDER BY enqueued ")
+	b.stmt.WriteString(" ORDER BY enqueued ")
 
-	return conn.QueryContext(req.Context(), fb.stmt.String(), fb.args...)
+	if noBefore {
+		b = nil
+	}
+	if noAfter {
+		a = nil
+	}
+	return
 }
 
-func enqueued(ctx context.Context, conn *sql.Conn, what, query string) *models.ImportTime {
-	if what == "" {
-		return nil
-	}
-
-	t, err := time.Parse(models.ImportTimeFormat, what)
-	if err != nil {
-		log.Printf("warn: %v\n", err)
-		return nil
-	}
+func neighbored(ctx context.Context, conn *sql.Conn, fb *filterBuilder) *models.ImportTime {
 
 	var when time.Time
-	err = conn.QueryRowContext(ctx, query, t).Scan(&when)
+	err := conn.QueryRowContext(ctx, fb.stmt.String(), fb.args...).Scan(&when)
 	switch {
 	case err == sql.ErrNoRows:
 		return nil
@@ -227,16 +250,8 @@
 		log.Printf("warn: %v\n", err)
 		return nil
 	}
-
 	return &models.ImportTime{when}
 }
-func enqueuedBefore(conn *sql.Conn, req *http.Request) *models.ImportTime {
-	return enqueued(req.Context(), conn, req.FormValue("from"), selectBeforeSQL)
-}
-
-func enqueuedAfter(conn *sql.Conn, req *http.Request) *models.ImportTime {
-	return enqueued(req.Context(), conn, req.FormValue("to"), selectAfterSQL)
-}
 
 func listImports(
 	_ interface{},
@@ -244,9 +259,16 @@
 	conn *sql.Conn,
 ) (jr JSONResult, err error) {
 
+	var list, before, after *filterBuilder
+
+	if list, before, after, err = buildFilters(req); err != nil {
+		return
+	}
+
+	ctx := req.Context()
+
 	var rows *sql.Rows
-	rows, err = queryImportListStmt(conn, req)
-	if err != nil {
+	if rows, err = conn.QueryContext(ctx, list.stmt.String(), list.args...); err != nil {
 		return
 	}
 	defer rows.Close()
@@ -257,10 +279,11 @@
 
 	for rows.Next() {
 		var it models.Import
+		var enqueued time.Time
 		if err = rows.Scan(
 			&it.ID,
 			&it.State,
-			&it.Enqueued,
+			&enqueued,
 			&it.Kind,
 			&it.User,
 			&signer,
@@ -272,6 +295,7 @@
 		if signer.Valid {
 			it.Signer = signer.String
 		}
+		it.Enqueued = models.ImportTime{enqueued}
 		imports = append(imports, &it)
 	}
 
@@ -279,6 +303,16 @@
 		return
 	}
 
+	var prev, next *models.ImportTime
+
+	if before != nil {
+		prev = neighbored(ctx, conn, before)
+	}
+
+	if after != nil {
+		next = neighbored(ctx, conn, after)
+	}
+
 	jr = JSONResult{
 		Result: struct {
 			Prev    *models.ImportTime `json:"prev,omitempty"`
@@ -286,8 +320,8 @@
 			Imports []*models.Import   `json:"imports"`
 		}{
 			Imports: imports,
-			Prev:    enqueuedBefore(conn, req),
-			Next:    enqueuedAfter(conn, req),
+			Prev:    prev,
+			Next:    next,
 		},
 	}
 	return