include CurrentApiClient
include ThemesForRails::ActionController
include LoadParam
+ include DbCurrentTime
respond_to :json
protect_from_forgery
theme :select_theme
- attr_accessor :resource_attrs
+ attr_writer :resource_attrs
+
+ MAX_UNIQUE_NAME_ATTEMPTS = 10
begin
rescue_from(Exception,
:with => :render_not_found)
end
+ def initialize *args
+ super
+ @object = nil
+ @objects = nil
+ @offset = nil
+ @limit = nil
+ @select = nil
+ @distinct = nil
+ @response_resource_name = nil
+ @attrs = nil
+ end
+
def default_url_options
if Rails.configuration.host
{:host => Rails.configuration.host}
if @object.respond_to? :name and params[:ensure_unique_name]
# Record the original name. See below.
name_stem = @object.name
- counter = 1
+ retries = MAX_UNIQUE_NAME_ATTEMPTS
+ else
+ retries = 0
end
begin
@object.save!
rescue ActiveRecord::RecordNotUnique => rn
- raise unless params[:ensure_unique_name]
+ raise unless retries > 0
+ retries -= 1
# Dig into the error to determine if it is specifically calling out a
# (owner_uuid, name) uniqueness violation. In this specific case, and
detail = err.result.error_field(PG::Result::PG_DIAG_MESSAGE_DETAIL)
raise unless /^Key \(owner_uuid, name\)=\([a-z0-9]{5}-[a-z0-9]{5}-[a-z0-9]{15}, .*?\) already exists\./.match detail
- # OK, this exception really is just a unique name constraint
- # violation, and we've been asked to ensure_unique_name.
- counter += 1
@object.uuid = nil
- @object.name = "#{name_stem} (#{counter})"
- redo
- end while false
+
+ new_name = "#{name_stem} (#{db_current_time.utc.iso8601(3)})"
+ if new_name == @object.name
+ # If the database is fast enough to do two attempts in the
+ # same millisecond, we need to wait to ensure we try a
+ # different timestamp on each attempt.
+ sleep 0.002
+ new_name = "#{name_stem} (#{db_current_time.utc.iso8601(3)})"
+ end
+ @object.name = new_name
+ retry
+ end
show
end
end
def find_object_by_uuid
- if params[:id] and params[:id].match /\D/
+ if params[:id] and params[:id].match(/\D/)
params[:uuid] = params.delete :id
end
@where = { uuid: params[:uuid] }
}
end
end
- super *opts
+ super(*opts)
end
def select_theme