Creating consistency check for creation of nodes, way and relations. Moving some...
authorShaun McDonald <shaun@shaunmcdonald.me.uk>
Mon, 13 Oct 2008 15:39:21 +0000 (15:39 +0000)
committerShaun McDonald <shaun@shaunmcdonald.me.uk>
Mon, 13 Oct 2008 15:39:21 +0000 (15:39 +0000)
app/controllers/node_controller.rb
app/controllers/relation_controller.rb
app/controllers/way_controller.rb
app/models/node.rb
app/models/relation.rb
app/models/way.rb
lib/consistency_validations.rb

index 62e680388471203ad94b1a2100ce041e8b446276..309b930b7f89af7344e160b25d5af9dd0599f144 100644 (file)
@@ -11,24 +11,21 @@ class NodeController < ApplicationController
 
   # Create a node from XML.
   def create
-    if request.put?
-      node = Node.from_xml(request.raw_post, true)
-      # FIXME remove debug
-      logger.debug request.raw_post
-      logger.debug node
-
-      if node
-        node.version = 0
-        #node.changeset_id = node.changeset
-        node.visible = true
-        node.save_with_history!
+    begin
+      if request.put?
+        node = Node.from_xml(request.raw_post, true)
 
-        render :text => node.id.to_s, :content_type => "text/plain"
+        if node
+          node.create_with_history @user
+          render :text => node.id.to_s, :content_type => "text/plain"
+        else
+          render :nothing => true, :status => :bad_request
+        end
       else
-        render :nothing => true, :status => :bad_request
+        render :nothing => true, :status => :method_not_allowed
       end
-    else
-      render :nothing => true, :status => :method_not_allowed
+    rescue OSM::APIError => ex
+      render ex.render_opts
     end
   end
 
index 09c878325fce76675fc6587fc694a89d832a4777..4b3fdf34fe7342851b5801f2c0a13702c097b721 100644 (file)
@@ -8,24 +8,21 @@ class RelationController < ApplicationController
   after_filter :compress_output
 
   def create
-    if request.put?
-      relation = Relation.from_xml(request.raw_post, true)
-
-      if relation
-        if !relation.preconditions_ok?
-          render :text => "", :status => :precondition_failed
-        else
-          relation.version = 0
-          #relation.user_id = @user.id
-          relation.save_with_history!
+    begin
+      if request.put?
+        relation = Relation.from_xml(request.raw_post, true)
 
+        if relation
+          relation.create_with_history @user
           render :text => relation.id.to_s, :content_type => "text/plain"
+        else
+          render :nothing => true, :status => :bad_request
         end
       else
-        render :nothing => true, :status => :bad_request
+        render :nothing => true, :status => :method_not_allowed
       end
-    else
-      render :nothing => true, :status => :method_not_allowed
+    rescue OSM::APIError => ex
+      render ex.render_opts
     end
   end
 
index 08270094d63e87c72677bfd49c9183d0cc08217d..e7cf0f7f1cf2c140f76331636fe5355af0553eff 100644 (file)
@@ -8,27 +8,21 @@ class WayController < ApplicationController
   after_filter :compress_output
 
   def create
-    if request.put?
-      way = Way.from_xml(request.raw_post, true)
-
-      if way
-        # FIXME move some of this to the model. The controller shouldn't need to
-        # know about the fact that the first version number is 0 on creation
-        # it will also allow use to run a variation on the check_consistency
-        # so that we don't get exceptions thrown when the changesets are not right
-        unless way.preconditions_ok?
-          render :text => "", :status => :precondition_failed
-        else
-          way.version = 0
-          way.save_with_history!
+    begin
+      if request.put?
+        way = Way.from_xml(request.raw_post, true)
 
+        if way
+          way.create_with_history @user
           render :text => way.id.to_s, :content_type => "text/plain"
+        else
+          render :nothing => true, :status => :bad_request
         end
       else
-        render :nothing => true, :status => :bad_request
+        render :nothing => true, :status => :method_not_allowed
       end
-    else
-      render :nothing => true, :status => :method_not_allowed
+    rescue OSM::APIError => ex
+      render ex.render_opts
     end
   end
 
index e7058a5adee06268b22ff9ffd562d25cc9138c56..d6a5143db1c3ec94263ef701177bc25201a28d89 100644 (file)
@@ -161,6 +161,13 @@ class Node < ActiveRecord::Base
     self.visible = true
     save_with_history!
   end
+  
+  def create_with_history(user)
+    check_create_consistency(self, user)
+    self.version = 0
+    self.visible = true
+    save_with_history!
+  end
 
   def to_xml
     doc = OSM::API.new.get_xml_doc
index dd2d1c7d5f1e4f18e6ae10703e780e8825b0bb69..195090e4b1f2755593773bc1fafb4755c0f37e6d 100644 (file)
@@ -251,6 +251,16 @@ class Relation < ActiveRecord::Base
     self.visible = true
     save_with_history!
   end
+  
+  def create_with_history(user)
+    check_create_consistency(self, user)
+    if !self.preconditions_ok?
+      raise OSM::APIPreconditionFailedError.new
+    end
+    self.version = 0
+    self.visible = true
+    save_with_history!
+  end
 
   def preconditions_ok?
     # These are hastables that store an id in the index of all 
index 6a5ad58ab9635d36279acba547bbe1618815a9ed..b2bdfb39b0e0e96bc6ee4d497b240ade8238eef2 100644 (file)
@@ -219,6 +219,16 @@ class Way < ActiveRecord::Base
     save_with_history!
   end
 
+  def create_with_history(user)
+    check_create_consistency(self, user)
+    if !self.preconditions_ok?
+      raise OSM::APIPreconditionsFailedError.new
+    end
+    self.version = 0
+    self.visible = true
+    save_with_history!
+  end
+
   def preconditions_ok?
     return false if self.nds.empty?
     self.nds.each do |n|
index 4becce89c44d41653b90443f83c643ca326207cb..8fd6c257d732d30d219df8ac0e2df12185ab4ed2 100644 (file)
@@ -16,4 +16,15 @@ module ConsistencyValidations
       raise OSM::APIChangesetAlreadyClosedError.new
     end
   end
+  
+  # This is similar to above, just some validations don't apply
+  def check_create_consistency(new, user)
+    if new.changeset.nil?
+      raise OSM::APIChangesetMissingError.new
+    elsif new.changeset.user_id != user.id
+      raise OSM::APIUserChangesetMismatchError.new
+    elsif not new.changeset.is_open?
+      raise OSM::APIChangesetAlreadyClosedError.new
+    end
+  end
 end