updateable_views_inheritance 1.4.5 → 1.4.6

Sign up to get free protection for your applications and to get access to all the features.
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