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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8712364c9596c4bf050aeac6f2c6471d180d9a4fccec891b4e1b65e3d80d6d9b
4
- data.tar.gz: 6b5fa6ac3a504c659a22da83717099976848d8e0499282daa6bf276b1b4766bb
3
+ metadata.gz: 1c36199deb17d6a32a617a2193c52ef0cb5e6b955464fb31b8509eb4aef0212d
4
+ data.tar.gz: 62286805f012a6db4bbc44de4a3ac9848f735d7d0e90d674f7605cbd48c590da
5
5
  SHA512:
6
- metadata.gz: 735b84529fa5855434e025cf1f22015af66f00d098284f9492b2b06529872478b478732f44b72442e4c30660b7b4a919a4bfe99cda357967a2d00af2fb915716
7
- data.tar.gz: ced8b499fe12b8451f0c8c1caf00aacb2cea83e2858279cf3c126e8241fbf3fc038d80f1256ad817762963ed6701c79bcfc2b5ff15c0abdeaf794ccbfeb35dbc
6
+ metadata.gz: a533be494b122a7b0e9bf2fcebd0083b314892cfe6da865faed721bd7cd5859820bc1eb969f098cfbb43ef4ec6d762521dbd9b911e57444fd286bdfa85540911
7
+ data.tar.gz: 45cd523f6e1430c3638ce7df73aabc87e09246a51d6b22591eea762c4d191fc7114c3f9a3f7d358dadf808c09844b8d5fa6a5f7480b45e61158f91796d1b8bf0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 1.4.6 (22 October 2024)
2
+
3
+ Features:
4
+
5
+ - Add option for child primary key.
6
+
1
7
  ## 1.4.5 (09 October 2024)
2
8
 
3
9
  Bugfixes:
data/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # Class Table Inheritance
2
2
 
3
3
  [![Build](https://github.com/tutuf/updateable_views_inheritance/actions/workflows/build.yml/badge.svg)](https://github.com/tutuf/updateable_views_inheritance/actions?query=workflow:build)
4
- [![Coverage](https://app.deepsource.com/gh/tutuf/updateable_views_inheritance.svg/?label=code+coverage&show_trend=true&token=AMfm8-_-qDZoknMh9-8IYp3R)](https://app.deepsource.com/gh/tutuf/updateable_views_inheritance/)
4
+ [![Codecov](https://codecov.io/gh/tutuf/updateable_views_inheritance/graph/badge.svg?token=L8P5LYNNU4)](https://codecov.io/gh/tutuf/updateable_views_inheritance)
5
+ [![DeepSource](https://app.deepsource.com/gh/tutuf/updateable_views_inheritance.svg/?label=active+issues&show_trend=true&token=AMfm8-_-qDZoknMh9-8IYp3R)](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
- # parent relation
10
+ # Parent relation
11
11
  # [:table]
12
- # default is <tt>"#{child_view}_data"</tt>
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
- # use together with :table option
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
- create_child_view(parent_relation, child_view, child_table)
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. If +relation+ is a table the result is its PK and sequence.
110
- # When it is a view, PK and sequence of the table at the root of the inheritance chain are returned.
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.nil? or result.empty?
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.
@@ -1,3 +1,3 @@
1
1
  module UpdateableViewsInheritance
2
- VERSION = "1.4.5"
2
+ VERSION = "1.4.6"
3
3
  end
@@ -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, :parent => :locomotives) do |t|
10
- t.decimal :water_consumption, :precision => 6, :scale => 2
11
- t.decimal :coal_consumption, :precision => 6, :scale => 2
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.5
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-09 00:00:00.000000000 Z
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.4.12
274
+ rubygems_version: 3.1.6
275
275
  signing_key:
276
276
  specification_version: 4
277
277
  summary: Class table inheritance for ActiveRecord