Class: Scenic::Adapters::Postgres
- Inherits:
-
Object
- Object
- Scenic::Adapters::Postgres
- Defined in:
- lib/scenic/adapters/postgres.rb,
lib/scenic/adapters/postgres/views.rb,
lib/scenic/adapters/postgres/errors.rb,
lib/scenic/adapters/postgres/indexes.rb,
lib/scenic/adapters/postgres/connection.rb,
lib/scenic/adapters/postgres/side_by_side.rb,
lib/scenic/adapters/postgres/index_creation.rb,
lib/scenic/adapters/postgres/temporary_name.rb,
lib/scenic/adapters/postgres/index_migration.rb,
lib/scenic/adapters/postgres/index_reapplication.rb,
lib/scenic/adapters/postgres/refresh_dependencies.rb
Overview
An adapter for managing Postgres views.
These methods are used internally by Scenic and are not intended for direct use. Methods that alter database schema are intended to be called via Statements, while #refresh_materialized_view is called via Scenic.database.
The methods are documented here for insight into specifics of how Scenic integrates with Postgres and the responsibilities of Scenic::Adapters.
Defined Under Namespace
Classes: ConcurrentRefreshesNotSupportedError, MaterializedViewsNotSupportedError, RefreshDependencies, SideBySide
Instance Method Summary collapse
-
#create_materialized_view(name, sql_definition, no_data: false) ⇒ void
Creates a materialized view in the database.
-
#create_view(name, sql_definition) ⇒ void
Creates a view in the database.
-
#drop_materialized_view(name) ⇒ void
Drops a materialized view in the database.
-
#drop_view(name) ⇒ void
Drops the named view from the database.
-
#initialize(connectable = ActiveRecord::Base) ⇒ Postgres
constructor
Creates an instance of the Scenic Postgres adapter.
-
#populated?(name) ⇒ boolean
True if supplied relation name is populated.
-
#refresh_materialized_view(name, concurrently: false, cascade: false) ⇒ void
Refreshes a materialized view from its SQL schema.
-
#replace_view(name, sql_definition) ⇒ void
Replaces a view in the database using
CREATE OR REPLACE VIEW. -
#update_materialized_view(name, sql_definition, no_data: false, side_by_side: false) ⇒ void
Updates a materialized view in the database.
-
#update_view(name, sql_definition) ⇒ void
Updates a view in the database.
-
#views ⇒ Array<Scenic::View>
Returns an array of views in the database.
Constructor Details
#initialize(connectable = ActiveRecord::Base) ⇒ Postgres
Creates an instance of the Scenic Postgres adapter.
This is the default adapter for Scenic. Configuring it via Scenic.configure is not required, but the example below shows how one would explicitly set it.
42 43 44 |
# File 'lib/scenic/adapters/postgres.rb', line 42 def initialize(connectable = ActiveRecord::Base) @connectable = connectable end |
Instance Method Details
#create_materialized_view(name, sql_definition, no_data: false) ⇒ void
This method returns an undefined value.
Creates a materialized view in the database
This is typically called in a migration via Statements#create_view.
139 140 141 142 143 144 145 146 147 |
# File 'lib/scenic/adapters/postgres.rb', line 139 def create_materialized_view(name, sql_definition, no_data: false) raise_unless_materialized_views_supported execute <<-SQL CREATE MATERIALIZED VIEW #{quote_table_name(name)} AS #{sql_definition.rstrip.chomp(";")} #{"WITH NO DATA" if no_data}; SQL end |
#create_view(name, sql_definition) ⇒ void
This method returns an undefined value.
Creates a view in the database.
This is typically called in a migration via Statements#create_view.
64 65 66 |
# File 'lib/scenic/adapters/postgres.rb', line 64 def create_view(name, sql_definition) execute "CREATE VIEW #{quote_table_name(name)} AS #{sql_definition};" end |
#drop_materialized_view(name) ⇒ void
This method returns an undefined value.
Drops a materialized view in the database
This is typically called in a migration via Statements#update_view.
194 195 196 197 |
# File 'lib/scenic/adapters/postgres.rb', line 194 def drop_materialized_view(name) raise_unless_materialized_views_supported execute "DROP MATERIALIZED VIEW #{quote_table_name(name)};" end |
#drop_view(name) ⇒ void
This method returns an undefined value.
Drops the named view from the database
This is typically called in a migration via Statements#drop_view.
121 122 123 |
# File 'lib/scenic/adapters/postgres.rb', line 121 def drop_view(name) execute "DROP VIEW #{quote_table_name(name)};" end |
#populated?(name) ⇒ boolean
True if supplied relation name is populated.
254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/scenic/adapters/postgres.rb', line 254 def populated?(name) raise_unless_materialized_views_supported schemaless_name = name.to_s.split(".").last sql = "SELECT relispopulated FROM pg_class WHERE relname = '#{schemaless_name}'" relations = execute(sql) if relations.count.positive? relations.first["relispopulated"].in?(["t", true]) else false end end |
#refresh_materialized_view(name, concurrently: false, cascade: false) ⇒ void
This method returns an undefined value.
Refreshes a materialized view from its SQL schema.
This is typically called from application code via Scenic.database.
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/scenic/adapters/postgres.rb', line 228 def refresh_materialized_view(name, concurrently: false, cascade: false) raise_unless_materialized_views_supported if concurrently raise_unless_concurrent_refresh_supported end if cascade refresh_dependencies_for(name, concurrently: concurrently) end if concurrently && populated?(name) execute "REFRESH MATERIALIZED VIEW CONCURRENTLY #{quote_table_name(name)};" else execute "REFRESH MATERIALIZED VIEW #{quote_table_name(name)};" end end |
#replace_view(name, sql_definition) ⇒ void
This method returns an undefined value.
Replaces a view in the database using CREATE OR REPLACE VIEW.
This results in a CREATE OR REPLACE VIEW. Most of the time the
explicitness of the two step process used in #update_view is preferred
to CREATE OR REPLACE VIEW because the former ensures that the view you
are trying to update did, in fact, already exist. Additionally,
CREATE OR REPLACE VIEW is allowed only to add new columns to the end
of an existing view schema. Existing columns cannot be re-ordered,
removed, or have their types changed. Drop and create overcomes this
limitation as well.
However, when there is a tangled dependency tree
CREATE OR REPLACE VIEW can be preferable.
This is typically called in a migration via Statements#replace_view.
110 111 112 |
# File 'lib/scenic/adapters/postgres.rb', line 110 def replace_view(name, sql_definition) execute "CREATE OR REPLACE VIEW #{quote_table_name(name)} AS #{sql_definition};" end |
#update_materialized_view(name, sql_definition, no_data: false, side_by_side: false) ⇒ void
This method returns an undefined value.
Updates a materialized view in the database.
Drops and recreates the materialized view. Attempts to maintain all previously existing and still applicable indexes on the materialized view after the view is recreated.
This is typically called in a migration via Statements#update_view.
170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/scenic/adapters/postgres.rb', line 170 def update_materialized_view(name, sql_definition, no_data: false, side_by_side: false) raise_unless_materialized_views_supported if side_by_side SideBySide .new(adapter: self, name: name, definition: sql_definition) .update else IndexReapplication.new(connection: connection).on(name) do drop_materialized_view(name) create_materialized_view(name, sql_definition, no_data: no_data) end end end |
#update_view(name, sql_definition) ⇒ void
This method returns an undefined value.
Updates a view in the database.
This results in a #drop_view followed by a #create_view. The
explicitness of that two step process is preferred to CREATE OR
REPLACE VIEW because the former ensures that the view you are trying to
update did, in fact, already exist. Additionally, CREATE OR REPLACE
VIEW is allowed only to add new columns to the end of an existing
view schema. Existing columns cannot be re-ordered, removed, or have
their types changed. Drop and create overcomes this limitation as well.
This is typically called in a migration via Statements#update_view.
84 85 86 87 |
# File 'lib/scenic/adapters/postgres.rb', line 84 def update_view(name, sql_definition) drop_view(name) create_view(name, sql_definition) end |
#views ⇒ Array<Scenic::View>
Returns an array of views in the database.
This collection of views is used by the [Scenic::SchemaDumper] to
populate the schema.rb file.
52 53 54 |
# File 'lib/scenic/adapters/postgres.rb', line 52 def views Views.new(connection).all end |