comparison pkg/models/intservices.go @ 4935:c64dba002726 fairway-marks-import

Load and prepare data models for layer groups. TODO: Feed config to GeoServer.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Sun, 16 Feb 2020 15:16:22 +0100
parents 4a9a1e323e11
children 4a816ecf70de
comparison
equal deleted inserted replaced
4934:c6af373b0832 4935:c64dba002726
25 "gemma.intevation.de/gemma/pkg/config" 25 "gemma.intevation.de/gemma/pkg/config"
26 ) 26 )
27 27
28 const DatabaseScheme = "waterway" 28 const DatabaseScheme = "waterway"
29 29
30 type IntEntry struct { 30 type (
31 Schema string `json:"schema"` 31 IntEntry struct {
32 Name string `json:"name"` 32 Schema string `json:"schema"`
33 SQL *string `json:"sql"` 33 Name string `json:"name"`
34 KeyColumn *string `json:"keycolumn"` 34 SQL *string `json:"sql"`
35 SRS *string `json:"srs"` 35 KeyColumn *string `json:"keycolumn"`
36 Style bool `json:"style"` 36 SRS *string `json:"srs"`
37 WMS bool `json:"wms"` 37 Style bool `json:"style"`
38 WFS bool `json:"wfs"` 38 WMS bool `json:"wms"`
39 } 39 WFS bool `json:"wfs"`
40 40 }
41 type IntServices struct { 41
42 entries []IntEntry 42 LayerGroup struct {
43 mu sync.Mutex 43 Name string `json:"name"`
44 } 44 Layers []string `json:"layers"`
45 }
46
47 IntServices struct {
48 mu sync.Mutex
49 entries []IntEntry
50 layerGroups []LayerGroup
51 }
52 )
45 53
46 const ( 54 const (
47 selectServicesSQL = ` 55 selectServicesSQL = `
48 SELECT schema, name, 56 SELECT schema, name,
49 view_def, key_column, auth_name || ':' || auth_srid, 57 view_def, key_column, auth_name || ':' || auth_srid,
50 style IS NOT NULL, as_wms, as_wfs 58 style IS NOT NULL, as_wms, as_wfs
51 FROM sys_admin.published_services 59 FROM sys_admin.published_services
52 LEFT JOIN spatial_ref_sys USING (srid) 60 LEFT JOIN spatial_ref_sys USING (srid)
53 WHERE schema = $1 61 WHERE schema = $1
54 ORDER by name` 62 ORDER by name`
63
64 selectGroupedLayersSQL = `
65 SELECT group_name, name
66 FROM sys_admin.grouped_layers
67 ORDER BY group_name, ord`
55 68
56 selectStyleSQL = ` 69 selectStyleSQL = `
57 SELECT style 70 SELECT style
58 FROM sys_admin.published_services 71 FROM sys_admin.published_services
59 WHERE name = $1 AND schema = $2` 72 WHERE name = $1 AND schema = $2`
89 } 102 }
90 return err 103 return err
91 }) 104 })
92 } 105 }
93 106
107 func (ps *IntServices) LayerGroups() []LayerGroup {
108 ps.mu.Lock()
109 defer ps.mu.Unlock()
110
111 if ps.entries == nil {
112 if err := ps.load(); err != nil {
113 log.Printf("error: %v\n", err)
114 return nil
115 }
116 }
117
118 // To avoid races we simple make a deep copy.
119 // As we don't have such many of them it light weight enough for now.
120 groups := make([]LayerGroup, len(ps.layerGroups))
121 for i := range groups {
122 layers := make([]string, len(ps.layerGroups[i].Layers))
123 copy(layers, ps.layerGroups[i].Layers)
124 groups[i] = LayerGroup{Name: ps.layerGroups[i].Name, Layers: layers}
125 }
126 return groups
127 }
128
94 func (ps *IntServices) Find(name string) (string, bool) { 129 func (ps *IntServices) Find(name string) (string, bool) {
95 ps.mu.Lock() 130 ps.mu.Lock()
96 defer ps.mu.Unlock() 131 defer ps.mu.Unlock()
97 132
98 if ps.entries == nil { 133 if ps.entries == nil {
127 } 162 }
128 163
129 func (ps *IntServices) load() error { 164 func (ps *IntServices) load() error {
130 // make empty slice to prevent retry if slice is empty. 165 // make empty slice to prevent retry if slice is empty.
131 ps.entries = []IntEntry{} 166 ps.entries = []IntEntry{}
167 ps.layerGroups = []LayerGroup{}
132 ctx := context.Background() 168 ctx := context.Background()
133 return auth.RunAs(ctx, "sys_admin", 169
134 func(conn *sql.Conn) error { 170 // Load the internal layers.
135 rows, err := conn.QueryContext( 171 entries := func(conn *sql.Conn) error {
136 ctx, selectServicesSQL, DatabaseScheme) 172 rows, err := conn.QueryContext(
137 if err != nil { 173 ctx, selectServicesSQL, DatabaseScheme)
174 if err != nil {
175 return err
176 }
177 defer rows.Close()
178 for rows.Next() {
179 var entry IntEntry
180 if err := rows.Scan(
181 &entry.Schema, &entry.Name,
182 &entry.SQL, &entry.KeyColumn, &entry.SRS, &entry.Style,
183 &entry.WMS, &entry.WFS,
184 ); err != nil {
138 return err 185 return err
139 } 186 }
140 defer rows.Close() 187 ps.entries = append(ps.entries, entry)
141 for rows.Next() { 188 }
142 var entry IntEntry 189 return rows.Err()
143 if err := rows.Scan( 190 }
144 &entry.Schema, &entry.Name, 191
145 &entry.SQL, &entry.KeyColumn, &entry.SRS, &entry.Style, 192 // Load the layer groups.
146 &entry.WMS, &entry.WFS, 193 groups := func(conn *sql.Conn) error {
147 ); err != nil { 194 rows, err := conn.QueryContext(ctx, selectGroupedLayersSQL)
148 return err 195 if err != nil {
149 } 196 return err
150 ps.entries = append(ps.entries, entry) 197 }
151 } 198 defer rows.Close()
152 return rows.Err() 199
153 }) 200 for rows.Next() {
201 var group, layer string
202 if err := rows.Scan(&group, &layer); err != nil {
203 return err
204 }
205 if n := len(ps.layerGroups); n > 0 && ps.layerGroups[n-1].Name == group {
206 ps.layerGroups[n-1].Layers = append(ps.layerGroups[n-1].Layers, layer)
207 } else {
208 ps.layerGroups = append(ps.layerGroups, LayerGroup{
209 Name: group,
210 Layers: []string{layer},
211 })
212 }
213 }
214 return rows.Err()
215 }
216
217 return auth.RunAllAs(ctx, "sys_admin", entries, groups)
154 } 218 }
155 219
156 func (ps *IntServices) Invalidate() { 220 func (ps *IntServices) Invalidate() {
157 ps.mu.Lock() 221 ps.mu.Lock()
158 ps.entries = nil 222 ps.entries = nil
223 ps.layerGroups = nil
159 ps.mu.Unlock() 224 ps.mu.Unlock()
160 } 225 }
161 226
162 func InternalAll(IntEntry) bool { return true } 227 func InternalAll(IntEntry) bool { return true }
163 func IntWMS(entry IntEntry) bool { return entry.WMS } 228 func IntWMS(entry IntEntry) bool { return entry.WMS }