Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
seuros committed Jan 19, 2024
1 parent dee7b57 commit d147b95
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 120 deletions.
4 changes: 0 additions & 4 deletions lib/closure_tree/has_closure_tree.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ def has_closure_tree(options = {})

include ClosureTree::DeterministicOrdering if _ct.order_option?
include ClosureTree::NumericDeterministicOrdering if _ct.order_is_numeric?

connection_pool.release_connection
rescue StandardError => e
raise e unless ClosureTree.configuration.database_less
end

alias_method :acts_as_tree, :has_closure_tree
Expand Down
2 changes: 0 additions & 2 deletions lib/closure_tree/has_closure_tree_root.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,6 @@ def has_closure_tree_root(assoc_name, options = {})

@closure_tree_roots[assoc_name][assoc_map] = root
end

connection_pool.release_connection
end
end
end
78 changes: 40 additions & 38 deletions lib/closure_tree/numeric_order_support.rb
Original file line number Diff line number Diff line change
@@ -1,53 +1,42 @@
module ClosureTree
module NumericOrderSupport

def self.adapter_for_connection(connection)
das = WithAdvisoryLock::DatabaseAdapterSupport.new(connection)
if das.postgresql?
::ClosureTree::NumericOrderSupport::PostgreSQLAdapter
elsif das.mysql?
::ClosureTree::NumericOrderSupport::MysqlAdapter
else
::ClosureTree::NumericOrderSupport::GenericAdapter
end
end

module MysqlAdapter
def reorder_with_parent_id(parent_id, minimum_sort_order_value = nil)
return if parent_id.nil? && dont_order_roots
module_function def reorder_with_parent_id(ct, parent_id, minimum_sort_order_value = nil)
return if parent_id.nil? && ct.dont_order_roots

min_where = if minimum_sort_order_value
"AND #{quoted_order_column} >= #{minimum_sort_order_value}"
"AND #{ct.quoted_order_column} >= #{minimum_sort_order_value}"
else
""
end
connection.execute 'SET @i = 0'
connection.execute <<-SQL.squish
UPDATE #{quoted_table_name}
SET #{quoted_order_column} = (@i := @i + 1) + #{minimum_sort_order_value.to_i - 1}
WHERE #{where_eq(parent_column_name, parent_id)} #{min_where}
ORDER BY #{nulls_last_order_by}
ct.connection.execute 'SET @i = 0'
ct.connection.execute <<-SQL.squish
UPDATE #{ct.quoted_table_name}
SET #{ct.quoted_order_column} = (@i := @i + 1) + #{minimum_sort_order_value.to_i - 1}
WHERE #{ct.where_eq(ct.parent_column_name, parent_id)} #{min_where}
ORDER BY #{ct.nulls_last_order_by}
SQL
end
end

module PostgreSQLAdapter
def reorder_with_parent_id(parent_id, minimum_sort_order_value = nil)
return if parent_id.nil? && dont_order_roots
module_function def reorder_with_parent_id(ct, parent_id, minimum_sort_order_value = nil)
return if parent_id.nil? && ct.dont_order_roots
min_where = if minimum_sort_order_value
"AND #{quoted_order_column} >= #{minimum_sort_order_value}"
"AND #{ct.quoted_order_column} >= #{minimum_sort_order_value}"
else
""
end
connection.execute <<-SQL.squish
UPDATE #{quoted_table_name}
SET #{quoted_order_column(false)} = t.seq + #{minimum_sort_order_value.to_i - 1}
ct.connection.execute <<-SQL.squish
UPDATE #{ct.quoted_table_name}
SET #{ct.quoted_order_column(false)} = t.seq + #{minimum_sort_order_value.to_i - 1}
FROM (
SELECT #{quoted_id_column_name} AS id, row_number() OVER(ORDER BY #{order_by}) AS seq
FROM #{quoted_table_name}
WHERE #{where_eq(parent_column_name, parent_id)} #{min_where}
SELECT #{ct.quoted_id_column_name} AS id, row_number() OVER(ORDER BY #{ct.order_by}) AS seq
FROM #{ct.quoted_table_name}
WHERE #{ct.where_eq(ct.parent_column_name, parent_id)} #{min_where}
) AS t
WHERE #{quoted_table_name}.#{quoted_id_column_name} = t.id and
#{quoted_table_name}.#{quoted_order_column(false)} is distinct from t.seq + #{minimum_sort_order_value.to_i - 1}
WHERE #{ct.quoted_table_name}.#{ct.quoted_id_column_name} = t.id and
#{ct.quoted_table_name}.#{ct.quoted_order_column(false)} is distinct from t.seq + #{minimum_sort_order_value.to_i - 1}
SQL
end

