closure_tree 6.4.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.
Files changed (57) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.travis.yml +19 -12
  4. data/Appraisals +75 -7
  5. data/CHANGELOG.md +92 -39
  6. data/Gemfile +0 -12
  7. data/README.md +67 -24
  8. data/_config.yml +1 -0
  9. data/closure_tree.gemspec +10 -7
  10. data/lib/closure_tree/finders.rb +32 -9
  11. data/lib/closure_tree/has_closure_tree.rb +4 -0
  12. data/lib/closure_tree/has_closure_tree_root.rb +4 -6
  13. data/lib/closure_tree/hash_tree_support.rb +4 -4
  14. data/lib/closure_tree/hierarchy_maintenance.rb +31 -11
  15. data/lib/closure_tree/model.rb +42 -16
  16. data/lib/closure_tree/numeric_deterministic_ordering.rb +20 -6
  17. data/lib/closure_tree/numeric_order_support.rb +7 -3
  18. data/lib/closure_tree/support.rb +18 -12
  19. data/lib/closure_tree/support_attributes.rb +10 -1
  20. data/lib/closure_tree/support_flags.rb +1 -4
  21. data/lib/closure_tree/version.rb +1 -1
  22. data/lib/generators/closure_tree/migration_generator.rb +8 -0
  23. data/lib/generators/closure_tree/templates/create_hierarchies_table.rb.erb +1 -1
  24. metadata +29 -75
  25. data/gemfiles/activerecord_4.2.gemfile +0 -19
  26. data/gemfiles/activerecord_5.0.gemfile +0 -19
  27. data/gemfiles/activerecord_5.0_foreigner.gemfile +0 -20
  28. data/gemfiles/activerecord_edge.gemfile +0 -20
  29. data/img/example.png +0 -0
  30. data/img/preorder.png +0 -0
  31. data/spec/cache_invalidation_spec.rb +0 -39
  32. data/spec/cuisine_type_spec.rb +0 -38
  33. data/spec/db/database.yml +0 -21
  34. data/spec/db/models.rb +0 -128
  35. data/spec/db/schema.rb +0 -166
  36. data/spec/fixtures/tags.yml +0 -98
  37. data/spec/generators/migration_generator_spec.rb +0 -48
  38. data/spec/has_closure_tree_root_spec.rb +0 -154
  39. data/spec/hierarchy_maintenance_spec.rb +0 -16
  40. data/spec/label_spec.rb +0 -554
  41. data/spec/matcher_spec.rb +0 -34
  42. data/spec/metal_spec.rb +0 -55
  43. data/spec/model_spec.rb +0 -9
  44. data/spec/namespace_type_spec.rb +0 -13
  45. data/spec/parallel_spec.rb +0 -159
  46. data/spec/spec_helper.rb +0 -24
  47. data/spec/support/database.rb +0 -52
  48. data/spec/support/database_cleaner.rb +0 -14
  49. data/spec/support/exceed_query_limit.rb +0 -18
  50. data/spec/support/hash_monkey_patch.rb +0 -13
  51. data/spec/support/query_counter.rb +0 -18
  52. data/spec/support/sqlite3_with_advisory_lock.rb +0 -10
  53. data/spec/support_spec.rb +0 -14
  54. data/spec/tag_examples.rb +0 -665
  55. data/spec/tag_spec.rb +0 -6
  56. data/spec/user_spec.rb +0 -174
  57. data/spec/uuid_tag_spec.rb +0 -6
