pg_ltree 1.1.9 → 1.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/Rakefile +6 -20
- data/lib/pg_ltree/base.rb +40 -0
- data/lib/pg_ltree/callbacks.rb +27 -0
- data/lib/pg_ltree/{ltree.rb → model.rb} +27 -58
- data/lib/pg_ltree/version.rb +1 -2
- data/lib/pg_ltree.rb +6 -14
- metadata +48 -32
- data/lib/pg_ltree/scoped_for.rb +0 -26
- data/lib/pg_ltree/versions/rails_older_than_51.rb +0 -28
- data/test/database.yml +0 -5
- data/test/database.yml.sample +0 -5
- data/test/pg_ltree/ltree_test.rb +0 -249
- data/test/pg_ltree/scoped_for_test.rb +0 -190
- data/test/pg_ltree_test.rb +0 -7
- data/test/test_helper.rb +0 -85
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 10ef65e0c0c08d2f3670fb0c688eae0e549d40feded3b2c9e63db1109d50b6e2
|
4
|
+
data.tar.gz: c50d76b1d9157dca93b1f49748718300f066b5799672d655aacda68917f48891
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e6742bfcefacebf4124b782c96b1f4b4ada81da57f41f25ebb2dd2eaed7f5f15b32011fc1f8facda0e5648b6b279b604786216ddd1baf6254bec53be6c1ff5b
|
7
|
+
data.tar.gz: 62739b19de39ea1df10d1cd62ea48b981d103b2b54b149ab06f918157637f07f798a9a247811ab4e68b884bee2c85b1e1d15089fce30ec213e69a61bda74cfef
|
data/Rakefile
CHANGED
@@ -1,22 +1,8 @@
|
|
1
|
-
require
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "standard/rake"
|
3
|
+
require "rspec/core/rake_task"
|
4
|
+
require "appraisal"
|
2
5
|
|
3
|
-
|
4
|
-
require 'rdoc/task'
|
5
|
-
|
6
|
-
gemspec = eval(File.read(Dir['*.gemspec'].first))
|
7
|
-
|
8
|
-
RDoc::Task.new(:rdoc) do |rdoc|
|
9
|
-
rdoc.rdoc_dir = 'rdoc'
|
10
|
-
rdoc.title = 'PgLtree'
|
11
|
-
rdoc.options << '--line-numbers'
|
12
|
-
rdoc.rdoc_files.include('README.rdoc')
|
13
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
14
|
-
end
|
15
|
-
|
16
|
-
Rake::TestTask.new(:test) do |t|
|
17
|
-
t.libs << 'lib'
|
18
|
-
t.libs << 'test'
|
19
|
-
t.pattern = 'test/**/*_test.rb'
|
20
|
-
t.verbose = false
|
21
|
-
end
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
22
7
|
|
8
|
+
task default: :spec
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative "model"
|
2
|
+
require_relative "callbacks"
|
3
|
+
|
4
|
+
module PgLtree
|
5
|
+
module Base
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
class_methods do
|
9
|
+
attr_reader :ltree_options
|
10
|
+
|
11
|
+
# Initialize ltree module for the model
|
12
|
+
#
|
13
|
+
# @param column [String] lTree column name
|
14
|
+
# @param cascade_update [Boolean] Update all child nodes when the self path is changed
|
15
|
+
# @param cascade_destroy [Boolean] Destroy all child nodes on self-destroying
|
16
|
+
def ltree(column = :path, cascade_update: true, cascade_destroy: true, cascade: nil)
|
17
|
+
if cascade
|
18
|
+
ActiveSupport::Deprecation.warn("'cascade' param is deprecated. Use 'cascade_update' and 'cascade_destroy' instead.")
|
19
|
+
end
|
20
|
+
|
21
|
+
@ltree_options = {
|
22
|
+
column: column,
|
23
|
+
cascade_update: cascade.nil? ? cascade_update : cascade,
|
24
|
+
cascade_destroy: cascade.nil? ? cascade_destroy : cascade
|
25
|
+
}
|
26
|
+
|
27
|
+
send(:include, PgLtree::Model)
|
28
|
+
send(:include, PgLtree::Callbacks)
|
29
|
+
end
|
30
|
+
|
31
|
+
def ltree_option_for(key)
|
32
|
+
ltree_options[key]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
included do
|
37
|
+
delegate :ltree_option_for, to: :class
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module PgLtree
|
2
|
+
module Callbacks
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
after_commit :cascade_update, on: :update, if: -> { ltree_option_for :cascade_update }
|
7
|
+
after_commit :cascade_destroy, on: :destroy, if: -> { ltree_option_for :cascade_destroy }
|
8
|
+
|
9
|
+
# Update child nodes path
|
10
|
+
#
|
11
|
+
# @return [ActiveRecord::Relation]
|
12
|
+
def cascade_update
|
13
|
+
ltree_scope
|
14
|
+
.where(["#{self.class.table_name}.#{ltree_path_column} <@ ?", ltree_path_before_last_save])
|
15
|
+
.where(["#{self.class.table_name}.#{ltree_path_column} != ?", ltree_path])
|
16
|
+
.update_all ["#{ltree_path_column} = ? || subpath(#{ltree_path_column}, nlevel(?))", ltree_path, ltree_path_before_last_save]
|
17
|
+
end
|
18
|
+
|
19
|
+
# Destroy child nodes
|
20
|
+
#
|
21
|
+
# @return [ActiveRecord::Relation]
|
22
|
+
def cascade_destroy
|
23
|
+
ltree_scope.where("#{self.class.table_name}.#{ltree_path_column} <@ ?", ltree_path_in_database).destroy_all
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,28 +1,12 @@
|
|
1
1
|
module PgLtree
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# @param column [String] ltree column name
|
10
|
-
def ltree(column = :path, cascade: true)
|
11
|
-
cattr_accessor :ltree_path_column
|
12
|
-
|
13
|
-
self.ltree_path_column = column
|
14
|
-
|
15
|
-
if cascade
|
16
|
-
after_update :cascade_update
|
17
|
-
after_destroy :cascade_destroy
|
18
|
-
end
|
19
|
-
|
20
|
-
extend ClassMethods
|
21
|
-
include InstanceMethods
|
22
|
-
end
|
2
|
+
module Model
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
class_methods do
|
6
|
+
def ltree_path_column
|
7
|
+
ltree_option_for :column
|
8
|
+
end
|
23
9
|
|
24
|
-
# Define class methods
|
25
|
-
module ClassMethods
|
26
10
|
# Get roots
|
27
11
|
#
|
28
12
|
# @return [ActiveRecord::Relation] relations of node's roots
|
@@ -43,9 +27,9 @@ module PgLtree
|
|
43
27
|
# @return [ActiveRecord::Relation] relations of node's leaves
|
44
28
|
def leaves
|
45
29
|
subquery = unscoped.select("#{table_name}.#{ltree_path_column}")
|
46
|
-
|
47
|
-
|
48
|
-
|
30
|
+
.from("#{table_name} AS subquery")
|
31
|
+
.where("#{table_name}.#{ltree_path_column} <> subquery.#{ltree_path_column}")
|
32
|
+
.where("#{table_name}.#{ltree_path_column} @> subquery.#{ltree_path_column}")
|
49
33
|
|
50
34
|
where.not ltree_path_column => subquery
|
51
35
|
end
|
@@ -67,8 +51,7 @@ module PgLtree
|
|
67
51
|
end
|
68
52
|
end
|
69
53
|
|
70
|
-
|
71
|
-
module InstanceMethods
|
54
|
+
included do
|
72
55
|
# Get default scope of ltree
|
73
56
|
#
|
74
57
|
# @return current class
|
@@ -79,9 +62,7 @@ module PgLtree
|
|
79
62
|
# Get lTree column
|
80
63
|
#
|
81
64
|
# @return [String] ltree column name
|
82
|
-
|
83
|
-
ltree_scope.ltree_path_column
|
84
|
-
end
|
65
|
+
delegate :ltree_path_column, to: :ltree_scope
|
85
66
|
|
86
67
|
# Get lTree value
|
87
68
|
#
|
@@ -138,21 +119,23 @@ module PgLtree
|
|
138
119
|
#
|
139
120
|
# return [Object] root node
|
140
121
|
def root
|
141
|
-
ltree_scope.where("#{
|
122
|
+
ltree_scope.where("#{self.class.table_name}.#{ltree_path_column} = SUBPATH(?, 0, 1)", ltree_path).first
|
142
123
|
end
|
143
124
|
|
144
125
|
# Get parent of the node
|
145
126
|
#
|
146
127
|
# return [Object] root node
|
147
128
|
def parent
|
148
|
-
ltree_scope.find_by "#{
|
129
|
+
ltree_scope.find_by "#{self.class.table_name}.#{ltree_path_column} = SUBPATH(?, 0, NLEVEL(?) - 1)", ltree_path,
|
130
|
+
ltree_path
|
149
131
|
end
|
150
132
|
|
151
133
|
# Get leaves of the node
|
152
134
|
#
|
153
135
|
# @return [ActiveRecord::Relation]
|
154
136
|
def leaves
|
155
|
-
ltree_scope.leaves.where("#{
|
137
|
+
ltree_scope.leaves.where("#{self.class.table_name}.#{ltree_path_column} <@ ?",
|
138
|
+
ltree_path).where.not ltree_path_column => ltree_path
|
156
139
|
end
|
157
140
|
|
158
141
|
# Check what current node have leaves
|
@@ -166,7 +149,7 @@ module PgLtree
|
|
166
149
|
#
|
167
150
|
# @return [ActiveRecord::Relation]
|
168
151
|
def self_and_ancestors
|
169
|
-
ltree_scope.where("#{
|
152
|
+
ltree_scope.where("#{self.class.table_name}.#{ltree_path_column} @> ?", ltree_path)
|
170
153
|
end
|
171
154
|
|
172
155
|
# Get ancestors
|
@@ -180,15 +163,7 @@ module PgLtree
|
|
180
163
|
#
|
181
164
|
# @return [ActiveRecord::Relation]
|
182
165
|
def self_and_descendants
|
183
|
-
ltree_scope.where("#{
|
184
|
-
end
|
185
|
-
|
186
|
-
# Get self and descendants
|
187
|
-
# @deprecated Please use {#self_and_descendants} instead
|
188
|
-
# @return [ActiveRecord::Relation]
|
189
|
-
def self_and_descendents
|
190
|
-
warn '[DEPRECATION] `self_and_descendents` is deprecated. Please use `self_and_descendants` instead.'
|
191
|
-
self_and_descendants
|
166
|
+
ltree_scope.where("#{self.class.table_name}.#{ltree_path_column} <@ ?", ltree_path)
|
192
167
|
end
|
193
168
|
|
194
169
|
# Get descendants
|
@@ -198,20 +173,12 @@ module PgLtree
|
|
198
173
|
self_and_descendants.where.not ltree_path_column => ltree_path
|
199
174
|
end
|
200
175
|
|
201
|
-
# Get descendants
|
202
|
-
# @deprecated Please use {#descendants} instead
|
203
|
-
# @return [ActiveRecord::Relation]
|
204
|
-
def descendents
|
205
|
-
warn '[DEPRECATION] `descendents` is deprecated. Please use `descendants` instead.'
|
206
|
-
descendants
|
207
|
-
end
|
208
|
-
|
209
176
|
# Get self and siblings
|
210
177
|
#
|
211
178
|
# @return [ActiveRecord::Relation]
|
212
179
|
def self_and_siblings
|
213
180
|
ltree_scope.where(
|
214
|
-
"SUBPATH(?, 0, NLEVEL(?) - 1) @> #{
|
181
|
+
"SUBPATH(?, 0, NLEVEL(?) - 1) @> #{self.class.table_name}.#{ltree_path_column} AND nlevel(#{self.class.table_name}.#{ltree_path_column}) = NLEVEL(?)",
|
215
182
|
ltree_path, ltree_path, ltree_path
|
216
183
|
)
|
217
184
|
end
|
@@ -227,23 +194,25 @@ module PgLtree
|
|
227
194
|
#
|
228
195
|
# @return [ActiveRecord::Relation]
|
229
196
|
def children
|
230
|
-
ltree_scope.where "? @> #{
|
231
|
-
|
197
|
+
ltree_scope.where "? @> #{self.class.table_name}.#{ltree_path_column} AND nlevel(#{self.class.table_name}.#{ltree_path_column}) = NLEVEL(?) + 1",
|
198
|
+
ltree_path, ltree_path
|
232
199
|
end
|
233
200
|
|
234
201
|
# Update all childen for current path
|
235
202
|
#
|
236
203
|
# @return [ActiveRecord::Relation]
|
237
204
|
def cascade_update
|
238
|
-
ltree_scope
|
239
|
-
|
205
|
+
ltree_scope
|
206
|
+
.where("#{self.class.table_name}.#{ltree_path_column} <@ ?", ltree_path_before_last_save)
|
207
|
+
.where("#{self.class.table_name}.#{ltree_path_column} != ?", ltree_path)
|
208
|
+
.update_all("#{ltree_path_column} = ? || subpath(#{ltree_path_column}, nlevel(?))", ltree_path, ltree_path_before_last_save)
|
240
209
|
end
|
241
210
|
|
242
211
|
# Delete all children for current path
|
243
212
|
#
|
244
213
|
# @return [ActiveRecord::Relation]
|
245
214
|
def cascade_destroy
|
246
|
-
ltree_scope.where("#{
|
215
|
+
ltree_scope.where("#{self.class.table_name}.#{ltree_path_column} <@ ?", ltree_path_in_database).destroy_all
|
247
216
|
end
|
248
217
|
end
|
249
218
|
end
|
data/lib/pg_ltree/version.rb
CHANGED
data/lib/pg_ltree.rb
CHANGED
@@ -1,17 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require 'pg_ltree/ltree'
|
3
|
-
require 'pg_ltree/scoped_for'
|
4
|
-
require 'pg_ltree/version'
|
1
|
+
require "active_support"
|
5
2
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
ActiveRecord::Base.extend(PgLtree::Ltree)
|
3
|
+
module PgLtree
|
4
|
+
autoload :Base, "pg_ltree/base"
|
5
|
+
end
|
10
6
|
|
11
|
-
|
12
|
-
|
13
|
-
# This is for backward compability
|
14
|
-
if ActiveRecord::VERSION::MAJOR < 5 || (ActiveRecord::VERSION::MAJOR == 5 && ActiveRecord::VERSION::MINOR < 1)
|
15
|
-
ActiveRecord::Base.extend(PgLtree::Versions::RailsOlderThan51)
|
16
|
-
end
|
7
|
+
ActiveSupport.on_load(:active_record) do
|
8
|
+
ActiveRecord::Base.include PgLtree::Base
|
17
9
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg_ltree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrei Panamarenka
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -36,7 +36,7 @@ dependencies:
|
|
36
36
|
requirements:
|
37
37
|
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: 0.
|
39
|
+
version: '0.19'
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: '2'
|
@@ -46,7 +46,7 @@ dependencies:
|
|
46
46
|
requirements:
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: 0.
|
49
|
+
version: '0.19'
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: '2'
|
@@ -93,7 +93,7 @@ dependencies:
|
|
93
93
|
- !ruby/object:Gem::Version
|
94
94
|
version: '0'
|
95
95
|
- !ruby/object:Gem::Dependency
|
96
|
-
name:
|
96
|
+
name: standard
|
97
97
|
requirement: !ruby/object:Gem::Requirement
|
98
98
|
requirements:
|
99
99
|
- - ">="
|
@@ -107,34 +107,62 @@ dependencies:
|
|
107
107
|
- !ruby/object:Gem::Version
|
108
108
|
version: '0'
|
109
109
|
- !ruby/object:Gem::Dependency
|
110
|
-
name:
|
110
|
+
name: yard
|
111
111
|
requirement: !ruby/object:Gem::Requirement
|
112
112
|
requirements:
|
113
|
-
- - "
|
113
|
+
- - "~>"
|
114
114
|
- !ruby/object:Gem::Version
|
115
|
-
version:
|
115
|
+
version: 0.9.28
|
116
116
|
type: :development
|
117
117
|
prerelease: false
|
118
118
|
version_requirements: !ruby/object:Gem::Requirement
|
119
119
|
requirements:
|
120
|
-
- - "
|
120
|
+
- - "~>"
|
121
121
|
- !ruby/object:Gem::Version
|
122
|
-
version:
|
122
|
+
version: 0.9.28
|
123
123
|
- !ruby/object:Gem::Dependency
|
124
124
|
name: appraisal
|
125
125
|
requirement: !ruby/object:Gem::Requirement
|
126
126
|
requirements:
|
127
|
-
- - "
|
127
|
+
- - "~>"
|
128
128
|
- !ruby/object:Gem::Version
|
129
|
-
version: '
|
129
|
+
version: '2.4'
|
130
130
|
type: :development
|
131
131
|
prerelease: false
|
132
132
|
version_requirements: !ruby/object:Gem::Requirement
|
133
133
|
requirements:
|
134
|
-
- - "
|
134
|
+
- - "~>"
|
135
135
|
- !ruby/object:Gem::Version
|
136
|
-
version: '
|
137
|
-
|
136
|
+
version: '2.4'
|
137
|
+
- !ruby/object:Gem::Dependency
|
138
|
+
name: rspec
|
139
|
+
requirement: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - "~>"
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '3.11'
|
144
|
+
type: :development
|
145
|
+
prerelease: false
|
146
|
+
version_requirements: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - "~>"
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '3.11'
|
151
|
+
- !ruby/object:Gem::Dependency
|
152
|
+
name: database_cleaner
|
153
|
+
requirement: !ruby/object:Gem::Requirement
|
154
|
+
requirements:
|
155
|
+
- - "~>"
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '2.0'
|
158
|
+
type: :development
|
159
|
+
prerelease: false
|
160
|
+
version_requirements: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - "~>"
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '2.0'
|
165
|
+
description: Organize ActiveRecord model into a tree structure using PostgreSQL LTree
|
138
166
|
email:
|
139
167
|
- andrei.panamarenka@gmail.com
|
140
168
|
executables: []
|
@@ -144,16 +172,10 @@ files:
|
|
144
172
|
- MIT-LICENSE
|
145
173
|
- Rakefile
|
146
174
|
- lib/pg_ltree.rb
|
147
|
-
- lib/pg_ltree/
|
148
|
-
- lib/pg_ltree/
|
175
|
+
- lib/pg_ltree/base.rb
|
176
|
+
- lib/pg_ltree/callbacks.rb
|
177
|
+
- lib/pg_ltree/model.rb
|
149
178
|
- lib/pg_ltree/version.rb
|
150
|
-
- lib/pg_ltree/versions/rails_older_than_51.rb
|
151
|
-
- test/database.yml
|
152
|
-
- test/database.yml.sample
|
153
|
-
- test/pg_ltree/ltree_test.rb
|
154
|
-
- test/pg_ltree/scoped_for_test.rb
|
155
|
-
- test/pg_ltree_test.rb
|
156
|
-
- test/test_helper.rb
|
157
179
|
homepage: https://github.com/sjke/pg_ltree
|
158
180
|
licenses:
|
159
181
|
- MIT
|
@@ -176,11 +198,5 @@ requirements: []
|
|
176
198
|
rubygems_version: 3.1.6
|
177
199
|
signing_key:
|
178
200
|
specification_version: 4
|
179
|
-
summary:
|
180
|
-
test_files:
|
181
|
-
- test/database.yml.sample
|
182
|
-
- test/pg_ltree_test.rb
|
183
|
-
- test/database.yml
|
184
|
-
- test/pg_ltree/scoped_for_test.rb
|
185
|
-
- test/pg_ltree/ltree_test.rb
|
186
|
-
- test/test_helper.rb
|
201
|
+
summary: Organize ActiveRecord model into a tree structure using PostgreSQL LTree
|
202
|
+
test_files: []
|
data/lib/pg_ltree/scoped_for.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
module PgLtree
|
2
|
-
# Narrowing the Scope for ActiveRecord Model
|
3
|
-
# @note When model have composite uniq key (for example: state + path), you should use this module for narrowing the scope
|
4
|
-
module ScopedFor
|
5
|
-
# Define base instance scope for model by columns
|
6
|
-
#
|
7
|
-
# @param columns [Array] List of scoped fields
|
8
|
-
def ltree_scoped_for(columns = [])
|
9
|
-
cattr_accessor :ltree_scoped_for
|
10
|
-
|
11
|
-
self.ltree_scoped_for = Array.wrap(columns)
|
12
|
-
|
13
|
-
include InstanceMethods
|
14
|
-
end
|
15
|
-
|
16
|
-
# Define instance methods
|
17
|
-
module InstanceMethods
|
18
|
-
# Get default scope of ltree
|
19
|
-
#
|
20
|
-
# @return current class
|
21
|
-
def ltree_scope
|
22
|
-
self.class.where(*(ltree_scoped_for.map { |column| { column => public_send(column) } }))
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module PgLtree
|
2
|
-
module Versions
|
3
|
-
module RailsOlderThan51
|
4
|
-
def ltree(column = :path, options: { cascade: true })
|
5
|
-
super
|
6
|
-
include InstanceMethods
|
7
|
-
end
|
8
|
-
|
9
|
-
module InstanceMethods
|
10
|
-
# Get lTree previous value
|
11
|
-
#
|
12
|
-
# Related changes in > Rails 5.1.0
|
13
|
-
# https://github.com/rails/rails/pull/25337
|
14
|
-
#
|
15
|
-
# @return [String] Rails 5.1 replace attribute_was method with two methods, this is a wrapper for older rails
|
16
|
-
def ltree_path_before_last_save
|
17
|
-
public_send :attribute_was, ltree_path_column
|
18
|
-
end
|
19
|
-
|
20
|
-
#
|
21
|
-
# @return [String] Rails 5.1 replace attribute_was method with two methods, this is a wrapper for older rails
|
22
|
-
def ltree_path_in_database
|
23
|
-
public_send :attribute_was, ltree_path_column
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
data/test/database.yml
DELETED
data/test/database.yml.sample
DELETED
data/test/pg_ltree/ltree_test.rb
DELETED
@@ -1,249 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class PgLtree::LtreeTest < BaseTest
|
4
|
-
def setup
|
5
|
-
super
|
6
|
-
%w(
|
7
|
-
Top
|
8
|
-
Top.Science
|
9
|
-
Top.Science.Astronomy
|
10
|
-
Top.Science.Astronomy.Astrophysics
|
11
|
-
Top.Science.Astronomy.Cosmology
|
12
|
-
Top.Hobbies
|
13
|
-
Top.Hobbies.Amateurs_Astronomy
|
14
|
-
Top.Collections
|
15
|
-
Top.Collections.Pictures
|
16
|
-
Top.Collections.Pictures.Astronomy
|
17
|
-
Top.Collections.Pictures.Astronomy.Stars
|
18
|
-
Top.Collections.Pictures.Astronomy.Galaxies
|
19
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
20
|
-
Top.Collections.Videos
|
21
|
-
Top.Collections.Videos.Vacation
|
22
|
-
Top.Collections.Videos.NewYear
|
23
|
-
).each do |path|
|
24
|
-
TreeNode.create! path: path
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
test 'Default configuration' do
|
29
|
-
assert_equal TreeNode.ltree_path_column, :path
|
30
|
-
end
|
31
|
-
|
32
|
-
test 'Custom configuration' do
|
33
|
-
assert_equal NotUniqTreeNode.ltree_path_column, :new_path
|
34
|
-
end
|
35
|
-
|
36
|
-
test '#roots' do
|
37
|
-
assert_equal TreeNode.roots.pluck(:path), ['Top']
|
38
|
-
end
|
39
|
-
|
40
|
-
test '#at_depth' do
|
41
|
-
assert_equal TreeNode.at_depth(5).pluck(:path), %w(
|
42
|
-
Top.Collections.Pictures.Astronomy.Stars
|
43
|
-
Top.Collections.Pictures.Astronomy.Galaxies
|
44
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
45
|
-
)
|
46
|
-
end
|
47
|
-
|
48
|
-
test '#leaves' do
|
49
|
-
assert_equal TreeNode.leaves.pluck(:path), %w(
|
50
|
-
Top.Science.Astronomy.Astrophysics
|
51
|
-
Top.Science.Astronomy.Cosmology
|
52
|
-
Top.Hobbies.Amateurs_Astronomy
|
53
|
-
Top.Collections.Pictures.Astronomy.Stars
|
54
|
-
Top.Collections.Pictures.Astronomy.Galaxies
|
55
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
56
|
-
Top.Collections.Videos.Vacation
|
57
|
-
Top.Collections.Videos.NewYear
|
58
|
-
)
|
59
|
-
end
|
60
|
-
|
61
|
-
test '#leaves with a relation' do
|
62
|
-
assert_equal TreeNode.where("path <> 'Top.Collections.Pictures.Astronomy.Stars'").leaves.pluck(:path), %w(
|
63
|
-
Top.Science.Astronomy.Astrophysics
|
64
|
-
Top.Science.Astronomy.Cosmology
|
65
|
-
Top.Hobbies.Amateurs_Astronomy
|
66
|
-
Top.Collections.Pictures.Astronomy.Galaxies
|
67
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
68
|
-
Top.Collections.Videos.Vacation
|
69
|
-
Top.Collections.Videos.NewYear
|
70
|
-
)
|
71
|
-
end
|
72
|
-
|
73
|
-
test '#where_path_liked' do
|
74
|
-
assert_equal TreeNode.where_path_liked('*{2}.Astronomy|Pictures').pluck(:path), %w(
|
75
|
-
Top.Science.Astronomy
|
76
|
-
Top.Collections.Pictures
|
77
|
-
)
|
78
|
-
end
|
79
|
-
|
80
|
-
test '#where_path_matches_ltxtquery' do
|
81
|
-
assert_equal TreeNode.where_path_matches_ltxtquery('Astro*% & !pictures@').pluck(:path), %w(
|
82
|
-
Top.Science.Astronomy
|
83
|
-
Top.Science.Astronomy.Astrophysics
|
84
|
-
Top.Science.Astronomy.Cosmology
|
85
|
-
Top.Hobbies.Amateurs_Astronomy
|
86
|
-
)
|
87
|
-
end
|
88
|
-
|
89
|
-
test '.root?' do
|
90
|
-
assert TreeNode.find_by(path: 'Top').root?
|
91
|
-
assert_not TreeNode.find_by(path: 'Top.Science').root?
|
92
|
-
end
|
93
|
-
|
94
|
-
test '.height' do
|
95
|
-
assert_equal 4, TreeNode.find_by(path: 'Top').height
|
96
|
-
assert_equal 0, TreeNode.find_by(path: 'Top.Science.Astronomy.Astrophysics').height
|
97
|
-
end
|
98
|
-
|
99
|
-
test '.depth' do
|
100
|
-
assert_equal TreeNode.find_by(path: 'Top.Hobbies.Amateurs_Astronomy').depth, 3
|
101
|
-
end
|
102
|
-
|
103
|
-
test '.depth on new record' do
|
104
|
-
assert_equal TreeNode.new(path: 'Top.Hobbies.Amateurs_Astronomy').depth, 3
|
105
|
-
end
|
106
|
-
|
107
|
-
test '.depth on new record when database is empty' do
|
108
|
-
TreeNode.delete_all
|
109
|
-
assert_equal TreeNode.new(path: 'Top.Hobbies.Amateurs_Astronomy').depth, 3
|
110
|
-
end
|
111
|
-
|
112
|
-
test '.root' do
|
113
|
-
assert_equal TreeNode.find_by(path: 'Top.Hobbies.Amateurs_Astronomy').root.path, 'Top'
|
114
|
-
end
|
115
|
-
|
116
|
-
test '.parent' do
|
117
|
-
assert_equal TreeNode.find_by(path: 'Top.Collections.Pictures.Astronomy.Astronauts').parent.path,
|
118
|
-
'Top.Collections.Pictures.Astronomy'
|
119
|
-
end
|
120
|
-
|
121
|
-
test '.leaves' do
|
122
|
-
assert_equal TreeNode.find_by(path: 'Top.Science').leaves.pluck(:path), %w(
|
123
|
-
Top.Science.Astronomy.Astrophysics
|
124
|
-
Top.Science.Astronomy.Cosmology
|
125
|
-
)
|
126
|
-
end
|
127
|
-
|
128
|
-
test '.leaf?' do
|
129
|
-
assert_not TreeNode.find_by(path: 'Top').leaf?
|
130
|
-
assert TreeNode.find_by(path: 'Top.Collections.Pictures.Astronomy.Astronauts').leaf?
|
131
|
-
end
|
132
|
-
|
133
|
-
test '.self_and_ancestors' do
|
134
|
-
assert_equal TreeNode.find_by(path: 'Top.Collections.Pictures.Astronomy.Astronauts').self_and_ancestors.pluck(:path), %w(
|
135
|
-
Top
|
136
|
-
Top.Collections
|
137
|
-
Top.Collections.Pictures
|
138
|
-
Top.Collections.Pictures.Astronomy
|
139
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
140
|
-
)
|
141
|
-
end
|
142
|
-
|
143
|
-
test '.ancestors' do
|
144
|
-
assert_equal TreeNode.find_by(path: 'Top.Collections.Pictures.Astronomy.Astronauts').ancestors.pluck(:path), %w(
|
145
|
-
Top
|
146
|
-
Top.Collections
|
147
|
-
Top.Collections.Pictures
|
148
|
-
Top.Collections.Pictures.Astronomy
|
149
|
-
)
|
150
|
-
end
|
151
|
-
|
152
|
-
test '.self_and_descendants' do
|
153
|
-
assert_equal TreeNode.find_by(path: 'Top.Science').self_and_descendants.pluck(:path), %w(
|
154
|
-
Top.Science
|
155
|
-
Top.Science.Astronomy
|
156
|
-
Top.Science.Astronomy.Astrophysics
|
157
|
-
Top.Science.Astronomy.Cosmology
|
158
|
-
)
|
159
|
-
end
|
160
|
-
|
161
|
-
test '.descendants' do
|
162
|
-
assert_equal TreeNode.find_by(path: 'Top.Science').descendants.pluck(:path), %w(
|
163
|
-
Top.Science.Astronomy
|
164
|
-
Top.Science.Astronomy.Astrophysics
|
165
|
-
Top.Science.Astronomy.Cosmology
|
166
|
-
)
|
167
|
-
end
|
168
|
-
|
169
|
-
test '.self_and_siblings' do
|
170
|
-
assert_equal TreeNode.find_by(path: 'Top.Collections.Pictures.Astronomy.Stars').self_and_siblings.pluck(:path), %w(
|
171
|
-
Top.Collections.Pictures.Astronomy.Stars
|
172
|
-
Top.Collections.Pictures.Astronomy.Galaxies
|
173
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
174
|
-
)
|
175
|
-
end
|
176
|
-
|
177
|
-
test '.siblings' do
|
178
|
-
assert_equal TreeNode.find_by(path: 'Top.Collections.Pictures.Astronomy.Stars').siblings.pluck(:path), %w(
|
179
|
-
Top.Collections.Pictures.Astronomy.Galaxies
|
180
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
181
|
-
)
|
182
|
-
end
|
183
|
-
|
184
|
-
test '.children' do
|
185
|
-
assert_equal TreeNode.find_by(path: 'Top.Hobbies').children.pluck(:path), %w(
|
186
|
-
Top.Hobbies.Amateurs_Astronomy
|
187
|
-
)
|
188
|
-
end
|
189
|
-
|
190
|
-
test '.cascade_update' do
|
191
|
-
node = TreeNode.find_by(path: 'Top.Hobbies')
|
192
|
-
node.update path: 'Top.WoW'
|
193
|
-
|
194
|
-
assert_equal node.self_and_descendants.pluck(:path), %w(
|
195
|
-
Top.WoW
|
196
|
-
Top.WoW.Amateurs_Astronomy
|
197
|
-
)
|
198
|
-
end
|
199
|
-
|
200
|
-
test '.cascade_destroy' do
|
201
|
-
assert_equal TreeNode.where("path <@ 'Top.Collections'").pluck(:path), %w(
|
202
|
-
Top.Collections
|
203
|
-
Top.Collections.Pictures
|
204
|
-
Top.Collections.Pictures.Astronomy
|
205
|
-
Top.Collections.Pictures.Astronomy.Stars
|
206
|
-
Top.Collections.Pictures.Astronomy.Galaxies
|
207
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
208
|
-
Top.Collections.Videos
|
209
|
-
Top.Collections.Videos.Vacation
|
210
|
-
Top.Collections.Videos.NewYear
|
211
|
-
)
|
212
|
-
|
213
|
-
TreeNode.find_by(path: 'Top.Collections.Pictures').destroy
|
214
|
-
|
215
|
-
assert_equal TreeNode.where("path <@ 'Top.Collections'").pluck(:path), %w(
|
216
|
-
Top.Collections
|
217
|
-
Top.Collections.Videos
|
218
|
-
Top.Collections.Videos.Vacation
|
219
|
-
Top.Collections.Videos.NewYear
|
220
|
-
)
|
221
|
-
end
|
222
|
-
|
223
|
-
test '.destroy' do
|
224
|
-
assert_equal TreeWithoutCascadeNode.where("path <@ 'Top.Collections'").pluck(:path), %w(
|
225
|
-
Top.Collections
|
226
|
-
Top.Collections.Pictures
|
227
|
-
Top.Collections.Pictures.Astronomy
|
228
|
-
Top.Collections.Pictures.Astronomy.Stars
|
229
|
-
Top.Collections.Pictures.Astronomy.Galaxies
|
230
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
231
|
-
Top.Collections.Videos
|
232
|
-
Top.Collections.Videos.Vacation
|
233
|
-
Top.Collections.Videos.NewYear
|
234
|
-
)
|
235
|
-
|
236
|
-
TreeWithoutCascadeNode.find_by(path: 'Top.Collections.Pictures').destroy
|
237
|
-
|
238
|
-
assert_equal TreeWithoutCascadeNode.where("path <@ 'Top.Collections'").pluck(:path), %w(
|
239
|
-
Top.Collections
|
240
|
-
Top.Collections.Pictures.Astronomy
|
241
|
-
Top.Collections.Pictures.Astronomy.Stars
|
242
|
-
Top.Collections.Pictures.Astronomy.Galaxies
|
243
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
244
|
-
Top.Collections.Videos
|
245
|
-
Top.Collections.Videos.Vacation
|
246
|
-
Top.Collections.Videos.NewYear
|
247
|
-
)
|
248
|
-
end
|
249
|
-
end
|
@@ -1,190 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class PgLtree::ScopedForTest < BaseTest
|
4
|
-
def setup
|
5
|
-
super
|
6
|
-
%w(
|
7
|
-
Top
|
8
|
-
Top.Science
|
9
|
-
Top.Science.Astronomy
|
10
|
-
Top.Science.Astronomy.Astrophysics
|
11
|
-
Top.Science.Astronomy.Cosmology
|
12
|
-
Top.Hobbies
|
13
|
-
Top.Hobbies.Amateurs_Astronomy
|
14
|
-
Top.Collections
|
15
|
-
Top.Collections.Pictures
|
16
|
-
Top.Collections.Pictures.Astronomy
|
17
|
-
Top.Collections.Pictures.Astronomy.Stars
|
18
|
-
Top.Collections.Pictures.Astronomy.Galaxies
|
19
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
20
|
-
Top.Collections.Videos
|
21
|
-
Top.Collections.Videos.Vacation
|
22
|
-
Top.Collections.Videos.NewYear
|
23
|
-
).each do |path|
|
24
|
-
%i( active deactive ).each do |status|
|
25
|
-
NotUniqTreeNode.create! new_path: path, status: status
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
test '#roots' do
|
31
|
-
assert_equal NotUniqTreeNode.roots.pluck(:new_path), %w(Top Top)
|
32
|
-
end
|
33
|
-
|
34
|
-
test '#at_depth' do
|
35
|
-
assert_equal NotUniqTreeNode.at_depth(5).pluck(:new_path), %w(
|
36
|
-
Top.Collections.Pictures.Astronomy.Stars
|
37
|
-
Top.Collections.Pictures.Astronomy.Stars
|
38
|
-
Top.Collections.Pictures.Astronomy.Galaxies
|
39
|
-
Top.Collections.Pictures.Astronomy.Galaxies
|
40
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
41
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
42
|
-
)
|
43
|
-
end
|
44
|
-
|
45
|
-
test '#leaves' do
|
46
|
-
assert_equal NotUniqTreeNode.where(status: :active).leaves.pluck(:new_path), %w(
|
47
|
-
Top.Science.Astronomy.Astrophysics
|
48
|
-
Top.Science.Astronomy.Cosmology
|
49
|
-
Top.Hobbies.Amateurs_Astronomy
|
50
|
-
Top.Collections.Pictures.Astronomy.Stars
|
51
|
-
Top.Collections.Pictures.Astronomy.Galaxies
|
52
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
53
|
-
Top.Collections.Videos.Vacation
|
54
|
-
Top.Collections.Videos.NewYear
|
55
|
-
)
|
56
|
-
end
|
57
|
-
|
58
|
-
test '#where_path_liked' do
|
59
|
-
assert_equal NotUniqTreeNode.where_path_liked('*{2}.Astronomy|Pictures').pluck(:new_path), %w(
|
60
|
-
Top.Science.Astronomy
|
61
|
-
Top.Science.Astronomy
|
62
|
-
Top.Collections.Pictures
|
63
|
-
Top.Collections.Pictures
|
64
|
-
)
|
65
|
-
end
|
66
|
-
|
67
|
-
def not_uniq_tree_node_find_by_path(path)
|
68
|
-
NotUniqTreeNode.find_by(status: :active, new_path: path)
|
69
|
-
end
|
70
|
-
|
71
|
-
test '.root?' do
|
72
|
-
assert not_uniq_tree_node_find_by_path('Top').root?
|
73
|
-
assert_not not_uniq_tree_node_find_by_path('Top.Science').root?
|
74
|
-
end
|
75
|
-
|
76
|
-
test '.depth' do
|
77
|
-
assert_equal not_uniq_tree_node_find_by_path('Top.Hobbies.Amateurs_Astronomy').depth, 3
|
78
|
-
end
|
79
|
-
|
80
|
-
test '.root' do
|
81
|
-
assert_equal not_uniq_tree_node_find_by_path('Top.Hobbies.Amateurs_Astronomy').root.new_path, 'Top'
|
82
|
-
end
|
83
|
-
|
84
|
-
test '.parent' do
|
85
|
-
assert_equal not_uniq_tree_node_find_by_path('Top.Collections.Pictures.Astronomy.Astronauts').parent.new_path,
|
86
|
-
'Top.Collections.Pictures.Astronomy'
|
87
|
-
end
|
88
|
-
|
89
|
-
test '.leaves' do
|
90
|
-
assert_equal not_uniq_tree_node_find_by_path('Top.Science').leaves.pluck(:new_path), %w(
|
91
|
-
Top.Science.Astronomy.Astrophysics
|
92
|
-
Top.Science.Astronomy.Cosmology
|
93
|
-
)
|
94
|
-
end
|
95
|
-
|
96
|
-
test '.leaf?' do
|
97
|
-
assert_not not_uniq_tree_node_find_by_path('Top').leaf?
|
98
|
-
assert not_uniq_tree_node_find_by_path('Top.Collections.Pictures.Astronomy.Astronauts').leaf?
|
99
|
-
end
|
100
|
-
|
101
|
-
test '.self_and_ancestors' do
|
102
|
-
assert_equal not_uniq_tree_node_find_by_path('Top.Collections.Pictures.Astronomy.Astronauts').self_and_ancestors.pluck(:new_path), %w(
|
103
|
-
Top
|
104
|
-
Top.Collections
|
105
|
-
Top.Collections.Pictures
|
106
|
-
Top.Collections.Pictures.Astronomy
|
107
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
108
|
-
)
|
109
|
-
end
|
110
|
-
|
111
|
-
test '.ancestors' do
|
112
|
-
assert_equal not_uniq_tree_node_find_by_path('Top.Collections.Pictures.Astronomy.Astronauts').ancestors.pluck(:new_path), %w(
|
113
|
-
Top
|
114
|
-
Top.Collections
|
115
|
-
Top.Collections.Pictures
|
116
|
-
Top.Collections.Pictures.Astronomy
|
117
|
-
)
|
118
|
-
end
|
119
|
-
|
120
|
-
test '.self_and_descendants' do
|
121
|
-
assert_equal not_uniq_tree_node_find_by_path('Top.Science').self_and_descendants.pluck(:new_path), %w(
|
122
|
-
Top.Science
|
123
|
-
Top.Science.Astronomy
|
124
|
-
Top.Science.Astronomy.Astrophysics
|
125
|
-
Top.Science.Astronomy.Cosmology
|
126
|
-
)
|
127
|
-
end
|
128
|
-
|
129
|
-
test '.descendants' do
|
130
|
-
assert_equal not_uniq_tree_node_find_by_path('Top.Science').descendants.pluck(:new_path), %w(
|
131
|
-
Top.Science.Astronomy
|
132
|
-
Top.Science.Astronomy.Astrophysics
|
133
|
-
Top.Science.Astronomy.Cosmology
|
134
|
-
)
|
135
|
-
end
|
136
|
-
|
137
|
-
test '.self_and_siblings' do
|
138
|
-
assert_equal not_uniq_tree_node_find_by_path('Top.Collections.Pictures.Astronomy.Stars').self_and_siblings.pluck(:new_path), %w(
|
139
|
-
Top.Collections.Pictures.Astronomy.Stars
|
140
|
-
Top.Collections.Pictures.Astronomy.Galaxies
|
141
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
142
|
-
)
|
143
|
-
end
|
144
|
-
|
145
|
-
test '.siblings' do
|
146
|
-
assert_equal not_uniq_tree_node_find_by_path('Top.Collections.Pictures.Astronomy.Stars').siblings.pluck(:new_path), %w(
|
147
|
-
Top.Collections.Pictures.Astronomy.Galaxies
|
148
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
149
|
-
)
|
150
|
-
end
|
151
|
-
|
152
|
-
test '.children' do
|
153
|
-
assert_equal not_uniq_tree_node_find_by_path('Top.Hobbies').children.pluck(:new_path), %w(
|
154
|
-
Top.Hobbies.Amateurs_Astronomy
|
155
|
-
)
|
156
|
-
end
|
157
|
-
|
158
|
-
test '.cascade_update' do
|
159
|
-
node = NotUniqTreeNode.find_by(new_path: 'Top.Hobbies', status: :active)
|
160
|
-
node.update new_path: 'Top.WoW'
|
161
|
-
|
162
|
-
assert_equal node.self_and_descendants.pluck(:new_path), %w(
|
163
|
-
Top.WoW
|
164
|
-
Top.WoW.Amateurs_Astronomy
|
165
|
-
)
|
166
|
-
end
|
167
|
-
|
168
|
-
test '.cascade_destroy' do
|
169
|
-
assert_equal NotUniqTreeNode.where("new_path <@ 'Top.Collections'").where(status: :active).pluck(:new_path), %w(
|
170
|
-
Top.Collections
|
171
|
-
Top.Collections.Pictures
|
172
|
-
Top.Collections.Pictures.Astronomy
|
173
|
-
Top.Collections.Pictures.Astronomy.Stars
|
174
|
-
Top.Collections.Pictures.Astronomy.Galaxies
|
175
|
-
Top.Collections.Pictures.Astronomy.Astronauts
|
176
|
-
Top.Collections.Videos
|
177
|
-
Top.Collections.Videos.Vacation
|
178
|
-
Top.Collections.Videos.NewYear
|
179
|
-
)
|
180
|
-
|
181
|
-
NotUniqTreeNode.find_by(new_path: 'Top.Collections.Pictures', status: :active).destroy
|
182
|
-
|
183
|
-
assert_equal NotUniqTreeNode.where("new_path <@ 'Top.Collections'").where(status: :active).pluck(:new_path), %w(
|
184
|
-
Top.Collections
|
185
|
-
Top.Collections.Videos
|
186
|
-
Top.Collections.Videos.Vacation
|
187
|
-
Top.Collections.Videos.NewYear
|
188
|
-
)
|
189
|
-
end
|
190
|
-
end
|
data/test/pg_ltree_test.rb
DELETED
data/test/test_helper.rb
DELETED
@@ -1,85 +0,0 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
begin
|
3
|
-
Bundler.require(:default, :development)
|
4
|
-
rescue Bundler::BundlerError => e
|
5
|
-
$stderr.puts e.message
|
6
|
-
$stderr.puts 'Run `bundle install` to install missing gems'
|
7
|
-
exit e.status_code
|
8
|
-
end
|
9
|
-
|
10
|
-
$VERBOSE=nil
|
11
|
-
|
12
|
-
require 'pg'
|
13
|
-
require 'pg_ltree'
|
14
|
-
require 'minitest/autorun'
|
15
|
-
|
16
|
-
class BaseTest < ActiveSupport::TestCase
|
17
|
-
def setup
|
18
|
-
prepare_db
|
19
|
-
end
|
20
|
-
|
21
|
-
def teardown
|
22
|
-
drop_db
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def prepare_db
|
28
|
-
begin
|
29
|
-
db_connection = YAML.load_file(File.expand_path('../database.yml', __FILE__))
|
30
|
-
rescue => e
|
31
|
-
$stderr.puts e.message
|
32
|
-
$stderr.puts 'Copy `test/database.yml.sample` to `test/database.yml` and configure connection to DB'
|
33
|
-
exit 0
|
34
|
-
end
|
35
|
-
|
36
|
-
begin
|
37
|
-
PG.connect(host: db_connection["host"], user: db_connection["username"], password: db_connection["password"])
|
38
|
-
.exec("CREATE DATABASE #{db_connection['database']}")
|
39
|
-
rescue
|
40
|
-
# Ignore errors on DB:CEATE
|
41
|
-
end
|
42
|
-
|
43
|
-
ActiveRecord::Base.establish_connection db_connection
|
44
|
-
ActiveRecord::Schema.verbose = false
|
45
|
-
|
46
|
-
ActiveRecord::Schema.define(version: 1) do
|
47
|
-
enable_extension 'plpgsql'
|
48
|
-
enable_extension 'ltree'
|
49
|
-
|
50
|
-
create_table 'not_uniq_tree_nodes', force: :cascade do |t|
|
51
|
-
t.string 'status'
|
52
|
-
t.ltree 'new_path'
|
53
|
-
end
|
54
|
-
|
55
|
-
create_table 'tree_nodes', force: :cascade do |t|
|
56
|
-
t.ltree 'path'
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def drop_db
|
62
|
-
tables = if ActiveRecord::VERSION::MAJOR < 5
|
63
|
-
ActiveRecord::Base.connection.tables
|
64
|
-
else
|
65
|
-
ActiveRecord::Base.connection.data_sources
|
66
|
-
end
|
67
|
-
tables.each { |table| ActiveRecord::Base.connection.drop_table(table) }
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
class NotUniqTreeNode < ActiveRecord::Base
|
72
|
-
extend PgLtree::ScopedFor
|
73
|
-
|
74
|
-
ltree :new_path
|
75
|
-
ltree_scoped_for :status
|
76
|
-
end
|
77
|
-
|
78
|
-
class TreeNode < ActiveRecord::Base
|
79
|
-
ltree
|
80
|
-
end
|
81
|
-
|
82
|
-
class TreeWithoutCascadeNode < ActiveRecord::Base
|
83
|
-
self.table_name = 'tree_nodes'
|
84
|
-
ltree :path, cascade: false
|
85
|
-
end
|