Mercurial > gemma
view pkg/geoserver/templates.go @ 4605:7650d2431f86 geoserver_sql_views
Separate schema and table name
Since a GeoServer data source is bound to a specific database schema,
names have to be given without schema qualification. Since we cannot
use regclass for names of SQL views, the name is now a varchar. This
way it's more straightforward to store schema and name separately.
author | Tom Gottfried <tom@intevation.de> |
---|---|
date | Thu, 05 Sep 2019 11:33:01 +0200 |
parents | 152b9eb5ca47 |
children | 124a5a7fe8d6 |
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) 2019 by via donau // – Österreichische Wasserstraßen-Gesellschaft mbH // Software engineering by Intevation GmbH // // Author(s): // * Sascha L. Teichmann <sascha.teichmann@intevation.de> // * Markus Kottländer <markus.kottlaender@intevation.de> package geoserver import ( "context" "database/sql" "regexp" "strings" "text/template" "gemma.intevation.de/gemma/pkg/auth" "gemma.intevation.de/gemma/pkg/models" ) const ( selectConfigValSQL = ` SELECT config_val FROM sys_admin.system_config WHERE config_key = $1` ) func init() { RegisterStylePreprocessor( "sounding_results_contour_lines_geoserver", templateContourLinesFunc("morphology_classbreaks")) RegisterStylePreprocessor( "sounding_differences", templateContourLinesFunc("morphology_classbreaks_compare")) RegisterStylePreprocessor( "distance_marks_geoserver", templateConfigValues) RegisterStylePreprocessor( "distance_marks_ashore_geoserver", templateConfigValues) RegisterStylePreprocessor( "waterway_area", templateConfigValues) RegisterStylePreprocessor( "waterway_axis", templateConfigValues) // TODO: Add more layers. } func templateConfigValues(tmplTxt string) (string, error) { tmpl, err := template.New("template").Parse(tmplTxt) if err != nil { return "", err } // Try to extract the needed keys from the template. keys := extractKeysFromTemplate(tmplTxt) kv, err := loadConfigValues(keys) if err != nil { return "", err } var buf strings.Builder if err = tmpl.Execute(&buf, kv); err != nil { return "", err } return buf.String(), nil } // TODO: Use the parse tree of the template to extract keys. var findKeysRe = regexp.MustCompile(`{{[-]?\s*\.([^-.\s]+)\s*[-]?}}`) func extractKeysFromTemplate(tmpl string) []string { parts := findKeysRe.FindAllStringSubmatch(tmpl, -1) keys := make(map[string]struct{}) for _, part := range parts { keys[part[1]] = struct{}{} } out := make([]string, len(keys)) var i int for key := range keys { out[i] = key i++ } return out } func loadConfigValues(keys []string) (map[string]string, error) { kv := make(map[string]string, len(keys)) if len(keys) == 0 { return kv, nil } ctx := context.Background() if err := auth.RunAs( ctx, "sys_admin", func(conn *sql.Conn) error { stmt, err := conn.PrepareContext(ctx, selectConfigValSQL) if err != nil { return err } defer stmt.Close() for _, key := range keys { var val string if err := stmt.QueryRowContext(ctx, key).Scan(&val); err != nil { return err } kv[key] = val } return nil }, ); err != nil { return nil, err } return kv, nil } func templateContourLinesFunc(configKey string) func(string) (string, error) { return func(data string) (string, error) { return templateContourLines(data, configKey) } } func templateContourLines(data, configKey string) (string, error) { tmpl, err := template.New("template").Parse(data) if err != nil { return "", err } var cb []models.ClassBreak if cb, err = countourLinesClassBreaks(configKey); err != nil { return "", err } var buf strings.Builder if err = tmpl.Execute(&buf, cb); err != nil { return "", err } return buf.String(), nil } func countourLinesClassBreaks(configKey string) ([]models.ClassBreak, error) { var config string ctx := context.Background() if err := auth.RunAs( ctx, "sys_admin", func(conn *sql.Conn) error { return conn.QueryRowContext( ctx, selectConfigValSQL, configKey, ).Scan(&config) }, ); err != nil { return nil, err } cc, err := models.ParseColorValues(config) if err != nil { return nil, err } return cc.ClassBreaks(), nil }