Creates the legacy code for node/way/relation for incomming data
[handlerosm.git] / handler_osm_put.c
blob91ddd752733148323d264a3d50ed91a207633db7
1 #include <cherokee/cherokee.h>
2 #include <Mapi.h>
3 #include <axl.h>
5 #include "handler_osm.h"
6 #include "handler_osm_db.h"
7 #include "handler_osm_put.h"
8 #include "handler_osm_sql.h"
10 static ret_t result_node_last_id(cherokee_handler_osm_t *hdl, MapiHdl *hdl1, cherokee_buffer_t *buf) {
11 cherokee_buffer_add_va (buf, "%d", mapi_get_last_id(*hdl1));
12 return ret_ok;
15 static ret_t node_update_or_insert (cherokee_handler_osm_t *hdl, MapiHdl *hdl1, cherokee_buffer_t *buf) {
16 if (mapi_rows_affected(*hdl1) == 0)
17 return ret_error;
19 return ret_ok;
22 static void do_members(cherokee_handler_osm_t *hdl, axlNode *node, unsigned long int relationid, unsigned short int update) {
23 axlNode * member;
24 if ((member = axl_node_get_first_child(node)) != NULL) {
25 cherokee_buffer_t members_node = CHEROKEE_BUF_INIT;
26 cherokee_buffer_t members_way = CHEROKEE_BUF_INIT;
27 cherokee_buffer_t members_relation = CHEROKEE_BUF_INIT;
28 unsigned long int idx = 0;
29 do {
30 if (NODE_CMP_NAME (member, "member") &&
31 axl_node_has_attribute(member, "type") &&
32 axl_node_has_attribute(member, "ref") &&
33 axl_node_has_attribute(member, "role")) {
35 unsigned long int ref = strtod(axl_node_get_attribute_value(member, "ref"), NULL);
36 if (errno != ERANGE && ref > 0) {
37 const char *type = axl_node_get_attribute_value(member, "type");
38 const char *role = axl_node_get_attribute_value(member, "role");
40 if (strcmp(type, "node") == 0) {
41 cherokee_buffer_add_va (&members_node, "%lu, ", ref);
42 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
43 if (update == 1) {
44 cherokee_buffer_add_va (&sql1, "UPDATE relation_members_node SET to_node = %lu, role = '%s' WHERE relation = %lu AND idx = %lu", ref, role, relationid, idx);
46 if (update == 0 || run_sql(hdl, &sql1, NULL, node_update_or_insert) == ret_error) {
47 cherokee_buffer_mrproper(&sql1);
48 cherokee_buffer_add_va (&sql1, "INSERT INTO relation_members_node (relation, idx, to_node, role) VALUES (%lu, %lu, %lu, '%s')", relationid, idx, ref, role);
49 run_sql(hdl, &sql1, NULL, NULL);
51 cherokee_buffer_mrproper(&sql1);
52 } else if (strcmp(type, "way") == 0) {
53 cherokee_buffer_add_va (&members_way, "%lu, ", ref);
54 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
55 if (update == 1) {
56 cherokee_buffer_add_va (&sql1, "UPDATE relation_members_way SET to_way = %lu, role = '%s' WHERE relation = %lu AND idx = %lu", ref, role, relationid, idx);
58 if (update == 0 || run_sql(hdl, &sql1, NULL, node_update_or_insert) == ret_error) {
59 cherokee_buffer_mrproper(&sql1);
60 cherokee_buffer_add_va (&sql1, "INSERT INTO relation_members_way (relation, idx, to_way, role) VALUES (%lu, %lu, %lu, '%s')", relationid, idx, ref, role);
61 run_sql(hdl, &sql1, NULL, NULL);
63 cherokee_buffer_mrproper(&sql1);
64 } else if (strcmp(type, "relation") == 0) {
65 cherokee_buffer_add_va (&members_relation, "%lu, ", ref);
66 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
67 if (update == 1) {
68 cherokee_buffer_add_va (&sql1, "UPDATE relation_members_relation SET to_relation = %lu, role = '%s' WHERE relation = %lu AND idx = %lu", ref, role, relationid, idx);
70 if (update == 0 || run_sql(hdl, &sql1, NULL, node_update_or_insert) == ret_error) {
71 cherokee_buffer_mrproper(&sql1);
72 cherokee_buffer_add_va (&sql1, "INSERT INTO relation_members_relation (relation, idx, to_relation, role) VALUES (%lu, %lu, %lu, '%s')", relationid, idx, ref, role);
73 run_sql(hdl, &sql1, NULL, NULL);
75 cherokee_buffer_mrproper(&sql1);
76 } else {
77 TRACE("osm", "%s: New type?\n", type);
79 idx++;
82 } while ((member = axl_node_get_next(member)) != NULL);
84 if (members_node.len > 0) {
85 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
86 cherokee_buffer_drop_ending(&members_node, 2);
87 cherokee_buffer_add_va (&sql1, "DELETE FROM relation_members_node WHERE relation = %lu AND to_node NOT IN (%s)", relationid, members_node.buf);
88 run_sql(hdl, &sql1, NULL, NULL);
89 cherokee_buffer_mrproper(&sql1);
91 cherokee_buffer_mrproper(&members_node);
93 if (members_way.len > 0) {
94 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
95 cherokee_buffer_drop_ending(&members_way, 2);
96 cherokee_buffer_add_va (&sql1, "DELETE FROM relation_members_way WHERE relation = %lu AND to_way NOT IN (%s)", relationid, members_way.buf);
97 run_sql(hdl, &sql1, NULL, NULL);
98 cherokee_buffer_mrproper(&sql1);
100 cherokee_buffer_mrproper(&members_way);
102 if (members_relation.len > 0) {
103 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
104 cherokee_buffer_drop_ending(&members_relation, 2);
105 cherokee_buffer_add_va (&sql1, "DELETE FROM relation_members_relation WHERE relation = %lu AND to_relation NOT IN (%s)", relationid, members_relation.buf);
106 run_sql(hdl, &sql1, NULL, NULL);
107 cherokee_buffer_mrproper(&sql1);
109 cherokee_buffer_mrproper(&members_relation);
115 static void do_nds(cherokee_handler_osm_t *hdl, axlNode *node, unsigned long int wayid, unsigned short int update) {
116 axlNode * nd;
117 if ((nd = axl_node_get_first_child(node)) != NULL) {
118 cherokee_buffer_t nds = CHEROKEE_BUF_INIT;
119 unsigned long int idx = 0;
120 do {
121 if (NODE_CMP_NAME (nd, "nd") &&
122 axl_node_has_attribute(nd, "ref")) {
124 unsigned long int ref = strtod(axl_node_get_attribute_value(nd, "ref"), NULL);
125 if (errno != ERANGE && ref > 0) {
126 cherokee_buffer_add_va (&nds, "%lu, ", ref);
128 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
129 if (update == 1) {
130 cherokee_buffer_add_va (&sql1, "UPDATE way_nds SET to_node = %lu WHERE way = %lu AND idx = %lu", ref, wayid, idx);
132 if (update == 0 || run_sql(hdl, &sql1, NULL, node_update_or_insert) == ret_error) {
133 cherokee_buffer_mrproper(&sql1);
134 cherokee_buffer_add_va (&sql1, "INSERT INTO way_nds (way, idx, to_node) VALUES (%lu, %lu, %lu)", wayid, idx, ref);
135 run_sql(hdl, &sql1, NULL, NULL);
137 cherokee_buffer_mrproper(&sql1);
138 idx++;
141 } while ((nd = axl_node_get_next(nd)) != NULL);
143 if (nds.len > 0) {
144 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
145 cherokee_buffer_drop_ending(&nds, 2);
146 cherokee_buffer_add_va (&sql1, "DELETE FROM way_nds WHERE relation = %lu AND to_node NOT IN (%s)", wayid, nds.buf);
147 run_sql(hdl, &sql1, NULL, NULL);
148 cherokee_buffer_mrproper(&sql1);
151 cherokee_buffer_mrproper(&nds);
155 static void do_tags(cherokee_handler_osm_t *hdl, axlNode *node, unsigned long int nodeid, unsigned short int update, char *create_sql, char *update_sql, char *delete_sql) {
156 axlNode * tag;
157 if ((tag = axl_node_get_first_child(node)) != NULL) {
158 cherokee_buffer_t keys = CHEROKEE_BUF_INIT;
159 do {
160 if (NODE_CMP_NAME (tag, "tag") &&
161 axl_node_has_attribute(tag, "k") &&
162 axl_node_has_attribute(tag, "v")) {
163 const char * key = axl_node_get_attribute_value(tag, "k");
164 size_t keylen = strlen(key);
166 if (keylen > 0 && keylen < 256) {
167 const char * value = axl_node_get_attribute_value(tag, "v");
168 size_t valuelen = strlen(value);
169 cherokee_buffer_add_va (&keys, "\'%s\', ", key);
171 if (valuelen > 0 && valuelen < 256) {
172 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
173 if (update == 1) {
174 cherokee_buffer_add_va (&sql1, update_sql,
175 value,
176 nodeid,
180 if (update == 0 || run_sql(hdl, &sql1, NULL, node_update_or_insert) == ret_error) {
181 cherokee_buffer_mrproper(&sql1);
182 cherokee_buffer_add_va (&sql1, create_sql,
183 nodeid,
184 key,
185 value);
186 run_sql(hdl, &sql1, NULL, NULL);
188 cherokee_buffer_mrproper(&sql1);
192 } while ((tag = axl_node_get_next(tag)) != NULL);
194 if (keys.len > 0) {
195 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
196 cherokee_buffer_drop_ending(&keys, 2);
197 cherokee_buffer_add_va (&sql1, delete_sql, nodeid, keys.buf);
198 run_sql(hdl, &sql1, NULL, NULL);
199 cherokee_buffer_mrproper(&sql1);
202 cherokee_buffer_mrproper(&keys);
206 ret_t
207 cherokee_handler_osm_init_put (cherokee_handler_osm_t *hdl)
209 off_t postl;
210 ret_t ret = ret_ok;
211 cherokee_buffer_t post = CHEROKEE_BUF_INIT;
212 cherokee_buffer_t *buf;
213 cherokee_connection_t *conn = HANDLER_CONN(hdl);
214 axlDoc * doc;
215 axlError * error;
217 /* Check for the post info
219 cherokee_post_get_len (&conn->post, &postl);
220 if (postl <= 0 || postl >= (INT_MAX-1)) {
221 conn->error_code = http_bad_request;
222 return ret_error;
225 buf = &hdl->buffer;
227 /* Process line per line
229 cherokee_post_walk_read (&conn->post, &post, (cuint_t) postl);
231 TRACE("post", "%s\n", post.buf);
233 doc = axl_doc_parse (post.buf, post.len, &error);
235 if (doc == NULL) {
236 printf ("Error found: %s\n", axl_error_get (error));
237 axl_error_free (error);
238 return ret_error;
239 } else {
240 axlNode * node = axl_doc_get_root (doc);
241 node = axl_node_get_first_child (node);
242 unsigned long int nodeid = 0;
244 if (axl_node_has_attribute(node, "id")) {
245 const char *id = axl_node_get_attribute_value(node, "id");
246 nodeid = strtoul(id, (char **) NULL, 10);
247 TRACE("osm", "%lu\n", nodeid);
250 if (nodeid != 0) {
251 /* UPDATE */
252 if (NODE_CMP_NAME (node, "node")) {
253 if (axl_node_has_attribute(node, "lat") &&
254 axl_node_has_attribute(node, "lon")) {
255 double lat, lon;
256 lat = strtod(axl_node_get_attribute_value(node, "lat"), NULL);
257 if (errno == ERANGE) {
258 conn->error_code = http_bad_request;
259 return ret_error;
262 lon = strtod(axl_node_get_attribute_value(node, "lon"), NULL);
263 if (errno == ERANGE) {
264 conn->error_code = http_bad_request;
265 return ret_error;
266 } else {
267 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
268 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_START);
269 run_sql(hdl, &sql1, NULL, NULL);
270 cherokee_buffer_mrproper(&sql1);
271 cherokee_buffer_add_va (&sql1, SQL_NODE_UPDATE_BY_ID, lat, lon, 0, nodeid);
272 run_sql(hdl, &sql1, NULL, NULL);
273 cherokee_buffer_mrproper(&sql1);
275 do_tags(hdl, node, nodeid, 1, SQL_NODE_CREATE_NODE_TAG, SQL_NODE_UPDATE_NODE_TAG, SQL_NODE_DELETE_NODE_TAG);
277 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_COMMIT);
278 run_sql(hdl, &sql1, buf, NULL);
279 cherokee_buffer_mrproper(&sql1);
282 } else if (NODE_CMP_NAME (node, "way")) {
283 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
284 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_START);
285 run_sql(hdl, &sql1, buf, NULL);
286 cherokee_buffer_mrproper(&sql1);
288 cherokee_buffer_add_va (&sql1, SQL_RELATION_UPDATE, 0, nodeid);
289 run_sql(hdl, &sql1, NULL, NULL);
290 cherokee_buffer_mrproper(&sql1);
292 do_tags(hdl, node, nodeid, 1, SQL_WAY_CREATE_NODE_TAG, SQL_WAY_UPDATE_NODE_TAG, SQL_WAY_DELETE_NODE_TAG);
293 do_nds(hdl, node, nodeid, 1); /* this sequence otherwise we screw up type = */
295 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_COMMIT);
296 run_sql(hdl, &sql1, buf, NULL);
297 cherokee_buffer_mrproper(&sql1);
298 } else if (NODE_CMP_NAME (node, "relation")) {
299 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
300 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_START);
301 run_sql(hdl, &sql1, buf, NULL);
302 cherokee_buffer_mrproper(&sql1);
304 cherokee_buffer_add_va (&sql1, SQL_RELATION_UPDATE, 0, nodeid);
305 run_sql(hdl, &sql1, NULL, NULL);
306 cherokee_buffer_mrproper(&sql1);
308 do_members(hdl, node, nodeid, 1);
309 do_tags(hdl, node, nodeid, 1, SQL_RELATION_CREATE_NODE_TAG, SQL_RELATION_UPDATE_NODE_TAG, SQL_RELATION_DELETE_NODE_TAG);
311 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_COMMIT);
312 run_sql(hdl, &sql1, buf, NULL);
313 cherokee_buffer_mrproper(&sql1);
315 } else {
316 /* CREATE */
317 if (NODE_CMP_NAME (node, "node")) {
318 if (axl_node_has_attribute(node, "lat") &&
319 axl_node_has_attribute(node, "lon")) {
320 double lat, lon;
321 lat = strtod(axl_node_get_attribute_value(node, "lat"), NULL);
322 if (errno == ERANGE) {
323 conn->error_code = http_bad_request;
324 return ret_error;
327 lon = strtod(axl_node_get_attribute_value(node, "lon"), NULL);
328 if (errno == ERANGE) {
329 conn->error_code = http_bad_request;
330 return ret_error;
331 } else {
332 /* TODO: more error checking */
333 long testid = 0;
334 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
336 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_START);
337 run_sql(hdl, &sql1, buf, NULL);
338 cherokee_buffer_mrproper(&sql1);
340 cherokee_buffer_add_va (&sql1, SQL_NODE_CREATE, lat, lon, 0);
341 run_sql(hdl, &sql1, buf, result_node_last_id);
342 cherokee_buffer_mrproper(&sql1);
344 testid = strtol(buf->buf, (char **) NULL, 10);
345 if (errno != ERANGE && testid > 0) {
346 nodeid = testid;
348 do_tags(hdl, node, nodeid, 0, SQL_NODE_CREATE_NODE_TAG, SQL_NODE_UPDATE_NODE_TAG, SQL_NODE_DELETE_NODE_TAG);
350 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_COMMIT);
351 run_sql(hdl, &sql1, buf, NULL);
352 cherokee_buffer_mrproper(&sql1);
353 } else {
354 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_ROLLBACK);
355 run_sql(hdl, &sql1, buf, NULL);
356 cherokee_buffer_mrproper(&sql1);
360 } else if (NODE_CMP_NAME (node, "way")) {
361 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
362 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_START);
363 run_sql(hdl, &sql1, buf, NULL);
364 cherokee_buffer_mrproper(&sql1);
366 cherokee_buffer_add_va (&sql1, SQL_WAY_CREATE, 0);
367 run_sql(hdl, &sql1, buf, result_node_last_id);
368 cherokee_buffer_mrproper(&sql1);
370 long testid = 0;
371 testid = strtol(buf->buf, (char **) NULL, 10);
372 if (errno != ERANGE && testid > 0) {
373 nodeid = testid;
375 do_tags(hdl, node, nodeid, 0, SQL_WAY_CREATE_NODE_TAG, SQL_WAY_UPDATE_NODE_TAG, SQL_WAY_DELETE_NODE_TAG);
376 do_nds(hdl, node, nodeid, 0); /* this sequence otherwise we screw up type= */
378 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_COMMIT);
379 run_sql(hdl, &sql1, buf, NULL);
380 cherokee_buffer_mrproper(&sql1);
381 } else {
382 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_ROLLBACK);
383 run_sql(hdl, &sql1, buf, NULL);
384 cherokee_buffer_mrproper(&sql1);
386 } else if (NODE_CMP_NAME (node, "relation")) {
387 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
388 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_START);
389 run_sql(hdl, &sql1, buf, NULL);
390 cherokee_buffer_mrproper(&sql1);
392 cherokee_buffer_add_va (&sql1, SQL_RELATION_CREATE, 0);
393 run_sql(hdl, &sql1, buf, result_node_last_id);
394 cherokee_buffer_mrproper(&sql1);
396 long testid = 0;
397 testid = strtol(buf->buf, (char **) NULL, 10);
398 if (errno != ERANGE && testid > 0) {
399 nodeid = testid;
400 do_members(hdl, node, nodeid, 0);
401 do_tags(hdl, node, nodeid, 0, SQL_RELATION_CREATE_NODE_TAG, SQL_RELATION_UPDATE_NODE_TAG, SQL_RELATION_DELETE_NODE_TAG);
403 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_COMMIT);
404 run_sql(hdl, &sql1, buf, NULL);
405 cherokee_buffer_mrproper(&sql1);
406 } else {
407 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_ROLLBACK);
408 run_sql(hdl, &sql1, buf, NULL);
409 cherokee_buffer_mrproper(&sql1);
413 axl_doc_free (doc);
416 cherokee_buffer_mrproper (&post);
417 return ret;