view pkg/controllers/search.go @ 744:6fe6839f5ce6

Make search return an array of features, including name. This form should be sufficiently generic.
author Sascha Wilde <wilde@intevation.de>
date Mon, 24 Sep 2018 13:51:26 +0200
parents fdff2de616ad
children 3cb012d4d9ef
line wrap: on
line source

package controllers

import (
	"database/sql"
	"fmt"
	"net/http"
	"regexp"
	"strconv"
	"strings"

	"gemma.intevation.de/gemma/pkg/models"
)

const (
	searchHectometreSQL = `SELECT json_agg(r)
FROM (SELECT location_code::text AS name,
             ST_AsGeoJSON(geom)::json AS geom
      FROM waterway.distance_marks
     WHERE (location_code).hectometre = $1) r`
)

var rkmRegex = regexp.MustCompile(
	"^[[:space:]]*([0-9]+)([,.]([0-9]))?[[:space:]]*$",
)

func searchFeature(
	input interface{},
	req *http.Request,
	db *sql.Conn,
) (jr JSONResult, err error) {

	s := input.(*models.SearchRequest)

	if len(s.SearchString) == 0 {
		err = JSONError{http.StatusBadRequest,
			"error: empty search string"}
		return
	}

	// Handle search for river kilometre:

	m := rkmRegex.FindStringSubmatch(s.SearchString)
	if len(m) != 0 {
		var hectometre int
		if hectometre, err = strconv.Atoi(m[1]); err != nil {
			return
		}

		hectometre *= 10
		if len(m) == 4 {
			var h int
			if h, err = strconv.Atoi(m[3]); err != nil {
				return
			}
			hectometre += h
		}

		var result string

		err = db.QueryRowContext(
			req.Context(),
			searchHectometreSQL,
			hectometre,
		).Scan(&result)

		switch {
		case err == sql.ErrNoRows:
			err = JSONError{
				Code: http.StatusNotFound,
				Message: fmt.Sprintf("Cannot find river hectometre %d.",
					hectometre),
			}
			return
		case err != nil:
			return
		}

		jr.Result = strings.NewReader(result)
	} else {
		err = JSONError{
			Code: http.StatusNotFound,
			Message: fmt.Sprintf("No Results for %s.",
				s.SearchString),
		}

	}

	return
}