Module: Scenic::Statements

Defined in:
lib/scenic/statements.rb

Overview

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

Instance Method Summary collapse

Instance Method Details

#create_view(name, version: nil, sql_definition: nil, materialized: false) ⇒ Object

Create a new database view.

Examples:

Create from db/views/searches_v02.sql

create_view(:searches, version: 2)

Create from provided SQL string

create_view(:active_users, sql_definition: <<-SQL)
  SELECT * FROM users WHERE users.active = 't'
SQL

Parameters:

  • name (String, Symbol)

    The name of the database view.

  • version (Fixnum) (defaults to: nil)

    The version number of the view, used to find the definition file in db/views. This defaults to 1 if not provided.

  • sql_definition (String) (defaults to: nil)

    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.

  • materialized (Boolean, Hash) (defaults to: false)

    Set to a truthy value to create a materialized view. Hash

Options Hash (materialized:):

  • :no_data (Boolean) — default: false

    Set to true to create materialized view without running the associated query. You will need to perform a non-concurrent refresh to populate with data.

Returns:

  • The database response from executing the create statement.



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
# File 'lib/scenic/statements.rb', line 27

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
    options = materialized_options(materialized)

    Scenic.database.create_materialized_view(
      name,
      sql_definition,
      no_data: options[:no_data]
    )
  else
    Scenic.database.create_view(name, sql_definition)
  end
end

#drop_view(name, revert_to_version: nil, materialized: false) ⇒ Object

Drop a database view by name.

Examples:

Drop a view, rolling back to version 3 on rollback

drop_view(:users_who_recently_logged_in, revert_to_version: 3)

Parameters:

  • name (String, Symbol)

    The name of the database view.

  • revert_to_version (Fixnum) (defaults to: nil)

    Used to reverse the drop_view command on rake db:rollback. The provided version will be passed as the version argument to #create_view.

  • materialized (Boolean) (defaults to: false)

    Set to true if dropping a meterialized view. defaults to false.

Returns:

  • The database response from executing the drop statement.



67
68
69
70
71
72
73
# File 'lib/scenic/statements.rb', line 67

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) ⇒ Object

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.

Examples:

replace_view :engagement_reports, version: 3, revert_to_version: 2

Parameters:

  • name (String, Symbol)

    The name of the database view.

  • version (Fixnum) (defaults to: nil)

    The version number of the view.

  • revert_to_version (Fixnum) (defaults to: nil)

    The version number to rollback to on rake db rollback

Returns:

  • The database response from executing the create statement.



162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/scenic/statements.rb', line 162

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) ⇒ Object

Update a database view to a new version.

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

Examples:

update_view :engagement_reports, version: 3, revert_to_version: 2
update_view :comments, version: 2, revert_to_version: 1, materialized: { side_by_side: true }

Parameters:

  • name (String, Symbol)

    The name of the database view.

  • version (Fixnum) (defaults to: nil)

    The version number of the view.

  • sql_definition (String) (defaults to: nil)

    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.

  • revert_to_version (Fixnum) (defaults to: nil)

    The version number to rollback to on rake db rollback

  • materialized (Boolean, Hash) (defaults to: false)

    True or a Hash if updating a materialized view.

Options Hash (materialized:):

  • :no_data (Boolean) — default: false

    Set to true to update a materialized view without loading data. You will need to perform a refresh to populate with data. Cannot be combined with the :side_by_side option.

  • :side_by_side (Boolean) — default: false

    Set to true to update update a materialized view using our side-by-side strategy, which will limit the time the view is locked at the cost of increasing disk usage. The view is initially updated with a temporary name and atomically swapped once it is successfully created with data. Cannot be combined with the :no_data option.

Returns:

  • The database response from executing the create statement.



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
# File 'lib/scenic/statements.rb', line 104

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
    options = materialized_options(materialized)

    if options[:no_data] && options[:side_by_side]
      raise(
        ArgumentError,
        "no_data and side_by_side options cannot be combined"
      )
    end

    if options[:side_by_side] && !transaction_open?
      raise "a transaction is required to perform a side-by-side update"
    end

    Scenic.database.update_materialized_view(
      name,
      sql_definition,
      no_data: options[:no_data],
      side_by_side: options[:side_by_side]
    )
  else
    Scenic.database.update_view(name, sql_definition)
  end
end