changeset 873:ad9272460ef3 geo-style

Do the XSLT to adjust the layer name when updating the style column in the database.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Sun, 30 Sep 2018 14:24:37 +0200
parents b882b2c796c1
children da526b58c9c4
files pkg/controllers/geostyling.go pkg/models/intservices.go
diffstat 2 files changed, 48 insertions(+), 88 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/controllers/geostyling.go	Sun Sep 30 13:58:49 2018 +0200
+++ b/pkg/controllers/geostyling.go	Sun Sep 30 14:24:37 2018 +0200
@@ -2,14 +2,11 @@
 
 import (
 	"bytes"
-	"database/sql"
 	"fmt"
 	"io"
 	"log"
 	"net/http"
-	"strings"
 
-	"gemma.intevation.de/gemma/pkg/auth"
 	"gemma.intevation.de/gemma/pkg/models"
 	"github.com/gorilla/mux"
 )
@@ -19,79 +16,20 @@
 	styleName    = "style"
 )
 
-const (
-	replaceNameXSLT = `<?xml version="1.0"?>
-<xsl:stylesheet version="1.0"
-  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
-  xmlns:sld="http://www.opengis.net/sld"
-  xmlns:se="http://www.opengis.net/se">
-
-  <xsl:param name="name"/>
-
-  <xsl:template
-    match="/sld:StyledLayerDescriptor/sld:NamedLayer/sld:Name/text()">
-	<xsl:value-of select="$name"/>
-  </xsl:template>
-
-  <xsl:template
-    match="/sld:StyledLayerDescriptor/sld:NamedLayer/se:Name/text()">
-	<xsl:value-of select="$name"/>
-  </xsl:template>
-
-  <xsl:template match="@*|node()">
-    <xsl:copy>
-      <xsl:apply-templates select="@*|node()"/>
-    </xsl:copy>
-  </xsl:template>
-</xsl:stylesheet>`
-
-	xsltSQL = `SELECT xslt_process($1, $2, $3)`
-)
-
-func runXSLT(
-	req *http.Request,
-	document, stylesheet string,
-	params ...string,
-) (string, error) {
-	var result string
-
-	var args strings.Builder
-
-	for len(params) > 1 {
-		if args.Len() > 0 {
-			args.WriteByte(',')
-		}
-		fmt.Fprintf(&args, "%s='%s'",
-			strings.Replace(params[0], ",", "", -1),
-			strings.Replace(params[1], ",", "", -1))
-		params = params[2:]
-	}
-
-	log.Printf("params: %s\n", args.String())
-
-	err := auth.RunAsSessionUser(req, func(conn *sql.Conn) error {
-		return conn.QueryRowContext(
-			req.Context(), xsltSQL,
-			document, stylesheet, args.String()).Scan(&result)
-	})
-
-	return result, err
-}
-
-func extractStyle(req *http.Request) ([]byte, error) {
+func extractStyle(req *http.Request) (string, error) {
 
 	f, _, err := req.FormFile(styleName)
 	if err != nil {
-		return nil, err
+		return "", err
 	}
 	defer f.Close()
 
 	var buf bytes.Buffer
 
 	if _, err := io.Copy(&buf, io.LimitReader(f, maxStyleSize)); err != nil {
-		return nil, err
+		return "", err
 	}
-	return buf.Bytes(), nil
+	return buf.String(), nil
 }
 
 func supportedWMSFeature(name string) bool {
@@ -120,16 +58,7 @@
 
 	log.Printf("uploaded file length: %d\n", len(style))
 
-	result, err := runXSLT(
-		req, string(style), replaceNameXSLT, "name", feature)
-
-	if err != nil {
-		log.Printf("error: %v\n", err)
-		http.Error(rw, "error: "+err.Error(), http.StatusBadRequest)
-		return
-	}
-
-	if err := models.UpdateInternalStyle(feature, result); err != nil {
+	if err := models.UpdateInternalStyle(req, feature, style); err != nil {
 		log.Printf("error: %v\n", err)
 		http.Error(rw, "error: "+err.Error(), http.StatusInternalServerError)
 		return
--- a/pkg/models/intservices.go	Sun Sep 30 13:58:49 2018 +0200
+++ b/pkg/models/intservices.go	Sun Sep 30 14:24:37 2018 +0200
@@ -3,7 +3,10 @@
 import (
 	"context"
 	"database/sql"
+	"fmt"
 	"log"
+	"net/http"
+	"strings"
 	"sync"
 
 	"gemma.intevation.de/gemma/pkg/auth"
@@ -28,22 +31,50 @@
 
 	updateStyleSQL = `
 UPDATE sys_admin.published_services
-SET style = $1
-WHERE name IN (SELECT oid FROM pg_class WHERE relname = $2)`
+SET style = xslt_process($1, $2, $3)::bytea
+WHERE name IN (SELECT oid FROM pg_class WHERE relname = $4)`
+)
+
+const (
+	replaceNameXSLT = `<?xml version="1.0"?>
+<xsl:stylesheet version="1.0"
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  xmlns:sld="http://www.opengis.net/sld"
+  xmlns:se="http://www.opengis.net/se">
+
+  <xsl:param name="name"/>
+
+  <xsl:template
+    match="/sld:StyledLayerDescriptor/sld:NamedLayer/sld:Name/text()">
+	<xsl:value-of select="$name"/>
+  </xsl:template>
+
+  <xsl:template
+    match="/sld:StyledLayerDescriptor/sld:NamedLayer/se:Name/text()">
+	<xsl:value-of select="$name"/>
+  </xsl:template>
+
+  <xsl:template match="@*|node()">
+    <xsl:copy>
+      <xsl:apply-templates select="@*|node()"/>
+    </xsl:copy>
+  </xsl:template>
+</xsl:stylesheet>`
 )
 
 var InternalServices = &IntServices{}
 
-func UpdateInternalStyle(name, style string) error {
-	return auth.RunAs("sys_admin", context.Background(),
-		func(conn *sql.Conn) error {
-			_, err := conn.ExecContext(
-				context.Background(), updateStyleSQL, style, name)
-			if err == nil {
-				InternalServices.Invalidate()
-			}
-			return err
-		})
+func UpdateInternalStyle(req *http.Request, name, style string) error {
+	return auth.RunAsSessionUser(req, func(conn *sql.Conn) error {
+		param := fmt.Sprintf("name='%s'", strings.Replace(name, ",", "", -1))
+		_, err := conn.ExecContext(
+			req.Context(), updateStyleSQL,
+			style, replaceNameXSLT, param, name)
+		if err == nil {
+			InternalServices.Invalidate()
+		}
+		return err
+	})
 }
 
 func (ps *IntServices) Find(name string) (string, bool) {