updateable_views_inheritance 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +110 -0
- data/Rakefile +35 -0
- data/doc/template/horo.rb +613 -0
- data/lib/generators/updateable_views_inheritance_migration/USAGE +8 -0
- data/lib/generators/updateable_views_inheritance_migration/templates/migration.rb +17 -0
- data/lib/generators/updateable_views_inheritance_migration/uvi_migration_generator.rb +12 -0
- data/lib/updateable_views_inheritance.rb +5 -0
- data/lib/updateable_views_inheritance/active_record.rb +16 -0
- data/lib/updateable_views_inheritance/postgresql_adapter.rb +450 -0
- data/lib/updateable_views_inheritance/version.rb +3 -0
- data/tasks/updateable_views_inheritance_tasks.rake +19 -0
- data/test/app/models/bicycle.rb +3 -0
- data/test/app/models/boat.rb +3 -0
- data/test/app/models/car.rb +3 -0
- data/test/app/models/electric_locomotive.rb +3 -0
- data/test/app/models/electric_train.rb +3 -0
- data/test/app/models/locomotive.rb +3 -0
- data/test/app/models/maglev_locomotive.rb +3 -0
- data/test/app/models/maglev_train.rb +3 -0
- data/test/app/models/rack_locomotive.rb +3 -0
- data/test/app/models/rack_train.rb +3 -0
- data/test/app/models/railed_vehicle.rb +3 -0
- data/test/app/models/steam_locomotive.rb +3 -0
- data/test/app/models/steam_train.rb +3 -0
- data/test/app/models/train.rb +3 -0
- data/test/app/models/vehicle.rb +3 -0
- data/test/app/models/wheeled_vehicle.rb +3 -0
- data/test/config/database.yml +19 -0
- data/test/config/environment.rb +14 -0
- data/test/config/routes.rb +3 -0
- data/test/config/schema.rb +3 -0
- data/test/content_test.rb +66 -0
- data/test/database.yml +7 -0
- data/test/deep_hierarchy_test.rb +64 -0
- data/test/fixtures/bicycles.yml +6 -0
- data/test/fixtures/boats.yml +6 -0
- data/test/fixtures/cars.yml +12 -0
- data/test/fixtures/electric_locomotives.yml +6 -0
- data/test/fixtures/electric_trains.yml +7 -0
- data/test/fixtures/maglev_locomotives.yml +7 -0
- data/test/fixtures/maglev_trains.yml +8 -0
- data/test/fixtures/migrations/1_add_class_table_inheritance.rb +15 -0
- data/test/fixtures/migrations/2_create_with_default_table.rb +19 -0
- data/test/fixtures/migrations/3_create_with_explicit_table.rb +11 -0
- data/test/fixtures/migrations/4_create_deeper_hierarchy.rb +11 -0
- data/test/fixtures/migrations/5_default_column_values.rb +13 -0
- data/test/fixtures/migrations/6_single_table_inheritance_view.rb +10 -0
- data/test/fixtures/migrations/7_second_deep_hierarchy.rb +70 -0
- data/test/fixtures/migrations/8_second_single_table_inheritance_view.rb +10 -0
- data/test/fixtures/rack_trains.yml +7 -0
- data/test/fixtures/steam_locomotives.yml +7 -0
- data/test/fixtures/steam_trains.yml +8 -0
- data/test/migration_test.rb +30 -0
- data/test/schema_test.rb +179 -0
- data/test/single_table_inheritance.rb +141 -0
- data/test/test_helper.rb +80 -0
- data/updateable_views_inheritance.gemspec +26 -0
- metadata +219 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
namespace :updateable_views_inheritance do
|
2
|
+
desc 'Generate fixture for updateable_views_inheritance table in test/fixtures'
|
3
|
+
task :fixture => :environment do
|
4
|
+
table_name = 'updateable_views_inheritance'
|
5
|
+
f = File.new(File.expand_path("test/fixtures/#{table_name}.yml", Rails.root), "w+")
|
6
|
+
f.puts(ActiveRecord::Base.connection.select_all("SELECT * FROM #{table_name}").inject({}) { |hsh, record|
|
7
|
+
hsh.merge({record['child_aggregate_view'] => record})
|
8
|
+
}.to_yaml)
|
9
|
+
f.close
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'Generate migration to create special table for the updateable_views_inheritance gem'
|
13
|
+
task :setup => :environment do
|
14
|
+
raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations?
|
15
|
+
require 'rails_generator'
|
16
|
+
require 'rails_generator/scripts/generate'
|
17
|
+
Rails::Generator::Scripts::Generate.new.run(["updateable_views_inheritance_migration", ENV["MIGRATION"] || "AddUpdatebleViewsInheritance"])
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
test:
|
2
|
+
adapter: sqlite3
|
3
|
+
dbfile: test.sqlite3.db
|
4
|
+
|
5
|
+
# adapter: sqlite
|
6
|
+
# dbfile: test.sqlite.db
|
7
|
+
|
8
|
+
# adapter: mysql
|
9
|
+
# host: localhost
|
10
|
+
# username:
|
11
|
+
# password:
|
12
|
+
# database: test
|
13
|
+
|
14
|
+
# adapter: postgresql
|
15
|
+
# host: localhost
|
16
|
+
# username:
|
17
|
+
# password:
|
18
|
+
# database: test
|
19
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
Rails::Initializer.run do |config|
|
3
|
+
|
4
|
+
config.cache_classes = true
|
5
|
+
|
6
|
+
config.whiny_nils = true
|
7
|
+
|
8
|
+
config.action_controller.consider_all_requests_local = true
|
9
|
+
config.action_controller.perform_caching = false
|
10
|
+
|
11
|
+
config.action_mailer.delivery_method = :test
|
12
|
+
config.action_mailer.perform_deliveries = true
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class ClassTableInheritanceContentTest < ActiveSupport::TestCase
|
4
|
+
def setup
|
5
|
+
ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 5)
|
6
|
+
# order of fixtures is important for the test - last loaded should not be with max(id)
|
7
|
+
ActiveRecord::Fixtures.create_fixtures(File.dirname(__FILE__) + '/fixtures/', :electric_locomotives)
|
8
|
+
ActiveRecord::Fixtures.create_fixtures(File.dirname(__FILE__) + '/fixtures/', :steam_locomotives)
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
ActiveRecord::Fixtures.reset_cache
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_find
|
16
|
+
locomotive = Locomotive.find(1)
|
17
|
+
assert locomotive.kind_of?(SteamLocomotive)
|
18
|
+
assert_equal %w(coal_consumption id max_speed name type water_consumption),
|
19
|
+
locomotive.attributes.keys.sort, "Could not instantiate properly child"
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_exec_query
|
23
|
+
res = ActiveRecord::Base.connection.exec_query(%q{INSERT INTO electric_locomotives (electricity_consumption, max_speed, name, type) VALUES (40, 120, 'test', 'ElectricLocomotive') RETURNING id})
|
24
|
+
assert !res.rows.empty?
|
25
|
+
assert_equal 3, res.rows.first.first.to_i
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_save_new
|
29
|
+
electric_locomotive = ElectricLocomotive.new(:name=> 'BoBo', :max_speed => 40, :electricity_consumption => 12)
|
30
|
+
assert electric_locomotive.save, "Couldn't save new"
|
31
|
+
assert electric_locomotive.id, "No id of saved object"
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_reset_sequence_after_loading_fixture
|
35
|
+
steam_locomotive = SteamLocomotive.new(:name => 'Mogul', :max_speed => 120, :water_consumption => 12.3, :coal_consumption => 54.6)
|
36
|
+
assert steam_locomotive.save
|
37
|
+
mogul = Locomotive.find(steam_locomotive.id)
|
38
|
+
assert mogul.kind_of?(SteamLocomotive)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_update
|
42
|
+
steam_locomotive = Locomotive.find(1)
|
43
|
+
steam_locomotive.update_attributes( :name => 'Rocket')
|
44
|
+
steam_locomotive.reload
|
45
|
+
assert_equal 'Rocket', steam_locomotive.name
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_delete_from_parent_relation
|
49
|
+
num_locomotives = Locomotive.count
|
50
|
+
num_steam_locomotives = SteamLocomotive.count
|
51
|
+
Locomotive.find(1).destroy
|
52
|
+
assert_equal num_locomotives - 1, Locomotive.count
|
53
|
+
assert_equal num_steam_locomotives - 1, SteamLocomotive.count
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_delete_from_child_relation
|
57
|
+
num_locomotives = Locomotive.count
|
58
|
+
num_steam_locomotives = SteamLocomotive.count
|
59
|
+
SteamLocomotive.find(1).destroy
|
60
|
+
assert_equal num_locomotives - 1, Locomotive.count
|
61
|
+
assert_equal num_steam_locomotives - 1, SteamLocomotive.count
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
end
|
data/test/database.yml
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class DeepHierarchyTest < ActiveSupport::TestCase
|
4
|
+
def setup
|
5
|
+
ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 8)
|
6
|
+
# order of fixtures is important for the test - last loaded should not be with max(id)
|
7
|
+
%w(boats electric_trains rack_trains steam_trains cars maglev_trains bicycles).each do |f|
|
8
|
+
ActiveRecord::Fixtures.create_fixtures(File.dirname(__FILE__) + '/fixtures/', f)
|
9
|
+
end
|
10
|
+
@connection = ActiveRecord::Base.connection
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
ActiveRecord::Fixtures.reset_cache
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_deeper_hierarchy
|
18
|
+
assert_equal [["boats"], ["railed_vehicles", ["trains", ["electric_trains", ["maglev_trains"]], ["rack_trains"], ["steam_trains"]]], ["wheeled_vehicles", ["bicycles"], ["cars"]]].sort,
|
19
|
+
@connection.send(:get_view_hierarchy_for, :vehicles).sort
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_leaves_relations
|
23
|
+
hierarchy = @connection.send(:get_view_hierarchy_for, :vehicles)
|
24
|
+
assert_equal %w(boats bicycles cars maglev_trains rack_trains steam_trains).sort,
|
25
|
+
@connection.send(:get_leaves_relations, hierarchy).sort
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_view_columns
|
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
|
+
@connection.columns(:all_vehicles).collect{|c| c.name}.sort
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_single_table_inheritance_deeper_hierarchy_records_number
|
34
|
+
assert_equal Vehicle.count, @connection.select_value("SELECT count(*) FROM all_vehicles").to_i
|
35
|
+
assert_equal SteamTrain.count, @connection.select_value("SELECT count(*) FROM all_vehicles WHERE vehicle_type='SteamTrain'").to_i
|
36
|
+
assert_equal ElectricTrain.count - MaglevTrain.count, @connection.select_value("SELECT count(*) FROM all_vehicles WHERE vehicle_type='ElectricTrain'").to_i
|
37
|
+
assert_equal RackTrain.count, @connection.select_value("SELECT count(*) FROM all_vehicles WHERE vehicle_type='RackTrain'").to_i
|
38
|
+
assert_equal MaglevTrain.count, @connection.select_value("SELECT count(*) FROM all_vehicles WHERE vehicle_type='MaglevTrain'").to_i
|
39
|
+
assert_equal Car.count, @connection.select_value("SELECT count(*) FROM all_vehicles WHERE vehicle_type='Car'").to_i
|
40
|
+
assert_equal Bicycle.count, @connection.select_value("SELECT count(*) FROM all_vehicles WHERE vehicle_type='Bicycle'").to_i
|
41
|
+
assert_equal Boat.count, @connection.select_value("SELECT count(*) FROM all_vehicles WHERE vehicle_type='Boat'").to_i
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_single_table_inheritance_deeper_hierarchy_contents
|
45
|
+
mag = MaglevTrain.find(:first)
|
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
|
+
end
|
48
|
+
|
49
|
+
class OrderColumnsInAggregateView < ActiveRecord::Migration
|
50
|
+
def self.up
|
51
|
+
rebuild_single_table_inheritance_view(:all_vehicles,:vehicles, %w(max_speed number_of_wheels id))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_single_table_inheritance_view_order_view_columns
|
56
|
+
OrderColumnsInAggregateView.up
|
57
|
+
assert_equal %w(max_speed number_of_wheels id),
|
58
|
+
(@connection.query("SELECT attname
|
59
|
+
FROM pg_class, pg_attribute
|
60
|
+
WHERE pg_class.relname = 'all_vehicles'
|
61
|
+
AND pg_class.oid = pg_attribute.attrelid
|
62
|
+
ORDER BY attnum").flatten)[0..2]
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class AddClassTableInheritance < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table(:updateable_views_inheritance, :id => false) do |t|
|
4
|
+
t.column :parent_relation, :string
|
5
|
+
t.column :child_aggregate_view, :string
|
6
|
+
t.column :child_relation, :string
|
7
|
+
end
|
8
|
+
|
9
|
+
execute "ALTER TABLE updateable_views_inheritance ADD PRIMARY KEY (parent_relation, child_aggregate_view, child_relation)"
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.down
|
13
|
+
drop_table :updateable_views_inheritance
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class CreateWithDefaultTable < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :locomotives do |t|
|
4
|
+
t.column :name, :string
|
5
|
+
t.column :max_speed, :integer
|
6
|
+
t.column :type, :string
|
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
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.down
|
16
|
+
drop_child :steam_locomotives
|
17
|
+
drop_table :locomotives
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class CreateWithExplicitTable < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_child(:electric_locomotives, :table => :raw_electric_locomotives, :parent => :locomotives) do |t|
|
4
|
+
t.decimal :electricity_consumption, :precision => 6, :scale => 2
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.down
|
9
|
+
drop_child :electric_locomotives
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class DefaultColumnValues < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_child(:rack_locomotives, :parent => :locomotives) do |t|
|
4
|
+
t.column :bidirectional, :boolean, :default => false
|
5
|
+
t.column :narrow_gauge, :boolean, :default => true
|
6
|
+
t.column :rail_system, :string, :default => 'Abt'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
drop_child :rack_locomotives
|
12
|
+
end
|
13
|
+
end
|