1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
|
# frozen_string_literal: true
require "cases/helper"
require "models/book"
require "support/schema_dumping_helper"
module ViewBehavior
include SchemaDumpingHelper
extend ActiveSupport::Concern
included do
fixtures :books
end
class Ebook < ActiveRecord::Base
self.table_name = "ebooks'"
self.primary_key = "id"
end
def setup
super
@connection = ActiveRecord::Base.lease_connection
create_view "ebooks'", <<~SQL
SELECT id, name, cover, status FROM books WHERE format = 'ebook'
SQL
end
def teardown
super
drop_view "ebooks'"
end
def test_reading
books = Ebook.all
assert_equal [books(:rfr).id], books.map(&:id)
assert_equal ["Ruby for Rails"], books.map(&:name)
end
def test_views
assert_equal [Ebook.table_name], @connection.views
end
def test_view_exists
view_name = Ebook.table_name
assert @connection.view_exists?(view_name), "'#{view_name}' view should exist"
end
def test_table_exists
view_name = Ebook.table_name
assert_not @connection.table_exists?(view_name), "'#{view_name}' table should not exist"
end
def test_views_ara_valid_data_sources
view_name = Ebook.table_name
assert @connection.data_source_exists?(view_name), "'#{view_name}' should be a data source"
end
def test_column_definitions
assert_equal([["id", :integer],
["name", :string],
["cover", :string],
["status", :integer]], Ebook.columns.map { |c| [c.name, c.type] })
end
def test_attributes
assert_equal({ "id" => 2, "name" => "Ruby for Rails", "cover" => "hard", "status" => 0 },
Ebook.first.attributes)
end
def test_does_not_assume_id_column_as_primary_key
model = Class.new(ActiveRecord::Base) do
self.table_name = "ebooks'"
end
assert_nil model.primary_key
end
def test_does_not_dump_view_as_table
schema = dump_table_schema "ebooks'"
assert_no_match %r{create_table "ebooks'"}, schema
end
private
def quote_table_name(name)
@connection.quote_table_name(name)
end
end
if ActiveRecord::Base.lease_connection.supports_views?
class ViewWithPrimaryKeyTest < ActiveRecord::TestCase
include ViewBehavior
private
def create_view(name, query)
@connection.execute "CREATE VIEW #{quote_table_name(name)} AS #{query}"
end
def drop_view(name)
@connection.execute "DROP VIEW #{quote_table_name(name)}" if @connection.view_exists? name
end
end
class ViewWithoutPrimaryKeyTest < ActiveRecord::TestCase
include SchemaDumpingHelper
self.use_transactional_tests = false
fixtures :books
class Paperback < ActiveRecord::Base; end
setup do
@connection = ActiveRecord::Base.lease_connection
@connection.execute <<~SQL
CREATE VIEW paperbacks
AS SELECT name, status FROM books WHERE format = 'paperback'
SQL
end
teardown do
@connection.execute "DROP VIEW paperbacks" if @connection&.view_exists? "paperbacks"
end
def test_reading
books = Paperback.all
assert_equal ["Agile Web Development with Rails"], books.map(&:name)
end
def test_views
assert_equal [Paperback.table_name], @connection.views
end
def test_view_exists
view_name = Paperback.table_name
assert @connection.view_exists?(view_name), "'#{view_name}' view should exist"
end
def test_table_exists
view_name = Paperback.table_name
assert_not @connection.table_exists?(view_name), "'#{view_name}' table should not exist"
end
def test_column_definitions
assert_equal([["name", :string],
["status", :integer]], Paperback.columns.map { |c| [c.name, c.type] })
end
def test_attributes
assert_equal({ "name" => "Agile Web Development with Rails", "status" => 2 },
Paperback.first.attributes)
end
def test_does_not_have_a_primary_key
assert_nil Paperback.primary_key
end
def test_does_not_dump_view_as_table
schema = dump_table_schema "paperbacks"
assert_no_match %r{create_table "paperbacks"}, schema
end
end
class UpdateableViewTest < ActiveRecord::TestCase
# SQLite does not support CREATE, INSERT, and DELETE for VIEW
if current_adapter?(:Mysql2Adapter, :TrilogyAdapter, :PostgreSQLAdapter)
self.use_transactional_tests = false
fixtures :books
class PrintedBook < ActiveRecord::Base
self.primary_key = "id"
end
setup do
@connection = ActiveRecord::Base.lease_connection
@connection.execute <<~SQL
CREATE VIEW printed_books
AS SELECT id, name, status, format FROM books WHERE format = 'paperback'
SQL
end
teardown do
@connection.execute "DROP VIEW printed_books" if @connection.view_exists? "printed_books"
end
def test_update_record
book = PrintedBook.first
book.name = "AWDwR"
book.save!
book.reload
assert_equal "AWDwR", book.name
end
def test_insert_record
PrintedBook.create! name: "Rails in Action", status: 0, format: "paperback"
new_book = PrintedBook.last
assert_equal "Rails in Action", new_book.name
end
def test_insert_record_populates_primary_key
book = PrintedBook.create! name: "Rails in Action", status: 0, format: "paperback"
assert_not_nil book.id
assert book.id > 0
end if current_adapter?(:PostgreSQLAdapter, :SQLite3Adapter) && supports_insert_returning?
def test_update_record_to_fail_view_conditions
book = PrintedBook.first
book.format = "ebook"
book.save!
assert_raises ActiveRecord::RecordNotFound do
book.reload
end
end
end # end of `if current_adapter?(:Mysql2Adapter, :TrilogyAdapter, :PostgreSQLAdapter)`
end
end # end of `if ActiveRecord::Base.lease_connection.supports_views?`
if ActiveRecord::Base.lease_connection.supports_materialized_views?
class MaterializedViewTest < ActiveRecord::PostgreSQLTestCase
include ViewBehavior
private
def create_view(name, query)
@connection.execute "CREATE MATERIALIZED VIEW #{quote_table_name(name)} AS #{query}"
end
def drop_view(name)
@connection.execute "DROP MATERIALIZED VIEW #{quote_table_name(name)}" if @connection.view_exists? name
end
end
end
|