changeset 5068:6e1174f031f4 time-sliding

merge default into time-slinding branch
author Fadi Abbud <fadi.abbud@intevation.de>
date Wed, 11 Mar 2020 13:26:02 +0100
parents 99ac62a56dd2 (current diff) 5269fd823ca7 (diff)
children 7ef8d3dab29b
files
diffstat 11 files changed, 354 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- a/client/package.json	Wed Mar 11 13:21:36 2020 +0100
+++ b/client/package.json	Wed Mar 11 13:26:02 2020 +0100
@@ -1,6 +1,6 @@
 {
   "name": "gemmajs",
-  "version": "4.4.0-dev",
+  "version": "5.0.0-dev",
   "license": "AGPL-3.0-or-later",
   "repository": {
     "type": "hg",
--- a/go.mod	Wed Mar 11 13:21:36 2020 +0100
+++ b/go.mod	Wed Mar 11 13:26:02 2020 +0100
@@ -8,31 +8,34 @@
 	github.com/fatih/structs v1.1.0
 	github.com/fogleman/contourmap v0.0.0-20190814184649-9f61d36c4199
 	github.com/gofrs/uuid v3.2.0+incompatible // indirect
-	github.com/gorilla/mux v1.7.3
+	github.com/gorilla/mux v1.7.4
 	github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect
-	github.com/jackc/pgx v3.6.0+incompatible
+	github.com/jackc/pgx v3.6.2+incompatible
 	github.com/jonas-p/go-shp v0.1.2-0.20190401125246-9fd306ae10a6
 	github.com/lib/pq v1.2.0 // indirect
-	github.com/magiconair/properties v1.8.1 // indirect
 	github.com/mitchellh/go-homedir v1.1.0
-	github.com/pelletier/go-toml v1.4.0 // indirect
-	github.com/pkg/errors v0.8.1 // indirect
+	github.com/pelletier/go-toml v1.6.0 // indirect
+	github.com/pkg/errors v0.9.1 // indirect
 	github.com/rs/cors v1.7.0
 	github.com/sergi/go-diff v1.0.0
 	github.com/shopspring/decimal v0.0.0-20190905144223-a36b5d85f337 // indirect
 	github.com/spf13/afero v1.2.2 // indirect
-	github.com/spf13/cobra v0.0.5
+	github.com/spf13/cast v1.3.1 // indirect
+	github.com/spf13/cobra v0.0.6
 	github.com/spf13/jwalterweatherman v1.1.0 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
-	github.com/spf13/viper v1.4.0
+	github.com/spf13/viper v1.6.2
 	github.com/tidwall/rtree v0.0.0-20180113144539-6cd427091e0e
 	github.com/tidwall/tinyqueue v0.0.0-20180302190814-1e39f5511563 // indirect
 	go.etcd.io/bbolt v1.3.3 // indirect
-	golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 // indirect
-	golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72
+	golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 // indirect
+	golang.org/x/net v0.0.0-20200301022130-244492dfa37a
+	golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 // indirect
 	golang.org/x/text v0.3.2 // indirect
-	gonum.org/v1/gonum v0.0.0-20190922162417-bcfb93e04962
+	gonum.org/v1/gonum v0.7.0
 	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
 	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
+	gopkg.in/ini.v1 v1.54.0 // indirect
 	gopkg.in/robfig/cron.v1 v1.2.0
+	gopkg.in/yaml.v2 v2.2.8 // indirect
 )
--- a/go.sum	Wed Mar 11 13:21:36 2020 +0100
+++ b/go.sum	Wed Mar 11 13:26:02 2020 +0100
@@ -15,11 +15,10 @@
 github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
 github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
 github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
-github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
 github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
-github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
+github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
@@ -50,8 +49,9 @@
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
-github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
-github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
+github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
 github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
 github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
@@ -62,11 +62,13 @@
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
 github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
-github.com/jackc/pgx v3.6.0+incompatible h1:bJeo4JdVbDAW8KB2m8XkFeo8CPipREoG37BwEoKGz+Q=
-github.com/jackc/pgx v3.6.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
+github.com/jackc/pgx v3.6.2+incompatible h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o=
+github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
 github.com/jonas-p/go-shp v0.1.2-0.20190401125246-9fd306ae10a6 h1:h5O7ee4tlSPVjdC75eSLX7jXZiHftthuHio/GtrhaSM=
 github.com/jonas-p/go-shp v0.1.2-0.20190401125246-9fd306ae10a6/go.mod h1:MRIhyxDQ6VVp0oYeD7yPGr5RSTNScUFKCDsI5DR7PtI=
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
 github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
@@ -93,12 +95,12 @@
 github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
 github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg=
-github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
+github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4=
+github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
 github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@@ -113,12 +115,17 @@
 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
 github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
 github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
-github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
 github.com/shopspring/decimal v0.0.0-20190905144223-a36b5d85f337 h1:Da9XEUfFxgyDOqUfwgoTDcWzmnlOnCGi6i4iPS+8Fbw=
 github.com/shopspring/decimal v0.0.0-20190905144223-a36b5d85f337/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
+github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
+github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
 github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
@@ -127,8 +134,10 @@
 github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
 github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
 github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
-github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
+github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
+github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cobra v0.0.6 h1:breEStsVwemnKh2/s6gMvSdMEkwW0sK8vGStnlVBMCs=
+github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
 github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
 github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
 github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
@@ -137,19 +146,21 @@
 github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
 github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
 github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
+github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E=
+github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
+github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
 github.com/tidwall/rtree v0.0.0-20180113144539-6cd427091e0e h1:+NL1GDIUOKxVfbp2KoJQD9cTQ6dyP2co9q4yzmT9FZo=
 github.com/tidwall/rtree v0.0.0-20180113144539-6cd427091e0e/go.mod h1:/h+UnNGt0IhNNJLkGikcdcJqm66zGD/uJGMRxK/9+Ao=
 github.com/tidwall/tinyqueue v0.0.0-20180302190814-1e39f5511563 h1:Otn9S136ELckZ3KKDyCkxapfufrqDqwmGjcHfAyXRrE=
 github.com/tidwall/tinyqueue v0.0.0-20180302190814-1e39f5511563/go.mod h1:mLqSmt7Dv/CNneF2wfcChfN1rvapyQr01LGKnKex0DQ=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
 github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
-github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
 go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk=
@@ -160,11 +171,10 @@
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M=
-golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
+golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
+golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2 h1:y102fOLFqhV41b+4GPiJoa0k/x+pJcEi2/HB1Y5T6fU=
@@ -178,8 +188,8 @@
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
-golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72 h1:PdU68SuVQNpTFEyGl0zoQOMysY+E0innv/QbAqV853w=
-golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
+golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -188,11 +198,11 @@
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190922100055-0a153f010e69 h1:rOhMmluY6kLMhdnrivzec6lLgaVbMHMn2ISQXJeJ5EM=
-golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
+golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
@@ -204,9 +214,10 @@
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
-gonum.org/v1/gonum v0.0.0-20190922162417-bcfb93e04962 h1:yv+jAHS1K6hZokuZ/tcwpvx+89W5QJVy896P6BsxfNk=
-gonum.org/v1/gonum v0.0.0-20190922162417-bcfb93e04962/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU=
+gonum.org/v1/gonum v0.7.0 h1:Hdks0L0hgznZLG9nzXb8vZ0rRvqNvAcgAp84y7Mwkgw=
+gonum.org/v1/gonum v0.7.0/go.mod h1:L02bwd0sqlsvRv41G7wGWFCsVNZFv/k1xzGIxeANHGM=
 gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc=
 gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
 gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
@@ -222,6 +233,10 @@
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
+gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
+gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.54.0 h1:oM5ElzbIi7gwLnNbPX2M25ED1vSAK3B6dex50eS/6Fs=
+gopkg.in/ini.v1 v1.54.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
 gopkg.in/robfig/cron.v1 v1.2.0 h1:PSJsm0uPEND0Rumxxbo7qNb7bxQUTIWDIdpPS59/tcw=
 gopkg.in/robfig/cron.v1 v1.2.0/go.mod h1:3I22DCB+7VAStCIqyArwi2xY9a7IioCiNjrsnCqs+HE=
@@ -229,5 +244,8 @@
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
--- a/pkg/geoserver/boot.go	Wed Mar 11 13:21:36 2020 +0100
+++ b/pkg/geoserver/boot.go	Wed Mar 11 13:26:02 2020 +0100
@@ -327,15 +327,20 @@
 			entries = append(entries, entry)
 		}
 
