Last before migration
[handlerosm.git] / handler_server_info.c
blob4d817729c4d2b22592afc4ad423c4462061f4fdc
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 /* Cherokee/MonetDB OSM Handler
5 * Authors:
6 * Alvaro Lopez Ortega <alvaro@alobbs.com>
7 * Stefan de Konink <handlerosm@kinkrsoftware.nl>
9 * Copyright (C) 2001-2008 Alvaro Lopez Ortega
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General Public
13 * License as published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 * USA
26 #include "common-internal.h"
27 #include "handler_server_info.h"
29 #ifdef HAVE_SYS_UTSNAME_H
30 # include <sys/utsname.h>
31 #endif
33 #include "util.h"
34 #include "connection.h"
35 #include "connection-protected.h"
36 #include "server.h"
37 #include "server-protected.h"
38 #include "plugin_loader.h"
39 #include "connection_info.h"
41 #include <axl.h>
43 #define CHANGES_TIME_DEFAULT 1
44 #define CHANGES_TIME_MAX 24
46 #define OSM_TAG "osm"
47 #define OSM_VERSION "0.5"
48 #define OSM_GENERATOR "Cherokee/MonetDB OSM Server"
49 #define OSM_ATTRIBUTES "version=\"" OSM_VERSION "\" generator=\"" OSM_GENERATOR "\""
51 #define NODE_TAG "node"
52 #define NODE_ATTRIBUTES "id=\"%s\" lat=\"%s\" lon=\"%s\" visible=\"true\" user=\"%s\" timestamp=\"%s\""
54 #define TAG_TAG "tag"
55 #define TAG_ATTRIBUTES "k=\"%s\" v=\"%s\""
57 #define WAY_TAG "way"
58 #define WAY_ATTRIBUTES "id=\"%s\" visible=\"true\" user=\"%s\" timestamp=\"%s\""
60 #define ND_TAG "nd"
61 #define ND_ATTRIBUTES "ref=\"%s\""
63 #define RELATION_TAG "relation"
64 #define RELATION_ATTRIBUTES "id=\"%s\" visible=\"true\" user=\"%s\" timestamp=\"%s\""
66 #define MEMBER_TAG "member"
67 #define MEMBER_ATTRIBUTES "type=\"%s\" ref=\"%s\" role=\"%s\""
68 #define MEMBER_TYPE_NODE "node"
69 #define MEMBER_TYPE_RELATION "relation"
71 #define XMLHEADER "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"CRLF
72 #define XML(THISTAG,LEVEL) LEVEL "<" THISTAG ## _TAG " " THISTAG ## _ATTRIBUTES
73 #define XMLCONTINUE ">" CRLF
74 #define XMLCLOSESHORT "/>" CRLF
75 #define XMLCLOSE(THISTAG,LEVEL) LEVEL "</" THISTAG ## _TAG ">" CRLF
77 #define PREFERENCES_TAG "preferences"
78 #define PREFERENCES_ATTRIBUTES ""
79 #define PREFERENCE_TAG "preference"
80 #define PREFERENCE_ATTRIBUTES "k=\"%s\" v=\"%s\""
85 #define LEGACY 1
88 #ifdef LEGACY
89 #define BBOX_VA_ARGS left, bottom, right, top
90 #define SQL_BY_BBOX " AND y > %f AND x > %f AND y < %f AND x < %f"
91 #define SQL_NODES "nodes_legacy"
92 #define SQL_NODE_SELECT "SELECT id, x, y, usernames.username, timestamp "
93 #else
94 #define BBOX_VA_ARGS bottom, left, bottom, right, top, right, top, left, bottom, left
95 #define SQL_BY_BBOX " AND WithIn(g, 'POLYGON((%f %f, %f %f, %f %f, %f %f, %f %f))') = TRUE"
96 #define SQL_NODES "nodes"
97 #define SQL_NODE_SELECT "SELECT id, X(g), Y(g), usernames.username, timestamp"
98 #endif
99 #define SQL_NODE_CREATE_GET_ID "SELECT id FROM " SQL_NODES " ORDER BY id DESC LIMIT 1;"
100 // #define SQL_NODE_CREATE "INSERT INTO " SQL_NODES " (x, y, username, timestamp) VALUES (%f, %f, %d, %s)"
101 #define SQL_NODE_CREATE "INSERT INTO " SQL_NODES " (x, y, username) VALUES (%f, %f, %d)"
102 #define SQL_NODE_CREATE_NODE_TAG "INSERT INTO node_tags (node, k, v) VALUES (%d, %s, %s)"
104 #define SQL_TRANSACTION_START "START TRANSACTION"
105 #define SQL_TRANSACTION_COMMIT "COMMIT"
106 #define SQL_TRANSACTION_ROLLBACK "ROLLBACK"
109 #define SQL_NODE SQL_NODE_SELECT \
110 "FROM " SQL_NODES ", usernames "\
111 "WHERE " SQL_NODES ".username = usernames.id"
114 #define SQL_BY_ID " AND id = %ld"
115 #define SQL_ORDER_BY_ID " ORDER BY id"
117 #define SQL_NODE_BY_ID SQL_NODE SQL_BY_ID
118 // #define SQL_NODE_BY_BBOX SQL_NODE SQL_BY_BBOX
120 /* #define SQL_NODE_BY_BBOX SQL_NODE_SELECT \
121 "FROM " SQL_NODES ", members_node, usernames, members_node AS loc1, " SQL_NODES " AS loc2 "\
122 "WHERE " SQL_NODES ".id = members_node.to_node AND "\
123 SQL_NODES ".username = usernames.id AND "\
124 "members_node.relation = loc1.relation AND "\
125 "loc2.id = loc1.to_node AND loc2.y > %f AND loc2.x > %f AND loc2.y < %f AND loc2.x < %f" \
126 "ORDER BY " SQL_NODES ".id"*/
127 //#define SQL_NODE_BY_BBOX "SELECT DISTINCT id, x, y, '0', timestamp FROM nodes_legacy, members_node, members_node AS loc1, nodes_legacy AS loc2 WHERE nodes_legacy.id = members_node.to_node AND members_node.relation = loc1.relation AND loc2.id = loc1.to_node AND loc2.y > %f AND loc2.x > %f AND loc2.y < %f AND loc2.x < %f;"
128 #define SQL_NODE_BY_BBOX "SELECT DISTINCT id, x, y, username, timestamp FROM nodes_legacy, usernames, members_node WHERE nodes_legacy.username = usernames.id AND members_node.to_node = nodes_legacy.id AND members_node.relation IN (SELECT DISTINCT relation FROM members_node, nodes_legacy WHERE members_node.to_node = nodes_legacy.id AND y > %f AND x > %f AND y < %f AND x < %f) ORDER BY nodes_legacy.id;"
130 #define SQL_NODE_TAGS_SELECT "SELECT node, k, v "
131 #define SQL_NODE_TAGS SQL_NODE_TAGS_SELECT " "\
132 "FROM node_tags, " SQL_NODES " "\
133 "WHERE node_tags.node = " SQL_NODES ".id"
135 #define SQL_NODE_TAGS_BY_ID SQL_NODE_TAGS SQL_BY_ID SQL_ORDER_BY_ID
136 #define SQL_NODE_TAGS_BY_BBOX SQL_NODE_TAGS SQL_BY_BBOX SQL_ORDER_BY_ID
138 #define SQL_RELATION_SELECT "SELECT DISTINCT id, usernames.username, timestamp "
139 #define SQL_RELATION SQL_RELATION_SELECT \
140 "FROM relations, usernames "\
141 "WHERE relations.username = usernames.id"
143 #define SQL_RELATION_BY_NODE SQL_RELATION_SELECT \
144 "FROM relations, usernames, " SQL_NODES ", members_node "\
145 "WHERE relations.username = usernames.id AND "\
146 SQL_NODES ".id = members_node.to_node AND members_node.relation = id"
148 #define SQL_RELATION_BY_NODE_ID SQL_RELATION_BY_NODE " AND " SQL_NODES ".id = %ld" SQL_ORDER_BY_ID
149 #define SQL_RELATION_BY_BBOX SQL_RELATION_BY_NODE SQL_BY_BBOX SQL_ORDER_BY_ID
150 #define SQL_RELATION_BY_ID SQL_RELATION " AND id = %ld"
153 #define SQL_REL_MEM_NOD_SELECT "SELECT DISTINCT relation, to_node, role "
154 #define SQL_RELATION_MEMBER_NODE SQL_REL_MEM_NOD_SELECT \
155 "FROM members_node "
156 #define SQL_RELATION_MEMBER_NODE_BY_ID SQL_RELATION_MEMBER_NODE "WHERE relation=%ld"
158 #define SQL_REL_MEM_REL_SELECT "SELECT DISTINCT relation, to_relation, role "
159 #define SQL_RELATION_MEMBER_RELATION SQL_REL_MEM_REL_SELECT \
160 "FROM members_relation "
162 #define SQL_RELATION_MEMBER_RELATION_BY_ID SQL_RELATION_MEMBER_RELATION "WHERE relation=%ld"
164 #define SQL_RELATION_MEMBER_NODE_BY_BBOX SQL_REL_MEM_NOD_SELECT \
165 "FROM members_node, members_node AS constr, " SQL_NODES " "\
166 "WHERE members_node.relation = constr.relation AND "\
167 SQL_NODES ".id = constr.to_node " SQL_BY_BBOX \
168 " ORDER BY relation, to_node"
170 #define SQL_RELATION_MEMBER_RELATION_BY_BBOX SQL_REL_MEM_NOD_SELECT \
171 "FROM members_relation, members_node, " SQL_NODES " "\
172 "WHERE members_node.relation = members_relation.relation AND "\
173 SQL_NODES ".id = members_node.to_node" SQL_BY_BBOX " ORDER BY relation, to_node"
175 #define SQL_RELATION_TAGS_SELECT "SELECT DISTINCT relation, k, v "
176 #define SQL_RELATION_TAGS SQL_RELATION_TAGS_SELECT " "\
177 "FROM relation_tags "\
178 "WHERE "
180 #define SQL_ORDER_BY_RELATION " ORDER BY relation"
181 #define SQL_RELATION_TAGS_BY_ID SQL_RELATION_TAGS "relation = %ld" SQL_ORDER_BY_RELATION
183 #define SQL_RELATION_TAGS_BY_BBOX1 SQL_RELATION_TAGS_SELECT \
184 "FROM " SQL_NODES ", members_node, relation_tags "\
185 "WHERE "\
186 SQL_NODES ".id = members_node.to_node AND members_node.relation = relation_tags.relation"\
187 SQL_BY_BBOX
188 #define SQL_RELATION_TAGS_BY_BBOX SQL_RELATION_TAGS_BY_BBOX1 SQL_ORDER_BY_RELATION
190 #define SQL_WAY SQL_RELATION_SELECT \
191 "FROM relations, usernames, relation_tags AS constr "\
192 "WHERE relations.username = usernames.id AND "\
193 "constr.relation = relations.id AND constr.k='type' AND constr.v='way'"
194 #define SQL_WAY_BY_ID SQL_WAY " AND id=%ld"
195 #define SQL_WAY_ND_SELECT "SELECT DISTINCT relation, to_node "
196 #define SQL_WAY_ND SQL_WAY_ND_SELECT \
197 "FROM members_node, relation_tags "\
198 "WHERE relation_tags.relation = members_node.relation AND k='type' AND v='way'"
200 #define SQL_WAY_ND_BY_ID SQL_WAY_ND " AND relation=%ld ORDER BY relation, idx"
201 #define SQL_WAY_BY_NODE SQL_RELATION_SELECT \
202 "FROM relations, usernames, " SQL_NODES ", members_node, relation_tags AS constr "\
203 "WHERE relations.username = usernames.id AND constr.relation = id "\
204 "AND constr.k='type' AND constr.v='way' AND "\
205 SQL_NODES ".id = members_node.to_node AND members_node.relation = id"
206 #define SQL_WAY_BY_NODE_ID SQL_WAY_BY_NODE " AND " SQL_NODES ".id = %ld ORDER BY id"
207 #define SQL_WAY_BY_BBOX SQL_WAY_BY_NODE SQL_BY_BBOX " ORDER BY id"
208 /* #define SQL_ND_BY_BBOX SQL_WAY_ND_SELECT \
209 "FROM members_node, relation_tags, " SQL_NODES " "\
210 "WHERE relation_tags.relation = members_node.relation AND k='type' AND v='way' "\
211 "AND " SQL_NODES ".id = members_node.to_node" SQL_BY_BBOX " ORDER BY relation, idx"*/
212 // #define SQL_ND_BY_BBOX "SELECT relation, to_node FROM members_node WHERE relation IN (SELECT DISTINCT relation FROM relation_tags, members_node, nodes_legacy WHERE relation_tags.relation = members_node.relation AND members_node.to_node = nodes_legacy.id AND y > %f AND x > %f AND y < %f AND x < %f AND relation_tags.k = 'type' AND relation_tags.v = 'way') ORDER BY members_node.relation, members_node.idx;"
215 #define SQL_ND_BY_BBOX "SELECT relation, to_node FROM members_node WHERE relation IN (SELECT DISTINCT relations.id FROM nodes_legacy, members_node, relations, relation_tags WHERE relations.id = relation_tags.relation AND members_node.relation = relations.id AND members_node.to_node = nodes_legacy.id AND y > %f AND x > %f AND y < %f AND x < %f AND k = 'type' AND v = 'way') ORDER BY relation, idx"
217 // #define SQL_ND_BY_BBOX "SELECT relation, to_node FROM members_node WHERE relation IN (SELECT id FROM relations WHERE id IN (SELECT DISTINCT relation FROM relation_tags, members_node, nodes_legacy WHERE relation_tags.relation = members_node.relation AND members_node.to_node = nodes_legacy.id AND y > %f AND x > %f AND y < %f AND x < %f AND relation_tags.k = 'type' AND relation_tags.v = 'way')) ORDER BY members_node.relation, members_node.idx;"
219 #define SQL_WAY_TAGS_BY_ID SQL_RELATION_TAGS_BY_ID
220 #define SQL_WAY_TAGS_BY_BBOX SQL_RELATION_TAGS_BY_BBOX1 SQL_ORDER_BY_RELATION
221 // #define SQL_WAY_TAGS_BY_BBOX SQL_RELATION_TAGS_BY_BBOX1 " AND k<>'type' AND v<>'way' " SQL_ORDER_BY_RELATION
224 /* Plug-in initialization
226 PLUGIN_INFO_HANDLER_EASIEST_INIT (server_info, http_get | http_put | http_post | http_delete );
229 /* Methods implementation
231 static ret_t
232 props_free (cherokee_handler_server_info_props_t *props)
234 return cherokee_module_props_free_base (MODULE_PROPS(props));
238 ret_t
239 cherokee_handler_server_info_configure (cherokee_config_node_t *conf, cherokee_server_t *srv, cherokee_module_props_t **_props)
241 cherokee_list_t *i;
242 cherokee_handler_server_info_props_t *props;
244 UNUSED(srv);
246 if (*_props == NULL) {
247 CHEROKEE_NEW_STRUCT (n, handler_server_info_props);
249 cherokee_module_props_init_base (MODULE_PROPS(n),
250 MODULE_PROPS_FREE(props_free));
251 n->just_about = false;
252 n->connection_details = false;
254 *_props = MODULE_PROPS(n);
257 props = PROP_SRV_INFO(*_props);
259 cherokee_config_node_foreach (i, conf) {
260 cherokee_config_node_t *subconf = CONFIG_NODE(i);
262 if (equal_buf_str (&subconf->key, "just_about")) {
263 props->just_about = atoi(subconf->val.buf);
264 } else if (equal_buf_str (&subconf->key, "connection_details")) {
265 props->connection_details = atoi(subconf->val.buf);
266 } else {
267 PRINT_MSG ("ERROR: Handler file: Unknown key: '%s'\n", subconf->key.buf);
268 return ret_error;
272 return ret_ok;
275 static void
276 user_preferences(cherokee_buffer_t *buf)
278 cherokee_buffer_t content = CHEROKEE_BUF_INIT;
279 cherokee_buffer_add_str (buf, XML(PREFERENCES, " "));
280 if (content.len > 0) {
281 cherokee_buffer_add_str (buf, XMLCONTINUE);
282 cherokee_buffer_add_buffer (buf, &content);
283 cherokee_buffer_mrproper (&content);
284 cherokee_buffer_add_str (buf, XMLCLOSE(PREFERENCES, " "));
285 } else
286 cherokee_buffer_add_str (buf, XMLCLOSESHORT);
288 printf("%s\n", __func__);
291 static void
292 gpx_data(cherokee_buffer_t *buf, unsigned long int id)
294 printf("%s\n", __func__);
297 static void
298 gpx_details(cherokee_buffer_t *buf, unsigned long int id)
300 printf("%s\n", __func__);
303 static void
304 node_ways(cherokee_buffer_t *buf, unsigned long int id)
306 printf("%s\n", __func__);
309 enum OSM_State { OSM_FIND_FIRST = 0, OSM_GPX_ID, OSM_GPX_COMMAND, OSM_NODE_ID, OSM_NODE_COMMAND, OSM_NODES, OSM_NODES_PRE_PARSE, OSM_WAY_ID, OSM_WAY_COMMAND, OSM_WAYS_PRE_PARSE, OSM_WAYS_SEARCH, OSM_RELATION_ID, OSM_RELATION_COMMAND, OSM_RELATIONS_PRE_PARSE, OSM_RELATIONS_SEARCH, OSM_DONE}; // Move to .h later
311 static void
312 objtype_full(cherokee_buffer_t *buf, unsigned long int id, enum OSM_State state)
314 printf("%s\n", __func__);
317 static void
318 objtype_history(cherokee_buffer_t *buf, unsigned long int id, enum OSM_State state)
320 printf("%s\n", __func__);
323 static void
324 objtype_relations(cherokee_buffer_t *buf, unsigned long int id, enum OSM_State state)
326 printf("%s\n", __func__);
329 parse_changes(cherokee_avl_t *arguments, cherokee_buffer_t *buf) {
330 unsigned long int hours;
331 unsigned long int zoom;
332 void *param;
333 ret_t ret;
335 ret = cherokee_avl_get_ptr (arguments, "zoom", &param);
336 if (ret == ret_ok) {
337 zoom = strtoul(param, (char **) NULL, 10);
338 } else
339 zoom = 12;
341 ret = cherokee_avl_get_ptr (arguments, "start", &param);
342 if (ret == ret_ok) {
343 void *param2;
344 ret = cherokee_avl_get_ptr (arguments, "end", &param2);
345 if (ret == ret_ok) {
346 changes_bystartend(buf, zoom, (char *)param, (char *)param2);
348 } else {
349 ret = cherokee_avl_get_ptr (arguments, "hours", &param);
350 if (ret == ret_ok) {
351 hours = strtoul(param, (char **) NULL, 10);
352 } else
353 hours = 1;
355 changes_byhour(buf, zoom, hours);
359 changes_byhour(cherokee_buffer_t *buf, unsigned long int zoom, unsigned long int hours) {
360 cherokee_buffer_add_va (buf, "%d %d", zoom, hours);
363 changes_bystartend(cherokee_buffer_t *buf, unsigned long int zoom, char *start, char *end) {
364 cherokee_buffer_add_va (buf, "%d %s %s", zoom, start, end);
367 static ret_t fetch_bbox(cherokee_avl_t *arguments, double *left, double *bottom, double *right, double *top) {
368 void *param;
369 if (ret_ok == cherokee_avl_get_ptr (arguments, "bbox", &param)) {
370 char *token;
371 char *string = (char *) param;
372 if ((token = (char *) strsep( &string , ",")) != NULL) {
373 *left = strtod(token, (char **) NULL);
374 if (errno != ERANGE && (token = (char *) strsep( &string , ",")) != NULL) {
375 *bottom = strtod(token, (char **) NULL);
376 if (errno != ERANGE && (token = (char *) strsep( &string , ",")) != NULL) {
377 *right = strtod(token, (char **) NULL);
378 if (errno != ERANGE && (token = (char *) strsep( &string , ",")) != NULL) {
379 *top = strtod(token, (char **) NULL);
380 if (errno != ERANGE) {
381 return ret_ok;
388 return ret_error;
391 static void parse_nodes(cherokee_avl_t *arguments, cherokee_buffer_t *buf) {
393 static void parse_nodes_search(cherokee_avl_t *arguments, cherokee_buffer_t *buf) {
396 static void parse_relations(cherokee_avl_t *arguments, cherokee_buffer_t *buf) {
398 static void parse_relations_search(cherokee_avl_t *arguments, cherokee_buffer_t *buf) {
401 static void parse_ways(cherokee_avl_t *arguments, cherokee_buffer_t *buf) {
403 static void parse_ways_search(cherokee_avl_t *arguments, cherokee_buffer_t *buf) {
405 static void parse_trackpoints(cherokee_avl_t *arguments, cherokee_buffer_t *buf) {
406 double left, bottom, right, top;
407 unsigned long int page;
408 void *param;
409 printf("%s\n", __func__);
411 if (ret_ok == fetch_bbox(arguments, &left, &bottom, &right, &top)) {
412 cherokee_buffer_add_va (buf, "%f %f %f %f", left, bottom, right, top);
415 if (ret_ok == cherokee_avl_get_ptr (arguments, "page", &param)) {
416 page = strtoul(param, (char **) NULL, 10);
417 if (errno == ERANGE)
418 page = 1;
419 } else {
420 page = 1;
424 static void result_node_to_xml(MapiHdl *hdl, MapiHdl *hdl2, cherokee_buffer_t *buf) {
425 unsigned long int id = 0, id_old = 0;
426 unsigned short int state = 3;
427 while (mapi_fetch_row(*hdl)) {
428 char *key, *value;
429 id = strtoul(mapi_fetch_field(*hdl, 0), (char **) NULL, 10);
430 if (id_old != id) {
431 switch (state) {
432 case 0:
433 cherokee_buffer_add_str (buf, XMLCLOSESHORT);
434 break;
435 case 1:
436 cherokee_buffer_add_va (buf, "%s", XMLCLOSE(NODE, " "));
437 break;
439 cherokee_buffer_add_va (buf, XML(NODE, " "), mapi_fetch_field(*hdl, 0),
440 mapi_fetch_field(*hdl, 1),
441 mapi_fetch_field(*hdl, 2),
442 mapi_fetch_field(*hdl, 3),
443 mapi_fetch_field(*hdl, 4) );
445 state = 0;
446 id_old = id;
448 /* if (mapi_get_row_count(*hdl2) > 0) {
449 while (mapi_fetch_row(*hdl2)) {
450 unsigned long int relationid = strtoul(mapi_fetch_field(*hdl2, 0), (char **) NULL, 10);
451 if (relationid == id) {
452 if (state == 0) {
453 cherokee_buffer_add_str (buf, XMLCONTINUE);
454 state = 1;
456 cherokee_buffer_add_va (buf, XML(TAG, " ") XMLCLOSESHORT, mapi_fetch_field(*hdl2, 1),
457 mapi_fetch_field(*hdl2, 2));
458 } else {
459 mapi_seek_row(*hdl2, -1, MAPI_SEEK_CUR);
460 break;
466 switch (state) {
467 case 0:
468 cherokee_buffer_add_str (buf, XMLCLOSESHORT);
469 break;
470 case 1:
471 cherokee_buffer_add_va (buf, "%s", XMLCLOSE(NODE, " "));
472 break;
476 static void result_node_last_id(cherokee_handler_server_info_t *hdl, MapiHdl *hdl1, cherokee_buffer_t *buf) {
477 if (mapi_fetch_row(*hdl1)) {
478 cherokee_buffer_add_va (buf, "%s", mapi_fetch_field(*hdl1, 0));
482 static void result_way_to_xml(cherokee_handler_server_info_t *hdl, MapiHdl *hdl1, MapiHdl *hdl2, MapiHdl *hdl3, cherokee_buffer_t *buf) {
483 unsigned long int id = 0, id_old = 0, member_id = 0, tag_id = 0;
484 unsigned short int state = 3;
485 while (mapi_fetch_row(*hdl1)) {
486 char *key, *value;
487 id = strtoul(mapi_fetch_field(*hdl1, 0), (char **) NULL, 10);
488 if (id_old != id) {
489 switch (state) {
490 case 0:
491 cherokee_buffer_add_str (buf, XMLCLOSESHORT);
492 break;
493 case 1:
494 cherokee_buffer_add_va (buf, "%s", XMLCLOSE(WAY, " "));
495 break;
497 cherokee_buffer_add_va (buf, XML(WAY, " "), mapi_fetch_field(*hdl1, 0),
498 mapi_fetch_field(*hdl1, 1),
499 mapi_fetch_field(*hdl1, 2) );
500 state = 0;
501 id_old = id;
503 if (mapi_get_row_count(*hdl2) > 0) {
504 if (member_id == 0) {
505 mapi_fetch_row(*hdl2);
506 member_id = strtoul(mapi_fetch_field(*hdl2, 0), (char **) NULL, 10);
509 if (member_id == id) {
510 if (state == 0) {
511 cherokee_buffer_add_str (buf, XMLCONTINUE);
512 state = 1;
515 while (member_id == id) {
516 char *value = mapi_fetch_field(*hdl2, 1);
518 if (value != NULL) {
519 cherokee_buffer_add_va (buf, XML(ND, " ")XMLCLOSESHORT, value);
520 } else {
521 printf("NULL BUG! %d\n", member_id);
523 if (mapi_fetch_row(*hdl2) != 0) {
524 member_id = strtoul(mapi_fetch_field(*hdl2, 0), (char **) NULL, 10);
525 } else {
526 printf("errorr \n");
527 mapi_explain(hdl->dbh,stderr);
528 member_id = 0;
533 while (mapi_fetch_row(*hdl2)) {
534 unsigned long int relationid = strtoul(mapi_fetch_field(*hdl2, 0), (char **) NULL, 10);
536 if (id > 6305628 && id < 6305660) {
537 printf("\n%ld %ld %s %s\n", id, relationid, mapi_fetch_field(*hdl2, 0), mapi_fetch_field(*hdl2, 1));
540 if (relationid == id) {
541 if (state == 0) {
542 cherokee_buffer_add_str (buf, XMLCONTINUE);
543 state = 1;
545 cherokee_buffer_add_va (buf, XML(ND, " ")XMLCLOSESHORT, mapi_fetch_field(*hdl2, 1));
546 } else {
547 if (id < 6305645)
548 printf("\n\nWE ARE SEEKING \n\n");
549 mapi_seek_row(*hdl2, -1, MAPI_SEEK_CUR);
550 break;
554 if (mapi_get_row_count(*hdl3) > 0) {
555 while (mapi_fetch_row(*hdl3)) {
556 unsigned long int relationid = strtoul(mapi_fetch_field(*hdl3, 0), (char **) NULL, 10);
557 if (relationid == id) {
558 char *key, *value;
559 if (state == 0) {
560 cherokee_buffer_add_str (buf, XMLCONTINUE);
561 state = 1;
563 key = mapi_fetch_field(*hdl3, 1);
564 value = mapi_fetch_field(*hdl3, 2);
565 if (key != NULL && value != NULL && strcmp(key, "type") != 0 && strcmp(value, "way") != 0) { // temporary until monet speeds up
566 cherokee_buffer_add_va (buf, XML(TAG, " ") XMLCLOSESHORT, mapi_fetch_field(*hdl3, 1),
567 mapi_fetch_field(*hdl3, 2));
569 } else {
570 mapi_seek_row(*hdl3, -1, MAPI_SEEK_CUR);
571 break;
577 switch (state) {
578 case 0:
579 cherokee_buffer_add_str (buf, XMLCLOSESHORT);
580 break;
581 case 1:
582 cherokee_buffer_add_va (buf, "%s", XMLCLOSE(WAY, " "));
583 break;
587 static void result_relation_to_xml(MapiHdl *hdl, MapiHdl *hdl2, MapiHdl *hdl3, MapiHdl *hdl4, cherokee_buffer_t *buf) {
588 unsigned long int id = 0, id_old = 0;
589 unsigned short int state = 3;
590 while (mapi_fetch_row(*hdl)) {
591 char *key, *value;
592 id = strtoul(mapi_fetch_field(*hdl, 0), (char **) NULL, 10);
593 if (id_old != id) {
594 switch (state) {
595 case 0:
596 cherokee_buffer_add_str (buf, XMLCLOSESHORT);
597 break;
598 case 1:
599 cherokee_buffer_add_va (buf, "%s", XMLCLOSE(RELATION, " "));
600 break;
602 cherokee_buffer_add_va (buf, XML(RELATION, " "), mapi_fetch_field(*hdl, 0),
603 mapi_fetch_field(*hdl, 1),
604 mapi_fetch_field(*hdl, 2) );
605 state = 0;
606 id_old = id;
608 if (mapi_get_row_count(*hdl2) > 0) {
609 while (mapi_fetch_row(*hdl2)) {
610 unsigned long int relationid = strtoul(mapi_fetch_field(*hdl2, 0), (char **) NULL, 10);
611 if (relationid == id) {
612 if (state == 0) {
613 cherokee_buffer_add_str (buf, XMLCONTINUE);
614 state = 1;
616 cherokee_buffer_add_va (buf, XML(MEMBER, " ")XMLCLOSESHORT, MEMBER_TYPE_NODE, mapi_fetch_field(*hdl2, 1), mapi_fetch_field(*hdl2, 2));
617 } else {
618 mapi_seek_row(*hdl2, -1, MAPI_SEEK_CUR);
619 break;
623 if (mapi_get_row_count(*hdl3) > 0) {
624 while (mapi_fetch_row(*hdl3)) {
625 unsigned long int relationid = strtoul(mapi_fetch_field(*hdl3, 0), (char **) NULL, 10);
627 if (relationid == id) {
628 if (state == 0) {
629 cherokee_buffer_add_str (buf, XMLCONTINUE);
630 state = 1;
632 cherokee_buffer_add_va (buf, XML(MEMBER, " ")XMLCLOSESHORT, MEMBER_TYPE_RELATION, mapi_fetch_field(*hdl3, 1), mapi_fetch_field(*hdl3, 2));
633 } else {
634 mapi_seek_row(*hdl3, -1, MAPI_SEEK_CUR);
635 break;
640 if (mapi_get_row_count(*hdl4) > 0) {
641 while (mapi_fetch_row(*hdl4)) {
642 unsigned long int relationid = strtoul(mapi_fetch_field(*hdl4, 0), (char **) NULL, 10);
643 if (relationid == id) {
644 if (state == 0) {
645 cherokee_buffer_add_str (buf, XMLCONTINUE);
646 state = 1;
648 cherokee_buffer_add_va (buf, XML(TAG, " ") XMLCLOSESHORT, mapi_fetch_field(*hdl4, 1),
649 mapi_fetch_field(*hdl4, 2));
650 } else {
651 mapi_seek_row(*hdl4, -1, MAPI_SEEK_CUR);
652 break;
658 switch (state) {
659 case 0:
660 cherokee_buffer_add_str (buf, XMLCLOSESHORT);
661 break;
662 case 1:
663 cherokee_buffer_add_va (buf, "%s", XMLCLOSE(RELATION, " "));
664 break;
668 ret_t
669 run_sql(cherokee_handler_server_info_t *hdl, cherokee_buffer_t *sql, cherokee_buffer_t *buf, void (*callback)()) {
670 ret_t ret = ret_error;
671 MapiHdl mapi_hdl = NULL;
672 if ((mapi_hdl = mapi_query(hdl->dbh, sql->buf)) != NULL && mapi_error(hdl->dbh) == MOK) {
673 if (callback != NULL)
674 callback(&mapi_hdl, buf);
675 mapi_close_handle(mapi_hdl);
676 ret = ret_ok;
679 return ret;
683 ret_t
684 run_sql2(cherokee_handler_server_info_t *hdl, cherokee_buffer_t *sql1, cherokee_buffer_t *sql2, cherokee_buffer_t *buf, void (*callback)()) {
685 ret_t ret = ret_error;
686 MapiHdl mapi_hdl1 = NULL;
687 MapiHdl mapi_hdl2 = NULL;
689 if ((mapi_hdl1 = mapi_query(hdl->dbh, sql1->buf)) != NULL && mapi_error(hdl->dbh) == MOK) {
690 if ((mapi_hdl2 = mapi_query(hdl->dbh, sql2->buf)) != NULL && mapi_error(hdl->dbh) == MOK) {
691 if (callback != NULL)
692 callback(&mapi_hdl1, &mapi_hdl2, buf);
693 mapi_close_handle(mapi_hdl2);
694 ret = ret_ok;
696 mapi_close_handle(mapi_hdl1);
699 return ret;
702 ret_t
703 run_sql3(cherokee_handler_server_info_t *hdl, cherokee_buffer_t *sql1, cherokee_buffer_t *sql2, cherokee_buffer_t *sql3, cherokee_buffer_t *buf, void (*callback)()) {
704 ret_t ret = ret_error;
705 MapiHdl mapi_hdl1 = NULL;
706 MapiHdl mapi_hdl2 = NULL;
707 MapiHdl mapi_hdl3 = NULL;
709 if ((mapi_hdl1 = mapi_query(hdl->dbh, sql1->buf)) != NULL && mapi_error(hdl->dbh) == MOK) {
710 if ((mapi_hdl2 = mapi_query(hdl->dbh, sql2->buf)) != NULL && mapi_error(hdl->dbh) == MOK) {
711 if ((mapi_hdl3 = mapi_query(hdl->dbh, sql3->buf)) != NULL && mapi_error(hdl->dbh) == MOK) {
712 if (callback != NULL)
713 callback(hdl, &mapi_hdl1, &mapi_hdl2, &mapi_hdl3, buf);
714 mapi_cache_freeup(mapi_hdl3, 100);
715 mapi_close_handle(mapi_hdl3);
716 ret = ret_ok;
718 mapi_close_handle(mapi_hdl2);
720 mapi_close_handle(mapi_hdl1);
723 return ret;
726 ret_t
727 run_sql4(cherokee_handler_server_info_t *hdl, cherokee_buffer_t *sql1, cherokee_buffer_t *sql2, cherokee_buffer_t *sql3, cherokee_buffer_t *sql4, cherokee_buffer_t *buf, void (*callback)()) {
728 ret_t ret = ret_error;
729 MapiHdl mapi_hdl1 = NULL;
730 MapiHdl mapi_hdl2 = NULL;
731 MapiHdl mapi_hdl3 = NULL;
732 MapiHdl mapi_hdl4 = NULL;
734 if ((mapi_hdl1 = mapi_query(hdl->dbh, sql1->buf)) != NULL && mapi_error(hdl->dbh) == MOK) {
735 if ((mapi_hdl2 = mapi_query(hdl->dbh, sql2->buf)) != NULL && mapi_error(hdl->dbh) == MOK) {
736 if ((mapi_hdl3 = mapi_query(hdl->dbh, sql3->buf)) != NULL && mapi_error(hdl->dbh) == MOK) {
737 if ((mapi_hdl4 = mapi_query(hdl->dbh, sql4->buf)) != NULL && mapi_error(hdl->dbh) == MOK) {
738 callback(&mapi_hdl1, &mapi_hdl2, &mapi_hdl3, &mapi_hdl4, buf);
739 mapi_cache_freeup(mapi_hdl4, 100);
740 mapi_close_handle(mapi_hdl4);
741 ret = ret_ok;
743 mapi_close_handle(mapi_hdl3);
745 mapi_close_handle(mapi_hdl2);
747 mapi_close_handle(mapi_hdl1);
750 return ret;
754 ret_t
755 get_object_by_id(cherokee_handler_server_info_t *hdl, unsigned long int id, cherokee_buffer_t *buf, enum OSM_State state) {
756 ret_t ret = ret_error;
757 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
758 cherokee_buffer_t sql2 = CHEROKEE_BUF_INIT;
759 cherokee_buffer_t sql3 = CHEROKEE_BUF_INIT;
760 cherokee_buffer_t sql4 = CHEROKEE_BUF_INIT;
761 switch (state) {
762 case OSM_NODE_COMMAND:
763 cherokee_buffer_add_va (&sql1, SQL_NODE_BY_ID, id);
764 cherokee_buffer_add_va (&sql2, SQL_NODE_TAGS_BY_ID, id);
765 TRACE("sql", "%s\n", sql1.buf);
766 TRACE("sql", "%s\n", sql2.buf);
767 ret = run_sql2(hdl, &sql1, &sql2, buf, result_node_to_xml);
768 break;
769 case OSM_WAY_COMMAND:
770 cherokee_buffer_add_va (&sql1, SQL_WAY_BY_ID, id);
771 cherokee_buffer_add_va (&sql2, SQL_WAY_ND_BY_ID, id);
772 cherokee_buffer_add_va (&sql3, SQL_WAY_TAGS_BY_ID, id);
773 TRACE("sql", "%s\n", sql1.buf);
774 TRACE("sql", "%s\n", sql2.buf);
775 TRACE("sql", "%s\n", sql3.buf);
776 ret = run_sql3(hdl, &sql1, &sql2, &sql3, buf, result_way_to_xml);
777 break;
778 case OSM_RELATION_COMMAND:
779 cherokee_buffer_add_va (&sql1, SQL_RELATION_BY_ID, id);
780 cherokee_buffer_add_va (&sql2, SQL_RELATION_MEMBER_NODE_BY_ID, id);
781 cherokee_buffer_add_va (&sql3, SQL_RELATION_MEMBER_RELATION_BY_ID, id);
782 cherokee_buffer_add_va (&sql4, SQL_RELATION_TAGS_BY_ID, id);
783 TRACE("sql", "%s\n", sql1.buf);
784 TRACE("sql", "%s\n", sql2.buf);
785 TRACE("sql", "%s\n", sql3.buf);
786 TRACE("sql", "%s\n", sql4.buf);
787 ret = run_sql4(hdl, &sql1, &sql2, &sql3, &sql4, buf, result_relation_to_xml);
788 break;
790 cherokee_buffer_mrproper(&sql4);
791 cherokee_buffer_mrproper(&sql3);
792 cherokee_buffer_mrproper(&sql2);
793 cherokee_buffer_mrproper(&sql1);
794 return ret;
797 static void parse_map(cherokee_handler_server_info_t *hdl, cherokee_buffer_t *buf) {
798 double left, bottom, right, top;
799 cherokee_avl_t *arguments = HANDLER_CONN(hdl)->arguments;
801 if (ret_ok == fetch_bbox(arguments, &left, &bottom, &right, &top)) {
802 TRACE ("osmapi", "%s BBOX: %f %f %f %f\n", __func__, left, bottom, right, top);
803 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
804 cherokee_buffer_t sql2 = CHEROKEE_BUF_INIT;
805 cherokee_buffer_t sql3 = CHEROKEE_BUF_INIT;
806 cherokee_buffer_t sql4 = CHEROKEE_BUF_INIT;
808 cherokee_buffer_add_va (&sql1, SQL_NODE_BY_BBOX, BBOX_VA_ARGS);
809 cherokee_buffer_add_va (&sql2, SQL_NODE_TAGS_BY_BBOX, BBOX_VA_ARGS);
810 TRACE("sql", "%s\n", sql1.buf);
811 TRACE("sql", "%s\n", sql2.buf);
812 run_sql2(hdl, &sql1, &sql2, buf, result_node_to_xml);
813 cherokee_buffer_mrproper(&sql1);
814 cherokee_buffer_mrproper(&sql2);
817 cherokee_buffer_add_va (&sql1, SQL_WAY_BY_BBOX, BBOX_VA_ARGS);
818 cherokee_buffer_add_va (&sql2, SQL_ND_BY_BBOX, BBOX_VA_ARGS);
819 cherokee_buffer_add_va (&sql3, SQL_WAY_TAGS_BY_BBOX, BBOX_VA_ARGS);
820 TRACE("sql", "%s\n", sql1.buf);
821 TRACE("sql", "%s\n", sql2.buf);
822 TRACE("sql", "%s\n", sql3.buf);
823 run_sql3(hdl, &sql1, &sql2, &sql3, buf, result_way_to_xml);
824 cherokee_buffer_mrproper(&sql3);
825 cherokee_buffer_mrproper(&sql2);
826 cherokee_buffer_mrproper(&sql1);
829 cherokee_buffer_add_va (&sql1, SQL_RELATION_BY_BBOX, BBOX_VA_ARGS);
830 cherokee_buffer_add_va (&sql2, SQL_RELATION_MEMBER_NODE_BY_BBOX, BBOX_VA_ARGS);
831 cherokee_buffer_add_va (&sql3, SQL_RELATION_MEMBER_RELATION_BY_BBOX, BBOX_VA_ARGS);
832 cherokee_buffer_add_va (&sql4, SQL_RELATION_TAGS_BY_BBOX, BBOX_VA_ARGS);
833 TRACE("sql", "%s\n", sql1.buf);
834 TRACE("sql", "%s\n", sql2.buf);
835 TRACE("sql", "%s\n", sql3.buf);
836 TRACE("sql", "%s\n", sql4.buf);
837 run_sql4(hdl, &sql1, &sql2, &sql3, &sql4, buf, result_relation_to_xml);
838 cherokee_buffer_mrproper(&sql4);
839 cherokee_buffer_mrproper(&sql3);
840 cherokee_buffer_mrproper(&sql2);
841 cherokee_buffer_mrproper(&sql1);*/
846 ret_t
847 server_info_build_page (cherokee_handler_server_info_t *hdl)
849 ret_t ret = ret_ok;
850 cherokee_server_t *srv;
851 cherokee_connection_t *conn;
852 cherokee_buffer_t *buf;
853 cherokee_buffer_t content = CHEROKEE_BUF_INIT;
855 /* Init
857 buf = &hdl->buffer;
858 srv = HANDLER_SRV(hdl);
859 conn = HANDLER_CONN(hdl);
861 /* Parse the Request */
863 if (strlen(conn->request.buf) > 1) {
864 enum OSM_State state = OSM_FIND_FIRST;
865 unsigned long int id = 0;
866 char *string = conn->request.buf;
867 char *token;
868 void *param;
869 while (state != OSM_DONE && (token = (char *) strsep( &string , "/")) != NULL) {
870 if (*token == '\0')
871 continue;
873 switch (state) {
874 case OSM_FIND_FIRST:
875 switch (token[0]) {
876 case 'c':
877 /* GET /api/0.5/changes?hours=1&zoom=16&start=none&end=none */
878 parse_changes(conn->arguments, &content);
879 state = OSM_DONE;
880 break;
881 case 'n':
882 if (strlen(token) == 5 && token[4] == 's')
883 state = OSM_NODES_PRE_PARSE;
884 else
885 state = OSM_NODE_ID;
886 break;
887 case 'w':
888 if (strlen(token) == 4 && token[3] == 's')
889 state = OSM_WAYS_PRE_PARSE;
890 else
891 state = OSM_WAY_ID;
892 break;
893 case 'r':
894 if (strlen(token) == 9 && token[8] == 's')
895 state = OSM_RELATIONS_PRE_PARSE;
896 else
897 state = OSM_RELATION_ID;
898 break;
899 case 'g':
900 state = OSM_GPX_ID;
901 break;
902 case 'u':
903 user_preferences(&content);
904 break;
905 case 'm':
906 /* GET /api/0.5/map?bbox=LEFT,BOTTOM,RIGHT,TOP */
907 parse_map(hdl, &content);
908 break;
909 case 't':
910 /* GET /api/0.5/trackpoints?bbox=LEFT,BOTTOM,RIGHT,TOP&page=PAGENUMBER */
911 parse_trackpoints(conn->arguments, &content);
912 break;
913 case 's':
914 break;
916 break;
917 case OSM_GPX_ID:
918 case OSM_NODE_ID:
919 case OSM_WAY_ID:
920 case OSM_RELATION_ID:
921 id = strtoul(token, (char **) NULL, 10);
922 if (errno != ERANGE) {
923 state++;
924 ret = get_object_by_id(hdl, id, &content, state);
925 } else
926 state = OSM_DONE;
927 break;
928 case OSM_GPX_COMMAND:
929 if (strlen(token) > 1) {
930 switch (token[1]) {
931 case 'a':
932 /* GET /api/0.5/gpx/<id>/data */
933 gpx_data(&content, id);
934 break;
935 case 'e':
936 /* GET /api/0.5/gpx/<id>/details */
937 gpx_details(&content, id);
938 break;
941 break;
943 /* GET /api/0.5/<objtype>/<id>/full
944 * GET /api/0.5/<objtype>/<id>/history
945 * GET /api/0.5/<objtype>/<id>/relations */
947 case OSM_NODE_COMMAND:
948 switch (token[0]) {
949 case 'w':
950 /* GET /api/0.5/node/<id>/ways */
951 node_ways(&content, id);
952 break;
954 case OSM_WAY_COMMAND:
955 case OSM_RELATION_COMMAND:
956 switch (token[0]) {
957 case 'f':
958 objtype_full(&content, id, state);
959 break;
960 case 'h':
961 objtype_history(&content, id, state);
962 break;
963 case 'r':
964 objtype_relations(&content, id, state);
965 break;
967 break;
968 case OSM_NODES_PRE_PARSE:
969 switch (token[0]) {
970 case '?':
971 /* GET /api/0.5/<objtype>s?<objtype>s=<id>[,<id>...] */
972 parse_nodes(conn->arguments, &content);
973 break;
974 case 's':
975 /* GET /api/0.5/nodes/search?type=<type>&value=<value> */
976 parse_nodes_search(conn->arguments, &content);
977 break;
979 break;
981 case OSM_RELATIONS_PRE_PARSE:
982 switch (token[0]) {
983 case '?':
984 /* GET /api/0.5/<objtype>s?<objtype>s=<id>[,<id>...] */
985 parse_relations(conn->arguments, &content);
986 break;
987 case 's':
988 /* GET /api/0.5/relations/search?type=<type>&value=<value> */
989 parse_relations_search(conn->arguments, &content);
990 break;
992 break;
994 case OSM_WAYS_PRE_PARSE:
995 switch (token[0]) {
996 case '?':
997 /* GET /api/0.5/<objtype>s?<objtype>s=<id>[,<id>...] */
998 parse_ways(conn->arguments, &content);
999 break;
1000 case 's':
1001 /* GET /api/0.5/ways/search?type=<type>&value=<value> */
1002 parse_ways_search(conn->arguments, &content);
1003 break;
1005 break;
1012 /* Add the page ending
1014 // cherokee_buffer_mrproper (&table);
1015 // cherokee_buffer_add_str (buf, PAGE_FOOT);
1016 //cherokee_buffer_add(&content, conn->request.buf+1, conn->request.len-1);
1018 cherokee_buffer_add_str (buf, XMLHEADER);
1019 cherokee_buffer_add_str (buf, XML(OSM, ""));
1020 if (content.len > 0) {
1021 cherokee_buffer_add_str (buf, XMLCONTINUE);
1022 cherokee_buffer_add_buffer (buf, &content);
1023 cherokee_buffer_mrproper (&content);
1024 cherokee_buffer_add_str (buf, XMLCLOSE(OSM, ""));
1025 } else
1026 cherokee_buffer_add_str (buf, XMLCLOSESHORT);
1031 ret_t
1032 cherokee_handler_server_info_new (cherokee_handler_t **hdl, cherokee_connection_t *cnt, cherokee_module_props_t *props)
1034 ret_t ret;
1035 CHEROKEE_NEW_STRUCT (n, handler_server_info);
1037 /* Init the base class object
1039 cherokee_handler_init_base(HANDLER(n), cnt, HANDLER_PROPS(props), PLUGIN_INFO_HANDLER_PTR(server_info));
1041 MODULE(n)->init = (handler_func_init_t) cherokee_handler_server_info_init;
1042 MODULE(n)->free = (module_func_free_t) cherokee_handler_server_info_free;
1043 HANDLER(n)->step = (handler_func_step_t) cherokee_handler_server_info_step;
1044 HANDLER(n)->add_headers = (handler_func_add_headers_t) cherokee_handler_server_info_add_headers;
1046 HANDLER(n)->support = hsupport_length;
1049 /* Init
1051 ret = cherokee_buffer_init (&n->buffer);
1052 if (unlikely(ret != ret_ok))
1053 return ret;
1055 ret = cherokee_buffer_ensure_size (&n->buffer, 4*1024);
1056 if (unlikely(ret != ret_ok))
1057 return ret;
1059 n->dbh = mapi_connect("localhost", 50000, "monetdb", "monetdb", "sql", NULL);
1061 if (mapi_error(n->dbh)) {
1062 n->dbh = NULL;
1063 return ret_error;
1066 if (! axl_init ())
1067 return ret_error;
1069 *hdl = HANDLER(n);
1070 return ret_ok;
1074 ret_t
1075 cherokee_handler_server_info_free (cherokee_handler_server_info_t *hdl)
1077 cherokee_buffer_mrproper (&hdl->buffer);
1078 if (hdl->dbh != NULL)
1079 mapi_destroy(hdl->dbh);
1081 axl_end();
1083 return ret_ok;
1086 ret_t
1087 cherokee_handler_server_info_init_put (cherokee_handler_server_info_t *hdl)
1089 off_t postl;
1090 ret_t ret = ret_ok;
1091 cherokee_buffer_t post = CHEROKEE_BUF_INIT;
1092 cherokee_buffer_t *buf;
1093 cherokee_connection_t *conn = HANDLER_CONN(hdl);
1094 axlDoc * doc;
1095 axlError * error;
1097 /* Check for the post info
1099 cherokee_post_get_len (&conn->post, &postl);
1100 if (postl <= 0 || postl >= (INT_MAX-1)) {
1101 conn->error_code = http_bad_request;
1102 return ret_error;
1105 buf = &hdl->buffer;
1107 /* Process line per line
1109 cherokee_post_walk_read (&conn->post, &post, (cuint_t) postl);
1111 doc = axl_doc_parse (post.buf, post.len, &error);
1113 if (doc == NULL) {
1114 printf ("Error found: %s\n", axl_error_get (error));
1115 axl_error_free (error);
1116 return ret_error;
1117 } else {
1118 axlNode * node = axl_doc_get_root (doc);
1119 node = axl_node_get_first_child (node);
1121 if (axl_node_has_attribute(node, "id")) {
1122 /* UPDATE */
1123 if (NODE_CMP_NAME (node, "node")) {
1124 if (axl_node_has_attribute(node, "lat") &&
1125 axl_node_has_attribute(node, "lon")) {
1127 printf("lat: %s lon: %s\n",
1128 axl_node_get_attribute_value(node, "lat"),
1129 axl_node_get_attribute_value(node, "lon"));
1131 } else if (NODE_CMP_NAME (node, "way")) {
1133 } else if (NODE_CMP_NAME (node, "relation")) {
1136 } else {
1137 /* CREATE */
1138 if (NODE_CMP_NAME (node, "node")) {
1139 if (axl_node_has_attribute(node, "lat") &&
1140 axl_node_has_attribute(node, "lon")) {
1141 double lat = strtod(axl_node_get_attribute_value(node, "lat"), NULL);
1143 if (errno != ERANGE) {
1144 /* TODO: more error checking */
1145 axlNode * tag;
1147 double lon = strtod(axl_node_get_attribute_value(node, "lon"), NULL);
1148 unsigned long int nodeid = 0;
1149 cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT;
1151 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_START);
1152 run_sql(hdl, &sql1, buf, NULL);
1153 cherokee_buffer_mrproper(&sql1);
1155 cherokee_buffer_add_va (&sql1, SQL_NODE_CREATE, lat, lon, 0);
1156 run_sql(hdl, &sql1, buf, NULL);
1157 cherokee_buffer_mrproper(&sql1);
1159 nodeid = strtoul(buf->buf, (char **) NULL, 10);
1160 if (errno != ERANGE) {
1161 cherokee_buffer_add_str (&sql1, SQL_NODE_CREATE_GET_ID);
1162 run_sql(hdl, &sql1, buf, result_node_last_id);
1163 cherokee_buffer_mrproper(&sql1);
1165 if ((tag = axl_node_get_first_child(node)) != NULL) {
1166 do {
1167 if (axl_node_has_attribute(tag, "k") &&
1168 axl_node_has_attribute(tag, "v")) {
1169 const char * key = axl_node_get_attribute_value(node, "k");
1170 size_t keylen = strlen(key);
1172 if (keylen > 0 && keylen < 256) {
1173 const char * value = axl_node_get_attribute_value(node, "v");
1174 size_t valuelen = strlen(value);
1176 if (valuelen > 0 && valuelen < 256) {
1177 cherokee_buffer_add_va (&sql1, SQL_NODE_CREATE_NODE_TAG,
1178 nodeid,
1179 key,
1180 value);
1181 run_sql(hdl, &sql1, buf, NULL);
1182 cherokee_buffer_mrproper(&sql1);
1186 /* axl_node_free(tag); ? */
1187 } while ((tag = axl_node_get_next(node)) != NULL);
1190 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_COMMIT);
1191 run_sql(hdl, &sql1, buf, NULL);
1192 cherokee_buffer_mrproper(&sql1);
1193 } else {
1194 cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_ROLLBACK);
1195 run_sql(hdl, &sql1, buf, NULL);
1196 cherokee_buffer_mrproper(&sql1);
1200 } else if (NODE_CMP_NAME (node, "way")) {
1202 } else if (NODE_CMP_NAME (node, "relation")) {
1206 axl_doc_free (doc);
1209 cherokee_buffer_mrproper (&post);
1210 return ret;
1215 ret_t
1216 cherokee_handler_server_info_init (cherokee_handler_server_info_t *hdl)
1218 cherokee_connection_t *conn = HANDLER_CONN(hdl);
1220 printf("\nuser: %s\n", conn->realm_ref);
1223 if (hdl->dbh == NULL) {
1224 conn->error_code = http_service_unavailable;
1225 return ret_error;
1228 switch (conn->header.method) {
1229 case http_get:
1230 cherokee_connection_parse_args (conn);
1231 if (server_info_build_page (hdl) == ret_error) {
1232 conn->error_code = http_internal_error;
1233 return ret_error;
1235 break;
1236 case http_put:
1237 return cherokee_handler_server_info_init_put(hdl);
1238 break;
1239 case http_post:
1240 conn->error_code = http_not_implemented;
1241 return ret_error;
1242 break;
1243 case http_delete:
1244 conn->error_code = http_not_implemented;
1245 return ret_error;
1246 break;
1247 default:
1248 printf("OTHER\n");
1249 conn->error_code = http_bad_request;
1250 return ret_error;
1253 return ret_ok;
1257 ret_t
1258 cherokee_handler_server_info_step (cherokee_handler_server_info_t *hdl, cherokee_buffer_t *buffer)
1260 if (cherokee_buffer_is_empty (&hdl->buffer))
1261 return ret_eof;
1263 cherokee_buffer_add (buffer, hdl->buffer.buf, 1024);
1264 cherokee_buffer_move_to_begin (&hdl->buffer, 1024);
1266 if (cherokee_buffer_is_empty (&hdl->buffer))
1267 return ret_eof_have_data;
1269 return ret_ok;
1271 /* if (hdl->buffer.len > 0) {
1272 cherokee_buffer_add_buffer (buffer, &hdl->buffer);
1273 cherokee_buffer_move_to_begin (&hdl->buffer, buffer->size);
1274 if (hdl->buffer.len == 0)
1275 return ret_eof_have_data;
1277 return ret_ok;
1278 } else
1279 return ret_eagain;*/
1283 ret_t
1284 cherokee_handler_server_info_add_headers (cherokee_handler_server_info_t *hdl, cherokee_buffer_t *buffer)
1286 cherokee_buffer_add_str (buffer, "Content-Type: text/xml; charset=utf-8"CRLF);
1287 // cherokee_buffer_add_str (buffer, "Content-Disposition: attachment; filename=\"map.osm\""CRLF);
1288 cherokee_buffer_add_va (buffer, "Content-Length: %d"CRLF, hdl->buffer.len);
1289 return ret_ok;