@@ -1,19 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "~> 4.2.0"
6
-
7
- platforms :ruby, :rbx do
8
- gem "mysql2"
9
- gem "pg"
10
- gem "sqlite3"
11
- end
12
-
13
- platforms :jruby do
14
- gem "activerecord-jdbcmysql-adapter"
15
- gem "activerecord-jdbcpostgresql-adapter"
16
- gem "activerecord-jdbcsqlite3-adapter"
17
- end
18
-
19
- gemspec :path => "../"
@@ -1,19 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "~> 5.0.0"
6
-
7
- platforms :ruby, :rbx do
8
- gem "mysql2"
9
- gem "pg"
10
- gem "sqlite3"
11
- end
12
-
13
- platforms :jruby do
14
- gem "activerecord-jdbcmysql-adapter"
15
- gem "activerecord-jdbcpostgresql-adapter"
16
- gem "activerecord-jdbcsqlite3-adapter"
17
- end
18
-
19
- gemspec :path => "../"
@@ -1,20 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "~> 5.0.0"
6
- gem "foreigner"
7
-
8
- platforms :ruby, :rbx do
9
- gem "mysql2"
10
- gem "pg"
11
- gem "sqlite3"
12
- end
13
-
14
- platforms :jruby do
15
- gem "activerecord-jdbcmysql-adapter"
16
- gem "activerecord-jdbcpostgresql-adapter"
17
- gem "activerecord-jdbcsqlite3-adapter"
18
- end
19
-
20
- gemspec :path => "../"
@@ -1,20 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", :github => "rails/rails"
6
- gem "arel", :github => "rails/arel"
7
-
8
- platforms :ruby, :rbx do
9
- gem "mysql2"
10
- gem "pg"
11
- gem "sqlite3"
12
- end
13
-
14
- platforms :jruby do
15
- gem "activerecord-jdbcmysql-adapter"
16
- gem "activerecord-jdbcpostgresql-adapter"
17
- gem "activerecord-jdbcsqlite3-adapter"
18
- end
19
-
20
- gemspec :path => "../"
Binary file
Binary file
@@ -1,39 +0,0 @@
1
- require 'spec_helper'
2
-
3
-
4
- describe 'cache invalidation', cache: true do
5
- before do
6
- Timecop.travel(10.seconds.ago) do
7
- #create a long tree with 2 branch
8
- @root = MenuItem.create(
9
- name: SecureRandom.hex(10)
10
- )
11
- 2.times do
12
- parent = @root
13
- 10.times do
14
- parent = parent.children.create(
15
- name: SecureRandom.hex(10)
16
- )
17
- end
18
- end
19
- @first_leaf = MenuItem.leaves.first
20
- @second_leaf = MenuItem.leaves.last
21
- end
22
- end
23
-
24
- describe 'touch option' do
25
- it 'should invalidate cache for all it ancestors' do
26
- old_time_stamp = @first_leaf.ancestors.pluck(:updated_at)
27
- @first_leaf.touch
28
- new_time_stamp = @first_leaf.ancestors.pluck(:updated_at)
29
- expect(old_time_stamp).to_not eq(new_time_stamp)
30
- end
31
-
32
- it 'should not invalidate cache for another branch' do
33
- old_time_stamp = @second_leaf.updated_at
34
- @first_leaf.touch
35
- new_time_stamp = @second_leaf.updated_at
36
- expect(old_time_stamp).to eq(new_time_stamp)
37
- end
38
- end
39
- end
@@ -1,38 +0,0 @@
1
- require 'spec_helper'
2
-
3
- def assert_lineage(e, m)
4
- expect(m.parent).to eq(e)
5
- expect(m.self_and_ancestors).to eq([m, e])
6
-
7
- # make sure reloading doesn't affect the self_and_ancestors:
8
- m.reload
9
- expect(m.self_and_ancestors).to eq([m, e])
10
- end
11
-
12
- describe CuisineType do
13
- it "finds self and parents when children << is used" do
14
- e = CuisineType.new(:name => "e")
15
- m = CuisineType.new(:name => "m")
16
- e.children << m
17
- e.save
18
- assert_lineage(e, m)
19
- end
20
-
21
- it "finds self and parents properly if the constructor is used" do
22
- e = CuisineType.create(:name => "e")
23
- m = CuisineType.create(:name => "m", :parent => e)
24
- assert_lineage(e, m)
25
- end
26
-
27
- it "sets the table_name of the hierarchy class properly" do
28
- expect(CuisineTypeHierarchy.table_name).to eq(ActiveRecord::Base.table_name_prefix + "cuisine_type_hierarchies" + ActiveRecord::Base.table_name_suffix)
29
- end
30
-
31
- it 'fixes self_and_ancestors properly on reparenting' do
32
- a = CuisineType.create! :name => 'a'
33
- b = CuisineType.create! :name => 'b'
34
- expect(b.self_and_ancestors.to_a).to eq([b])
35
- a.children << b
36
- expect(b.self_and_ancestors.to_a).to eq([b, a])
37
- end
38
- end
@@ -1,21 +0,0 @@
1
- common: &common
2
- database: <%= db_name %>
3
- host: localhost
4
- pool: 50
5
- timeout: 5000
6
- reaping_frequency: 1000
7
- min_messages: ERROR
8
-
9
- sqlite:
10
- <<: *common
11
- adapter: <%= "jdbc" if defined? JRUBY_VERSION %>sqlite3
12
-
13
- postgresql:
14
- <<: *common
15
- adapter: postgresql
16
- username: postgres
17
-
18
- mysql:
19
- <<: *common
20
- adapter: mysql2
21
- username: root
@@ -1,128 +0,0 @@
1
- class Tag < ActiveRecord::Base
2
- has_closure_tree :dependent => :destroy, :order => :name
3
- before_destroy :add_destroyed_tag
4
-
5
- def to_s
6
- name
7
- end
8
-
9
- def add_destroyed_tag
10
- # Proof for the tests that the destroy rather than the delete method was called:
11
- DestroyedTag.create(:name => name)
12
- end
13
- end
14
-
15
- class UUIDTag < ActiveRecord::Base
16
- self.primary_key = :uuid
17
- before_create :set_uuid
18
- has_closure_tree dependent: :destroy, order: 'name', parent_column_name: 'parent_uuid'
19
- before_destroy :add_destroyed_tag
20
-
21
- def set_uuid
22
- self.uuid = SecureRandom.uuid
23
- end
24
-
25
- def to_s
26
- name
27
- end
28
-
29
- def add_destroyed_tag
30
- # Proof for the tests that the destroy rather than the delete method was called:
31
- DestroyedTag.create(:name => name)
32
- end
33
- end
34
-
35
- class DestroyedTag < ActiveRecord::Base
36
- end
37
-
38
- class Group < ActiveRecord::Base
39
- has_closure_tree_root :root_user
40
- end
41
-
42
- class Grouping < ActiveRecord::Base
43
- has_closure_tree_root :root_person, class_name: "User", foreign_key: :group_id
44
- end
45
-
46
- class UserSet < ActiveRecord::Base
47
- has_closure_tree_root :root_user, class_name: "Useur"
48
- end
49
-
50
- class Team < ActiveRecord::Base
51
- has_closure_tree_root :root_user, class_name: "User", foreign_key: :grp_id
52
- end
53
-
54
- class User < ActiveRecord::Base
55
- acts_as_tree :parent_column_name => "referrer_id",
56
- :name_column => 'email',
57
- :hierarchy_class_name => 'ReferralHierarchy',
58
- :hierarchy_table_name => 'referral_hierarchies'
59
-
60
- has_many :contracts, inverse_of: :user
61
- belongs_to :group # Can't use and don't need inverse_of here when using has_closure_tree_root.
62
-
63
- def indirect_contracts
64
- Contract.where(:user_id => descendant_ids)
65
- end
66
-
67
- def to_s
68
- email
69
- end
70
- end
71
-
72
- class Contract < ActiveRecord::Base
73
- belongs_to :user, inverse_of: :contracts
74
- belongs_to :contract_type, inverse_of: :contracts
75
- end
76
-
77
- class ContractType < ActiveRecord::Base
78
- has_many :contracts, inverse_of: :contract_type
79
- end
80
-
81
- class Label < ActiveRecord::Base
82
- # make sure order doesn't matter
83
- acts_as_tree :order => :column_whereby_ordering_is_inferred, # <- symbol, and not "sort_order"
84
- :parent_column_name => "mother_id",
85
- :dependent => :destroy
86
-
87
- def to_s
88
- "#{self.class}: #{name}"
89
- end
90
- end
91
-
92
- class EventLabel < Label
93
- end
94
-
95
- class DateLabel < Label
96
- end
97
-
98
- class DirectoryLabel < Label
99
- end
100
-
101
- class CuisineType < ActiveRecord::Base
102
- acts_as_tree
103
- end
104
-
105
- module Namespace
106
- def self.table_name_prefix
107
- 'namespace_'
108
- end
109
- class Type < ActiveRecord::Base
110
- has_closure_tree dependent: :destroy
111
- end
112
- end
113
-
114
- class Metal < ActiveRecord::Base
115
- self.table_name = "#{table_name_prefix}metal#{table_name_suffix}"
116
- has_closure_tree order: 'sort_order', name_column: 'value'
117
- self.inheritance_column = 'metal_type'
118
- end
119
-
120
- class Adamantium < Metal
121
- end
122
-
123
- class Unobtanium < Metal
124
- end
125
-
126
- class MenuItem < ActiveRecord::Base
127
- has_closure_tree touch: true, with_advisory_lock: false
128
- end
@@ -1,166 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- ActiveRecord::Schema.define(:version => 0) do
4
-
5
- create_table "tags" do |t|
6
- t.string "name"
7
- t.string "title"
8
- t.integer "parent_id"
9
- t.integer "sort_order"
10
- t.timestamps null: false
11
- end
12
-
13
- add_foreign_key(:tags, :tags, :column => 'parent_id')
14
-
15
- create_table "tag_hierarchies", :id => false do |t|
16
- t.integer "ancestor_id", :null => false
17
- t.integer "descendant_id", :null => false
18
- t.integer "generations", :null => false
19
- end
20
-
21
- add_foreign_key(:tag_hierarchies, :tags, :column => 'ancestor_id')
22
- add_foreign_key(:tag_hierarchies, :tags, :column => 'descendant_id')
23
-
24
- create_table "uuid_tags", :id => false do |t|
25
- t.string "uuid", :unique => true
26
- t.string "name"
27
- t.string "title"
28
- t.string "parent_uuid"
29
- t.integer "sort_order"
30
- t.timestamps null: false
31
- end
32
-
33
- create_table "uuid_tag_hierarchies", :id => false do |t|
34
- t.string "ancestor_id", :null => false
35
- t.string "descendant_id", :null => false
36
- t.integer "generations", :null => false
37
- end
38
-
39
- create_table "destroyed_tags" do |t|
40
- t.string "name"
41
- end
42
-
43
- add_index "tag_hierarchies", [:ancestor_id, :descendant_id, :generations], :unique => true, :name => "tag_anc_desc_idx"
44
- add_index "tag_hierarchies", [:descendant_id], :name => "tag_desc_idx"
45
-
46
- create_table "groups" do |t|
47
- t.string "name", null: false
48
- end
49
-
50
- create_table "groupings" do |t|
51
- t.string "name", null: false
52
- end
53
-
54
- create_table "user_sets" do |t|
55
- t.string "name", null: false
56
- end
57
-
58
- create_table "teams" do |t|
59
- t.string "name", null: false
60
- end
61
-
62
- create_table "users" do |t|
63
- t.string "email"
64
- t.integer "referrer_id"
65
- t.integer "group_id"
66
- t.timestamps null: false
67
- end
68
-
69
- add_foreign_key(:users, :users, :column => 'referrer_id')
70
-
71
- create_table "contracts" do |t|
72
- t.integer "user_id", :null => false
73
- t.integer "contract_type_id"
74
- t.string "title"
75
- end
76
-
77
- create_table "contract_types" do |t|
78
- t.string "name", :null => false
79
- end
80
-
81
- create_table "referral_hierarchies", :id => false do |t|
82
- t.integer "ancestor_id", :null => false
83
- t.integer "descendant_id", :null => false
84
- t.integer "generations", :null => false
85
- end
86
-
87
- add_index "referral_hierarchies", [:ancestor_id, :descendant_id, :generations], :unique => true, :name => "ref_anc_desc_idx"
88
- add_index "referral_hierarchies", [:descendant_id], :name => "ref_desc_idx"
89
-
90
- create_table "labels" do |t|
91
- t.string "name"
92
- t.string "type"
93
- t.integer "column_whereby_ordering_is_inferred"
94
- t.integer "mother_id"
95
- end
96
-
97
- add_foreign_key(:labels, :labels, :column => 'mother_id')
98
-
99
- create_table "label_hierarchies", :id => false do |t|
100
- t.integer "ancestor_id", :null => false
101
- t.integer "descendant_id", :null => false
102
- t.integer "generations", :null => false
103
- end
104
-
105
- add_index "label_hierarchies", [:ancestor_id, :descendant_id, :generations], :unique => true, :name => "lh_anc_desc_idx"
106
- add_index "label_hierarchies", [:descendant_id], :name => "lh_desc_idx"
107
-
108
- create_table "cuisine_types" do |t|
109
- t.string "name"
110
- t.integer "parent_id"
111
- end
112
-
113
- create_table "cuisine_type_hierarchies", :id => false do |t|
114
- t.integer "ancestor_id", :null => false
115
- t.integer "descendant_id", :null => false
116
- t.integer "generations", :null => false
117
- end
118
-
119
- create_table "namespace_types" do |t|
120
- t.string "name"
121
- t.integer "parent_id"
122
- end
123
-
124
- create_table "namespace_type_hierarchies", :id => false do |t|
125
- t.integer "ancestor_id", :null => false
126
- t.integer "descendant_id", :null => false
127
- t.integer "generations", :null => false
128
- end
129
-
130
- create_table "metal" do |t|
131
- t.integer "parent_id"
132
- t.string "metal_type"
133
- t.string "value"
134
- t.string "description"
135
- t.integer "sort_order"
136
- end
137
-
138
- add_foreign_key(:metal, :metal, :column => 'parent_id')
139
-
140
- create_table "metal_hierarchies", :id => false do |t|
141
- t.integer "ancestor_id", :null => false
142
- t.integer "descendant_id", :null => false
143
- t.integer "generations", :null => false
144
- end
145
-
146
- add_foreign_key(:metal_hierarchies, :metal, :column => 'ancestor_id')
147
- add_foreign_key(:metal_hierarchies, :metal, :column => 'descendant_id')
148
-
149
- create_table 'menu_items' do |t|
150
- t.string 'name'
151
- t.integer 'parent_id'
152
- t.timestamps null: false
153
- end
154
-
155
- add_foreign_key(:menu_items, :menu_items, :column => 'parent_id')
156
-
157
- create_table 'menu_item_hierarchies', :id => false do |t|
158
- t.integer 'ancestor_id', :null => false
159
- t.integer 'descendant_id', :null => false
160
- t.integer 'generations', :null => false
161
- end
162
-
163
- add_foreign_key(:menu_item_hierarchies, :menu_items, :column => 'ancestor_id')
164
- add_foreign_key(:menu_item_hierarchies, :menu_items, :column => 'descendant_id')
165
-
166
- end