module Scenic::Statements

Methods that are made available in migrations for managing Scenic views.

Public Instance Methods

create_view(name, version: nil, sql_definition: nil, materialized: false) click to toggle source

Create a new database view.

@param name [String, Symbol] The name of the database view. @param version [Fixnum] The version number of the view, used to find the

definition file in `db/views`. This defaults to `1` if not provided.

@param sql_definition [String] The SQL query for the view schema. An error

will be raised if `sql_definition` and `version` are both set,
as they are mutually exclusive.

@param materialized [Boolean, Hash] Set to true to create a materialized

view. Set to { no_data: true } to create materialized view without
loading data. Defaults to false.

@return The database response from executing the create statement.

@example Create from ‘db/views/searches_v02.sql`

create_view(:searches, version: 2)

@example Create from provided SQL string

create_view(:active_users, sql_definition: <<-SQL)
  SELECT * FROM users WHERE users.active = 't'
SQL
# File lib/scenic/statements.rb, line 25
def create_view(name, version: nil, sql_definition: nil, materialized: false)
  if version.present? && sql_definition.present?
    raise(
      ArgumentError,
      "sql_definition and version cannot both be set"
    )
  end

  if version.blank? && sql_definition.blank?
    version = 1
  end

  sql_definition ||= definition(name, version)

  if materialized
    Scenic.database.create_materialized_view(
      name,
      sql_definition,
      no_data: no_data(materialized)
    )
  else
    Scenic.database.create_view(name, sql_definition)
  end
end
drop_view(name, revert_to_version: nil, materialized: false) click to toggle source

Drop a database view by name.

@param name [String, Symbol] The name of the database view. @param revert_to_version [Fixnum] Used to reverse the ‘drop_view` command

on `rake db:rollback`. The provided version will be passed as the
`version` argument to {#create_view}.

@param materialized [Boolean] Set to true if dropping a meterialized view.

defaults to false.

@return The database response from executing the drop statement.

@example Drop a view, rolling back to version 3 on rollback

drop_view(:users_who_recently_logged_in, revert_to_version: 3)
# File lib/scenic/statements.rb, line 63
def drop_view(name, revert_to_version: nil, materialized: false)
  if materialized
    Scenic.database.drop_materialized_view(name)
  else
    Scenic.database.drop_view(name)
  end
end
replace_view(name, version: nil, revert_to_version: nil, materialized: false) click to toggle source

Update a database view to a new version using ‘CREATE OR REPLACE VIEW`.

The existing view is replaced using the supplied ‘version` parameter.

Does not work with materialized views due to lack of database support.

@param name [String, Symbol] The name of the database view. @param version [Fixnum] The version number of the view. @param revert_to_version [Fixnum] The version number to rollback to on

`rake db rollback`

@return The database response from executing the create statement.

@example

replace_view :engagement_reports, version: 3, revert_to_version: 2
# File lib/scenic/statements.rb, line 135
def replace_view(name, version: nil, revert_to_version: nil, materialized: false)
  if version.blank?
    raise ArgumentError, "version is required"
  end

  if materialized
    raise ArgumentError, "Cannot replace materialized views"
  end

  sql_definition = definition(name, version)

  Scenic.database.replace_view(name, sql_definition)
end
update_view(name, version: nil, sql_definition: nil, revert_to_version: nil, materialized: false) click to toggle source

Update a database view to a new version.

The existing view is dropped and recreated using the supplied ‘version` parameter.

@param name [String, Symbol] The name of the database view. @param version [Fixnum] The version number of the view. @param sql_definition [String] The SQL query for the view schema. An error

will be raised if `sql_definition` and `version` are both set,
as they are mutually exclusive.

@param revert_to_version [Fixnum] The version number to rollback to on

`rake db rollback`

@param materialized [Boolean, Hash] True if updating a materialized view.

Set to { no_data: true } to update materialized view without loading
data. Defaults to false.

@return The database response from executing the create statement.

@example

update_view :engagement_reports, version: 3, revert_to_version: 2
# File lib/scenic/statements.rb, line 91
def update_view(name, version: nil, sql_definition: nil, revert_to_version: nil, materialized: false)
  if version.blank? && sql_definition.blank?
    raise(
      ArgumentError,
      "sql_definition or version must be specified"
    )
  end

  if version.present? && sql_definition.present?
    raise(
      ArgumentError,
      "sql_definition and version cannot both be set"
    )
  end

  sql_definition ||= definition(name, version)

  if materialized
    Scenic.database.update_materialized_view(
      name,
      sql_definition,
      no_data: no_data(materialized)
    )
  else
    Scenic.database.update_view(name, sql_definition)
  end
end

Private Instance Methods

definition(name, version) click to toggle source
# File lib/scenic/statements.rb, line 151
def definition(name, version)
  Scenic::Definition.new(name, version).to_sql
end
no_data(materialized) click to toggle source
# File lib/scenic/statements.rb, line 155
def no_data(materialized)
  if materialized.is_a?(Hash)
    materialized.fetch(:no_data, false)
  else
    false
  end
end