api06: Move version-checking into the models, raising an exception on mismatch
authorGabriel Ebner <gabriel@svn.openstreetmap.org>
Mon, 12 May 2008 21:05:11 +0000 (21:05 +0000)
committerGabriel Ebner <gabriel@svn.openstreetmap.org>
Mon, 12 May 2008 21:05:11 +0000 (21:05 +0000)
(still not implemented for delete requests though.)

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/osm.rb

index fa6759c..379ee77 100644 (file)
@@ -49,10 +49,6 @@ class NodeController < ApplicationController
     begin
       node = Node.find(params[:id])
       new_node = Node.from_xml(request.raw_post)
-      if new_node.version != node.version
-        render :text => "Version mismatch: Provided " + new_node.version.to_s + ", server had: " + node.version.to_s, :status => :bad_request
-        return
-      end  
 
       if new_node and new_node.id == node.id
         node.update_from(new_node, @user)
@@ -60,6 +56,9 @@ class NodeController < ApplicationController
       else
         render :nothing => true, :status => :bad_request
       end
+    rescue OSM::APIVersionMismatchError ex
+      render :text => "Version mismatch: Provided " + ex.provided.to_s +
+       ", server had: " + ex.latest.to_s, :status => :bad_request
     rescue ActiveRecord::RecordNotFound
       render :nothing => true, :status => :not_found
     end
index d7b9de1..dabf6ea 100644 (file)
@@ -64,6 +64,9 @@ class RelationController < ApplicationController
       render :nothing => true, :status => :not_found
     rescue OSM::APIPreconditionFailedError
       render :text => "", :status => :precondition_failed
+    rescue OSM::APIVersionMismatchError => ex
+      render :text => "Version mismatch: Provided " + ex.provided.to_s +
+       ", server had: " + ex.latest.to_s, :status => :bad_request
     rescue
       render :nothing => true, :status => :internal_server_error
     end
index d3a1b03..b22d35d 100644 (file)
@@ -49,11 +49,6 @@ class WayController < ApplicationController
     begin
       way = Way.find(params[:id])
       new_way = Way.from_xml(request.raw_post)
-      if new_way.version != way.version
-        render :text => "Version mismatch: Provided " + new_way.version.to_s + ", server had: " + way.version.to_s, :status => :bad_request
-        return
-      end  
-        
 
       if new_way and new_way.id == way.id
         way.update_from(new_way, @user)
@@ -63,6 +58,9 @@ class WayController < ApplicationController
       end
     rescue OSM::APIPreconditionFailedError
       render :text => "", :status => :precondition_failed
+    rescue OSM::APIVersionMismatchError => ex
+      render :text => "Version mismatch: Provided " + ex.provided.to_s +
+       ", server had: " + ex.latest.to_s, :status => :bad_request
     rescue ActiveRecord::RecordNotFound
       render :nothing => true, :status => :not_found
     end
index 5f41338..b027f2f 100644 (file)
@@ -140,6 +140,10 @@ class Node < GeoRecord
   end
 
   def update_from(new_node, user)
+    if new_node.version != version
+      raise OSM::APIVersionMismatchError.new(new_node.version, version)
+    end
+
     self.user_id = user.id
     self.latitude = new_node.latitude 
     self.longitude = new_node.longitude
index b7cb0f1..984732c 100644 (file)
@@ -224,6 +224,8 @@ class Relation < ActiveRecord::Base
   def update_from(new_relation, user)
     if !new_relation.preconditions_ok?
       raise OSM::APIPreconditionFailedError.new
+    elsif new_relation.version != version
+      raise OSM::APIVersionMismatchError.new(new_relation.version, version)
     else
       self.user_id = user.id
       self.tags = new_relation.tags
index de69f75..a6192e2 100644 (file)
@@ -199,6 +199,8 @@ class Way < ActiveRecord::Base
   def update_from(new_way, user)
     if !new_way.preconditions_ok?
       raise OSM::APIPreconditionFailedError.new
+    elsif new_way.version != version
+      raise OSM::APIVersionMismatchError.new(new_way.version, version)
     else
       self.user_id = user.id
       self.tags = new_way.tags
index bd93510..a8cb103 100644 (file)
@@ -24,6 +24,15 @@ module OSM
   class APIAlreadyDeletedError < APIError
   end
 
+  # Raised when the provided version is not equal to the latest in the db.
+  class APIVersionMismatchError < APIError
+    def initialize(provided, latest)
+      @provided, @latest = provided, latest
+    end
+
+    attr_reader :provided, :latest
+  end
+
   # Helper methods for going to/from mercator and lat/lng.
   class Mercator
     include Math