Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-10-04 15:06:14 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-10-04 15:06:14 +0300
commit0d46bf06388d485824bc2f1e736b92b2a8a397e4 (patch)
tree626a835841722463da4def7905b95e874eb77578 /app/models/concerns/atomic_internal_id.rb
parent1f1bdf54e1974f89f3a6ba734ec2c42552e90639 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/models/concerns/atomic_internal_id.rb')
-rw-r--r--app/models/concerns/atomic_internal_id.rb74
1 files changed, 54 insertions, 20 deletions
diff --git a/app/models/concerns/atomic_internal_id.rb b/app/models/concerns/atomic_internal_id.rb
index 95de11a72bf..b510129b35d 100644
--- a/app/models/concerns/atomic_internal_id.rb
+++ b/app/models/concerns/atomic_internal_id.rb
@@ -27,53 +27,73 @@ module AtomicInternalId
extend ActiveSupport::Concern
class_methods do
- def has_internal_id(column, scope:, init:, presence: true) # rubocop:disable Naming/PredicateName
+ def has_internal_id(column, scope:, init:, ensure_if: nil, presence: true) # rubocop:disable Naming/PredicateName
# We require init here to retain the ability to recalculate in the absence of a
# InternaLId record (we may delete records in `internal_ids` for example).
raise "has_internal_id requires a init block, none given." unless init
+ raise "has_internal_id needs to be defined on association." unless self.reflect_on_association(scope)
- before_validation :"ensure_#{scope}_#{column}!", on: :create
+ before_validation :"track_#{scope}_#{column}!", on: :create
+ before_validation :"ensure_#{scope}_#{column}!", on: :create, if: ensure_if
validates column, presence: presence
define_method("ensure_#{scope}_#{column}!") do
- scope_value = association(scope).reader
+ scope_value = internal_id_read_scope(scope)
value = read_attribute(column)
-
return value unless scope_value
- scope_attrs = { scope_value.class.table_name.singularize.to_sym => scope_value }
- usage = self.class.table_name.to_sym
-
- if value.present? && (@iid_needs_tracking || Feature.enabled?(:iid_always_track, default_enabled: true))
- # The value was set externally, e.g. by the user
- # We update the InternalId record to keep track of the greatest value.
- InternalId.track_greatest(self, scope_attrs, usage, value, init)
-
- @iid_needs_tracking = false
- elsif !value.present?
+ if value.nil?
# We don't have a value yet and use a InternalId record to generate
# the next value.
- value = InternalId.generate_next(self, scope_attrs, usage, init)
+ value = InternalId.generate_next(
+ self,
+ internal_id_scope_attrs(scope),
+ internal_id_scope_usage,
+ init)
write_attribute(column, value)
end
value
end
+ define_method("track_#{scope}_#{column}!") do
+ iid_always_track = Feature.enabled?(:iid_always_track, default_enabled: true)
+ return unless @internal_id_needs_tracking || iid_always_track
+
+ @internal_id_needs_tracking = false
+
+ scope_value = internal_id_read_scope(scope)
+ value = read_attribute(column)
+ return unless scope_value
+
+ if value.present?
+ # The value was set externally, e.g. by the user
+ # We update the InternalId record to keep track of the greatest value.
+ InternalId.track_greatest(
+ self,
+ internal_id_scope_attrs(scope),
+ internal_id_scope_usage,
+ value,
+ init)
+ end
+ end
+
define_method("#{column}=") do |value|
super(value).tap do |v|
# Indicate the iid was set from externally
- @iid_needs_tracking = true
+ @internal_id_needs_tracking = true
end
end
define_method("reset_#{scope}_#{column}") do
if value = read_attribute(column)
- scope_value = association(scope).reader
- scope_attrs = { scope_value.class.table_name.singularize.to_sym => scope_value }
- usage = self.class.table_name.to_sym
+ did_reset = InternalId.reset(
+ self,
+ internal_id_scope_attrs(scope),
+ internal_id_scope_usage,
+ value)
- if InternalId.reset(self, scope_attrs, usage, value)
+ if did_reset
write_attribute(column, nil)
end
end
@@ -82,4 +102,18 @@ module AtomicInternalId
end
end
end
+
+ def internal_id_scope_attrs(scope)
+ scope_value = internal_id_read_scope(scope)
+
+ { scope_value.class.table_name.singularize.to_sym => scope_value } if scope_value
+ end
+
+ def internal_id_scope_usage
+ self.class.table_name.to_sym
+ end
+
+ def internal_id_read_scope(scope)
+ association(scope).reader
+ end
end