From 3183aea1d006cd00d719915b42eeb68a6d6769f0 Mon Sep 17 00:00:00 2001 From: Stefan de Konink Date: Sun, 21 Dec 2008 05:39:26 +0100 Subject: [PATCH] This big chunk allows to import diffs directly as if it where a zillion local requests; yes you have to be God ;) --- handler_osm_delete.c | 4 +- handler_osm_delete.h | 1 + handler_osm_put.c | 179 +++++++++++++++++++++++++++++++++------------------ handler_osm_sql.h | 9 ++- 4 files changed, 126 insertions(+), 67 deletions(-) diff --git a/handler_osm_delete.c b/handler_osm_delete.c index e53db6e..1bcae0d 100644 --- a/handler_osm_delete.c +++ b/handler_osm_delete.c @@ -7,8 +7,6 @@ #include "handler_osm_delete.h" #include "handler_osm_sql.h" -static ret_t delete_object_by_id(cherokee_handler_osm_t *hdl, unsigned long int id, osm_state_delete_t state); - ret_t cherokee_handler_osm_init_delete (cherokee_handler_osm_t *hdl) { ret_t ret = ret_error; @@ -56,7 +54,7 @@ cherokee_handler_osm_init_delete (cherokee_handler_osm_t *hdl) { return ret; } -static ret_t +ret_t delete_object_by_id(cherokee_handler_osm_t *hdl, unsigned long int id, osm_state_delete_t state) { ret_t ret; cherokee_buffer_t sql = CHEROKEE_BUF_INIT; diff --git a/handler_osm_delete.h b/handler_osm_delete.h index 41be343..ffdf41c 100644 --- a/handler_osm_delete.h +++ b/handler_osm_delete.h @@ -12,3 +12,4 @@ typedef enum { OSM_DELETE_FIRST = 0, OSM_DELETE_DONE } osm_state_delete_t; ret_t cherokee_handler_osm_init_delete (cherokee_handler_osm_t *hdl); +ret_t delete_object_by_id(cherokee_handler_osm_t *hdl, unsigned long int id, osm_state_delete_t state); diff --git a/handler_osm_put.c b/handler_osm_put.c index 379b38b..18569dc 100644 --- a/handler_osm_put.c +++ b/handler_osm_put.c @@ -7,6 +7,7 @@ #include "handler_osm_db.h" #include "handler_osm_put.h" #include "handler_osm_sql.h" +#include "handler_osm_delete.h" static ret_t result_node_last_id(cherokee_handler_osm_t *hdl, MapiHdl *hdl1, cherokee_buffer_t *buf) { cherokee_buffer_add_va (buf, "%d", mapi_get_last_id(*hdl1)); @@ -205,10 +206,9 @@ static void do_tags(cherokee_handler_osm_t *hdl, axlNode *node, unsigned long in } static ret_t -create_node(cherokee_handler_osm_t *hdl, axlNode * node) { +create_node(cherokee_handler_osm_t *hdl, axlNode * node, unsigned long int userid) { cherokee_connection_t *conn = HANDLER_CONN(hdl); - cherokee_buffer_t *buf; - buf = &hdl->buffer; + cherokee_buffer_t *buf = &hdl->buffer; if (NODE_CMP_NAME (node, "node")) { if (axl_node_has_attribute(node, "lat") && @@ -229,7 +229,7 @@ create_node(cherokee_handler_osm_t *hdl, axlNode * node) { long testid = 0; cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT; - cherokee_buffer_add_va (&sql1, SQL_NODE_CREATE, lon, lat, 0); + cherokee_buffer_add_va (&sql1, SQL_NODE_CREATE, lon, lat, userid); run_sql(hdl, &sql1, buf, result_node_last_id); cherokee_buffer_mrproper(&sql1); @@ -244,7 +244,7 @@ create_node(cherokee_handler_osm_t *hdl, axlNode * node) { } } else if (NODE_CMP_NAME (node, "way")) { cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT; - cherokee_buffer_add_va (&sql1, SQL_WAY_CREATE, 0); + cherokee_buffer_add_va (&sql1, SQL_WAY_CREATE, userid); run_sql(hdl, &sql1, buf, result_node_last_id); cherokee_buffer_mrproper(&sql1); @@ -260,7 +260,7 @@ create_node(cherokee_handler_osm_t *hdl, axlNode * node) { } } else if (NODE_CMP_NAME (node, "relation")) { cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT; - cherokee_buffer_add_va (&sql1, SQL_RELATION_CREATE, 0); + cherokee_buffer_add_va (&sql1, SQL_RELATION_CREATE, userid); run_sql(hdl, &sql1, buf, result_node_last_id); cherokee_buffer_mrproper(&sql1); @@ -280,57 +280,86 @@ create_node(cherokee_handler_osm_t *hdl, axlNode * node) { } static ret_t -update_node(cherokee_handler_osm_t *hdl, axlNode * node, unsigned long int nodeid) { +update_node(cherokee_handler_osm_t *hdl, axlNode * node, unsigned long int nodeid, unsigned long int userid, short int timestamp) { cherokee_connection_t *conn = HANDLER_CONN(hdl); - cherokee_buffer_t *buf; - buf = &hdl->buffer; - if (NODE_CMP_NAME (node, "node")) { - if (axl_node_has_attribute(node, "lat") && - axl_node_has_attribute(node, "lon")) { - double lat, lon; - lat = strtod(axl_node_get_attribute_value(node, "lat"), NULL); - if (errno == ERANGE) { - conn->error_code = http_bad_request; - return ret_error; - } + if (axl_node_has_attribute_value(node, "visible", "false")) { + /* the user wants to delete stuff by updating, that is nice + * but we will not update. Instead we do what the user request: + * deletion. + */ + if (NODE_CMP_NAME (node, "node")) { + return delete_object_by_id(hdl, nodeid, OSM_DELETE_NODE_COMMAND); + } else if (NODE_CMP_NAME (node, "way")) { + return delete_object_by_id(hdl, nodeid, OSM_DELETE_WAY_COMMAND); + } else if (NODE_CMP_NAME (node, "relation")) { + return delete_object_by_id(hdl, nodeid, OSM_DELETE_RELATION_COMMAND); + } + } else { + if (NODE_CMP_NAME (node, "node")) { + if (axl_node_has_attribute(node, "lat") && + axl_node_has_attribute(node, "lon")) { + double lat, lon; + lat = strtod(axl_node_get_attribute_value(node, "lat"), NULL); + if (errno == ERANGE) { + conn->error_code = http_bad_request; + return ret_error; + } - lon = strtod(axl_node_get_attribute_value(node, "lon"), NULL); - if (errno == ERANGE) { - conn->error_code = http_bad_request; - return ret_error; - } else { - cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT; - cherokee_buffer_add_va (&sql1, SQL_NODE_UPDATE_BY_ID, lon, lat, 0, nodeid); - run_sql(hdl, &sql1, NULL, NULL); - cherokee_buffer_mrproper(&sql1); + lon = strtod(axl_node_get_attribute_value(node, "lon"), NULL); + if (errno == ERANGE) { + conn->error_code = http_bad_request; + return ret_error; + } else { + cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT; + if (timestamp == 1 && axl_node_has_attribute(node, "timestamp")) { + cherokee_buffer_add_va (&sql1, SQL_NODE_UPDATE_BY_ID, lon, lat, userid, + "'", axl_node_get_attribute_value(node, "timestamp"), "'", nodeid); + } else { + cherokee_buffer_add_va (&sql1, SQL_NODE_UPDATE_BY_ID, lon, lat, userid, SQL_NOW, nodeid); + } + run_sql(hdl, &sql1, NULL, NULL); + cherokee_buffer_mrproper(&sql1); - do_tags(hdl, node, nodeid, 1, SQL_NODE_CREATE_NODE_TAG, SQL_NODE_UPDATE_NODE_TAG, SQL_NODE_DELETE_NODE_TAG); + do_tags(hdl, node, nodeid, 1, SQL_NODE_CREATE_NODE_TAG, SQL_NODE_UPDATE_NODE_TAG, SQL_NODE_DELETE_NODE_TAG); - return ret_ok; + return ret_ok; + } } - } - } else if (NODE_CMP_NAME (node, "way")) { - cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT; - cherokee_buffer_add_va (&sql1, SQL_RELATION_UPDATE, 0, nodeid); - run_sql(hdl, &sql1, NULL, NULL); - cherokee_buffer_mrproper(&sql1); + } else if (NODE_CMP_NAME (node, "way")) { + cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT; + if (timestamp == 1 && axl_node_has_attribute(node, "timestamp")) { + cherokee_buffer_add_va (&sql1, SQL_WAY_UPDATE, userid, + "'", axl_node_get_attribute_value(node, "timestamp"), "'", nodeid); + } else { + cherokee_buffer_add_va (&sql1, SQL_WAY_UPDATE, userid, SQL_NOW, nodeid); + } + run_sql(hdl, &sql1, NULL, NULL); + cherokee_buffer_mrproper(&sql1); - do_tags(hdl, node, nodeid, 1, SQL_WAY_CREATE_NODE_TAG, SQL_WAY_UPDATE_NODE_TAG, SQL_WAY_DELETE_NODE_TAG); - do_nds(hdl, node, nodeid, 1); /* this sequence otherwise we screw up type = */ + do_tags(hdl, node, nodeid, 1, SQL_WAY_CREATE_NODE_TAG, SQL_WAY_UPDATE_NODE_TAG, SQL_WAY_DELETE_NODE_TAG); + do_nds(hdl, node, nodeid, 1); /* this sequence otherwise we screw up type = */ - return ret_ok; - } else if (NODE_CMP_NAME (node, "relation")) { - cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT; - cherokee_buffer_add_va (&sql1, SQL_RELATION_UPDATE, 0, nodeid); - run_sql(hdl, &sql1, NULL, NULL); - cherokee_buffer_mrproper(&sql1); + return ret_ok; + } else if (NODE_CMP_NAME (node, "relation")) { + cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT; + if (timestamp == 1 && axl_node_has_attribute(node, "timestamp")) { + cherokee_buffer_add_va (&sql1, SQL_RELATION_UPDATE, userid, + "'", axl_node_get_attribute_value(node, "timestamp"), "'", nodeid); + } else { + cherokee_buffer_add_va (&sql1, SQL_RELATION_UPDATE, userid, SQL_NOW, nodeid); + } + run_sql(hdl, &sql1, NULL, NULL); + cherokee_buffer_mrproper(&sql1); - do_members(hdl, node, nodeid, 1); - do_tags(hdl, node, nodeid, 1, SQL_RELATION_CREATE_NODE_TAG, SQL_RELATION_UPDATE_NODE_TAG, SQL_RELATION_DELETE_NODE_TAG); + do_members(hdl, node, nodeid, 1); + do_tags(hdl, node, nodeid, 1, SQL_RELATION_CREATE_NODE_TAG, SQL_RELATION_UPDATE_NODE_TAG, SQL_RELATION_DELETE_NODE_TAG); + + return ret_ok; + } - return ret_ok; } + SHOULDNT_HAPPEN; return ret_error; } @@ -369,35 +398,63 @@ cherokee_handler_osm_init_put (cherokee_handler_osm_t *hdl) axl_error_free (error); ret = ret_error; } else { + unsigned long int userid = 0; + unsigned long int activeuserid = 0; axlNode * node = axl_doc_get_root (doc); node = axl_node_get_first_child (node); - unsigned long int nodeid = 0; - - if (axl_node_has_attribute(node, "id")) { - const char *id = axl_node_get_attribute_value(node, "id"); - nodeid = strtoul(id, (char **) NULL, 10); - TRACE("osm", "%lu\n", nodeid); - } - + ret = ret_ok; + /* het mooiste zou zijn om het onderstaande in twee functies te zetten * update vs create. * Als dat gebeurd is kan hier (of in de 'update' code gechecked worden * op 'root' of op normale user en aan de hand daarvan weer switchen op * empty == create of full == update) */ - cherokee_buffer_t sql1 = CHEROKEE_BUF_INIT; + cherokee_buffer_t tmp = CHEROKEE_BUF_INIT; cherokee_buffer_add_str (&sql1, SQL_TRANSACTION_START); run_sql(hdl, &sql1, &hdl->buffer, NULL); cherokee_buffer_mrproper(&sql1); + cherokee_buffer_add_va (&sql1, SQL_USERID_BY_NAME, conn->realm_ref->buf); + run_sql(hdl, &sql1, &tmp, NULL); + if (tmp.len > 0) + userid = strtoul(tmp.buf, (char **) NULL, 10); - if (nodeid != 0) { - /* UPDATE */ - ret = update_node(hdl, node, nodeid); - } else { - /* CREATE */ - ret = create_node(hdl, node); + cherokee_buffer_mrproper(&sql1); + cherokee_buffer_mrproper(&tmp); + + activeuserid = userid; + + while (node != NULL && ret == ret_ok) { + unsigned long int nodeid = 0; + + if (axl_node_has_attribute(node, "id")) { + const char *id = axl_node_get_attribute_value(node, "id"); + nodeid = strtoul(id, (char **) NULL, 10); + TRACE("osm", "%lu\n", nodeid); + } + + if (userid == 0) { + const char *username = axl_node_get_attribute_value(node, "user"); + if (username != NULL) { + cherokee_buffer_add_va (&sql1, SQL_USERID_BY_NAME, username); + run_sql(hdl, &sql1, &tmp, NULL); + if (tmp.len > 0) + activeuserid = strtoul(tmp.buf, (char **) NULL, 10); + cherokee_buffer_mrproper(&tmp); + } + } + + if (nodeid > 0) { + /* UPDATE */ + ret = update_node(hdl, node, nodeid, activeuserid, (userid == 0)); + } else { + /* CREATE */ + ret = create_node(hdl, node, activeuserid); + } + + node = axl_node_get_next(node); } if (ret != ret_ok) { diff --git a/handler_osm_sql.h b/handler_osm_sql.h index 9f5fc2f..f515d25 100644 --- a/handler_osm_sql.h +++ b/handler_osm_sql.h @@ -54,6 +54,7 @@ #define UINT_BITMAX "11930464.71111111" +#define SQL_NOW "", "now", "" #ifdef LEGACY_SQL #define BBOX_VA_ARGS top, bottom, left, right @@ -75,19 +76,19 @@ // #define SQL_NODE_CREATE "INSERT INTO " SQL_NODES " (long, lat, username, timestamp) VALUES (%f, %f, %d, %s)" #define SQL_NODE_CREATE "INSERT INTO " SQL_NODES " (long, lat, username) VALUES (%f, %f, %d)" #define SQL_NODE_CREATE_NODE_TAG "INSERT INTO node_tags (node, k, v) VALUES (%d, '%s', '%s')" - #define SQL_NODE_UPDATE_BY_ID "UPDATE " SQL_NODES " SET long = %f, lat = %f, username = %d WHERE id = %d" + #define SQL_NODE_UPDATE_BY_ID "UPDATE " SQL_NODES " SET long = %f, lat = %f, username = %d, timestamp = %s%s%s WHERE id = %d" #define SQL_NODE_UPDATE_NODE_TAG "UPDATE node_tags SET v = '%s' WHERE node = %d AND k = '%s'" #define SQL_NODE_DELETE_NODE_TAG "DELETE FROM node_tags WHERE node = %lu AND k NOT IN (%s)" #define SQL_RELATION_CREATE "INSERT INTO relations (username) VALUES (%lu)" - #define SQL_RELATION_UPDATE "UPDATE relations SET username = %d WHERE id = %lu" + #define SQL_RELATION_UPDATE "UPDATE relations SET username = %d, timestamp = %s%s%s WHERE id = %lu" #define SQL_RELATION_CREATE_NODE_TAG "INSERT INTO relation_tags (relation, k, v) VALUES (%d, '%s', '%s')" #define SQL_RELATION_UPDATE_NODE_TAG "UPDATE relation_tags SET v = '%s' WHERE relation = %d AND k = '%s'" #define SQL_RELATION_DELETE_NODE_TAG "DELETE FROM relation_tags WHERE relation = %d AND k NOT IN (%s)" #define SQL_WAY_CREATE "INSERT INTO ways (username) VALUES (%lu)" - #define SQL_WAY_UPDATE "UPDATE ways SET username = %d WHERE id = %lu" + #define SQL_WAY_UPDATE "UPDATE ways SET username = %d, timestamp = %s%s%s WHERE id = %lu" #define SQL_WAY_CREATE_NODE_TAG "INSERT INTO way_tags (walat, k, v) VALUES (%d, '%s', '%s')" #define SQL_WAY_UPDATE_NODE_TAG "UPDATE way_tags SET v = '%s' WHERE walat = %d AND k = '%s'" #define SQL_WAY_DELETE_NODE_TAG "DELETE FROM way_tags WHERE walat = %d AND k NOT IN (%s)" @@ -220,3 +221,5 @@ #define SQL_WAY_TAGS_BY_ID SQL_RELATION_TAGS_BY_ID #define SQL_WAY_TAGS_BY_BBOX SQL_RELATION_TAGS_BY_BBOX1 SQL_ORDER_BY_RELATION // #define SQL_WAY_TAGS_BY_BBOX SQL_RELATION_TAGS_BY_BBOX1 " AND k<>'type' AND v<>'way' " SQL_ORDER_BY_RELATION + + #define SQL_USERID_BY_NAME "SELECT '0';" -- 2.11.4.GIT