Mercurial > gemma
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 } |