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 create_node(cherokee_handler_osm_t
*hdl
, axlNode
* node
) {
209 cherokee_connection_t
*conn
= HANDLER_CONN(hdl
);
210 cherokee_buffer_t
*buf
;
213 if (NODE_CMP_NAME (node
, "node")) {
214 if (axl_node_has_attribute(node
, "lat") &&
215 axl_node_has_attribute(node
, "lon")) {
217 lat
= strtod(axl_node_get_attribute_value(node
, "lat"), NULL
);
218 if (errno
== ERANGE
) {
219 conn
->error_code
= http_bad_request
;
223 lon
= strtod(axl_node_get_attribute_value(node
, "lon"), NULL
);
224 if (errno
== ERANGE
) {
225 conn
->error_code
= http_bad_request
;
228 /* TODO: more error checking */
230 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
232 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_START
);
233 run_sql(hdl
, &sql1
, buf
, NULL
);
234 cherokee_buffer_mrproper(&sql1
);
236 cherokee_buffer_add_va (&sql1
, SQL_NODE_CREATE
, lon
, lat
, 0);
237 run_sql(hdl
, &sql1
, buf
, result_node_last_id
);
238 cherokee_buffer_mrproper(&sql1
);
240 testid
= strtol(buf
->buf
, (char **) NULL
, 10);
241 if (errno
!= ERANGE
&& testid
> 0) {
242 do_tags(hdl
, node
, testid
, 0, SQL_NODE_CREATE_NODE_TAG
, SQL_NODE_UPDATE_NODE_TAG
, SQL_NODE_DELETE_NODE_TAG
);
244 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_COMMIT
);
245 run_sql(hdl
, &sql1
, buf
, NULL
);
246 cherokee_buffer_mrproper(&sql1
);
248 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_ROLLBACK
);
249 run_sql(hdl
, &sql1
, buf
, NULL
);
250 cherokee_buffer_mrproper(&sql1
);
254 } else if (NODE_CMP_NAME (node
, "way")) {
255 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
256 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_START
);
257 run_sql(hdl
, &sql1
, buf
, NULL
);
258 cherokee_buffer_mrproper(&sql1
);
260 cherokee_buffer_add_va (&sql1
, SQL_WAY_CREATE
, 0);
261 run_sql(hdl
, &sql1
, buf
, result_node_last_id
);
262 cherokee_buffer_mrproper(&sql1
);
265 testid
= strtol(buf
->buf
, (char **) NULL
, 10);
266 if (errno
!= ERANGE
&& testid
> 0) {
267 do_tags(hdl
, node
, testid
, 0, SQL_WAY_CREATE_NODE_TAG
, SQL_WAY_UPDATE_NODE_TAG
, SQL_WAY_DELETE_NODE_TAG
);
268 do_nds(hdl
, node
, testid
, 0); /* this sequence otherwise we screw up type= */
270 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_COMMIT
);
271 run_sql(hdl
, &sql1
, buf
, NULL
);
272 cherokee_buffer_mrproper(&sql1
);
274 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_ROLLBACK
);
275 run_sql(hdl
, &sql1
, buf
, NULL
);
276 cherokee_buffer_mrproper(&sql1
);
278 } else if (NODE_CMP_NAME (node
, "relation")) {
279 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
280 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_START
);
281 run_sql(hdl
, &sql1
, buf
, NULL
);
282 cherokee_buffer_mrproper(&sql1
);
284 cherokee_buffer_add_va (&sql1
, SQL_RELATION_CREATE
, 0);
285 run_sql(hdl
, &sql1
, buf
, result_node_last_id
);
286 cherokee_buffer_mrproper(&sql1
);
289 testid
= strtol(buf
->buf
, (char **) NULL
, 10);
290 if (errno
!= ERANGE
&& testid
> 0) {
291 do_members(hdl
, node
, testid
, 0);
292 do_tags(hdl
, node
, testid
, 0, SQL_RELATION_CREATE_NODE_TAG
, SQL_RELATION_UPDATE_NODE_TAG
, SQL_RELATION_DELETE_NODE_TAG
);
294 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_COMMIT
);
295 run_sql(hdl
, &sql1
, buf
, NULL
);
296 cherokee_buffer_mrproper(&sql1
);
298 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_ROLLBACK
);
299 run_sql(hdl
, &sql1
, buf
, NULL
);
300 cherokee_buffer_mrproper(&sql1
);
307 update_node(cherokee_handler_osm_t
*hdl
, axlNode
* node
, unsigned long int nodeid
) {
308 cherokee_connection_t
*conn
= HANDLER_CONN(hdl
);
309 cherokee_buffer_t
*buf
;
312 if (NODE_CMP_NAME (node
, "node")) {
313 if (axl_node_has_attribute(node
, "lat") &&
314 axl_node_has_attribute(node
, "lon")) {
316 lat
= strtod(axl_node_get_attribute_value(node
, "lat"), NULL
);
317 if (errno
== ERANGE
) {
318 conn
->error_code
= http_bad_request
;
322 lon
= strtod(axl_node_get_attribute_value(node
, "lon"), NULL
);
323 if (errno
== ERANGE
) {
324 conn
->error_code
= http_bad_request
;
327 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
328 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_START
);
329 run_sql(hdl
, &sql1
, NULL
, NULL
);
330 cherokee_buffer_mrproper(&sql1
);
331 cherokee_buffer_add_va (&sql1
, SQL_NODE_UPDATE_BY_ID
, lon
, lat
, 0, nodeid
);
332 run_sql(hdl
, &sql1
, NULL
, NULL
);
333 cherokee_buffer_mrproper(&sql1
);
335 do_tags(hdl
, node
, nodeid
, 1, SQL_NODE_CREATE_NODE_TAG
, SQL_NODE_UPDATE_NODE_TAG
, SQL_NODE_DELETE_NODE_TAG
);
337 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_COMMIT
);
338 run_sql(hdl
, &sql1
, buf
, NULL
);
339 cherokee_buffer_mrproper(&sql1
);
342 } else if (NODE_CMP_NAME (node
, "way")) {
343 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
344 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_START
);
345 run_sql(hdl
, &sql1
, buf
, NULL
);
346 cherokee_buffer_mrproper(&sql1
);
348 cherokee_buffer_add_va (&sql1
, SQL_RELATION_UPDATE
, 0, nodeid
);
349 run_sql(hdl
, &sql1
, NULL
, NULL
);
350 cherokee_buffer_mrproper(&sql1
);
352 do_tags(hdl
, node
, nodeid
, 1, SQL_WAY_CREATE_NODE_TAG
, SQL_WAY_UPDATE_NODE_TAG
, SQL_WAY_DELETE_NODE_TAG
);
353 do_nds(hdl
, node
, nodeid
, 1); /* this sequence otherwise we screw up type = */
355 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_COMMIT
);
356 run_sql(hdl
, &sql1
, buf
, NULL
);
357 cherokee_buffer_mrproper(&sql1
);
358 } else if (NODE_CMP_NAME (node
, "relation")) {
359 cherokee_buffer_t sql1
= CHEROKEE_BUF_INIT
;
360 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_START
);
361 run_sql(hdl
, &sql1
, buf
, NULL
);
362 cherokee_buffer_mrproper(&sql1
);
364 cherokee_buffer_add_va (&sql1
, SQL_RELATION_UPDATE
, 0, nodeid
);
365 run_sql(hdl
, &sql1
, NULL
, NULL
);
366 cherokee_buffer_mrproper(&sql1
);
368 do_members(hdl
, node
, nodeid
, 1);
369 do_tags(hdl
, node
, nodeid
, 1, SQL_RELATION_CREATE_NODE_TAG
, SQL_RELATION_UPDATE_NODE_TAG
, SQL_RELATION_DELETE_NODE_TAG
);
371 cherokee_buffer_add_str (&sql1
, SQL_TRANSACTION_COMMIT
);
372 run_sql(hdl
, &sql1
, buf
, NULL
);
373 cherokee_buffer_mrproper(&sql1
);
381 cherokee_handler_osm_init_put (cherokee_handler_osm_t
*hdl
)
385 cherokee_buffer_t post
= CHEROKEE_BUF_INIT
;
386 cherokee_connection_t
*conn
= HANDLER_CONN(hdl
);
390 /* Check for the post info
392 cherokee_post_get_len (&conn
->post
, &postl
);
393 if (postl
<= 0 || postl
>= (INT_MAX
-1)) {
394 conn
->error_code
= http_bad_request
;
399 /* Process line per line
401 cherokee_post_walk_read (&conn
->post
, &post
, (cuint_t
) postl
);
403 TRACE("post", "%s\n", post
.buf
);
405 doc
= axl_doc_parse (post
.buf
, post
.len
, &error
);
408 printf ("Error found: %s\n", axl_error_get (error
));
409 axl_error_free (error
);
412 axlNode
* node
= axl_doc_get_root (doc
);
413 node
= axl_node_get_first_child (node
);
414 unsigned long int nodeid
= 0;
416 if (axl_node_has_attribute(node
, "id")) {
417 const char *id
= axl_node_get_attribute_value(node
, "id");
418 nodeid
= strtoul(id
, (char **) NULL
, 10);
419 TRACE("osm", "%lu\n", nodeid
);
422 /* het mooiste zou zijn om het onderstaande in twee functies te zetten
424 * Als dat gebeurd is kan hier (of in de 'update' code gechecked worden
425 * op 'root' of op normale user en aan de hand daarvan weer switchen op
426 * empty == create of full == update)
431 ret
= update_node(hdl
, node
, nodeid
);
434 ret
= create_node(hdl
, node
);
440 cherokee_buffer_mrproper (&post
);