Mercurial > gemma
view pkg/models/intservices.go @ 1755:d3fe20a13339
Import: Filter fairway availabilities by period and resolve insert confilcts.
author | Raimund Renkert <raimund.renkert@intevation.de> |
---|---|
date | Thu, 10 Jan 2019 16:43:42 +0100 |
parents | cabf4789e02b |
children | dfe9cde6a20c |
line wrap: on
line source
// 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 <sascha.teichmann@intevation.de> // * Tom Gottfried <tom.gottfried@intevation.de> package models import ( "context" "database/sql" "log" "net/http" "sync" "gemma.intevation.de/gemma/pkg/auth" "gemma.intevation.de/gemma/pkg/config" ) type IntEntry struct { Name string `json:"name"` Style bool `json:"style"` WMS bool `json:"wms"` WFS bool `json:"wfs"` } type IntServices struct { entries []IntEntry mu sync.Mutex } const ( selectServicesSQL = ` SELECT relname, style IS NOT NULL, as_wms, as_wfs FROM sys_admin.published_services JOIN pg_class ON name = oid ORDER by relname` selectStyleSQL = ` SELECT XMLSERIALIZE(DOCUMENT style AS text) FROM sys_admin.published_services JOIN pg_class ON name = oid WHERE relname = $1` updateStyleSQL = ` UPDATE sys_admin.published_services SET style = XMLPARSE(DOCUMENT $1) WHERE name IN (SELECT oid FROM pg_class WHERE relname = $2)` ) var InternalServices = &IntServices{} func (e *IntEntry) LoadStyle() (string, error) { var style string ctx := context.Background() err := auth.RunAs(ctx, "sys_admin", func(conn *sql.Conn) error { return conn.QueryRowContext( ctx, selectStyleSQL, e.Name).Scan(&style) }) return style, err } func UpdateInternalStyle(req *http.Request, name, style string) error { return auth.RunAsSessionUser(req, func(conn *sql.Conn) error { _, err := conn.ExecContext( req.Context(), updateStyleSQL, style, name) if err == nil { InternalServices.Invalidate() } return err }) } func (ps *IntServices) Find(name string) (string, bool) { ps.mu.Lock() defer ps.mu.Unlock() if ps.entries == nil { if err := ps.load(); err != nil { log.Printf("error: %v\n", err) return "", false } } if ps.has(name) { return config.GeoServerURL() + "/" + name, true } return "", false } func (ps *IntServices) has(service string) bool { var check func(*IntEntry) bool switch service { case "wms": check = func(e *IntEntry) bool { return e.WMS } case "wfs": check = func(e *IntEntry) bool { return e.WFS } default: return false } for i := range ps.entries { if check(&ps.entries[i]) { return true } } return false } func (ps *IntServices) load() error { // make empty slice to prevent retry if slice is empty. ps.entries = []IntEntry{} ctx := context.Background() return auth.RunAs(ctx, "sys_admin", func(conn *sql.Conn) error { rows, err := conn.QueryContext( ctx, selectServicesSQL) if err != nil { return err } defer rows.Close() for rows.Next() { var entry IntEntry if err := rows.Scan( &entry.Name, &entry.Style, &entry.WMS, &entry.WFS, ); err != nil { return err } ps.entries = append(ps.entries, entry) } return rows.Err() }) } func (ps *IntServices) Invalidate() { ps.mu.Lock() ps.entries = nil ps.mu.Unlock() } func InternalAll(IntEntry) bool { return true } func IntWMS(entry IntEntry) bool { return entry.WMS } func IntWFS(entry IntEntry) bool { return entry.WFS } func IntWithStyle(entry IntEntry) bool { return entry.Style } func IntByName(name string) func(IntEntry) bool { return func(entry IntEntry) bool { return entry.Name == name } } func IntAnd(accept ...func(IntEntry) bool) func(IntEntry) bool { return func(entry IntEntry) bool { for _, a := range accept { if !a(entry) { return false } } return true } } func (ps *IntServices) Filter(accept func(IntEntry) bool) []IntEntry { ps.mu.Lock() defer ps.mu.Unlock() if ps.entries == nil { if err := ps.load(); err != nil { log.Printf("error: %v\n", err) return nil } } pe := make([]IntEntry, 0, len(ps.entries)) for _, e := range ps.entries { if accept(e) { pe = append(pe, e) } } return pe }