updateable_views_inheritance 1.2.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CHANGELOG.md +8 -2
- data/README.rdoc +10 -10
- data/lib/updateable_views_inheritance/postgresql_adapter.rb +21 -21
- data/lib/updateable_views_inheritance/version.rb +1 -1
- data/test/config/routes.rb +1 -1
- data/test/config/schema.rb +1 -1
- data/test/content_test.rb +6 -6
- data/test/deep_hierarchy_test.rb +9 -9
- data/test/install_generator_test.rb +1 -1
- data/test/schema_test.rb +43 -33
- data/test/single_table_inheritance.rb +17 -17
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MDFhNTFiOTNiNDBhYjg4MzY5NTBmMWQ1MjYyMWU1MGQyMTE0OTJmYw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
Y2I1NDc5YTAwNzVlMTdkODNjNjYwMmFlMjAxZDQ5MDk2ZDI4MWJkNg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YzMxMjM3Y2I5MGJmMzBiN2ZjNGNiMzllOGYwMjA2ZDg0MjFlM2YxYmEzMzc5
|
10
|
+
OTU5M2Y5ZmUxMDJhOTUxN2NjNTlhZWNjNjU4NWUzOGM0YzgxMDg5NDRjN2Zj
|
11
|
+
OGJjNjYzMzlmOTVlYjlmMTMwOTRiOTZmMTJkZmY1OWViODAzZTQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YmU5NzU4ODA5YjNiYmU3NjE1MzdjODc1NTllM2IyMDk5NDFhNDVlM2EwNDQz
|
14
|
+
ZTdmZGUzMDkxZGU1OTEwNWFiMGNjOTE1NGM1NDcwNGIyOTJlNGRjZGZkMzg4
|
15
|
+
ZmY1Njk1YmM4MDg1ODRiODNjOTY4NmJjZWZhMjVkMDdjODJiNGQ=
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## 1.2.1 (27 August 2014)
|
2
|
+
|
3
|
+
Bugfixes:
|
4
|
+
|
5
|
+
- parent relations can be in a schema
|
6
|
+
|
1
7
|
## 1.2.0 (27 August 2014)
|
2
8
|
|
3
9
|
Features:
|
@@ -9,7 +15,7 @@ Features:
|
|
9
15
|
Bugfixes:
|
10
16
|
|
11
17
|
- fixed generating migration on installation
|
12
|
-
|
18
|
+
|
13
19
|
Documentation:
|
14
20
|
|
15
21
|
- README brought up to date
|
@@ -29,6 +35,6 @@ Features:
|
|
29
35
|
## 1.0.0 (14 September 2009)
|
30
36
|
|
31
37
|
Features:
|
32
|
-
|
38
|
+
|
33
39
|
- class_table_inheritance plugin has behaved stably in production for a year
|
34
40
|
- supports rails 2.1, 2.2 and 2.3
|
data/README.rdoc
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
Class Table Inheritance for ActiveRecord using updateable views.
|
4
4
|
|
5
|
-
More about the pattern on http://www.martinfowler.com/eaaCatalog/classTableInheritance.html. This gem messes very little with Rails inheritance mechanism.
|
6
|
-
Instead it relies on updatable views in the database to represent classes in the inheritance chain. The approach was {first suggested by John
|
5
|
+
More about the pattern on http://www.martinfowler.com/eaaCatalog/classTableInheritance.html. This gem messes very little with Rails inheritance mechanism.
|
6
|
+
Instead it relies on updatable views in the database to represent classes in the inheritance chain. The approach was {first suggested by John
|
7
7
|
Wilger}[http://web.archive.org/web/20060408145717/johnwilger.com/articles/2005/09/29/class-table-inheritance-in-rails-with-postgresql].
|
8
8
|
|
9
9
|
|
@@ -46,17 +46,17 @@ after every change to the class hierarchy. Otherwise tests may fail.
|
|
46
46
|
t.column :max_speed, :integer
|
47
47
|
t.column :type, :string
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
create_child(:steam_locomotives, :parent => :locomotives) do |t|
|
51
51
|
t.decimal :water_consumption, :precision => 6, :scale => 2
|
52
52
|
t.decimal :coal_consumption, :precision => 6, :scale => 2
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
create_child(:electric_locomotives, :table => :raw_electric_locomotives, :parent => :locomotives) do |t|
|
56
56
|
t.decimal :electricity_consumption, :precision => 6, :scale => 2
|
57
57
|
end
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
def self.down
|
61
61
|
drop_child :steam_locomotives
|
62
62
|
drop_child :electric_locomotives
|
@@ -67,7 +67,7 @@ after every change to the class hierarchy. Otherwise tests may fail.
|
|
67
67
|
And the models:
|
68
68
|
class Locomotive
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
class SteamLocomotive < Locomotive
|
72
72
|
self.table_name = :steam_locomotives
|
73
73
|
end
|
@@ -87,7 +87,7 @@ Note that models of children classes must specify table name explicitly.
|
|
87
87
|
rename_column(:name, :title)
|
88
88
|
rebuild_parent_and_children_views(:locomotives)
|
89
89
|
end
|
90
|
-
end
|
90
|
+
end
|
91
91
|
|
92
92
|
===Renaming Underlying Tables
|
93
93
|
|
@@ -110,12 +110,12 @@ The approach of this gem is completely independent from Rails built-in Single Ta
|
|
110
110
|
If you use fixtures, you must run <tt>rake updateable_views_inheritance:fixture</tt> to generate fixture for the updateable_views_inheritance table after you add/remove
|
111
111
|
classes from the hierarchy or change underlying table or view names. <b>Without it primary key sequence for inheritors' tables won't be bumped to the max and it might not be possible to save objects!</b> If you don't use fixtures for the classes in the hierarchy you don't need to do that.
|
112
112
|
|
113
|
-
This gem re-enables referential integrity on fixture loading. This means that
|
113
|
+
This gem re-enables referential integrity on fixture loading. This means that
|
114
114
|
|
115
115
|
fixtures :all
|
116
|
-
|
116
|
+
|
117
117
|
may fail when there are foreign key constraints on tables. To fix this, explicitly declare fixture load order in <tt>test_helper.rb</tt>:
|
118
118
|
|
119
119
|
fixtures :roots, :trunks, :leafs, ...
|
120
|
-
|
120
|
+
|
121
121
|
for all fixtures you want to load.
|
@@ -2,7 +2,7 @@ module ActiveRecord #:nodoc:
|
|
2
2
|
module ConnectionAdapters #:nodoc:
|
3
3
|
class PostgreSQLAdapter
|
4
4
|
# Use this in migration to create child table and view.
|
5
|
-
# Options:
|
5
|
+
# Options:
|
6
6
|
# [:parent]
|
7
7
|
# parent relation
|
8
8
|
# [:child_table_name]
|
@@ -13,10 +13,10 @@ module ActiveRecord #:nodoc:
|
|
13
13
|
schema, unqualified_child_view_name = Utils.extract_schema_and_table(child_view)
|
14
14
|
|
15
15
|
parent_relation = options[:parent].to_s
|
16
|
-
if
|
17
|
-
parent_table = parent_relation
|
18
|
-
else # view, interpreted as inheritance chain deeper than two levels
|
16
|
+
if is_view?(parent_relation) # interpreted as inheritance chain deeper than two levels
|
19
17
|
parent_table = query("SELECT child_relation FROM updateable_views_inheritance WHERE child_aggregate_view = #{quote(parent_relation)}")[0][0]
|
18
|
+
else
|
19
|
+
parent_table = parent_relation
|
20
20
|
end
|
21
21
|
|
22
22
|
child_table = options[:table] || quote_table_name("#{child_view}_data")
|
@@ -29,10 +29,10 @@ module ActiveRecord #:nodoc:
|
|
29
29
|
execute "ALTER TABLE #{child_table} ADD PRIMARY KEY (#{child_table_pk})"
|
30
30
|
execute "ALTER TABLE #{child_table} ADD FOREIGN KEY (#{child_table_pk})
|
31
31
|
REFERENCES #{parent_table} ON DELETE CASCADE ON UPDATE CASCADE"
|
32
|
-
|
32
|
+
|
33
33
|
create_child_view(parent_relation, child_view, child_table)
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
# Drop child view and table
|
37
37
|
def drop_child(child_view)
|
38
38
|
drop_view(child_view)
|
@@ -40,7 +40,7 @@ module ActiveRecord #:nodoc:
|
|
40
40
|
drop_table(child_table)
|
41
41
|
execute "DELETE FROM updateable_views_inheritance WHERE child_aggregate_view = #{quote(child_view)}"
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
# Creates aggregate updateable view of parent and child relations. The convention for naming child tables is
|
45
45
|
# <tt>"#{child_view}_data"</tt>. If you don't follow it, supply +child_table_name+ as third argument.
|
46
46
|
def create_child_view(parent_table, child_view, child_table=nil)
|
@@ -200,7 +200,7 @@ module ActiveRecord #:nodoc:
|
|
200
200
|
c = columns_hash[col.name]
|
201
201
|
if(c && col.sql_type != c.sql_type)
|
202
202
|
conflict_column_names << col.name
|
203
|
-
else
|
203
|
+
else
|
204
204
|
columns_hash[col.name] = col
|
205
205
|
end
|
206
206
|
end
|
@@ -228,7 +228,7 @@ module ActiveRecord #:nodoc:
|
|
228
228
|
def supports_disable_referential_integrity?
|
229
229
|
false
|
230
230
|
end
|
231
|
-
|
231
|
+
|
232
232
|
def table_exists_with_updateable_views_inheritance_support?(name)
|
233
233
|
is_view?(name) ? true : table_exists_without_updateable_views_inheritance_support?(name)
|
234
234
|
end
|
@@ -247,12 +247,12 @@ module ActiveRecord #:nodoc:
|
|
247
247
|
end
|
248
248
|
@@klasses.uniq
|
249
249
|
end
|
250
|
-
|
250
|
+
|
251
251
|
# Returns the class object for +table_name+
|
252
252
|
def get_klass_for_table(table_name)
|
253
253
|
klass_for_tables()[table_name.to_s]
|
254
254
|
end
|
255
|
-
|
255
|
+
|
256
256
|
# Returns hash with tables and thier corresponding class.
|
257
257
|
# {table_name1 => ClassName1, ...}
|
258
258
|
def klass_for_tables
|
@@ -263,7 +263,7 @@ module ActiveRecord #:nodoc:
|
|
263
263
|
end
|
264
264
|
@@tables_klasses
|
265
265
|
end
|
266
|
-
|
266
|
+
|
267
267
|
# Returns filenames for models in the current Rails application
|
268
268
|
def model_filenames
|
269
269
|
Dir.chdir("#{Rails.root}/app/models"){ Dir["**/*.rb"] }
|
@@ -296,7 +296,7 @@ module ActiveRecord #:nodoc:
|
|
296
296
|
CREATE OR REPLACE RULE #{quote_column_name("#{child_view}_insert")} AS
|
297
297
|
ON INSERT TO #{child_view} DO INSTEAD (
|
298
298
|
SELECT setval('#{parent_pk_seq}', NEW.#{parent_pk});
|
299
|
-
INSERT INTO #{parent_table}
|
299
|
+
INSERT INTO #{parent_table}
|
300
300
|
( #{ [parent_pk, parent_columns].flatten.join(", ") } )
|
301
301
|
VALUES( currval('#{parent_pk_seq}') #{ parent_columns.empty? ? '' : ',' + parent_columns.collect{ |col| "NEW." + col}.join(",") } )
|
302
302
|
#{insert_returning_clause(child_view, parent_columns.unshift(parent_pk)) if supports_insert_with_returning?};
|
@@ -320,7 +320,7 @@ module ActiveRecord #:nodoc:
|
|
320
320
|
#{ parent_columns.empty? ? '':
|
321
321
|
"UPDATE #{parent_table}
|
322
322
|
SET #{ parent_columns.collect{ |col| col + "= NEW." +col }.join(", ") }
|
323
|
-
WHERE #{parent_pk} = OLD.#{parent_pk};"}
|
323
|
+
WHERE #{parent_pk} = OLD.#{parent_pk};"}
|
324
324
|
#{ child_columns.empty? ? '':
|
325
325
|
"UPDATE #{child_table}
|
326
326
|
SET #{ child_columns.collect{ |col| col + " = NEW." +col }.join(", ") }
|
@@ -329,7 +329,7 @@ module ActiveRecord #:nodoc:
|
|
329
329
|
)
|
330
330
|
end_sql
|
331
331
|
end
|
332
|
-
|
332
|
+
|
333
333
|
def insert_returning_clause(child_view,parent_columns)
|
334
334
|
"RETURNING "+
|
335
335
|
columns(child_view).map do |c|
|
@@ -340,7 +340,7 @@ module ActiveRecord #:nodoc:
|
|
340
340
|
end
|
341
341
|
end.join(",")
|
342
342
|
end
|
343
|
-
|
343
|
+
|
344
344
|
# Set default values from the table columns for a view
|
345
345
|
def set_defaults(view_name, table_name)
|
346
346
|
column_definitions(table_name).each do |column_name, type, default, notnull|
|
@@ -376,9 +376,9 @@ module ActiveRecord #:nodoc:
|
|
376
376
|
res[0] if res
|
377
377
|
end
|
378
378
|
end
|
379
|
-
|
379
|
+
|
380
380
|
# Single Table Inheritance Aggregate View
|
381
|
-
|
381
|
+
|
382
382
|
# Nested list for the +parent_relation+ inheritance hierarchy
|
383
383
|
# Every descendant relation is presented as an array with relation's name as first element
|
384
384
|
# and the other elements are the relation's children presented in the same way as lists.
|
@@ -398,7 +398,7 @@ module ActiveRecord #:nodoc:
|
|
398
398
|
end
|
399
399
|
hierarchy
|
400
400
|
end
|
401
|
-
|
401
|
+
|
402
402
|
def get_leaves_relations(hierarchy)
|
403
403
|
return [] if hierarchy.nil? || hierarchy.empty?
|
404
404
|
head, hierarchy = hierarchy.first, hierarchy[1..(hierarchy.size)]
|
@@ -410,10 +410,10 @@ module ActiveRecord #:nodoc:
|
|
410
410
|
return get_leaves_relations(hierarchy).compact
|
411
411
|
end
|
412
412
|
end
|
413
|
-
|
413
|
+
|
414
414
|
def generate_single_table_inheritanche_union_clause(rel, column_names, conflict_column_names, columns_hash, quoted_inheritance_column)
|
415
415
|
relation_columns = columns(rel).collect{|c| c.name}
|
416
|
-
columns_select = column_names.inject([]) do |arr, col_name|
|
416
|
+
columns_select = column_names.inject([]) do |arr, col_name|
|
417
417
|
sql_type = conflict_column_names.include?(col_name) ? 'text' : columns_hash[col_name].sql_type
|
418
418
|
value = "NULL::#{sql_type}"
|
419
419
|
if(relation_columns.include?(col_name))
|
data/test/config/routes.rb
CHANGED
data/test/config/schema.rb
CHANGED
data/test/content_test.rb
CHANGED
@@ -11,11 +11,11 @@ class UpdateableViewsInheritanceContentTest < ActiveSupport::TestCase
|
|
11
11
|
def teardown
|
12
12
|
ActiveRecord::Fixtures.reset_cache
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def test_find
|
16
16
|
locomotive = Locomotive.find(1)
|
17
17
|
assert locomotive.kind_of?(SteamLocomotive)
|
18
|
-
assert_equal %w(coal_consumption id max_speed name type water_consumption),
|
18
|
+
assert_equal %w(coal_consumption id max_speed name type water_consumption),
|
19
19
|
locomotive.attributes.keys.sort, "Could not instantiate properly child"
|
20
20
|
end
|
21
21
|
|
@@ -24,7 +24,7 @@ class UpdateableViewsInheritanceContentTest < ActiveSupport::TestCase
|
|
24
24
|
assert !res.rows.empty?
|
25
25
|
assert_equal 3, res.rows.first.first.to_i
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def test_save_new
|
29
29
|
electric_locomotive = ElectricLocomotive.new(:name=> 'BoBo', :max_speed => 40, :electricity_consumption => 12)
|
30
30
|
assert electric_locomotive.save, "Couldn't save new"
|
@@ -37,14 +37,14 @@ class UpdateableViewsInheritanceContentTest < ActiveSupport::TestCase
|
|
37
37
|
mogul = Locomotive.find(steam_locomotive.id)
|
38
38
|
assert mogul.kind_of?(SteamLocomotive)
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
def test_update
|
42
42
|
steam_locomotive = Locomotive.find(1)
|
43
43
|
steam_locomotive.update_attributes( :name => 'Rocket')
|
44
44
|
steam_locomotive.reload
|
45
45
|
assert_equal 'Rocket', steam_locomotive.name
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def test_delete_from_parent_relation
|
49
49
|
num_locomotives = Locomotive.count
|
50
50
|
num_steam_locomotives = SteamLocomotive.count
|
@@ -52,7 +52,7 @@ class UpdateableViewsInheritanceContentTest < ActiveSupport::TestCase
|
|
52
52
|
assert_equal num_locomotives - 1, Locomotive.count
|
53
53
|
assert_equal num_steam_locomotives - 1, SteamLocomotive.count
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
def test_delete_from_child_relation
|
57
57
|
num_locomotives = Locomotive.count
|
58
58
|
num_steam_locomotives = SteamLocomotive.count
|
data/test/deep_hierarchy_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
2
|
|
3
|
-
class DeepHierarchyTest < ActiveSupport::TestCase
|
3
|
+
class DeepHierarchyTest < ActiveSupport::TestCase
|
4
4
|
def setup
|
5
5
|
ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 8)
|
6
6
|
# order of fixtures is important for the test - last loaded should not be with max(id)
|
@@ -9,27 +9,27 @@ class DeepHierarchyTest < ActiveSupport::TestCase
|
|
9
9
|
end
|
10
10
|
@connection = ActiveRecord::Base.connection
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def teardown
|
14
14
|
ActiveRecord::Fixtures.reset_cache
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
def test_deeper_hierarchy
|
18
18
|
assert_equal [["boats"], ["railed_vehicles", ["trains", ["electric_trains", ["maglev_trains"]], ["rack_trains"], ["steam_trains"]]], ["wheeled_vehicles", ["bicycles"], ["cars"]]].sort,
|
19
19
|
@connection.send(:get_view_hierarchy_for, :vehicles).sort
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def test_leaves_relations
|
23
23
|
hierarchy = @connection.send(:get_view_hierarchy_for, :vehicles)
|
24
24
|
assert_equal %w(boats bicycles cars maglev_trains rack_trains steam_trains).sort,
|
25
25
|
@connection.send(:get_leaves_relations, hierarchy).sort
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def test_view_columns
|
29
29
|
assert_equal %w(id vehicle_type name number_of_wheels number_of_doors number_of_gears number_of_rails mast_number max_speed water_consumption coal_consumption electricity_consumption bidirectional narrow_gauge magnetic_field rail_system).sort,
|
30
30
|
@connection.columns(:all_vehicles).collect{|c| c.name}.sort
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
def test_single_table_inheritance_deeper_hierarchy_records_number
|
34
34
|
assert_equal Vehicle.count, @connection.select_value("SELECT count(*) FROM all_vehicles").to_i
|
35
35
|
assert_equal SteamTrain.count, @connection.select_value("SELECT count(*) FROM all_vehicles WHERE vehicle_type='SteamTrain'").to_i
|
@@ -40,18 +40,18 @@ class DeepHierarchyTest < ActiveSupport::TestCase
|
|
40
40
|
assert_equal Bicycle.count, @connection.select_value("SELECT count(*) FROM all_vehicles WHERE vehicle_type='Bicycle'").to_i
|
41
41
|
assert_equal Boat.count, @connection.select_value("SELECT count(*) FROM all_vehicles WHERE vehicle_type='Boat'").to_i
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
def test_single_table_inheritance_deeper_hierarchy_contents
|
45
45
|
mag = MaglevTrain.find(:first)
|
46
46
|
assert_equal [mag.id.to_s, mag.name, mag.number_of_rails.to_s, mag.max_speed.to_s, mag.magnetic_field.to_s, (sprintf("%.2f",mag.electricity_consumption))], (@connection.query("SELECT id, name, number_of_rails, max_speed, magnetic_field, electricity_consumption FROM all_vehicles WHERE id=#{mag.id}").first)
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
class OrderColumnsInAggregateView < ActiveRecord::Migration
|
50
50
|
def self.up
|
51
51
|
rebuild_single_table_inheritance_view(:all_vehicles,:vehicles, %w(max_speed number_of_wheels id))
|
52
52
|
end
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
def test_single_table_inheritance_view_order_view_columns
|
56
56
|
OrderColumnsInAggregateView.up
|
57
57
|
assert_equal %w(max_speed number_of_wheels id),
|
@@ -5,7 +5,7 @@ class InstallGeneratorTest < Rails::Generators::TestCase
|
|
5
5
|
destination File.join(Rails.root, "tmp")
|
6
6
|
setup :prepare_destination
|
7
7
|
tests UpdateableViewsInheritance::Generators::InstallGenerator
|
8
|
-
|
8
|
+
|
9
9
|
test "create migration" do
|
10
10
|
run_generator
|
11
11
|
assert_migration 'db/migrate/create_updateable_views_inheritance.rb'
|
data/test/schema_test.rb
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
2
|
|
3
|
-
class UpdateableViewsInheritanceSchemaTest < ActiveSupport::TestCase
|
3
|
+
class UpdateableViewsInheritanceSchemaTest < ActiveSupport::TestCase
|
4
4
|
def setup
|
5
5
|
ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 5)
|
6
6
|
@connection = ActiveRecord::Base.connection
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
def test_pk_and_sequence_for
|
10
10
|
assert_equal ['id', 'public.locomotives_id_seq'], @connection.pk_and_sequence_for(:maglev_locomotives), "Could not get pk and sequence for child aggregate view"
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def test_primary_key
|
14
14
|
assert_equal 'id', @connection.primary_key(:maglev_locomotives), "Wrong or no primary key for child aggregate view"
|
15
15
|
end
|
16
|
-
|
17
|
-
|
16
|
+
|
17
|
+
|
18
18
|
def test_content_columns
|
19
19
|
assert !SteamLocomotive.content_columns.include?("id")
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def test_views
|
23
|
-
assert_equal ["electric_locomotives", "maglev_locomotives", "rack_locomotives", "steam_locomotives"],
|
23
|
+
assert_equal ["electric_locomotives", "maglev_locomotives", "rack_locomotives", "steam_locomotives"],
|
24
24
|
@connection.views.sort
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
class ParentTableWithOnlyOneColumn < ActiveRecord::Migration
|
28
28
|
def self.up
|
29
29
|
create_table(:parent_pk_only){}
|
@@ -33,13 +33,13 @@ class UpdateableViewsInheritanceSchemaTest < ActiveSupport::TestCase
|
|
33
33
|
create_child_view :parent_pk_only, :child
|
34
34
|
end
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def test_parent_table_with_only_one_column
|
38
38
|
ParentTableWithOnlyOneColumn.up
|
39
39
|
assert @connection.views.include?('child')
|
40
40
|
assert_equal %w(id name), @connection.columns(:child).map{|c| c.name}.sort
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
class ChildTableWithOnlyOneColumn < ActiveRecord::Migration
|
44
44
|
def self.up
|
45
45
|
create_table :parent do |t|
|
@@ -49,22 +49,22 @@ class UpdateableViewsInheritanceSchemaTest < ActiveSupport::TestCase
|
|
49
49
|
create_child_view :parent, :child_pk_only
|
50
50
|
end
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
def test_child_table_with_only_one_column
|
54
54
|
ChildTableWithOnlyOneColumn.up
|
55
55
|
assert @connection.views.include?('child_pk_only'), "Could not create child view when child table has only one column"
|
56
56
|
assert_equal %w(id name), @connection.columns(:child_pk_only).map{|c| c.name}.sort
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
def test_serial_pk_has_default_in_view
|
60
60
|
assert_equal %q|nextval('locomotives_id_seq'::regclass)|,
|
61
61
|
@connection.query(<<-end_sql, 'Serial PK has default in view')[0][0]
|
62
62
|
SELECT pg_catalog.pg_get_expr(d.adbin, d.adrelid) as constraint
|
63
63
|
FROM pg_catalog.pg_attrdef d, pg_catalog.pg_attribute a, pg_catalog.pg_class c
|
64
|
-
WHERE d.adrelid = a.attrelid
|
65
|
-
AND d.adnum = a.attnum
|
66
|
-
AND a.atthasdef
|
67
|
-
AND c.relname = 'maglev_locomotives'
|
64
|
+
WHERE d.adrelid = a.attrelid
|
65
|
+
AND d.adnum = a.attnum
|
66
|
+
AND a.atthasdef
|
67
|
+
AND c.relname = 'maglev_locomotives'
|
68
68
|
AND a.attrelid = c.oid
|
69
69
|
AND a.attname = 'id'
|
70
70
|
AND a.attnum > 0 AND NOT a.attisdropped
|
@@ -75,12 +75,12 @@ class UpdateableViewsInheritanceSchemaTest < ActiveSupport::TestCase
|
|
75
75
|
RackLocomotive.reset_column_information
|
76
76
|
assert_equal 'Abt', RackLocomotive.new.rail_system
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
def test_default_value_boolean_of_view_column
|
80
80
|
assert !RackLocomotive.new.bidirectional
|
81
81
|
assert RackLocomotive.new.narrow_gauge
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
class ChangeDefaultValueOfColumn < ActiveRecord::Migration
|
85
85
|
def self.up
|
86
86
|
remove_parent_and_children_views(:rack_locomotives)
|
@@ -88,24 +88,24 @@ class UpdateableViewsInheritanceSchemaTest < ActiveSupport::TestCase
|
|
88
88
|
rebuild_parent_and_children_views(:rack_locomotives)
|
89
89
|
end
|
90
90
|
end
|
91
|
-
|
91
|
+
|
92
92
|
def test_change_default_value_of_column
|
93
93
|
ChangeDefaultValueOfColumn.up
|
94
94
|
RackLocomotive.reset_column_information
|
95
95
|
assert_equal 'Marsh', RackLocomotive.new.rail_system
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
class RemoveChildrenViews < ActiveRecord::Migration
|
99
99
|
def self.up
|
100
100
|
remove_parent_and_children_views(:locomotives)
|
101
101
|
end
|
102
102
|
end
|
103
|
-
|
103
|
+
|
104
104
|
def test_remove_parent_and_children_views
|
105
105
|
RemoveChildrenViews.up
|
106
106
|
assert @connection.views.empty?
|
107
107
|
end
|
108
|
-
|
108
|
+
|
109
109
|
class RemoveColumnInParentTable < ActiveRecord::Migration
|
110
110
|
def self.up
|
111
111
|
remove_parent_and_children_views(:locomotives)
|
@@ -113,7 +113,7 @@ class UpdateableViewsInheritanceSchemaTest < ActiveSupport::TestCase
|
|
113
113
|
rebuild_parent_and_children_views(:locomotives)
|
114
114
|
end
|
115
115
|
end
|
116
|
-
|
116
|
+
|
117
117
|
def test_remove_column_parent_table
|
118
118
|
RemoveColumnInParentTable.up
|
119
119
|
assert_equal %w(coal_consumption id name type water_consumption),
|
@@ -121,7 +121,7 @@ class UpdateableViewsInheritanceSchemaTest < ActiveSupport::TestCase
|
|
121
121
|
assert_equal %w(electricity_consumption id magnetic_field name type),
|
122
122
|
@connection.columns(:maglev_locomotives).map{ |c| c.name }.sort
|
123
123
|
end
|
124
|
-
|
124
|
+
|
125
125
|
class RenameColumnInParentTable < ActiveRecord::Migration
|
126
126
|
def self.up
|
127
127
|
ActiveRecord::Fixtures.create_fixtures(File.dirname(__FILE__) + '/fixtures/', :electric_locomotives)
|
@@ -140,25 +140,25 @@ class UpdateableViewsInheritanceSchemaTest < ActiveSupport::TestCase
|
|
140
140
|
@connection.columns(:steam_locomotives).map{ |c| c.name }.sort
|
141
141
|
assert_equal %w(electricity_consumption id magnetic_field maximal_speed name type),
|
142
142
|
@connection.columns(:maglev_locomotives).map{ |c| c.name }.sort
|
143
|
-
|
143
|
+
|
144
144
|
end
|
145
|
-
|
145
|
+
|
146
146
|
class AddColumnToParentTable < ActiveRecord::Migration
|
147
147
|
def self.up
|
148
148
|
add_column(:raw_electric_locomotives, :number_of_engines, :integer)
|
149
149
|
rebuild_parent_and_children_views(:electric_locomotives)
|
150
150
|
end
|
151
151
|
end
|
152
|
-
|
152
|
+
|
153
153
|
def test_add_column_to_parent_table
|
154
154
|
AddColumnToParentTable.up
|
155
155
|
assert_equal %w(electricity_consumption id max_speed name number_of_engines type),
|
156
156
|
@connection.columns(:electric_locomotives).map{ |c| c.name }.sort
|
157
157
|
assert_equal %w(electricity_consumption id magnetic_field max_speed name number_of_engines type),
|
158
158
|
@connection.columns(:maglev_locomotives).map{ |c| c.name }.sort
|
159
|
-
|
159
|
+
|
160
160
|
end
|
161
|
-
|
161
|
+
|
162
162
|
class ChangeChildRelationView < ActiveRecord::Migration
|
163
163
|
def self.up
|
164
164
|
remove_parent_and_children_views(:electric_locomotives)
|
@@ -166,13 +166,13 @@ class UpdateableViewsInheritanceSchemaTest < ActiveSupport::TestCase
|
|
166
166
|
rebuild_parent_and_children_views(:electric_locomotives)
|
167
167
|
end
|
168
168
|
end
|
169
|
-
|
169
|
+
|
170
170
|
def test_change_child_relation_view
|
171
171
|
ChangeChildRelationView.up
|
172
172
|
assert_equal %w(electric_consumption id max_speed name type),
|
173
173
|
@connection.columns(:electric_locomotives).map{ |c| c.name }.sort
|
174
174
|
end
|
175
|
-
|
175
|
+
|
176
176
|
def test_table_exists
|
177
177
|
#TODO: test table_exists? monkey patch
|
178
178
|
end
|
@@ -180,7 +180,12 @@ class UpdateableViewsInheritanceSchemaTest < ActiveSupport::TestCase
|
|
180
180
|
class CreateChildInSchema < ActiveRecord::Migration
|
181
181
|
def self.up
|
182
182
|
execute "CREATE SCHEMA interrail"
|
183
|
-
|
183
|
+
create_table 'interrail.locomotives' do |t|
|
184
|
+
t.column :interrail_name, :string
|
185
|
+
t.column :interrail_max_speed, :integer
|
186
|
+
t.column :type, :string
|
187
|
+
end
|
188
|
+
create_child('interrail.steam_locomotives', :parent => 'interrail.locomotives') do |t|
|
184
189
|
t.decimal :interrail_water_consumption, :precision => 6, :scale => 2
|
185
190
|
t.decimal :interrail_coal_consumption, :precision => 6, :scale => 2
|
186
191
|
end
|
@@ -189,7 +194,12 @@ class UpdateableViewsInheritanceSchemaTest < ActiveSupport::TestCase
|
|
189
194
|
|
190
195
|
def test_create_child_in_schema
|
191
196
|
CreateChildInSchema.up
|
192
|
-
assert_equal %w(id
|
197
|
+
assert_equal %w(id
|
198
|
+
interrail_coal_consumption
|
199
|
+
interrail_max_speed
|
200
|
+
interrail_name
|
201
|
+
interrail_water_consumption
|
202
|
+
type),
|
193
203
|
@connection.columns('interrail.steam_locomotives').map{ |c| c.name }.sort
|
194
204
|
end
|
195
205
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
2
|
|
3
|
-
class SingleTableInheritanceAggregateViewTest < ActiveSupport::TestCase
|
3
|
+
class SingleTableInheritanceAggregateViewTest < ActiveSupport::TestCase
|
4
4
|
def setup
|
5
5
|
ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 6)
|
6
6
|
# order of fixtures is important for the test - last loaded should not be with max(id)
|
@@ -9,13 +9,13 @@ class SingleTableInheritanceAggregateViewTest < ActiveSupport::TestCase
|
|
9
9
|
end
|
10
10
|
@connection = ActiveRecord::Base.connection
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def test_single_table_inheritance_view_schema
|
14
14
|
@connection = ActiveRecord::Base.connection
|
15
15
|
assert_equal %w(coal_consumption id max_speed name type water_consumption electricity_consumption bidirectional narrow_gauge magnetic_field rail_system).sort,
|
16
16
|
@connection.columns(:all_locomotives).map{ |c| c.name }.sort
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
def test_single_table_inheritance_records_number
|
20
20
|
assert_equal Locomotive.count, @connection.query("SELECT count(*) FROM all_locomotives").first.first.to_i
|
21
21
|
assert_equal SteamLocomotive.count, @connection.query("SELECT count(*) FROM all_locomotives WHERE type='SteamLocomotive'").first.first.to_i
|
@@ -23,13 +23,13 @@ class SingleTableInheritanceAggregateViewTest < ActiveSupport::TestCase
|
|
23
23
|
assert_equal RackLocomotive.count, @connection.query("SELECT count(*) FROM all_locomotives WHERE type='RackLocomotive'").first.first.to_i
|
24
24
|
assert_equal MaglevLocomotive.count, @connection.query("SELECT count(*) FROM all_locomotives WHERE type='MaglevLocomotive'").first.first.to_i
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
def test_single_table_inheritance_save
|
28
28
|
electric_locomotive = ElectricLocomotive.new(:name=> 'BoBo', :max_speed => 40, :electricity_consumption => 12)
|
29
29
|
assert electric_locomotive.save
|
30
30
|
assert_equal electric_locomotive.name, @connection.query("SELECT name FROm all_locomotives WHERE id=#{electric_locomotive.id}").first.first
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
class AddColumnToParentTable < ActiveRecord::Migration
|
34
34
|
def self.up
|
35
35
|
add_column(:raw_electric_locomotives, :number_of_engines, :integer)
|
@@ -38,13 +38,13 @@ class SingleTableInheritanceAggregateViewTest < ActiveSupport::TestCase
|
|
38
38
|
create_single_table_inheritance_view(:all_locomotives, :locomotives)
|
39
39
|
end
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
def test_single_table_inheritance_view_add_column_to_parent_table
|
43
43
|
AddColumnToParentTable.up
|
44
44
|
assert_equal %w(coal_consumption id max_speed name type water_consumption electricity_consumption bidirectional narrow_gauge magnetic_field rail_system number_of_engines).sort,
|
45
45
|
@connection.columns(:all_locomotives).map{ |c| c.name }.sort
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
class RemoveColumnInParentTable < ActiveRecord::Migration
|
49
49
|
def self.up
|
50
50
|
drop_view(:all_locomotives)
|
@@ -54,20 +54,20 @@ class SingleTableInheritanceAggregateViewTest < ActiveSupport::TestCase
|
|
54
54
|
create_single_table_inheritance_view(:all_locomotives,:locomotives)
|
55
55
|
end
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
def test_single_table_inheritance_view_remove_column_parent_table
|
59
59
|
RemoveColumnInParentTable.up
|
60
60
|
assert_equal %w(coal_consumption id name type water_consumption electricity_consumption bidirectional narrow_gauge magnetic_field rail_system).sort,
|
61
61
|
@connection.columns(:all_locomotives).map{ |c| c.name }.sort
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
class RenameColumnInParentTable < ActiveRecord::Migration
|
65
65
|
def self.up
|
66
66
|
drop_view(:all_locomotives)
|
67
67
|
remove_parent_and_children_views(:locomotives)
|
68
68
|
rename_column(:locomotives, :max_speed, :maximal_speed)
|
69
69
|
rebuild_parent_and_children_views(:locomotives)
|
70
|
-
create_single_table_inheritance_view(:all_locomotives, :locomotives)
|
70
|
+
create_single_table_inheritance_view(:all_locomotives, :locomotives)
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
@@ -76,7 +76,7 @@ class SingleTableInheritanceAggregateViewTest < ActiveSupport::TestCase
|
|
76
76
|
assert_equal %w(coal_consumption id maximal_speed name type water_consumption electricity_consumption bidirectional narrow_gauge magnetic_field rail_system).sort,
|
77
77
|
@connection.columns(:all_locomotives).map{ |c| c.name }.sort
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
class ChangeChildRelationView < ActiveRecord::Migration
|
81
81
|
def self.up
|
82
82
|
drop_view(:all_locomotives)
|
@@ -86,13 +86,13 @@ class SingleTableInheritanceAggregateViewTest < ActiveSupport::TestCase
|
|
86
86
|
create_single_table_inheritance_view(:all_locomotives, :locomotives)
|
87
87
|
end
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
def test_single_table_inheritance_view_change_child_relation_view
|
91
91
|
ChangeChildRelationView.up
|
92
92
|
assert_equal %w(coal_consumption id max_speed name type water_consumption electric_consumption bidirectional narrow_gauge magnetic_field rail_system).sort,
|
93
93
|
@connection.columns(:all_locomotives).map{ |c| c.name }.sort
|
94
94
|
end
|
95
|
-
|
95
|
+
|
96
96
|
class ConflictColumns < ActiveRecord::Migration
|
97
97
|
def self.up
|
98
98
|
drop_view(:all_locomotives)
|
@@ -103,14 +103,14 @@ class SingleTableInheritanceAggregateViewTest < ActiveSupport::TestCase
|
|
103
103
|
create_single_table_inheritance_view(:all_locomotives, :locomotives)
|
104
104
|
end
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
107
|
def test_single_table_inheritance_view_conflict_columns
|
108
108
|
ConflictColumns.up
|
109
109
|
assert_equal %w(coal_consumption id max_speed name type water_consumption electricity_consumption bidirectional narrow_gauge magnetic_field rail_system number_of_engines).sort,
|
110
110
|
@connection.columns(:all_locomotives).map{ |c| c.name }.sort
|
111
111
|
assert_equal 'text', @connection.columns(:all_locomotives).detect{|c| c.name == "number_of_engines"}.sql_type
|
112
112
|
end
|
113
|
-
|
113
|
+
|
114
114
|
class ConflictColumnsWithValues < ActiveRecord::Migration
|
115
115
|
def self.up
|
116
116
|
add_column(:raw_electric_locomotives, :number_of_engines, :integer)
|
@@ -123,7 +123,7 @@ class SingleTableInheritanceAggregateViewTest < ActiveSupport::TestCase
|
|
123
123
|
create_single_table_inheritance_view(:all_locomotives, :locomotives)
|
124
124
|
end
|
125
125
|
end
|
126
|
-
|
126
|
+
|
127
127
|
def test_single_table_inheritance_view_conflict_columns_with_values
|
128
128
|
ConflictColumnsWithValues.up
|
129
129
|
assert_equal %w(coal_consumption id max_speed name type water_consumption electricity_consumption bidirectional narrow_gauge magnetic_field rail_system number_of_engines).sort,
|
@@ -132,7 +132,7 @@ class SingleTableInheritanceAggregateViewTest < ActiveSupport::TestCase
|
|
132
132
|
assert_equal 'one', @connection.query("SELECT number_of_engines FROM all_locomotives WHERE id=#{SteamLocomotive.find(:first).id}").first.first
|
133
133
|
assert_equal '2', @connection.query("SELECT number_of_engines FROM all_locomotives WHERE id=#{ElectricLocomotive.find(:first).id}").first.first
|
134
134
|
end
|
135
|
-
|
135
|
+
|
136
136
|
def test_respond_to_missing_attributes
|
137
137
|
Locomotive.table_name = :all_locomotives
|
138
138
|
assert !MaglevLocomotive.new.respond_to?(:non_existing_attribute_in_the_hierarchy), "Active Record is gone haywire - responds to attributes that are never defined"
|