Class: Namespace::TraversalHierarchy
- Inherits:
-
Object
- Object
- Namespace::TraversalHierarchy
- Defined in:
- app/models/namespace/traversal_hierarchy.rb
Instance Attribute Summary collapse
-
#root ⇒ Object
Returns the value of attribute root.
Class Method Summary collapse
Instance Method Summary collapse
-
#incorrect_traversal_ids ⇒ Object
Identify all incorrect traversal_ids in the current namespace hierarchy.
-
#initialize(root) ⇒ TraversalHierarchy
constructor
A new instance of TraversalHierarchy.
-
#sync_traversal_ids! ⇒ Object
Update all traversal_ids in the current namespace hierarchy.
Constructor Details
#initialize(root) ⇒ TraversalHierarchy
Returns a new instance of TraversalHierarchy.
22 23 24 25 26 |
# File 'app/models/namespace/traversal_hierarchy.rb', line 22 def initialize(root) raise StandardError, 'Must specify a root node' if root.parent_id @root = root end |
Instance Attribute Details
#root ⇒ Object
Returns the value of attribute root.
16 17 18 |
# File 'app/models/namespace/traversal_hierarchy.rb', line 16 def root @root end |
Class Method Details
.for_namespace(namespace) ⇒ Object
18 19 20 |
# File 'app/models/namespace/traversal_hierarchy.rb', line 18 def self.for_namespace(namespace) new(recursive_root_ancestor(namespace)) end |
Instance Method Details
#incorrect_traversal_ids ⇒ Object
Identify all incorrect traversal_ids in the current namespace hierarchy.
59 60 61 62 63 |
# File 'app/models/namespace/traversal_hierarchy.rb', line 59 def incorrect_traversal_ids Namespace .joins("INNER JOIN (#{recursive_traversal_ids}) as cte ON namespaces.id = cte.id") .where('namespaces.traversal_ids::bigint[] <> cte.traversal_ids') end |
#sync_traversal_ids! ⇒ Object
Update all traversal_ids in the current namespace hierarchy.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'app/models/namespace/traversal_hierarchy.rb', line 29 def sync_traversal_ids! # An issue in Rails since 2013 prevents this kind of join based update in # ActiveRecord. https://github.com/rails/rails/issues/13496 # Ideally it would be: # `incorrect_traversal_ids.update_all('traversal_ids = cte.traversal_ids')` sql = <<-SQL UPDATE namespaces SET traversal_ids = cte.traversal_ids FROM (#{recursive_traversal_ids}) as cte WHERE namespaces.id = cte.id AND namespaces.traversal_ids::bigint[] <> cte.traversal_ids SQL # Hint: when a user is created, it also creates a Namespaces::UserNamespace in # `ensure_namespace_correct`. This method is then called within the same # transaction of the user INSERT. Gitlab::Database::QueryAnalyzers::PreventCrossDatabaseModification.temporary_ignore_tables_in_transaction( %w[namespaces], url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/424279' ) do Namespace.transaction do @root.lock!("FOR NO KEY UPDATE") Namespace.connection.exec_query(sql) end end rescue ActiveRecord::Deadlocked db_deadlock_counter.increment(source: 'Namespace#sync_traversal_ids!') raise end |