closure_tree 7.1.0 → 7.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +4 -1
- data/CHANGELOG.md +4 -0
- data/README.md +1 -1
- data/lib/closure_tree.rb +0 -1
- data/lib/closure_tree/finders.rb +4 -4
- data/lib/closure_tree/hash_tree_support.rb +1 -1
- data/lib/closure_tree/hierarchy_maintenance.rb +2 -2
- data/lib/closure_tree/model.rb +11 -15
- data/lib/closure_tree/numeric_deterministic_ordering.rb +2 -2
- data/lib/closure_tree/numeric_order_support.rb +2 -2
- data/lib/closure_tree/support.rb +6 -6
- data/lib/closure_tree/support_attributes.rb +1 -1
- data/lib/closure_tree/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0625b057493bad32e0431a7ac4cdba5abc8ee8ac29d09edab97953a68e670bd
|
4
|
+
data.tar.gz: b99a0700c15e962034444aa6393a774a20ea8fd996c312af1aadf2ad941d938f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 630b296849c1c26b4129e21d29e502d02fa61daa481b1c518846817208ab92f6c8ff75c708a687f1068a2c4ce84ad60b7d711d58a4e03a2a53a2f2ee6c459a89
|
7
|
+
data.tar.gz: b40be25daf8524d0a9cd5776163ec5a0be247fdf20e7172e3b2bd64b4002591224de88f145c20dacf087c0ec11dbfbc24ca56ef4ec27415f29977e9f092d2ac3
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
### 7.2.0
|
4
|
+
- Ruby 2.7 support
|
5
|
+
- Ordering raw SQL argument wrapped with Arel.sql
|
6
|
+
|
3
7
|
### 7.1.0
|
4
8
|
Closure Tree is now tested against Rails 6.0
|
5
9
|
- Directly require core_ext for String#strip_heredoc[PR 350](https://github.com/ClosureTree/closure_tree/pull/350)
|
data/README.md
CHANGED
@@ -662,7 +662,7 @@ end
|
|
662
662
|
|
663
663
|
Closure tree is [tested under every valid combination](http://travis-ci.org/#!/ClosureTree/closure_tree) of
|
664
664
|
|
665
|
-
* Ruby 2.5, 2.6
|
665
|
+
* Ruby 2.5, 2.6 and 2.7
|
666
666
|
* ActiveRecord 4.2, 5.x and 6.0
|
667
667
|
* PostgreSQL, MySQL, and SQLite. Concurrency tests are only run with MySQL and PostgreSQL.
|
668
668
|
|
data/lib/closure_tree.rb
CHANGED
data/lib/closure_tree/finders.rb
CHANGED
@@ -34,7 +34,7 @@ module ClosureTree
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def find_all_by_generation(generation_level)
|
37
|
-
s = _ct.base_class.joins(<<-SQL.
|
37
|
+
s = _ct.base_class.joins(<<-SQL.squish)
|
38
38
|
INNER JOIN (
|
39
39
|
SELECT descendant_id
|
40
40
|
FROM #{_ct.quoted_hierarchy_table_name}
|
@@ -70,7 +70,7 @@ module ClosureTree
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def leaves
|
73
|
-
s = joins(<<-SQL.
|
73
|
+
s = joins(<<-SQL.squish)
|
74
74
|
INNER JOIN (
|
75
75
|
SELECT ancestor_id
|
76
76
|
FROM #{_ct.quoted_hierarchy_table_name}
|
@@ -113,7 +113,7 @@ module ClosureTree
|
|
113
113
|
end
|
114
114
|
|
115
115
|
def find_all_by_generation(generation_level)
|
116
|
-
s = joins(<<-SQL.
|
116
|
+
s = joins(<<-SQL.squish)
|
117
117
|
INNER JOIN (
|
118
118
|
SELECT #{primary_key} as root_id
|
119
119
|
FROM #{_ct.quoted_table_name}
|
@@ -143,7 +143,7 @@ module ClosureTree
|
|
143
143
|
last_joined_table = _ct.table_name
|
144
144
|
path.reverse.each_with_index do |ea, idx|
|
145
145
|
next_joined_table = "p#{idx}"
|
146
|
-
scope = scope.joins(<<-SQL.
|
146
|
+
scope = scope.joins(<<-SQL.squish)
|
147
147
|
INNER JOIN #{_ct.quoted_table_name} #{ _ct.t_alias_keyword } #{next_joined_table}
|
148
148
|
ON #{next_joined_table}.#{_ct.quoted_id_column_name} =
|
149
149
|
#{connection.quote_table_name(last_joined_table)}.#{_ct.quoted_parent_column_name}
|
@@ -4,7 +4,7 @@ module ClosureTree
|
|
4
4
|
# Deepest generation, within limit, for each descendant
|
5
5
|
# NOTE: Postgres requires HAVING clauses to always contains aggregate functions (!!)
|
6
6
|
having_clause = limit_depth ? "HAVING MAX(generations) <= #{limit_depth - 1}" : ''
|
7
|
-
generation_depth = <<-SQL.
|
7
|
+
generation_depth = <<-SQL.squish
|
8
8
|
INNER JOIN (
|
9
9
|
SELECT descendant_id, MAX(generations) as depth
|
10
10
|
FROM #{quoted_hierarchy_table_name}
|
@@ -67,7 +67,7 @@ module ClosureTree
|
|
67
67
|
delete_hierarchy_references unless (defined? @was_new_record) && @was_new_record
|
68
68
|
hierarchy_class.create!(:ancestor => self, :descendant => self, :generations => 0)
|
69
69
|
unless root?
|
70
|
-
_ct.connection.execute <<-SQL.
|
70
|
+
_ct.connection.execute <<-SQL.squish
|
71
71
|
INSERT INTO #{_ct.quoted_hierarchy_table_name}
|
72
72
|
(ancestor_id, descendant_id, generations)
|
73
73
|
SELECT x.ancestor_id, #{_ct.quote(_ct_id)}, x.generations + 1
|
@@ -94,7 +94,7 @@ module ClosureTree
|
|
94
94
|
# It shouldn't affect performance of postgresql.
|
95
95
|
# See http://dev.mysql.com/doc/refman/5.0/en/subquery-errors.html
|
96
96
|
# Also: PostgreSQL doesn't support INNER JOIN on DELETE, so we can't use that.
|
97
|
-
_ct.connection.execute <<-SQL.
|
97
|
+
_ct.connection.execute <<-SQL.squish
|
98
98
|
DELETE FROM #{_ct.quoted_hierarchy_table_name}
|
99
99
|
WHERE descendant_id IN (
|
100
100
|
SELECT DISTINCT descendant_id
|
data/lib/closure_tree/model.rb
CHANGED
@@ -6,7 +6,7 @@ module ClosureTree
|
|
6
6
|
|
7
7
|
included do
|
8
8
|
|
9
|
-
belongs_to :parent, nil,
|
9
|
+
belongs_to :parent, nil, **_ct.belongs_to_with_optional_option(
|
10
10
|
class_name: _ct.model_class.to_s,
|
11
11
|
foreign_key: _ct.parent_column_name,
|
12
12
|
inverse_of: :children,
|
@@ -15,11 +15,11 @@ module ClosureTree
|
|
15
15
|
|
16
16
|
order_by_generations = -> { Arel.sql("#{_ct.quoted_hierarchy_table_name}.generations ASC") }
|
17
17
|
|
18
|
-
has_many :children, *_ct.
|
18
|
+
has_many :children, *_ct.has_many_order_with_option, **{
|
19
19
|
class_name: _ct.model_class.to_s,
|
20
20
|
foreign_key: _ct.parent_column_name,
|
21
21
|
dependent: _ct.options[:dependent],
|
22
|
-
inverse_of: :parent
|
22
|
+
inverse_of: :parent } do
|
23
23
|
# We have to redefine hash_tree because the activerecord relation is already scoped to parent_id.
|
24
24
|
def hash_tree(options = {})
|
25
25
|
# we want limit_depth + 1 because we don't do self_and_descendants.
|
@@ -28,25 +28,21 @@ module ClosureTree
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
has_many :ancestor_hierarchies, *_ct.
|
31
|
+
has_many :ancestor_hierarchies, *_ct.has_many_order_without_option(order_by_generations),
|
32
32
|
class_name: _ct.hierarchy_class_name,
|
33
|
-
foreign_key: 'descendant_id'
|
34
|
-
order: order_by_generations)
|
33
|
+
foreign_key: 'descendant_id'
|
35
34
|
|
36
|
-
has_many :self_and_ancestors, *_ct.
|
35
|
+
has_many :self_and_ancestors, *_ct.has_many_order_without_option(order_by_generations),
|
37
36
|
through: :ancestor_hierarchies,
|
38
|
-
source: :ancestor
|
39
|
-
order: order_by_generations)
|
37
|
+
source: :ancestor
|
40
38
|
|
41
|
-
has_many :descendant_hierarchies, *_ct.
|
39
|
+
has_many :descendant_hierarchies, *_ct.has_many_order_without_option(order_by_generations),
|
42
40
|
class_name: _ct.hierarchy_class_name,
|
43
|
-
foreign_key: 'ancestor_id'
|
44
|
-
order: order_by_generations)
|
41
|
+
foreign_key: 'ancestor_id'
|
45
42
|
|
46
|
-
has_many :self_and_descendants, *_ct.
|
43
|
+
has_many :self_and_descendants, *_ct.has_many_order_with_option(order_by_generations),
|
47
44
|
through: :descendant_hierarchies,
|
48
|
-
source: :descendant
|
49
|
-
order: order_by_generations)
|
45
|
+
source: :descendant
|
50
46
|
end
|
51
47
|
|
52
48
|
# Delegate to the Support instance on the class:
|
@@ -51,7 +51,7 @@ module ClosureTree
|
|
51
51
|
|
52
52
|
# If node is nil, order the whole tree.
|
53
53
|
def _ct_sum_order_by(node = nil)
|
54
|
-
stats_sql = <<-SQL.
|
54
|
+
stats_sql = <<-SQL.squish
|
55
55
|
SELECT
|
56
56
|
count(*) as total_descendants,
|
57
57
|
max(generations) as max_depth
|
@@ -74,7 +74,7 @@ module ClosureTree
|
|
74
74
|
raise ClosureTree::RootOrderingDisabledError.new("Root ordering is disabled on this model")
|
75
75
|
end
|
76
76
|
|
77
|
-
join_sql = <<-SQL.
|
77
|
+
join_sql = <<-SQL.squish
|
78
78
|
JOIN #{_ct.quoted_hierarchy_table_name} anc_hier
|
79
79
|
ON anc_hier.descendant_id = #{_ct.quoted_table_name}.#{_ct.quoted_id_column_name}
|
80
80
|
JOIN #{_ct.quoted_table_name} anc
|
@@ -21,7 +21,7 @@ module ClosureTree
|
|
21
21
|
""
|
22
22
|
end
|
23
23
|
connection.execute 'SET @i = 0'
|
24
|
-
connection.execute <<-SQL.
|
24
|
+
connection.execute <<-SQL.squish
|
25
25
|
UPDATE #{quoted_table_name}
|
26
26
|
SET #{quoted_order_column} = (@i := @i + 1) + #{minimum_sort_order_value.to_i - 1}
|
27
27
|
WHERE #{where_eq(parent_column_name, parent_id)} #{min_where}
|
@@ -38,7 +38,7 @@ module ClosureTree
|
|
38
38
|
else
|
39
39
|
""
|
40
40
|
end
|
41
|
-
connection.execute <<-SQL.
|
41
|
+
connection.execute <<-SQL.squish
|
42
42
|
UPDATE #{quoted_table_name}
|
43
43
|
SET #{quoted_order_column(false)} = t.seq + #{minimum_sort_order_value.to_i - 1}
|
44
44
|
FROM (
|
data/lib/closure_tree/support.rb
CHANGED
@@ -80,20 +80,20 @@ module ClosureTree
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def belongs_to_with_optional_option(opts)
|
83
|
-
|
83
|
+
ActiveRecord::VERSION::MAJOR < 5 ? opts.except(:optional) : opts
|
84
84
|
end
|
85
85
|
|
86
86
|
# lambda-ize the order, but don't apply the default order_option
|
87
|
-
def
|
88
|
-
[lambda { order(
|
87
|
+
def has_many_order_without_option(order_by_opt)
|
88
|
+
[lambda { order(order_by_opt.call) }]
|
89
89
|
end
|
90
90
|
|
91
|
-
def
|
92
|
-
order_options = [
|
91
|
+
def has_many_order_with_option(order_by_opt=nil)
|
92
|
+
order_options = [order_by_opt, order_by].compact
|
93
93
|
[lambda {
|
94
94
|
order_options = order_options.map { |o| o.is_a?(Proc) ? o.call : o }
|
95
95
|
order(order_options)
|
96
|
-
}
|
96
|
+
}]
|
97
97
|
end
|
98
98
|
|
99
99
|
def ids_from(scope)
|
data/lib/closure_tree/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: closure_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.
|
4
|
+
version: 7.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew McEachen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-09-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|