1 #include <cherokee/common-internal.h>
2 #include <cherokee/cherokee.h>
6 #include "handler_osm.h"
7 #include "handler_osm_db.h"
8 #include "handler_osm_put.h"
9 #include "handler_osm_sql.h"
11 static ret_t
result_node_last_id(cherokee_handler_osm_t
*hdl
, MapiHdl
*hdl1
, cherokee_buffer_t
*buf
) {
12 cherokee_buffer_add_va (buf
, "%d", mapi_get_last_id(*hdl1
));
16 static ret_t
node_update_or_insert (cherokee_handler_osm_t
*hdl
, MapiHdl
*hdl1
, cherokee_buffer_t
*buf
) {
17 if (mapi_rows_affected(*hdl1
) == 0)
23 static void do_members(cherokee_handler_osm_t
*hdl
, axlNode
*node
, unsigned long int relationid
, unsigned short int update
) {
25 if ((member
= axl_node_get_first_child(node
)) != NULL
) {
26 cherokee_buffer_t members_node
= CHEROKEE_BUF_INIT
;
27 cherokee_buffer_t members_way
= CHEROKEE_BUF_INIT
;
28 cherokee_buffer_t members_relation
= CHEROKEE_BUF_INIT
;
29 unsigned long int idx
= 0;
31 if (NODE_CMP_NAME (member
, "member") &&
32 axl_node_has_attribute(member
, "type") &&
33 axl_node_has_attribute(member
, "ref") &&
34 axl_node_has_attribute(member
, "role")) {
36 unsigned long int ref
= strtod(axl_node_get_attribute_value(member
, "ref"), NULL
);
37 if (errno
!= ERANGE
&& ref
> 0) {
38 const char *type
= axl_node_get_attribute_value(member
, "type");
39 const char *role
= axl_node_get_attribute_value(member
, "role");
41 if (strcmp(type
, "node") == 0) {
42 cherokee_buffer_add_va (&members_node
, "%lu, ", ref
);
43 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
45 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
);
47 if (update
== 0 || run_sql(hdl
, &sql1
, NULL
, node_update_or_insert
) == ret_error
) {
48 cherokee_buffer_mrproper(&sql1
);
49 cherokee_buffer_add_va (&sql1
, "INSERT INTO relation_members_node (relation, idx, to_node, role) VALUES (%lu, %lu, %lu, '%s')", relationid
, idx
, ref
, role
);
50 run_sql(hdl
, &sql1
, NULL
, NULL
);
52 cherokee_buffer_mrproper(&sql1
);
53 } else if (strcmp(type
, "way") == 0) {
54 cherokee_buffer_add_va (&members_way
, "%lu, ", ref
);
55 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
57 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
);
59 if (update
== 0 || run_sql(hdl
, &sql1
, NULL
, node_update_or_insert
) == ret_error
) {
60 cherokee_buffer_mrproper(&sql1
);
61 cherokee_buffer_add_va (&sql1
, "INSERT INTO relation_members_way (relation, idx, to_way, role) VALUES (%lu, %lu, %lu, '%s')", relationid
, idx
, ref
, role
);
62 run_sql(hdl
, &sql1
, NULL
, NULL
);
64 cherokee_buffer_mrproper(&sql1
);
65 } else if (strcmp(type
, "relation") == 0) {
66 cherokee_buffer_add_va (&members_relation
, "%lu, ", ref
);
67 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
69 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
);
71 if (update
== 0 || run_sql(hdl
, &sql1
, NULL
, node_update_or_insert
) == ret_error
) {
72 cherokee_buffer_mrproper(&sql1
);
73 cherokee_buffer_add_va (&sql1
, "INSERT INTO relation_members_relation (relation, idx, to_relation, role) VALUES (%lu, %lu, %lu, '%s')", relationid
, idx
, ref
, role
);
74 run_sql(hdl
, &sql1
, NULL
, NULL
);
76 cherokee_buffer_mrproper(&sql1
);
78 TRACE("osm", "%s: New type?\n", type
);
83 } while ((member
= axl_node_get_next(member
)) != NULL
);
85 if (members_node
.len
> 0) {
86 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
87 cherokee_buffer_drop_ending(&members_node
, 2);
88 cherokee_buffer_add_va (&sql1
, "DELETE FROM relation_members_node WHERE relation = %lu AND to_node NOT IN (%s)", relationid
, members_node
.buf
);
89 run_sql(hdl
, &sql1
, NULL
, NULL
);
90 cherokee_buffer_mrproper(&sql1
);
92 cherokee_buffer_mrproper(&members_node
);
94 if (members_way
.len
> 0) {
95 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
96 cherokee_buffer_drop_ending(&members_way
, 2);
97 cherokee_buffer_add_va (&sql1
, "DELETE FROM relation_members_way WHERE relation = %lu AND to_way NOT IN (%s)", relationid
, members_way
.buf
);
98 run_sql(hdl
, &sql1
, NULL
, NULL
);
99 cherokee_buffer_mrproper(&sql1
);
101 cherokee_buffer_mrproper(&members_way
);
103 if (members_relation
.len
> 0) {
104 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
105 cherokee_buffer_drop_ending(&members_relation
, 2);
106 cherokee_buffer_add_va (&sql1
, "DELETE FROM relation_members_relation WHERE relation = %lu AND to_relation NOT IN (%s)", relationid
, members_relation
.buf
);
107 run_sql(hdl
, &sql1
, NULL
, NULL
);
108 cherokee_buffer_mrproper(&sql1
);
110 cherokee_buffer_mrproper(&members_relation
);
116 static void do_nds(cherokee_handler_osm_t
*hdl
, axlNode
*node
, unsigned long int wayid
, unsigned short int update
) {
118 if ((nd
= axl_node_get_first_child(node
)) != NULL
) {
119 cherokee_buffer_t nds
= CHEROKEE_BUF_INIT
;
120 unsigned long int idx
= 0;
122 if (NODE_CMP_NAME (nd
, "nd") &&
123 axl_node_has_attribute(nd
, "ref")) {
125 unsigned long int ref
= strtod(axl_node_get_attribute_value(nd
, "ref"), NULL
);
126 if (errno
!= ERANGE
&& ref
> 0) {
127 cherokee_buffer_add_va (&nds
, "%lu, ", ref
);
129 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
131 cherokee_buffer_add_va (&sql1
, "UPDATE way_nds SET to_node = %lu WHERE way = %lu AND idx = %lu", ref
, wayid
, idx
);
133 if (update
== 0 || run_sql(hdl
, &sql1
, NULL
, node_update_or_insert
) == ret_error
) {
134 cherokee_buffer_mrproper(&sql1
);
135 cherokee_buffer_add_va (&sql1
, "INSERT INTO way_nds (way, idx, to_node) VALUES (%lu, %lu, %lu)", wayid
, idx
, ref
);
136 run_sql(hdl
, &sql1
, NULL
, NULL
);
138 cherokee_buffer_mrproper(&sql1
);
142 } while ((nd
= axl_node_get_next(nd
)) != NULL
);
145 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
146 cherokee_buffer_drop_ending(&nds
, 2);
147 cherokee_buffer_add_va (&sql1
, "DELETE FROM way_nds WHERE relation = %lu AND to_node NOT IN (%s)", wayid
, nds
.buf
);
148 run_sql(hdl
, &sql1
, NULL
, NULL
);
149 cherokee_buffer_mrproper(&sql1
);
152 cherokee_buffer_mrproper(&nds
);
156 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
) {
158 if ((tag
= axl_node_get_first_child(node
)) != NULL
) {
159 cherokee_buffer_t keys
= CHEROKEE_BUF_INIT
;
161 if (NODE_CMP_NAME (tag
, "tag") &&
162 axl_node_has_attribute(tag
, "k") &&
163 axl_node_has_attribute(tag
, "v")) {
164 const char * key
= axl_node_get_attribute_value(tag
, "k");
165 size_t keylen
= strlen(key
);
167 if (keylen
> 0 && keylen
< 256) {
168 const char * value
= axl_node_get_attribute_value(tag
, "v");
169 size_t valuelen
= strlen(value
);
170 cherokee_buffer_add_va (&keys
, "\'%s\', ", key
);
172 if (valuelen
> 0 && valuelen
< 256) {
173 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
175 cherokee_buffer_add_va (&sql1
, update_sql
,
181 if (update
== 0 || run_sql(hdl
, &sql1
, NULL
, node_update_or_insert
) == ret_error
) {
182 cherokee_buffer_mrproper(&sql1
);
183 cherokee_buffer_add_va (&sql1
, create_sql
,
187 run_sql(hdl
, &sql1
, NULL
, NULL
);
189 cherokee_buffer_mrproper(&sql1
);
193 } while ((tag
= axl_node_get_next(tag
)) != NULL
);
196 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
197 cherokee_buffer_drop_ending(&keys
, 2);
198 cherokee_buffer_add_va (&sql1
, delete_sql
, nodeid
, keys
.buf
);
199 run_sql(hdl
, &sql1
, NULL
, NULL
);
200 cherokee_buffer_mrproper(&sql1
);
203 cherokee_buffer_mrproper(&keys
);
208 cherokee_handler_osm_init_put (cherokee_handler_osm_t
*hdl
)
212 cherokee_buffer_t post
= CHEROKEE_BUF_INIT
;
213 cherokee_buffer_t
*buf
;
214 cherokee_connection_t
*conn
= HANDLER_CONN(hdl
);
218 /* Check for the post info
220 cherokee_post_get_len (&conn
->post
, &postl
);
221 if (postl
<= 0 || postl
>= (INT_MAX
-1)) {
222 conn
->error_code
= http_bad_request
;
228 /* Process line per line
230 cherokee_post_walk_read (&conn
->post
, &post
, (cuint_t
) postl
);
232 TRACE("post", "%s\n", post
.buf
);
234 doc
= axl_doc_parse (post
.buf
, post
.len
, &error
);
237 printf ("Error found: %s\n", axl_error_get (error
));
238 axl_error_free (error
);
241 axlNode
* node
= axl_doc_get_root (doc
);
242 node
= axl_node_get_first_child (node
);
243 unsigned long int nodeid
= 0;
245 if (axl_node_has_attribute(node
, "id")) {
246 const char *id
= axl_node_get_attribute_value(node
, "id");
247 nodeid
= strtoul(id
, (char **) NULL
, 10);
248 TRACE("osm", "%lu\n", nodeid
);
253 if (NODE_CMP_NAME (node
, "node")) {
254 if (axl_node_has_attribute(node
, "lat") &&
255 axl_node_has_attribute(node
, "lon")) {
257 lat
= strtod(axl_node_get_attribute_value(node
, "lat"), NULL
);
258 if (errno
== ERANGE
) {
259 conn
->error_code
= http_bad_request
;
263 lon
= strtod(axl_node_get_attribute_value(node
, "lon"), NULL
);
264 if (errno
== ERANGE
) {
265 conn
->error_code
= http_bad_request
;
268 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
269 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_START
);
270 run_sql(hdl
, &sql1
, NULL
, NULL
);
271 cherokee_buffer_mrproper(&sql1
);
272 cherokee_buffer_add_va (&sql1
, SQL_NODE_UPDATE_BY_ID
, lat
, lon
, 0, nodeid
);
273 run_sql(hdl
, &sql1
, NULL
, NULL
);
274 cherokee_buffer_mrproper(&sql1
);
276 do_tags(hdl
, node
, nodeid
, 1, SQL_NODE_CREATE_NODE_TAG
, SQL_NODE_UPDATE_NODE_TAG
, SQL_NODE_DELETE_NODE_TAG
);
278 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_COMMIT
);
279 run_sql(hdl
, &sql1
, buf
, NULL
);
280 cherokee_buffer_mrproper(&sql1
);
283 } else if (NODE_CMP_NAME (node
, "way")) {
284 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
285 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_START
);
286 run_sql(hdl
, &sql1
, buf
, NULL
);
287 cherokee_buffer_mrproper(&sql1
);
289 cherokee_buffer_add_va (&sql1
, SQL_RELATION_UPDATE
, 0, nodeid
);
290 run_sql(hdl
, &sql1
, NULL
, NULL
);
291 cherokee_buffer_mrproper(&sql1
);
293 do_tags(hdl
, node
, nodeid
, 1, SQL_WAY_CREATE_NODE_TAG
, SQL_WAY_UPDATE_NODE_TAG
, SQL_WAY_DELETE_NODE_TAG
);
294 do_nds(hdl
, node
, nodeid
, 1); /* this sequence otherwise we screw up type = */
296 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_COMMIT
);
297 run_sql(hdl
, &sql1
, buf
, NULL
);
298 cherokee_buffer_mrproper(&sql1
);
299 } else if (NODE_CMP_NAME (node
, "relation")) {
300 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
301 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_START
);
302 run_sql(hdl
, &sql1
, buf
, NULL
);
303 cherokee_buffer_mrproper(&sql1
);
305 cherokee_buffer_add_va (&sql1
, SQL_RELATION_UPDATE
, 0, nodeid
);
306 run_sql(hdl
, &sql1
, NULL
, NULL
);
307 cherokee_buffer_mrproper(&sql1
);
309 do_members(hdl
, node
, nodeid
, 1);
310 do_tags(hdl
, node
, nodeid
, 1, SQL_RELATION_CREATE_NODE_TAG
, SQL_RELATION_UPDATE_NODE_TAG
, SQL_RELATION_DELETE_NODE_TAG
);
312 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_COMMIT
);
313 run_sql(hdl
, &sql1
, buf
, NULL
);
314 cherokee_buffer_mrproper(&sql1
);
318 if (NODE_CMP_NAME (node
, "node")) {
319 if (axl_node_has_attribute(node
, "lat") &&
320 axl_node_has_attribute(node
, "lon")) {
322 lat
= strtod(axl_node_get_attribute_value(node
, "lat"), NULL
);
323 if (errno
== ERANGE
) {
324 conn
->error_code
= http_bad_request
;
328 lon
= strtod(axl_node_get_attribute_value(node
, "lon"), NULL
);
329 if (errno
== ERANGE
) {
330 conn
->error_code
= http_bad_request
;
333 /* TODO: more error checking */
335 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
337 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_START
);
338 run_sql(hdl
, &sql1
, buf
, NULL
);
339 cherokee_buffer_mrproper(&sql1
);
341 cherokee_buffer_add_va (&sql1
, SQL_NODE_CREATE
, lat
, lon
, 0);
342 run_sql(hdl
, &sql1
, buf
, result_node_last_id
);
343 cherokee_buffer_mrproper(&sql1
);
345 testid
= strtol(buf
->buf
, (char **) NULL
, 10);
346 if (errno
!= ERANGE
&& testid
> 0) {
349 do_tags(hdl
, node
, nodeid
, 0, SQL_NODE_CREATE_NODE_TAG
, SQL_NODE_UPDATE_NODE_TAG
, SQL_NODE_DELETE_NODE_TAG
);
351 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_COMMIT
);
352 run_sql(hdl
, &sql1
, buf
, NULL
);
353 cherokee_buffer_mrproper(&sql1
);
355 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_ROLLBACK
);
356 run_sql(hdl
, &sql1
, buf
, NULL
);
357 cherokee_buffer_mrproper(&sql1
);
361 } else if (NODE_CMP_NAME (node
, "way")) {
362 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
363 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_START
);
364 run_sql(hdl
, &sql1
, buf
, NULL
);
365 cherokee_buffer_mrproper(&sql1
);
367 cherokee_buffer_add_va (&sql1
, SQL_WAY_CREATE
, 0);
368 run_sql(hdl
, &sql1
, buf
, result_node_last_id
);
369 cherokee_buffer_mrproper(&sql1
);
372 testid
= strtol(buf
->buf
, (char **) NULL
, 10);
373 if (errno
!= ERANGE
&& testid
> 0) {
376 do_tags(hdl
, node
, nodeid
, 0, SQL_WAY_CREATE_NODE_TAG
, SQL_WAY_UPDATE_NODE_TAG
, SQL_WAY_DELETE_NODE_TAG
);
377 do_nds(hdl
, node
, nodeid
, 0); /* this sequence otherwise we screw up type= */
379 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_COMMIT
);
380 run_sql(hdl
, &sql1
, buf
, NULL
);
381 cherokee_buffer_mrproper(&sql1
);
383 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_ROLLBACK
);
384 run_sql(hdl
, &sql1
, buf
, NULL
);
385 cherokee_buffer_mrproper(&sql1
);
387 } else if (NODE_CMP_NAME (node
, "relation")) {
388 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
389 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_START
);
390 run_sql(hdl
, &sql1
, buf
, NULL
);
391 cherokee_buffer_mrproper(&sql1
);
393 cherokee_buffer_add_va (&sql1
, SQL_RELATION_CREATE
, 0);
394 run_sql(hdl
, &sql1
, buf
, result_node_last_id
);
395 cherokee_buffer_mrproper(&sql1
);
398 testid
= strtol(buf
->buf
, (char **) NULL
, 10);
399 if (errno
!= ERANGE
&& testid
> 0) {
401 do_members(hdl
, node
, nodeid
, 0);
402 do_tags(hdl
, node
, nodeid
, 0, SQL_RELATION_CREATE_NODE_TAG
, SQL_RELATION_UPDATE_NODE_TAG
, SQL_RELATION_DELETE_NODE_TAG
);
404 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_COMMIT
);
405 run_sql(hdl
, &sql1
, buf
, NULL
);
406 cherokee_buffer_mrproper(&sql1
);
408 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_ROLLBACK
);
409 run_sql(hdl
, &sql1
, buf
, NULL
);
410 cherokee_buffer_mrproper(&sql1
);
417 cherokee_buffer_mrproper (&post
);