Expand All @@ -57,18 +46,31 @@ def rows_updated(result)
end

module GenericAdapter
def reorder_with_parent_id(parent_id, minimum_sort_order_value = nil)
return if parent_id.nil? && dont_order_roots
scope = model_class.
where(parent_column_sym => parent_id).
order(nulls_last_order_by)
module_function def reorder_with_parent_id(ct, parent_id, minimum_sort_order_value = nil)
return if parent_id.nil? && ct.dont_order_roots
binding.irb
scope = ct.
where(ct.parent_column_sym => parent_id).
order(ct.nulls_last_order_by)
if minimum_sort_order_value
scope = scope.where("#{quoted_order_column} >= #{minimum_sort_order_value}")
scope = scope.where("#{ct.quoted_order_column} >= #{minimum_sort_order_value}")
end
scope.each_with_index do |ea, idx|
ea.update_order_value(idx + minimum_sort_order_value.to_i)
end
end
end


module_function def adapter_for_connection(ct, parent_id, minimum_sort_order_value = nil)
das = WithAdvisoryLock::DatabaseAdapterSupport.new(ct.connection)
if das.postgresql?
PostgreSQLAdapter.reorder_with_parent_id(ct, parent_id, minimum_sort_order_value = nil)
elsif das.mysql?
MysqlAdapter.reorder_with_parent_id(ct, parent_id, minimum_sort_order_value = nil)
else
GenericAdapter.reorder_with_parent_id(ct, parent_id, minimum_sort_order_value = nil)
end
end
end
end
7 changes: 4 additions & 3 deletions lib/closure_tree/support.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ def initialize(model_class, options)
:numeric_order => false
}.merge(options)
raise ArgumentError, "name_column can't be 'path'" if options[:name_column] == 'path'
if order_is_numeric?
extend NumericOrderSupport.adapter_for_connection(connection)
end
end

def hierarchy_class_for_model
Expand All @@ -54,6 +51,10 @@ def hash
hierarchy_class
end

def reorder_with_parent_id(parent_id, minimum_sort_order_value = nil)
NumericOrderSupport.adapter_for_connection(self, parent_id, minimum_sort_order_value)
end

def hierarchy_table_name
# We need to use the table_name, not something like ct_class.to_s.demodulize + "_hierarchies",
# because they may have overridden the table name, which is what we want to be consistent with
Expand Down
7 changes: 1 addition & 6 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
ActiveRecord::Base.configurations = {
default_env: {
primary: {
primary: true,
url: primary_database_url,
properties: { allowPublicKeyRetrieval: true } # for JRuby madness
},
Expand Down Expand Up @@ -99,14 +100,8 @@ def sqlite?
# Require our gem
require 'closure_tree'

ActiveRecord::Tasks::DatabaseTasks.drop_current(:primary)
ActiveRecord::Tasks::DatabaseTasks.create_current(:primary)
ActiveRecord::Tasks::DatabaseTasks.drop_current(:secondary)
ActiveRecord::Tasks::DatabaseTasks.create_current(:secondary)

# Load test helpers
require_relative 'support/schema'
require_relative 'support/models'
require_relative 'support/helpers'
require_relative 'support/exceed_query_limit'
require_relative 'support/query_counter'
Expand Down
13 changes: 13 additions & 0 deletions spec/support/models.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# frozen_string_literal: true



class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true

connects_to database: { writing: :primary, reading: :primary }
end

class SecondDatabaseRecord < ActiveRecord::Base
self.abstract_class = true

connects_to database: { writing: :secondary, reading: :secondary }
end
class Tag < ApplicationRecord
has_closure_tree dependent: :destroy, order: :name
before_destroy :add_destroyed_tag
Expand Down
Loading

0 comments on commit d147b95

Please sign in to comment.