1 #include <cherokee/cherokee.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
));
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)
22 static void do_members(cherokee_handler_osm_t
*hdl
, axlNode
*node
, unsigned long int relationid
, unsigned short int update
) {
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;
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
;
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
;
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
;
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
);
77 TRACE("osm", "%s: New type?\n", type
);
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
) {
117 if ((nd
= axl_node_get_first_child(node
)) != NULL
) {
118 cherokee_buffer_t nds
= CHEROKEE_BUF_INIT
;
119 unsigned long int idx
= 0;
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
;
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
);
141 } while ((nd
= axl_node_get_next(nd
)) != NULL
);
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
) {
157 if ((tag
= axl_node_get_first_child(node
)) != NULL
) {
158 cherokee_buffer_t keys
= CHEROKEE_BUF_INIT
;
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
;
174 cherokee_buffer_add_va (&sql1
, update_sql
,
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
,
186 run_sql(hdl
, &sql1
, NULL
, NULL
);
188 cherokee_buffer_mrproper(&sql1
);
192 } while ((tag
= axl_node_get_next(tag
)) != NULL
);
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
);
207 cherokee_handler_osm_init_put (cherokee_handler_osm_t
*hdl
)
211 cherokee_buffer_t post
= CHEROKEE_BUF_INIT
;
212 cherokee_buffer_t
*buf
;
213 cherokee_connection_t
*conn
= HANDLER_CONN(hdl
);
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
;
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
);
236 printf ("Error found: %s\n", axl_error_get (error
));
237 axl_error_free (error
);
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
);
252 if (NODE_CMP_NAME (node
, "node")) {
253 if (axl_node_has_attribute(node
, "lat") &&
254 axl_node_has_attribute(node
, "lon")) {
256 lat
= strtod(axl_node_get_attribute_value(node
, "lat"), NULL
);
257 if (errno
== ERANGE
) {
258 conn
->error_code
= http_bad_request
;
262 lon
= strtod(axl_node_get_attribute_value(node
, "lon"), NULL
);
263 if (errno
== ERANGE
) {
264 conn
->error_code
= http_bad_request
;
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
);
317 if (NODE_CMP_NAME (node
, "node")) {
318 if (axl_node_has_attribute(node
, "lat") &&
319 axl_node_has_attribute(node
, "lon")) {
321 lat
= strtod(axl_node_get_attribute_value(node
, "lat"), NULL
);
322 if (errno
== ERANGE
) {
323 conn
->error_code
= http_bad_request
;
327 lon
= strtod(axl_node_get_attribute_value(node
, "lon"), NULL
);
328 if (errno
== ERANGE
) {
329 conn
->error_code
= http_bad_request
;
332 /* TODO: more error checking */
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) {
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
);
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
);
371 testid
= strtol(buf
->buf
, (char **) NULL
, 10);
372 if (errno
!= ERANGE
&& testid
> 0) {
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
);
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
);
397 testid
= strtol(buf
->buf
, (char **) NULL
, 10);
398 if (errno
!= ERANGE
&& testid
> 0) {
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
);
407 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_ROLLBACK
);
408 run_sql(hdl
, &sql1
, buf
, NULL
);
409 cherokee_buffer_mrproper(&sql1
);
416 cherokee_buffer_mrproper (&post
);