Mercurial > gemma
comparison pkg/imports/st.go @ 1906:32c56e6c089a
Stretch import: Added forgotten source file.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Fri, 18 Jan 2019 17:13:12 +0100 |
parents | |
children | 6ffc372cde1e |
comparison
equal
deleted
inserted
replaced
1904:931b15be6d7f | 1906:32c56e6c089a |
---|---|
1 // This is Free Software under GNU Affero General Public License v >= 3.0 | |
2 // without warranty, see README.md and license for details. | |
3 // | |
4 // SPDX-License-Identifier: AGPL-3.0-or-later | |
5 // License-Filename: LICENSES/AGPL-3.0.txt | |
6 // | |
7 // Copyright (C) 2018 by via donau | |
8 // – Österreichische Wasserstraßen-Gesellschaft mbH | |
9 // Software engineering by Intevation GmbH | |
10 // | |
11 // Author(s): | |
12 // * Sascha L. Teichmann <sascha.teichmann@intevation.de> | |
13 | |
14 package imports | |
15 | |
16 import ( | |
17 "context" | |
18 "database/sql" | |
19 "errors" | |
20 "time" | |
21 | |
22 "gemma.intevation.de/gemma/pkg/common" | |
23 "gemma.intevation.de/gemma/pkg/models" | |
24 ) | |
25 | |
26 type Stretch struct { | |
27 Name string `json:"name"` | |
28 From models.Isrs `json:"from"` | |
29 To models.Isrs `json:"to"` | |
30 ObjNam string `json:"objnam"` | |
31 NObjNam *string `json:"nobjnam"` | |
32 Source string `json:"source-organization"` | |
33 Date models.Date `json:"date-info"` | |
34 Countries models.UniqueCountries `json:"countries"` | |
35 } | |
36 | |
37 const STJobKind JobKind = "st" | |
38 | |
39 type stJobCreator struct{} | |
40 | |
41 func init() { | |
42 RegisterJobCreator(STJobKind, stJobCreator{}) | |
43 } | |
44 | |
45 func (stJobCreator) Description() string { return "stretch" } | |
46 | |
47 func (stJobCreator) AutoAccept() bool { return false } | |
48 | |
49 func (stJobCreator) Create(_ JobKind, data string) (Job, error) { | |
50 st := new(Stretch) | |
51 if err := common.FromJSONString(data, st); err != nil { | |
52 return nil, err | |
53 } | |
54 return st, nil | |
55 } | |
56 | |
57 func (stJobCreator) Depends() []string { | |
58 return []string{ | |
59 "stretches", | |
60 } | |
61 } | |
62 | |
63 const ( | |
64 stDeleteSQL = ` | |
65 DELETE FROM waterway.stretches WHERE | |
66 staging_done AND name = ( | |
67 SELECT name | |
68 FROM waterway.stretches WHERE | |
69 id = ( | |
70 SELECT key from waterway.track_imports | |
71 WHERE import_id = $1 AND | |
72 relation = 'waterway.stretches'::regclass) | |
73 AND NOT staging_done | |
74 )` | |
75 | |
76 stStageDoneSQL = ` | |
77 UPDATE waterway.stretches SET staging_done = true | |
78 WHERE id IN ( | |
79 SELECT key from waterway.track_imports | |
80 WHERE import_id = $1 AND | |
81 relation = 'waterway.stretches'::regclass)` | |
82 | |
83 stInsertSQL = ` | |
84 WITH r AS ( | |
85 SELECT isrsrange( | |
86 isrs( | |
87 $1::char(2), | |
88 $2::char(3), | |
89 $3::char(5), | |
90 $4::char(5), | |
91 $5::int), | |
92 isrs( | |
93 $6::char(2), | |
94 $7::char(3), | |
95 $8::char(5), | |
96 $9::char(5), | |
97 $10::int)) AS r | |
98 ) | |
99 INSERT INTO waterway.stretches ( | |
100 name, | |
101 stretch, | |
102 geom, | |
103 objnam, | |
104 nobjnam, | |
105 date_info | |
106 ) VALUES ( | |
107 $11, | |
108 (SELECT r FROM r), | |
109 ISRSrange_area( | |
110 (SELECT r FROM r), | |
111 (SELECT ST_Union(CAST(area AS geometry)) | |
112 FROM waterway.waterway_area)), | |
113 $12, | |
114 $13, | |
115 $14) | |
116 RETURNING id` | |
117 | |
118 stInsertCountrySQL = ` | |
119 INSERT INTO waterway.stretch_countries ( | |
120 stretches_id, | |
121 country_code | |
122 ) VALUES ( | |
123 $1, | |
124 $2 | |
125 )` | |
126 ) | |
127 | |
128 // StageDone moves the imported stretch out of the staging area. | |
129 func (stJobCreator) StageDone( | |
130 ctx context.Context, | |
131 tx *sql.Tx, | |
132 id int64, | |
133 ) error { | |
134 if _, err := tx.ExecContext(ctx, stDeleteSQL, id); err != nil { | |
135 return err | |
136 } | |
137 _, err := tx.ExecContext(ctx, stStageDoneSQL, id) | |
138 return err | |
139 } | |
140 | |
141 // CleanUp of a stretch import is a NOP. | |
142 func (*Stretch) CleanUp() error { return nil } | |
143 | |
144 // Do executes the actual bottleneck import. | |
145 func (st *Stretch) Do( | |
146 ctx context.Context, | |
147 importID int64, | |
148 conn *sql.Conn, | |
149 feedback Feedback, | |
150 ) (interface{}, error) { | |
151 | |
152 start := time.Now() | |
153 | |
154 feedback.Info("Storing stretch '%s'", st.Name) | |
155 | |
156 if len(st.Countries) == 0 { | |
157 return nil, errors.New("List of countries is empty") | |
158 } | |
159 | |
160 tx, err := conn.BeginTx(ctx, nil) | |
161 if err != nil { | |
162 return nil, err | |
163 } | |
164 defer tx.Rollback() | |
165 | |
166 insertCountryStmt, err := tx.PrepareContext(ctx, stInsertCountrySQL) | |
167 if err != nil { | |
168 return nil, err | |
169 } | |
170 | |
171 var nobjnm sql.NullString | |
172 if st.NObjNam != nil { | |
173 nobjnm = sql.NullString{String: *st.NObjNam, Valid: true} | |
174 } | |
175 | |
176 var id int64 | |
177 if err := tx.QueryRowContext( | |
178 ctx, | |
179 stInsertSQL, | |
180 st.From.CountryCode, | |
181 st.From.LoCode, | |
182 st.From.FairwaySection, | |
183 st.From.Orc, | |
184 st.From.Hectometre, | |
185 st.To.CountryCode, | |
186 st.To.LoCode, | |
187 st.To.FairwaySection, | |
188 st.To.Orc, | |
189 st.To.Hectometre, | |
190 st.Name, | |
191 st.ObjNam, | |
192 nobjnm, | |
193 st.Date.Time, | |
194 ).Scan(&err); err != nil { | |
195 return nil, err | |
196 } | |
197 | |
198 // store the associated countries. | |
199 for _, c := range st.Countries { | |
200 if _, err := insertCountryStmt.ExecContext(ctx, id, c); err != nil { | |
201 return nil, err | |
202 } | |
203 } | |
204 | |
205 feedback.Info("Storing stretch '%s' took %s", st.Name, time.Since(start)) | |
206 if err := tx.Commit(); err != nil { | |
207 return nil, err | |
208 } | |
209 feedback.Info("Import of stretch was successful") | |
210 | |
211 summary := struct { | |
212 Stretch string `json:"stretch"` | |
213 }{ | |
214 Stretch: st.Name, | |
215 } | |
216 | |
217 return &summary, nil | |
218 } |