From a04b9a80b506b04a03f0ef8fe3fe99ec7aaac9dc Mon Sep 17 00:00:00 2001 From: Markus Herzog Date: Fri, 16 Nov 2018 14:50:47 +0100 Subject: [PATCH] Add an option `database_type` Problem: When using `numeric_ordering: true`, closure_tree tries to find out the type of database during the initialization process. This can be problematic, for example when doing `rails db:create`, in which case there is no database, yet. Another scenario is `rails asssets:prcompile` in a Docker container that is being made for production, but it doesn't have access to the production database yet, because it isn't rolled out, yet. Solution: I have added an option to specify the database_type manually. This option is *only* used then numeric_ordering is set to `true` --- lib/closure_tree/has_closure_tree.rb | 3 ++- lib/closure_tree/numeric_order_support.rb | 11 +++++++++++ lib/closure_tree/support.rb | 14 +++++++++++++- lib/closure_tree/support_flags.rb | 4 ++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/lib/closure_tree/has_closure_tree.rb b/lib/closure_tree/has_closure_tree.rb index b0bc5b1a..b83e1fb5 100644 --- a/lib/closure_tree/has_closure_tree.rb +++ b/lib/closure_tree/has_closure_tree.rb @@ -11,7 +11,8 @@ def has_closure_tree(options = {}) :dont_order_roots, :numeric_order, :touch, - :with_advisory_lock + :with_advisory_lock, + :database_type ) class_attribute :_ct diff --git a/lib/closure_tree/numeric_order_support.rb b/lib/closure_tree/numeric_order_support.rb index 0223a415..f6a59408 100644 --- a/lib/closure_tree/numeric_order_support.rb +++ b/lib/closure_tree/numeric_order_support.rb @@ -12,6 +12,17 @@ def self.adapter_for_connection(connection) end end + def self.adapter_for_database_type(database_type) + case database_type + when :postgres + ::ClosureTree::NumericOrderSupport::PostgreSQLAdapter + when :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 diff --git a/lib/closure_tree/support.rb b/lib/closure_tree/support.rb index 75108d79..2878c337 100644 --- a/lib/closure_tree/support.rb +++ b/lib/closure_tree/support.rb @@ -27,7 +27,8 @@ def initialize(model_class, options) }.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) + database_type = database_type_from_options || database_type_from_connection + extend NumericOrderSupport.adapter_for_database_type(database_type) end end @@ -170,5 +171,16 @@ def create(model_class, attributes) def create!(model_class, attributes) create(model_class, attributes).tap { |ea| ea.save! } end + + def database_type_from_connection + das = WithAdvisoryLock::DatabaseAdapterSupport.new(connection) + if das.postgresql? + :postgres + elsif das.mysql? + :mysql + else + :generic + end + end end end diff --git a/lib/closure_tree/support_flags.rb b/lib/closure_tree/support_flags.rb index cdf7fd8b..928e6e70 100644 --- a/lib/closure_tree/support_flags.rb +++ b/lib/closure_tree/support_flags.rb @@ -31,5 +31,9 @@ def has_inheritance_column?(hash = columns_hash) def has_name? model_class.new.attributes.include? options[:name_column] end + + def database_type_from_options + options[:database_type] + end end end