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/index_reapplication.rb,
lib/scenic/adapters/postgres/refresh_dependencies.rb
Overview
An adapter for managing Postgres views.
These methods are used interally 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
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) ⇒ 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.
38 39 40 |
# File 'lib/scenic/adapters/postgres.rb', line 38 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.
135 136 137 138 139 140 141 142 143 |
# File 'lib/scenic/adapters/postgres.rb', line 135 def create_materialized_view(name, sql_definition, no_data: false) raise_unless_materialized_views_supported execute "CREATE MATERIALIZED VIEW \#{quote_table_name(name)} AS\n\#{sql_definition.rstrip.chomp(\";\")}\n\#{\"WITH NO DATA\" if no_data};\n" 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.
60 61 62 |
# File 'lib/scenic/adapters/postgres.rb', line 60 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.
181 182 183 184 |
# File 'lib/scenic/adapters/postgres.rb', line 181 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.
117 118 119 |
# File 'lib/scenic/adapters/postgres.rb', line 117 def drop_view(name) execute "DROP VIEW #{quote_table_name(name)};" end |
#populated?(name) ⇒ boolean
True if supplied relation name is populated. Useful for checking the
state of materialized views which may error if created WITH NO DATA
and used before they are refreshed. True for all other relation types.
235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/scenic/adapters/postgres.rb', line 235 def populated?(name) raise_unless_materialized_views_supported schemaless_name = name.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.
210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/scenic/adapters/postgres.rb', line 210 def refresh_materialized_view(name, concurrently: false, cascade: false) raise_unless_materialized_views_supported if cascade refresh_dependencies_for(name, concurrently: concurrently) end if concurrently raise_unless_concurrent_refresh_supported 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.
106 107 108 |
# File 'lib/scenic/adapters/postgres.rb', line 106 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) ⇒ 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.
163 164 165 166 167 168 169 170 |
# File 'lib/scenic/adapters/postgres.rb', line 163 def update_materialized_view(name, sql_definition, no_data: false) raise_unless_materialized_views_supported IndexReapplication.new(connection: connection).on(name) do drop_materialized_view(name) create_materialized_view(name, sql_definition, no_data: no_data) 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.
80 81 82 83 |
# File 'lib/scenic/adapters/postgres.rb', line 80 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.
48 49 50 |
# File 'lib/scenic/adapters/postgres.rb', line 48 def views Views.new(connection).all end |