From 6ebb7045fe53d831502f054cf5007843e023d094 Mon Sep 17 00:00:00 2001 From: Gabriel Ebner Date: Sun, 4 May 2008 15:16:58 +0000 Subject: [PATCH] api06: Fix diff uploading (still doesn't give a useful response): Modification and deletion works fine now. Rollback also works apparently. Just auto increment doesn't get reset. --- app/controllers/changeset_controller.rb | 33 +++++++----------- app/controllers/node_controller.rb | 45 ++++--------------------- app/controllers/relation_controller.rb | 44 +++++------------------- app/controllers/way_controller.rb | 25 +++----------- app/models/node.rb | 25 ++++++++++++++ app/models/relation.rb | 28 +++++++++++++++ app/models/way.rb | 14 ++++++++ 7 files changed, 98 insertions(+), 116 deletions(-) diff --git a/app/controllers/changeset_controller.rb b/app/controllers/changeset_controller.rb index 34579d166..585821a55 100644 --- a/app/controllers/changeset_controller.rb +++ b/app/controllers/changeset_controller.rb @@ -78,34 +78,27 @@ class ChangesetController < ApplicationController create_prim rel_ids, relation, nd end - doc.find('//osm/modify/node').each do |nd| - unless NodeController.new.update_internal nil, Node.from_xml_node(nd) - raise OSM::APIPreconditionFailedError.new - end + doc.find('//osm/modify/relation').each do |nd| + new_relation = Relation.from_xml_node(nd) + Relation.find(new_relation.id).update_from new_relation, @user end doc.find('//osm/modify/way').each do |nd| - unless WayController.update_internal nil, fix_way(Way.from_xml_node(nd), node_ids) - raise OSM::APIPreconditionFailedError.new - end + new_way = Way.from_xml_node(nd) + Way.find(new_way.id).update_from new_way, @user end - doc.find('//osm/modify/relation').each do |nd| - unless RelationController.update_internal nil, fix_rel(Relation.from_xml_node(nd), ids) - raise OSM::APIPreconditionFailedError.new - end + doc.find('//osm/modify/node').each do |nd| + new_node = Node.from_xml_node(nd) + Node.find(new_node.id).update_from new_node, @user end - doc.find('//osm/delete/node').each do |nd| - unless NodeController.delete_internal nil, Node.from_xml_node(n) - raise OSM::APIPreconditionFailedError.new - end + doc.find('//osm/delete/relation').each do |nd| + Relation.find(nd['id']).delete_with_history(@user) end doc.find('//osm/delete/way').each do |nd| - Way.from_xml_node(nd).delete_with_relations_and_history(@user) + Way.find(nd['id']).delete_with_relations_and_history(@user) end - doc.find('//osm/delete/relation').each do |nd| - unless RelationController.delete_internal nil, fix_rel(Relation.from_xml_node(nd), ids) - raise OSM::APIPreconditionFailedError.new - end + doc.find('//osm/delete/node').each do |nd| + Node.find(nd['id']).delete_with_history(@user) end end diff --git a/app/controllers/node_controller.rb b/app/controllers/node_controller.rb index ae5245016..f6a673fe5 100644 --- a/app/controllers/node_controller.rb +++ b/app/controllers/node_controller.rb @@ -51,7 +51,7 @@ class NodeController < ApplicationController new_node = Node.from_xml(request.raw_post) if new_node and new_node.id == node.id - update_internal node, new_node + node.update_from(new_node, @user) render :nothing => true else render :nothing => true, :status => :bad_request @@ -61,51 +61,18 @@ class NodeController < ApplicationController end end - def update_internal(node, new_node) - node = Node.find(new_node.id) if node.nil? - - node.user_id = @user.id - node.latitude = new_node.latitude - node.longitude = new_node.longitude - node.tags = new_node.tags - node.visible = true - node.save_with_history! - - return true - end - # Delete a node. Doesn't actually delete it, but retains its history in a wiki-like way. # FIXME remove all the fricking SQL def delete begin node = Node.find(params[:id]) - - res = delete_internal(node) - unless res - render :text => "", :status => :precondition_failed - else - render :text => "", :status => res - end + node.delete_with_history(@user) rescue ActiveRecord::RecordNotFound render :nothing => true, :status => :not_found - end - end - - def delete_internal(node) - if node.visible - if WayNode.find(:first, :joins => "INNER JOIN current_ways ON current_ways.id = current_way_nodes.id", :conditions => [ "current_ways.visible = 1 AND current_way_nodes.node_id = ?", node.id ]) - return false - elsif RelationMember.find(:first, :joins => "INNER JOIN current_relations ON current_relations.id=current_relation_members.id", :conditions => [ "visible = 1 AND member_type='node' and member_id=?", params[:id]]) - return false - else - node.user_id = @user.id - node.visible = 0 - node.save_with_history! - - return :ok - end - else - return :gone + rescue OSM::APIAlreadyDeletedError + render :text => "", :status => :gone + rescue OSM::APIPreconditionFailedError + render :text => "", :status => :precondition_failed end end diff --git a/app/controllers/relation_controller.rb b/app/controllers/relation_controller.rb index 894ab40e8..caacd4fb9 100644 --- a/app/controllers/relation_controller.rb +++ b/app/controllers/relation_controller.rb @@ -51,22 +51,14 @@ class RelationController < ApplicationController new_relation = Relation.from_xml(request.raw_post) if new_relation and new_relation.id == relation.id - if !new_relation.preconditions_ok? - render :text => "", :status => :precondition_failed - else - relation.user_id = @user.id - relation.tags = new_relation.tags - relation.members = new_relation.members - relation.visible = true - relation.save_with_history! - - render :nothing => true - end + relation.update_from new_relation, user else render :nothing => true, :status => :bad_request end rescue ActiveRecord::RecordNotFound render :nothing => true, :status => :not_found + rescue OSM::APIPreconditionFailedError + render :text => "", :status => :precondition_failed rescue render :nothing => true, :status => :internal_server_error end @@ -76,13 +68,11 @@ class RelationController < ApplicationController #XXX check if member somewhere! begin relation = Relation.find(params[:id]) - - res = delete_internal(node) - unless res - render :text => "", :status => :precondition_failed - else - render :text => "", :status => res - end + relation.delete_with_history(@user) + rescue OSM::APIAlreadyDeletedError + render :text => "", :status => :gone + rescue OSM::APIPreconditionFailedError + render :text => "", :status => :precondition_failed rescue ActiveRecord::RecordNotFound render :nothing => true, :status => :not_found rescue @@ -90,24 +80,6 @@ class RelationController < ApplicationController end end - def delete_internal(relation) - if relation.visible - if RelationMember.find(:first, :joins => "INNER JOIN current_relations ON current_relations.id=current_relation_members.id", :conditions => [ "visible = 1 AND member_type='relation' and member_id=?", params[:id]]) - return false - else - relation.user_id = @user.id - relation.tags = [] - relation.members = [] - relation.visible = false - relation.save_with_history! - - return :ok - end - else - return :gone - end - end - # ----------------------------------------------------------------- # full # diff --git a/app/controllers/way_controller.rb b/app/controllers/way_controller.rb index fd01008fa..3f5f66197 100644 --- a/app/controllers/way_controller.rb +++ b/app/controllers/way_controller.rb @@ -51,35 +51,18 @@ class WayController < ApplicationController new_way = Way.from_xml(request.raw_post) if new_way and new_way.id == way.id - unless update_internal(way, new_way) - render :text => "", :status => :precondition_failed - else - render :nothing => true - end + way.update_from(new_way, @user) + render :nothing => true else render :nothing => true, :status => :bad_request end + rescue OSM::APIPreconditionFailedError + render :text => "", :status => :precondition_failed rescue ActiveRecord::RecordNotFound render :nothing => true, :status => :not_found end end - def update_internal way, new_way - way = Way.find(new_way.id) if way.nil? - - if !new_way.preconditions_ok? - return false - else - way.user_id = @user.id - way.tags = new_way.tags - way.nds = new_way.nds - way.visible = true - way.save_with_history! - - return true - end - end - # This is the API call to delete a way def delete begin diff --git a/app/models/node.rb b/app/models/node.rb index 872c5c922..7a103efa5 100644 --- a/app/models/node.rb +++ b/app/models/node.rb @@ -122,6 +122,31 @@ class Node < GeoRecord end end + def delete_with_history(user) + if self.visible + if WayNode.find(:first, :joins => "INNER JOIN current_ways ON current_ways.id = current_way_nodes.id", :conditions => [ "current_ways.visible = 1 AND current_way_nodes.node_id = ?", self.id ]) + raise OSM::APIPreconditionFailedError.new + elsif RelationMember.find(:first, :joins => "INNER JOIN current_relations ON current_relations.id=current_relation_members.id", :conditions => [ "visible = 1 AND member_type='node' and member_id=?", self.id]) + raise OSM::APIPreconditionFailedError.new + else + self.user_id = user.id + self.visible = 0 + save_with_history! + end + else + raise OSM::APIAlreadyDeletedError.new + end + end + + def update_from(new_node, user) + self.user_id = user.id + self.latitude = new_node.latitude + self.longitude = new_node.longitude + self.tags = new_node.tags + self.visible = true + save_with_history! + end + def to_xml doc = OSM::API.new.get_xml_doc doc.root << to_xml_node() diff --git a/app/models/relation.rb b/app/models/relation.rb index 2c155e9e1..559b78440 100644 --- a/app/models/relation.rb +++ b/app/models/relation.rb @@ -205,6 +205,34 @@ class Relation < ActiveRecord::Base end end + def delete_with_history(user) + if self.visible + if RelationMember.find(:first, :joins => "INNER JOIN current_relations ON current_relations.id=current_relation_members.id", :conditions => [ "visible = 1 AND member_type='relation' and member_id=?", self.id ]) + raise OSM::APIPreconditionFailedError.new + else + self.user_id = user.id + self.tags = [] + self.members = [] + self.visible = false + save_with_history! + end + else + raise OSM::APIAlreadyDeletedError.new + end + end + + def update_from(new_relation, user) + if !new_relation.preconditions_ok? + raise OSM::APIPreconditionFailedError.new + else + self.user_id = user.id + self.tags = new_relation.tags + self.members = new_relation.members + self.visible = true + save_with_history! + end + end + def preconditions_ok? self.members.each do |m| if (m[0] == "node") diff --git a/app/models/way.rb b/app/models/way.rb index 0c927c11c..e16ec53e0 100644 --- a/app/models/way.rb +++ b/app/models/way.rb @@ -196,6 +196,18 @@ class Way < ActiveRecord::Base end end + def update_from(new_way, user) + if !new_way.preconditions_ok? + raise OSM::APIPreconditionFailedError.new + else + self.user_id = user.id + self.tags = new_way.tags + self.nds = new_way.nds + self.visible = true + save_with_history! + end + end + def preconditions_ok? return false if self.nds.empty? self.nds.each do |n| @@ -213,6 +225,8 @@ class Way < ActiveRecord::Base # FIXME # this should actually delete the relations, # not just throw a PreconditionFailed if it's a member of a relation!! + + # FIXME: this should probably renamed to delete_with_history if RelationMember.find(:first, :joins => "INNER JOIN current_relations ON current_relations.id=current_relation_members.id", :conditions => [ "visible = 1 AND member_type='way' and member_id=?", self.id]) raise OSM::APIPreconditionFailedError -- 2.39.5