active_tree 0.3 → 0.3.1
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/lib/active_tree/models/concerns/active_tree_able.rb +9 -51
- data/lib/active_tree/models/model.rb +2 -1
- data/lib/active_tree/store.rb +140 -0
- data/lib/active_tree/version.rb +1 -1
- data/lib/active_tree.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3e791b0f19ec736feb7d89abd9cf24081c7e4bcd862b08cea3f095432cbf9a9
|
4
|
+
data.tar.gz: e74e6e2fec69129d45f6b5c62332c42f3537039bc44dfc0dbf0d711a5eba5e00
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 102b71e83e19b2bcf330eef8d4fbc001cfec5015368301705c79611ef8ea5d19f2e00d8de6944398b7db83250e9a87a135cde71a8a9a87e05695b1c25e7d7938
|
7
|
+
data.tar.gz: fec20af4b4653f1526cdf321e826fb3a125840708f96205ba9ea2da2d5b0a0927d9fe2d7099096eff2b6ee24f497db6499bdd6cb970a8f0f4a0fbc996560c735
|
@@ -13,8 +13,13 @@ module ActiveTree
|
|
13
13
|
before_destroy :active_tree_delete_storage
|
14
14
|
|
15
15
|
# instance methods
|
16
|
+
def store
|
17
|
+
ActiveTree::Store.new id, ACTIVE_TREE_OPTIONS
|
18
|
+
end # store
|
19
|
+
|
16
20
|
def active_tree_role
|
17
|
-
"active_tree_owner_#{id}_#{ ACTIVE_TREE_OPTIONS[:owner_role_suffix] }"
|
21
|
+
#"active_tree_owner_#{id}_#{ ACTIVE_TREE_OPTIONS[:owner_role_suffix] }"
|
22
|
+
store.role_name
|
18
23
|
end # role
|
19
24
|
|
20
25
|
# Generates a JWT token the client (SPA) can pass to PostgREST for privilege escalation
|
@@ -24,64 +29,17 @@ module ActiveTree
|
|
24
29
|
end # .generate_jwt
|
25
30
|
|
26
31
|
|
27
|
-
#
|
28
|
-
def active_tree_table_name
|
29
|
-
ACTIVE_TREE_OPTIONS[:table_name]
|
30
|
-
end # .active_tree_table_name
|
31
|
-
|
32
|
-
|
33
|
-
# Creates LCA table partition and role for owner
|
32
|
+
# Creates table partition and role for owner
|
34
33
|
def active_tree_create_storage
|
35
|
-
|
36
|
-
# create data partition
|
37
|
-
active_tree_sql "create table if not exists #{active_tree_table_name}_#{id} partition of #{active_tree_table_name} for values in (#{id})"
|
38
|
-
# create partition indexes
|
39
|
-
active_tree_sql "create index index_#{id}_by_id on #{active_tree_table_name}_#{id} (id)"
|
40
|
-
active_tree_sql "create index index_#{id}_by_owner_id on #{active_tree_table_name}_#{id} (owner_id)"
|
41
|
-
active_tree_sql "create index index_#{id}_by_type on #{active_tree_table_name}_#{id} (type)"
|
42
|
-
active_tree_sql "create index index_#{id}_by_parent_entity_id on #{active_tree_table_name}_#{id} (parent_entity_id)"
|
43
|
-
active_tree_sql "create index index_#{id}_by_path on #{active_tree_table_name}_#{id} using gist (path)"
|
44
|
-
active_tree_sql "create index index_#{id}_by_data_provider_and_data_external_id on #{active_tree_table_name}_#{id} (data_provider, data_external_id)"
|
45
|
-
|
46
|
-
|
47
|
-
if ACTIVE_TREE_OPTIONS[:create_postgrest_roles]
|
48
|
-
# drop role if it exists
|
49
|
-
active_tree_sql "drop role if exists #{ active_tree_role }"
|
50
|
-
|
51
|
-
# create role
|
52
|
-
active_tree_sql "create role #{ active_tree_role }"
|
53
|
-
|
54
|
-
# grant privs
|
55
|
-
active_tree_sql "grant all privileges on #{active_tree_table_name}_#{id} to #{ active_tree_role }"
|
56
|
-
end
|
57
|
-
|
34
|
+
store.up!
|
58
35
|
end # create_storage
|
59
36
|
|
60
37
|
|
61
38
|
# Deletes or detaches the partition and removes the role for this owner
|
62
39
|
def active_tree_delete_storage
|
63
|
-
|
64
|
-
if ACTIVE_TREE_OPTIONS[:create_postgrest_roles]
|
65
|
-
# revoke privs
|
66
|
-
active_tree_sql "REVOKE ALL PRIVILEGES ON #{active_tree_table_name}_#{id} FROM #{ active_tree_role }"
|
67
|
-
|
68
|
-
# delete role
|
69
|
-
active_tree_sql "drop role #{ active_tree_role }"
|
70
|
-
end
|
71
|
-
|
72
|
-
if ACTIVE_TREE_OPTIONS[:destroy_partition_on_owner_destroy]
|
73
|
-
# delete partition
|
74
|
-
active_tree_sql "drop table if exists #{active_tree_table_name}_#{id}"
|
75
|
-
else
|
76
|
-
# detach and forget about it
|
77
|
-
active_tree_sql "alter table #{active_tree_table_name} detach partition #{ active_tree_role }"
|
78
|
-
end
|
40
|
+
store.down!
|
79
41
|
end # delete_storage
|
80
42
|
|
81
|
-
def active_tree_sql sql
|
82
|
-
ActiveRecord::Base.connection.execute sql
|
83
|
-
end # active_tree_sql
|
84
|
-
|
85
43
|
end # ClassMethods
|
86
44
|
end
|
87
45
|
end
|
@@ -37,7 +37,8 @@ class ActiveTree::Model < ActiveRecord::Base
|
|
37
37
|
|
38
38
|
partition_suffix = "_#{owner_id}"
|
39
39
|
|
40
|
-
table = "#{ self.table_name }#{ partition_suffix }"
|
40
|
+
#table = "#{ self.table_name }#{ partition_suffix }"
|
41
|
+
table = ActiveTree::Store.new(owner_id).partition_name
|
41
42
|
|
42
43
|
ApplicationRecord.connection.schema_cache.clear!
|
43
44
|
return self if !ApplicationRecord.connection.schema_cache.data_source_exists? table
|
@@ -0,0 +1,140 @@
|
|
1
|
+
class ActiveTree::Store
|
2
|
+
attr_accessor :options
|
3
|
+
attr_accessor :debug_sql
|
4
|
+
|
5
|
+
class StoreException < StandardError
|
6
|
+
def initialize(msg="This is a custom exception", exception_type="custom")
|
7
|
+
@exception_type = exception_type
|
8
|
+
super(msg)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(owner_id = nil, options = ACTIVE_TREE_OPTIONS)
|
13
|
+
raise StoreException.new("Unspecified owner_id, please pass an unique identifier for the partitions: ActiveTree::Store.new(your_owner_id)") if !owner_id
|
14
|
+
raise StoreException.new("owner_id must be an integer!") if !owner_id.is_a?(Integer)
|
15
|
+
@owner_id = owner_id
|
16
|
+
@options = options
|
17
|
+
@debug_sql = false
|
18
|
+
end
|
19
|
+
|
20
|
+
def up!
|
21
|
+
create_partition_for_owner # also adds indexes
|
22
|
+
setup_role if @options[:create_postgrest_roles] == true
|
23
|
+
end # up!
|
24
|
+
|
25
|
+
def down!
|
26
|
+
drop_role if @options[:create_postgrest_roles] == true
|
27
|
+
remove_partition
|
28
|
+
end # down!
|
29
|
+
|
30
|
+
def clear_schema_cache
|
31
|
+
ActiveRecord::Base.connection.schema_cache.clear!
|
32
|
+
end # clear_schema_cache
|
33
|
+
|
34
|
+
# partition management
|
35
|
+
|
36
|
+
def has_partition?
|
37
|
+
clear_schema_cache
|
38
|
+
ActiveRecord::Base.connection.schema_cache.data_source_exists? partition_name
|
39
|
+
end
|
40
|
+
|
41
|
+
def create_partition_for_owner(indexes = [ :id, :owner_id, :type, :parent_entity_id, :path, [:data_provider, :data_external_id ] ])
|
42
|
+
create_partition indexes
|
43
|
+
end
|
44
|
+
|
45
|
+
def create_partition(indexes = [])
|
46
|
+
return false if has_partition?
|
47
|
+
|
48
|
+
run "create table if not exists #{partition_name} partition of #{ @options[:table_name] } for values in ( #{@owner_id} )"
|
49
|
+
|
50
|
+
indexes.each do |index|
|
51
|
+
create_index(index) if !has_index?( index )
|
52
|
+
end if indexes.size > 0
|
53
|
+
end # create_partition
|
54
|
+
|
55
|
+
def partition_name
|
56
|
+
"#{@options[:table_name]}_#{@owner_id}"
|
57
|
+
end # partition_name
|
58
|
+
|
59
|
+
def should_drop_partition?
|
60
|
+
@options[:destroy_partition_on_owner_destroy] == true
|
61
|
+
end
|
62
|
+
|
63
|
+
def remove_partition
|
64
|
+
if should_drop_partition?
|
65
|
+
drop_partition
|
66
|
+
else
|
67
|
+
detach_partition
|
68
|
+
end
|
69
|
+
end # remove_partition
|
70
|
+
|
71
|
+
def detach_partition
|
72
|
+
return false if !has_partition?
|
73
|
+
run "alter table #{@options[:table_name]} detach partition #{partition_name}"
|
74
|
+
end # detach_partition
|
75
|
+
def drop_partition
|
76
|
+
return false if !has_partition?
|
77
|
+
run "drop table #{partition_name}"
|
78
|
+
end # drop partition
|
79
|
+
|
80
|
+
# index management
|
81
|
+
|
82
|
+
def partition_indexes
|
83
|
+
clear_schema_cache
|
84
|
+
ActiveRecord::Base.connection.indexes( partition_name ).map(&:name)
|
85
|
+
end
|
86
|
+
|
87
|
+
def has_index? name
|
88
|
+
partition_indexes.include?( index_name(name).truncate(63) )
|
89
|
+
end # has_index
|
90
|
+
def create_index index
|
91
|
+
return false if has_index? index
|
92
|
+
name = index_name index
|
93
|
+
using = name.include?("path") ? "using gist" : ""
|
94
|
+
|
95
|
+
cols = [index].flatten.join(",")
|
96
|
+
|
97
|
+
run "create index #{name} on #{partition_name} #{using} ( #{ cols } )"
|
98
|
+
end # create_index
|
99
|
+
def drop_index index
|
100
|
+
return false if !has_index? index
|
101
|
+
run "drop index if exists #{ index_name(index) }"
|
102
|
+
end # drop_index
|
103
|
+
|
104
|
+
def index_name identifier
|
105
|
+
i = [identifier].flatten.join("_")
|
106
|
+
"#{partition_name}_by_#{i}"
|
107
|
+
end
|
108
|
+
|
109
|
+
# TODO role management
|
110
|
+
|
111
|
+
def setup_role
|
112
|
+
drop_role
|
113
|
+
create_role
|
114
|
+
end # setup_role
|
115
|
+
|
116
|
+
def role_name
|
117
|
+
"active_tree_owner_#{@owner_id}_#{ @options[:owner_role_suffix] }"
|
118
|
+
end # role_name
|
119
|
+
|
120
|
+
def drop_role
|
121
|
+
run "drop role if exists #{role_name}"
|
122
|
+
end # drop role
|
123
|
+
|
124
|
+
def create_role
|
125
|
+
run "create role #{role_name}"
|
126
|
+
end # create role
|
127
|
+
|
128
|
+
def assign_to_partition
|
129
|
+
run "grant all privileges on #{partition_name} to #{ role_name }"
|
130
|
+
end
|
131
|
+
|
132
|
+
# running SQL
|
133
|
+
|
134
|
+
def run sql
|
135
|
+
puts sql if @debug_sql
|
136
|
+
ActiveRecord::Base.connection.execute sql
|
137
|
+
true
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
data/lib/active_tree/version.rb
CHANGED
data/lib/active_tree.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick @ Earthster
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-10-
|
11
|
+
date: 2021-10-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -77,6 +77,7 @@ files:
|
|
77
77
|
- lib/active_tree/models/model.rb
|
78
78
|
- lib/active_tree/queries/active_tree_query.rb
|
79
79
|
- lib/active_tree/queries/model_query.rb
|
80
|
+
- lib/active_tree/store.rb
|
80
81
|
- lib/active_tree/version.rb
|
81
82
|
- lib/generators/active_tree/install_generator.rb
|
82
83
|
- lib/generators/active_tree/templates/config.yml.tt
|