updateable_views_inheritance 1.4.5 → 1.4.6
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/CHANGELOG.md +6 -0
- data/README.md +27 -1
- data/lib/updateable_views_inheritance/postgresql_adapter.rb +20 -13
- data/lib/updateable_views_inheritance/version.rb +1 -1
- data/test/fixtures/migrations/2_create_with_default_table.rb +6 -6
- data/test/schema_test.rb +31 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c36199deb17d6a32a617a2193c52ef0cb5e6b955464fb31b8509eb4aef0212d
|
4
|
+
data.tar.gz: 62286805f012a6db4bbc44de4a3ac9848f735d7d0e90d674f7605cbd48c590da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a533be494b122a7b0e9bf2fcebd0083b314892cfe6da865faed721bd7cd5859820bc1eb969f098cfbb43ef4ec6d762521dbd9b911e57444fd286bdfa85540911
|
7
|
+
data.tar.gz: 45cd523f6e1430c3638ce7df73aabc87e09246a51d6b22591eea762c4d191fc7114c3f9a3f7d358dadf808c09844b8d5fa6a5f7480b45e61158f91796d1b8bf0
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# Class Table Inheritance
|
2
2
|
|
3
3
|
[](https://github.com/tutuf/updateable_views_inheritance/actions?query=workflow:build)
|
4
|
-
[](https://codecov.io/gh/tutuf/updateable_views_inheritance)
|
5
|
+
[](https://app.deepsource.com/gh/tutuf/updateable_views_inheritance/)
|
5
6
|
|
6
7
|
Class Table Inheritance for ActiveRecord using updateable views
|
7
8
|
|
@@ -138,6 +139,31 @@ end
|
|
138
139
|
```
|
139
140
|
Useful when converting legacy DB schema to use inheritance.
|
140
141
|
|
142
|
+
### Using view as a child table
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
execute <<-SQL.squish
|
146
|
+
CREATE VIEW punk_locomotives_data AS (
|
147
|
+
SELECT steam_locomotives.id,
|
148
|
+
steam_locomotives.coal_consumption AS coal,
|
149
|
+
NULL AS electro
|
150
|
+
FROM steam_locomotives
|
151
|
+
UNION ALL
|
152
|
+
SELECT electric_locomotives.id,
|
153
|
+
NULL AS coal,
|
154
|
+
electric_locomotives.electricity_consumption AS electro
|
155
|
+
FROM electric_locomotives)
|
156
|
+
SQL
|
157
|
+
create_child(:punk_locomotives,
|
158
|
+
{ parent: :locomotives,
|
159
|
+
child_table: :punk_locomotives_data,
|
160
|
+
child_table_pk: :id,
|
161
|
+
skip_creating_child_table: true })
|
162
|
+
```
|
163
|
+
Views in PostgreSQL cannot have primary keys, so you have to manually specify it
|
164
|
+
when you use. Note that views also cannot have `NOT NULL` constraints, although
|
165
|
+
the `NOT NULL` constraint of the underlying table will still be enforced.
|
166
|
+
|
141
167
|
## Compatibility with Single Table Inheritance
|
142
168
|
|
143
169
|
The approach of this gem is completely independent from Rails built-in Single
|
@@ -7,11 +7,16 @@ module ActiveRecord #:nodoc:
|
|
7
7
|
# Use this in migration to create child table and view.
|
8
8
|
# Options:
|
9
9
|
# [:parent]
|
10
|
-
#
|
10
|
+
# Parent relation
|
11
11
|
# [:table]
|
12
|
-
#
|
12
|
+
# Deprecated. Use :child_table instead
|
13
|
+
# [:child_table]
|
14
|
+
# Default is <tt>"#{child_view}_data"</tt>
|
15
|
+
# [:child_table_pk]
|
16
|
+
# Handy when :child_table is a view and PK cannot be inferred
|
17
|
+
# from the database.
|
13
18
|
# [:skip_creating_child_table]
|
14
|
-
#
|
19
|
+
# When given, :child_table option also must be specified
|
15
20
|
def create_child(child_view, options)
|
16
21
|
raise 'Please call me with a parent, for example: create_child(:steam_locomotives, :parent => :locomotives)' unless options[:parent]
|
17
22
|
|
@@ -26,7 +31,7 @@ module ActiveRecord #:nodoc:
|
|
26
31
|
parent_relation
|
27
32
|
end
|
28
33
|
|
29
|
-
child_table = options[:table] || quote_table_name("#{child_view}_data")
|
34
|
+
child_table = options[:child_table] || options[:table] || quote_table_name("#{child_view}_data")
|
30
35
|
|
31
36
|
unless options.key?(:skip_creating_child_table)
|
32
37
|
unqualified_child_view_name = Utils.extract_schema_qualified_name(child_view).identifier
|
@@ -41,7 +46,9 @@ module ActiveRecord #:nodoc:
|
|
41
46
|
REFERENCES #{parent_table} ON DELETE CASCADE ON UPDATE CASCADE"
|
42
47
|
end
|
43
48
|
|
44
|
-
|
49
|
+
child_table_pk ||= options[:child_table_pk].to_s if options[:child_table_pk]
|
50
|
+
|
51
|
+
create_child_view(parent_relation, child_view, child_table, child_table_pk)
|
45
52
|
end
|
46
53
|
|
47
54
|
# Drop child view and table
|
@@ -54,7 +61,7 @@ module ActiveRecord #:nodoc:
|
|
54
61
|
|
55
62
|
# Creates aggregate updateable view of parent and child relations. The convention for naming child tables is
|
56
63
|
# <tt>"#{child_view}_data"</tt>. If you don't follow it, supply +child_table_name+ as third argument.
|
57
|
-
def create_child_view(parent_table, child_view, child_table=nil)
|
64
|
+
def create_child_view(parent_table, child_view, child_table=nil, child_table_pk=nil)
|
58
65
|
child_table ||= child_view.to_s + "_data"
|
59
66
|
|
60
67
|
parent_columns = columns(parent_table)
|
@@ -63,7 +70,7 @@ module ActiveRecord #:nodoc:
|
|
63
70
|
child_column_names = child_columns.collect{|c| c.name}
|
64
71
|
parent_column_names = parent_columns.collect{|c| c.name}
|
65
72
|
|
66
|
-
child_pk = pk_and_sequence_for(child_table)[0]
|
73
|
+
child_pk = child_table_pk || pk_and_sequence_for(child_table)[0]
|
67
74
|
child_column_names.delete(child_pk)
|
68
75
|
|
69
76
|
parent_pk, parent_pk_seq = pk_and_sequence_for(parent_table)
|
@@ -106,10 +113,12 @@ module ActiveRecord #:nodoc:
|
|
106
113
|
res && res.first
|
107
114
|
end
|
108
115
|
|
109
|
-
# Returns a relation's primary key and belonging sequence.
|
110
|
-
#
|
116
|
+
# Returns a relation's primary key and belonging sequence.
|
117
|
+
# If +relation+ is a table the result is its PK and sequence.
|
118
|
+
# When it is a view, PK and sequence of the table at the root
|
119
|
+
# of the inheritance chain are returned.
|
111
120
|
def pk_and_sequence_for(relation)
|
112
|
-
result = query(<<-SQL, 'PK')[0]
|
121
|
+
result = query(<<-SQL.squish, 'PK')[0]
|
113
122
|
SELECT attr.attname
|
114
123
|
FROM pg_attribute attr,
|
115
124
|
pg_constraint cons
|
@@ -118,15 +127,13 @@ module ActiveRecord #:nodoc:
|
|
118
127
|
AND cons.contype = 'p'
|
119
128
|
AND attr.attnum = ANY(cons.conkey)
|
120
129
|
SQL
|
121
|
-
if result.
|
130
|
+
if result.blank? #result.empty?
|
122
131
|
parent = parent_table(relation)
|
123
132
|
pk_and_sequence_for(parent) if parent
|
124
133
|
else
|
125
134
|
# log(result[0], "PK for #{relation}") {}
|
126
135
|
[result[0], query("SELECT pg_get_serial_sequence('#{relation}', '#{result[0]}') ")[0][0]]
|
127
136
|
end
|
128
|
-
rescue
|
129
|
-
nil
|
130
137
|
end
|
131
138
|
|
132
139
|
# Drops a view from the database.
|
@@ -5,15 +5,15 @@ class CreateWithDefaultTable < ActiveRecord::Migration
|
|
5
5
|
t.column :max_speed, :integer
|
6
6
|
t.column :type, :string
|
7
7
|
end
|
8
|
-
|
9
|
-
create_child(:steam_locomotives, :
|
10
|
-
t.decimal :water_consumption, :
|
11
|
-
t.decimal :coal_consumption, :
|
8
|
+
|
9
|
+
create_child(:steam_locomotives, parent: :locomotives) do |t|
|
10
|
+
t.decimal :water_consumption, precision: 6, scale: 2, null: false
|
11
|
+
t.decimal :coal_consumption, precision: 6, scale: 2, null: false
|
12
12
|
end
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def self.down
|
16
16
|
drop_child :steam_locomotives
|
17
17
|
drop_table :locomotives
|
18
18
|
end
|
19
|
-
end
|
19
|
+
end
|
data/test/schema_test.rb
CHANGED
@@ -80,6 +80,10 @@ class UpdateableViewsInheritanceSchemaTest < ActiveSupport::TestCase
|
|
80
80
|
assert RackLocomotive.new.narrow_gauge
|
81
81
|
end
|
82
82
|
|
83
|
+
def test_does_not_preserve_not_null_on_views
|
84
|
+
assert SteamLocomotive.columns.find { |c| c.name == 'water_consumption' }.null
|
85
|
+
end
|
86
|
+
|
83
87
|
class ChangeDefaultValueOfColumn < ActiveRecord::Migration
|
84
88
|
def self.up
|
85
89
|
remove_parent_and_children_views(:rack_locomotives)
|
@@ -251,4 +255,31 @@ class UpdateableViewsInheritanceSchemaTest < ActiveSupport::TestCase
|
|
251
255
|
ReservedSQLWords.up
|
252
256
|
assert @connection.columns(:table).map(&:name).include?("column")
|
253
257
|
end
|
258
|
+
|
259
|
+
class ChildTableIsActuallyView < ActiveRecord::Migration
|
260
|
+
def self.up
|
261
|
+
execute <<-SQL.squish
|
262
|
+
CREATE VIEW punk_locomotives_data AS (
|
263
|
+
SELECT steam_locomotives.id,
|
264
|
+
steam_locomotives.coal_consumption AS coal,
|
265
|
+
NULL AS electro
|
266
|
+
FROM steam_locomotives
|
267
|
+
UNION ALL
|
268
|
+
SELECT electric_locomotives.id,
|
269
|
+
NULL AS coal,
|
270
|
+
electric_locomotives.electricity_consumption AS electro
|
271
|
+
FROM electric_locomotives)
|
272
|
+
SQL
|
273
|
+
create_child(:punk_locomotives,
|
274
|
+
{ parent: :locomotives,
|
275
|
+
child_table: :punk_locomotives_data,
|
276
|
+
child_table_pk: :id,
|
277
|
+
skip_creating_child_table: true })
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
def test_child_table_is_view
|
282
|
+
ChildTableIsActuallyView.up
|
283
|
+
assert @connection.columns(:punk_locomotives).map(&:name).sort == %w(coal electro id max_speed name type)
|
284
|
+
end
|
254
285
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: updateable_views_inheritance
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sava Chankov
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-10-
|
12
|
+
date: 2024-10-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -271,7 +271,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
271
271
|
- !ruby/object:Gem::Version
|
272
272
|
version: '0'
|
273
273
|
requirements: []
|
274
|
-
rubygems_version: 3.
|
274
|
+
rubygems_version: 3.1.6
|
275
275
|
signing_key:
|
276
276
|
specification_version: 4
|
277
277
|
summary: Class table inheritance for ActiveRecord
|