-		/* XXX: Experimental
-		if table == "sounding_differences" {
+		if attr := tables[i].WMSTAttribute; attr != nil {
 			di := map[string]interface{}{
 				"enabled":             true,
-				"attribute":           "minuend",
-				"endAttribute":        "subtrahend",
+				"attribute":           *attr,
 				"presentation":        "CONTINUOUS_INTERVAL",
 				"units":               "ISO8601",
 				"nearestMatchEnabled": false,
+				"defaultValue": map[string]string{
+					"strategy":       "FIXED",
+					"referenceValue": "PT1M/PRESENT",
+				},
+			}
+			if endAttr := tables[i].WMSTEndAttribute; endAttr != nil {
+				di["endAttribute"] = *endAttr
 			}
 			entry := map[string]interface{}{
 				"@key":          "time",
@@ -343,7 +348,6 @@
 			}
 			entries = append(entries, entry)
 		}
-		*/
 
 		if len(entries) > 0 {
 			ft["metadata"] = map[string]interface{}{
--- a/pkg/models/intservices.go	Wed Mar 11 13:21:36 2020 +0100
+++ b/pkg/models/intservices.go	Wed Mar 11 13:26:02 2020 +0100
@@ -29,14 +29,16 @@
 
 type (
 	IntEntry struct {
-		Schema    string  `json:"schema"`
-		Name      string  `json:"name"`
-		SQL       *string `json:"sql"`
-		KeyColumn *string `json:"keycolumn"`
-		SRS       *string `json:"srs"`
-		Style     bool    `json:"style"`
-		WMS       bool    `json:"wms"`
-		WFS       bool    `json:"wfs"`
+		Schema           string  `json:"schema"`
+		Name             string  `json:"name"`
+		SQL              *string `json:"sql"`
+		KeyColumn        *string `json:"keycolumn"`
+		SRS              *string `json:"srs"`
+		Style            bool    `json:"style"`
+		WMS              bool    `json:"wms"`
+		WFS              bool    `json:"wfs"`
+		WMSTAttribute    *string `json:"wmst-attribute"`
+		WMSTEndAttribute *string `json:"wmst-end-attribute"`
 	}
 
 	LayerGroup struct {
@@ -53,9 +55,17 @@
 
 const (
 	selectServicesSQL = `
-SELECT schema, name,
-  view_def, key_column, auth_name || ':' || auth_srid,
-  style IS NOT NULL, as_wms, as_wfs
+SELECT
+  schema,
+  name,
+  view_def,
+  key_column,
+  auth_name || ':' || auth_srid,
+  style IS NOT NULL,
+  as_wms,
+  as_wfs,
+  wmst_attribute,
+  wmst_end_attribute
 FROM sys_admin.published_services
   LEFT JOIN spatial_ref_sys USING (srid)
 WHERE schema = $1
@@ -181,6 +191,7 @@
 				&entry.Schema, &entry.Name,
 				&entry.SQL, &entry.KeyColumn, &entry.SRS, &entry.Style,
 				&entry.WMS, &entry.WFS,
+				&entry.WMSTAttribute, &entry.WMSTEndAttribute,
 			); err != nil {
 				return err
 			}
--- a/schema/default_sysconfig.sql	Wed Mar 11 13:21:36 2020 +0100
+++ b/schema/default_sysconfig.sql	Wed Mar 11 13:26:02 2020 +0100
@@ -86,30 +86,40 @@
                 ORDER BY location, date_issue DESC) AS fca
             -- Show only forecasts issued with latest measurements or later
             ON fca.location = g.location AND fca.date_issue >= wl.date_issue
+    $$), (
+    'fairway_marks_tmpl', $$
+        SELECT id,
+            lower(validity) AS valid_from,
+            COALESCE(upper(validity), current_timestamp) AS valid_to,
+            geom,
+            datsta,
+            datend,
+            persta,
+            perend,
+            objnam,
+            nobjnm,
+            inform,
+            ninfom,
+            scamin,
+            picrep,
+            txtdsc,
+            sordat,
+            sorind,
+            %s
+        FROM waterway.fairway_marks_%s
     $$);
 
+-- Directly accessed tables
+INSERT INTO sys_admin.published_services (schema, name) VALUES
+    ('waterway', 'waterway_axis'),
+    ('waterway', 'waterway_area'),
+    ('waterway', 'waterway_profiles'),
+    ('waterway', 'fairway_dimensions');
+
+-- GeoServer SQL views without time support
 INSERT INTO sys_admin.published_services (
     schema, name, srid, key_column, view_def
 ) VALUES
-    -- Directly accessed tables
-    ('waterway', 'waterway_axis', NULL, NULL, NULL),
-    ('waterway', 'waterway_area', NULL, NULL, NULL),
-    ('waterway', 'waterway_profiles', NULL, NULL, NULL),
-    ('waterway', 'fairway_dimensions', NULL, NULL, NULL),
-    ('waterway', 'fairway_marks_bcnlat_hydro', NULL, NULL, NULL),
-    ('waterway', 'fairway_marks_bcnlat_ienc', NULL, NULL, NULL),
-    ('waterway', 'fairway_marks_boycar', NULL, NULL, NULL),
-    ('waterway', 'fairway_marks_boylat_hydro', NULL, NULL, NULL),
-    ('waterway', 'fairway_marks_boylat_ienc', NULL, NULL, NULL),
-    ('waterway', 'fairway_marks_boysaw', NULL, NULL, NULL),
-    ('waterway', 'fairway_marks_boyspp', NULL, NULL, NULL),
-    ('waterway', 'fairway_marks_daymar_hydro', NULL, NULL, NULL),
-    ('waterway', 'fairway_marks_daymar_ienc', NULL, NULL, NULL),
-    ('waterway', 'fairway_marks_lights', NULL, NULL, NULL),
-    ('waterway', 'fairway_marks_rtpbcn', NULL, NULL, NULL),
-    ('waterway', 'fairway_marks_topmar', NULL, NULL, NULL),
-    ('waterway', 'fairway_marks_notmrk', NULL, NULL, NULL),
-    -- GeoServer SQL views
     ('waterway', 'gauges_geoserver', 4326, 'isrs_code', $$
         SELECT
             isrs_code,
@@ -288,6 +298,78 @@
                     AND srm.date_info::timestamptz <@ bn.validity
     $$);
 
+
+-- GeoServer SQL views with time support
+INSERT INTO sys_admin.published_services (
+    schema, name, srid, key_column,
+    wmst_attribute, wmst_end_attribute,
+    view_def
+) VALUES
+    ('waterway', 'fairway_marks_bcnlat_hydro', 4326, 'id',
+        'valid_from', 'valid_to', format(
+            (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+            'colour, colpat, condtn, bcnshp, catlam', 'bcnlat_hydro')),
+    ('waterway', 'fairway_marks_bcnlat_ienc', 4326, 'id',
+        'valid_from', 'valid_to', format(
+            (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+            $$colour, colpat, condtn, bcnshp, catlam,
+                string_agg(CAST(dirimp AS varchar), ',') AS dirimp$$,
+            $$bcnlat_ienc LEFT JOIN waterway.fairway_marks_bcnlat_dirimps
+                ON id = fm_bcnlat_id GROUP BY id$$)),
+    ('waterway', 'fairway_marks_boycar', 4326, 'id',
+        'valid_from', 'valid_to', format(
+            (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+            'colour, colpat, conrad, marsys, boyshp, catcam', 'boycar')),
+    ('waterway', 'fairway_marks_boylat_hydro', 4326, 'id',
+        'valid_from', 'valid_to', format(
+            (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+            'colour, colpat, conrad, marsys, boyshp, catlam', 'boylat_hydro')),
+    ('waterway', 'fairway_marks_boylat_ienc', 4326, 'id',
+        'valid_from', 'valid_to', format(
+            (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+            'colour, colpat, conrad, marsys, boyshp, catlam', 'boylat_ienc')),
+    ('waterway', 'fairway_marks_boysaw', 4326, 'id',
+        'valid_from', 'valid_to', format(
+            (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+            'colour, colpat, conrad, marsys, boyshp', 'boysaw')),
+    ('waterway', 'fairway_marks_boyspp', 4326, 'id',
+        'valid_from', 'valid_to', format(
+            (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+            'colour, colpat, conrad, marsys, boyshp, catspm', 'boyspp')),
+    ('waterway', 'fairway_marks_daymar_hydro', 4326, 'id',
+        'valid_from', 'valid_to', format(
+            (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+            'colour, colpat, condtn, topshp', 'daymar_hydro')),
+    ('waterway', 'fairway_marks_daymar_ienc', 4326, 'id',
+        'valid_from', 'valid_to', format(
+            (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+            $$colour, colpat, condtn, topshp, orient,
+                string_agg(CAST(dirimp AS varchar), ',') AS dirimp$$,
+            $$daymar_ienc LEFT JOIN waterway.fairway_marks_daymar_dirimps
+                ON id = fm_daymar_id GROUP BY id$$)),
+    ('waterway', 'fairway_marks_lights', 4326, 'id',
+        'valid_from', 'valid_to', format(
+            (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+            $$colour, condtn, orient, catlit, exclit, litchr, litvis,
+                mltylt, sectr1, sectr2, siggrp, sigper, sigseq, status$$,
+            'lights')),
+    ('waterway', 'fairway_marks_rtpbcn', 4326, 'id',
+        'valid_from', 'valid_to', format(
+            (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+            'condtn, siggrp, catrtb, radwal', 'rtpbcn')),
+    ('waterway', 'fairway_marks_topmar', 4326, 'id',
+        'valid_from', 'valid_to', format(
+            (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+            'colour, colpat, condtn, topshp', 'topmar')),
+    ('waterway', 'fairway_marks_notmrk', 4326, 'id', 'valid_from', 'valid_to',
+        format(
+            (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+            $$condtn, marsys, orient, status, addmrk, catnmk,
+                disipd, disipu, disbk1, disbk2, fnctnm, bnkwtw,
+                string_agg(CAST(dirimp AS varchar), ',') AS dirimp$$,
+            $$notmrk LEFT JOIN waterway.fairway_marks_notmrk_dirimps
+                ON id = fm_notmrk_id GROUP BY id$$));
+
 --
 -- group layers
 --
--- a/schema/gemma.sql	Wed Mar 11 13:21:36 2020 +0100
+++ b/schema/gemma.sql	Wed Mar 11 13:26:02 2020 +0100
@@ -71,22 +71,30 @@
 
 -- Trigger function to be used as a constraint trigger to enforce uniqueness
 -- of geometries in the column with its name given as an argument to the
--- trigger function
+-- trigger function. If additional column names are given,
+-- the group of given columns is tested for equality.
 CREATE OR REPLACE FUNCTION prevent_st_equals() RETURNS trigger AS
 $$
 DECLARE
     new_geom geometry;
+    tg_arg text;
+    filters text;
     has_equal boolean;
 BEGIN
     EXECUTE format('SELECT CAST($1.%I AS geometry)', TG_ARGV[0])
         INTO new_geom
         USING NEW;
+    FOREACH tg_arg IN ARRAY TG_ARGV[1:] LOOP
+        -- Test each additional argument for equality
+        filters = format('%s AND %2$I = $2.%2$I', filters, tg_arg);
+    END LOOP;
     EXECUTE format(
-            'SELECT bool_or(ST_Equals($1, CAST(%I AS geometry))) FROM %I.%I '
-                'WHERE id <> $2',
-            TG_ARGV[0], TG_TABLE_SCHEMA, TG_TABLE_NAME)
+            'SELECT EXISTS(SELECT 1 FROM %I.%I '
+                'WHERE id <> $2.id AND ST_Equals($1, CAST(%I AS geometry))'
+                '%s)',
+             TG_TABLE_SCHEMA, TG_TABLE_NAME, TG_ARGV[0], filters)
         INTO has_equal
-        USING new_geom, NEW.id;
+        USING new_geom, NEW;
     IF has_equal THEN
         RAISE EXCEPTION
             'new row for relation "%" violates constraint trigger "%"',
@@ -409,6 +417,8 @@
         style bytea,
         as_wms boolean NOT NULL DEFAULT TRUE,
         as_wfs boolean NOT NULL DEFAULT TRUE,
+        wmst_attribute     varchar DEFAULT NULL,
+        wmst_end_attribute varchar DEFAULT NULL,
         -- Either give a valid relation or a SQL statement:
         CHECK (to_regclass(schema || '.' || name) IS NOT NULL
             OR view_def IS NOT NULL)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/schema/updates/1420/01.wmst_attributes.sql	Wed Mar 11 13:26:02 2020 +0100
@@ -0,0 +1,2 @@
+ALTER TABLE sys_admin.published_services ADD COLUMN wmst_attribute     varchar DEFAULT NULL;
+ALTER TABLE sys_admin.published_services ADD COLUMN wmst_end_attribute varchar DEFAULT NULL;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/schema/updates/1421/01.fairway-marks_wms-t.sql	Wed Mar 11 13:26:02 2020 +0100
@@ -0,0 +1,108 @@
+CREATE TEMP TABLE base_views (name, def) AS VALUES (
+    'fairway_marks_tmpl', $$
+        SELECT id,
+            lower(validity) AS valid_from,
+            COALESCE(upper(validity), current_timestamp) AS valid_to,
+            geom,
+            datsta,
+            datend,
+            persta,
+            perend,
+            objnam,
+            nobjnm,
+            inform,
+            ninfom,
+            scamin,
+            picrep,
+            txtdsc,
+            sordat,
+            sorind,
+            %s
+        FROM waterway.fairway_marks_%s
+    $$);
+
+-- Settings common to all fairway marks layers
+UPDATE sys_admin.published_services SET
+        srid = 4326,
+        key_column = 'id',
+        wmst_attribute = 'valid_from',
+        wmst_end_attribute = 'valid_to'
+    WHERE schema = 'waterway' AND name LIKE 'fairway_marks_%';
+
+-- Add SQL view definition for fairway marks layers
+UPDATE sys_admin.published_services SET view_def = format(
+        (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+        'colour, colpat, conrad, marsys, boyshp, catcam', 'boycar')
+    WHERE schema = 'waterway' AND name = 'fairway_marks_boycar';
+
+UPDATE sys_admin.published_services SET view_def = format(
+        (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+        'colour, colpat, conrad, marsys, boyshp', 'boysaw')
+    WHERE schema = 'waterway' AND name = 'fairway_marks_boysaw';
+
+UPDATE sys_admin.published_services SET view_def = format(
+        (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+        'colour, colpat, conrad, marsys, boyshp, catspm', 'boyspp')
+    WHERE schema = 'waterway' AND name = 'fairway_marks_boyspp';
+
+UPDATE sys_admin.published_services SET view_def = format(
+        (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+        $$colour, condtn, orient, catlit, exclit, litchr, litvis,
+        mltylt, sectr1, sectr2, siggrp, sigper, sigseq, status$$,
+        'lights')
+    WHERE schema = 'waterway' AND name = 'fairway_marks_lights';
+
+UPDATE sys_admin.published_services SET view_def = format(
+        (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+        'condtn, siggrp, catrtb, radwal', 'rtpbcn')
+    WHERE schema = 'waterway' AND name = 'fairway_marks_rtpbcn';
+
+UPDATE sys_admin.published_services SET view_def = format(
+        (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+        'colour, colpat, condtn, topshp', 'topmar')
+    WHERE schema = 'waterway' AND name = 'fairway_marks_topmar';
+
+UPDATE sys_admin.published_services SET view_def = format(
+        (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+        $$condtn, marsys, orient, status, addmrk, catnmk,
+        disipd, disipu, disbk1, disbk2, fnctnm, bnkwtw,
+            string_agg(CAST(dirimp AS varchar), ',') AS dirimp$$,
+        $$notmrk LEFT JOIN waterway.fairway_marks_notmrk_dirimps
+            ON id = fm_notmrk_id GROUP BY id$$)
+    WHERE schema = 'waterway' AND name = 'fairway_marks_notmrk';
+
+UPDATE sys_admin.published_services SET view_def = format(
+        (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+        'colour, colpat, condtn, bcnshp, catlam', 'bcnlat_hydro')
+    WHERE schema = 'waterway' AND name = 'fairway_marks_bcnlat_hydro';
+
+UPDATE sys_admin.published_services SET view_def = format(
+        (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+        $$colour, colpat, condtn, bcnshp, catlam,
+            string_agg(CAST(dirimp AS varchar), ',') AS dirimp$$,
+        $$bcnlat_ienc LEFT JOIN waterway.fairway_marks_bcnlat_dirimps
+            ON id = fm_bcnlat_id GROUP BY id$$)
+    WHERE schema = 'waterway' AND name = 'fairway_marks_bcnlat_ienc';
+
+UPDATE sys_admin.published_services SET view_def = format(
+        (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+        'colour, colpat, conrad, marsys, boyshp, catlam', 'boylat_hydro')
+    WHERE schema = 'waterway' AND name = 'fairway_marks_boylat_hydro';
+
+UPDATE sys_admin.published_services SET view_def = format(
+        (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+        'colour, colpat, conrad, marsys, boyshp, catlam', 'boylat_ienc')
+    WHERE schema = 'waterway' AND name = 'fairway_marks_boylat_ienc';
+
+UPDATE sys_admin.published_services SET view_def = format(
+        (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+        'colour, colpat, condtn, topshp', 'daymar_hydro')
+    WHERE schema = 'waterway' AND name = 'fairway_marks_daymar_hydro';
+
+UPDATE sys_admin.published_services SET view_def = format(
+        (SELECT def FROM base_views WHERE name = 'fairway_marks_tmpl'),
+        $$colour, colpat, condtn, topshp, orient,
+            string_agg(CAST(dirimp AS varchar), ',') AS dirimp$$,
+        $$daymar_ienc LEFT JOIN waterway.fairway_marks_daymar_dirimps
+            ON id = fm_daymar_id GROUP BY id$$)
+    WHERE schema = 'waterway' AND name = 'fairway_marks_daymar_ienc';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/schema/updates/1422/01.amend_trigger_func.sql	Wed Mar 11 13:26:02 2020 +0100
@@ -0,0 +1,39 @@
+CREATE OR REPLACE FUNCTION prevent_st_equals() RETURNS trigger AS
+$$
+DECLARE
+    new_geom geometry;
+    tg_arg text;
+    filters text;
+    has_equal boolean;
+BEGIN
+    EXECUTE format('SELECT CAST($1.%I AS geometry)', TG_ARGV[0])
+        INTO new_geom
+        USING NEW;
+    FOREACH tg_arg IN ARRAY TG_ARGV[1:] LOOP
+        -- Test each additional argument for equality
+        filters = format('%s AND %2$I = $2.%2$I', filters, tg_arg);
+    END LOOP;
+    EXECUTE format(
+            'SELECT EXISTS(SELECT 1 FROM %I.%I '
+                'WHERE id <> $2.id AND ST_Equals($1, CAST(%I AS geometry))'
+                '%s)',
+             TG_TABLE_SCHEMA, TG_TABLE_NAME, TG_ARGV[0], filters)
+        INTO has_equal
+        USING new_geom, NEW;
+    IF has_equal THEN
+        RAISE EXCEPTION
+            'new row for relation "%" violates constraint trigger "%"',
+                TG_TABLE_NAME, TG_NAME
+            USING
+                DETAIL = format('Failing row contains geometry in %s',
+                    Box2D(new_geom)),
+                ERRCODE = 23505,
+                SCHEMA = TG_TABLE_SCHEMA,
+                TABLE = TG_TABLE_NAME,
+                COLUMN = TG_ARGV[0],
+                CONSTRAINT = TG_NAME;
+    END IF;
+    RETURN NEW;
+END;
+$$
+LANGUAGE plpgsql;
--- a/schema/version.sql	Wed Mar 11 13:21:36 2020 +0100
+++ b/schema/version.sql	Wed Mar 11 13:26:02 2020 +0100
@@ -1,1 +1,1 @@
-INSERT INTO gemma_schema_version(version) VALUES (1410);
+INSERT INTO gemma_schema_version(version) VALUES (1422);