spectacles 6.0.0 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/.standard.yml +4 -0
  4. data/CHANGELOG.md +58 -0
  5. data/CODE_OF_CONDUCT.md +132 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +136 -0
  8. data/Rakefile +15 -15
  9. data/lib/spectacles/abstract_adapter_override.rb +3 -3
  10. data/lib/spectacles/materialized_view.rb +7 -7
  11. data/lib/spectacles/railtie.rb +3 -3
  12. data/lib/spectacles/schema_dumper.rb +1 -1
  13. data/lib/spectacles/schema_statements/abstract_adapter.rb +15 -9
  14. data/lib/spectacles/schema_statements/mysql2_adapter.rb +6 -26
  15. data/lib/spectacles/schema_statements/postgresql_adapter.rb +31 -33
  16. data/lib/spectacles/schema_statements/sqlite3_adapter.rb +5 -20
  17. data/lib/spectacles/schema_statements/sqlserver_adapter.rb +5 -5
  18. data/lib/spectacles/schema_statements/vertica_adapter.rb +5 -5
  19. data/lib/spectacles/schema_statements.rb +2 -2
  20. data/lib/spectacles/version.rb +3 -1
  21. data/lib/spectacles/view.rb +5 -5
  22. data/lib/spectacles.rb +14 -12
  23. metadata +37 -44
  24. data/.gitignore +0 -8
  25. data/.travis.yml +0 -14
  26. data/Gemfile +0 -20
  27. data/LICENSE +0 -20
  28. data/Readme.rdoc +0 -120
  29. data/specs/adapters/mysql2_adapter_spec.rb +0 -16
  30. data/specs/adapters/postgresql_adapter_spec.rb +0 -68
  31. data/specs/adapters/sqlite3_adapter_spec.rb +0 -14
  32. data/specs/spec_helper.rb +0 -53
  33. data/specs/spectacles/abstract_adapter_override_spec.rb +0 -14
  34. data/specs/spectacles/schema_statements/abstract_adapter_spec.rb +0 -82
  35. data/specs/spectacles/view_spec.rb +0 -7
  36. data/specs/support/minitest_matchers.rb +0 -5
  37. data/specs/support/minitest_shared.rb +0 -20
  38. data/specs/support/schema_statement_examples.rb +0 -241
  39. data/specs/support/view_examples.rb +0 -62
  40. data/spectacles.gemspec +0 -33
@@ -1,21 +1,21 @@
1
- require 'spectacles/schema_statements/abstract_adapter'
1
+ require "spectacles/schema_statements/abstract_adapter"
2
2
 
3
3
  module Spectacles
4
4
  module SchemaStatements
5
5
  module PostgreSQLAdapter
6
6
  include Spectacles::SchemaStatements::AbstractAdapter
7
7
 
8
- def views(name = nil) #:nodoc:
8
+ def views(name = nil) # :nodoc:
9
9
  q = <<-SQL
10
- SELECT t.table_name, t.table_type
11
- FROM information_schema.tables AS t
12
- INNER JOIN pg_class AS c ON c.relname = t.table_name
13
- WHERE t.table_schema = ANY(current_schemas(false))
14
- AND t.table_type = 'VIEW'
10
+ SELECT t.table_name
11
+ FROM information_schema.views AS t
12
+ INNER JOIN pg_class AS c ON c.relname = t.table_name AND c.relnamespace = to_regnamespace(t.table_schema)::oid
13
+ WHERE t.table_schema = ANY(current_schemas(true))
14
+ AND table_schema NOT IN ('information_schema', 'pg_catalog')
15
15
  AND pg_catalog.pg_get_userbyid(c.relowner) = #{quote(database_username)}
16
16
  SQL
17
17
 
18
- execute(q, name).map { |row| row['table_name'] }
18
+ execute(q, name).map { |row| row["table_name"] }
19
19
  end
20
20
 
21
21
  def view_build_query(view, name = nil)
@@ -46,7 +46,7 @@ module Spectacles
46
46
  AND relkind = 'm';
47
47
  SQL
48
48
 
49
- execute(query, name).map { |row| row['relname'] }
49
+ execute(query, name).map { |row| row["relname"] }
50
50
  end
51
51
 
52
52
  # Returns a tuple [string, hash], where string is the query used
@@ -59,8 +59,7 @@ module Spectacles
59
59
  WHERE a.relname=#{quote(view)}
60
60
  AND b.matviewname=a.relname
61
61
  SQL
62
-
63
- row = result[0]
62
+ row = result.to_a[0]
64
63
 
65
64
  storage = row["reloptions"]
66
65
  tablespace = row["tablespace"]
@@ -68,37 +67,37 @@ module Spectacles
68
67
  definition = row["definition"].strip.sub(/;$/, "")
69
68
 
70
69
  options = {}
71
- options[:data] = false if ispopulated == 'f' || ispopulated == false
70
+ options[:data] = false if ispopulated == "f" || ispopulated == false
72
71
  options[:storage] = parse_storage_definition(storage) if storage.present?
73
72
  options[:tablespace] = tablespace if tablespace.present?
74
73
 
75
74
  [definition, options]
76
75
  end
77
76
 
78
- def create_materialized_view_statement(view_name, query, options={})
77
+ def create_materialized_view_statement(view_name, query, options = {})
79
78
  columns = if options[:columns]
80
- "(" + options[:columns].map { |c| quote_column_name(c) }.join(",") + ")"
81
- else
82
- ""
83
- end
79
+ "(" + options[:columns].map { |c| quote_column_name(c) }.join(",") + ")"
80
+ else
81
+ ""
82
+ end
84
83
 
85
- storage = if options[:storage] && options[:storage].any?
86
- "WITH (" + options[:storage].map { |key, value| "#{key}=#{value}" }.join(", ") + ")"
87
- else
88
- ""
89
- end
84
+ storage = if options[:storage]&.any?
85
+ "WITH (" + options[:storage].map { |key, value| "#{key}=#{value}" }.join(", ") + ")"
86
+ else
87
+ ""
88
+ end
90
89
 
91
90
  tablespace = if options[:tablespace]
92
- "TABLESPACE #{quote_table_name(options[:tablespace])}"
93
- else
94
- ""
95
- end
91
+ "TABLESPACE #{quote_table_name(options[:tablespace])}"
92
+ else
93
+ ""
94
+ end
96
95
 
97
96
  with_data = if options.fetch(:data, true)
98
- "WITH DATA"
99
- else
100
- "WITH NO DATA"
101
- end
97
+ "WITH DATA"
98
+ else
99
+ "WITH NO DATA"
100
+ end
102
101
 
103
102
  <<-SQL.squish
104
103
  CREATE MATERIALIZED VIEW #{quote_table_name(view_name)}
@@ -145,10 +144,9 @@ module Spectacles
145
144
  storage = storage.first if storage.is_a?(Array)
146
145
 
147
146
  storage = storage.gsub(/^{|}$/, "")
148
- storage.split(/,/).inject({}) do |hash, item|
149
- key, value = item.strip.split(/=/)
147
+ storage.split(",").each_with_object({}) do |item, hash|
148
+ key, value = item.strip.split("=")
150
149
  hash[key.to_sym] = value
151
- hash
152
150
  end
153
151
  end
154
152
 
@@ -1,38 +1,23 @@
1
- require 'spectacles/schema_statements/abstract_adapter'
1
+ require "spectacles/schema_statements/abstract_adapter"
2
2
 
3
3
  module Spectacles
4
4
  module SchemaStatements
5
5
  module SQLite3Adapter
6
6
  include Spectacles::SchemaStatements::AbstractAdapter
7
7
 
8
- # overrides the #tables method from ActiveRecord's SQLite3Adapter
9
- # to return only tables, and not views.
10
- def tables(name = nil, table_name = nil)
11
- sql = <<-SQL
12
- SELECT name
13
- FROM sqlite_master
14
- WHERE type = 'table' AND NOT name = 'sqlite_sequence'
15
- SQL
16
- sql << " AND name = #{quote_table_name(table_name)}" if table_name
17
-
18
- exec_query(sql, 'SCHEMA').map do |row|
19
- row['name']
20
- end
21
- end
22
-
23
8
  def generate_view_query(*columns)
24
9
  <<-SQL
25
- SELECT #{columns.join(',')}
10
+ SELECT #{columns.join(",")}
26
11
  FROM sqlite_master
27
12
  WHERE type = 'view'
28
13
  SQL
29
14
  end
30
15
 
31
- def views #:nodoc:
16
+ def views # :nodoc:
32
17
  sql = generate_view_query(:name)
33
18
 
34
19
  exec_query(sql, "SCHEMA").map do |row|
35
- row['name']
20
+ row["name"]
36
21
  end
37
22
  end
38
23
 
@@ -41,7 +26,7 @@ module Spectacles
41
26
  sql << " AND name = #{quote_table_name(table_name)}"
42
27
 
43
28
  row = exec_query(sql, "SCHEMA").first
44
- row['sql'].gsub(/CREATE VIEW .*? AS/i, "")
29
+ row["sql"].gsub(/CREATE VIEW .*? AS/i, "")
45
30
  end
46
31
  end
47
32
  end
@@ -1,22 +1,22 @@
1
- require 'spectacles/schema_statements/abstract_adapter'
1
+ require "spectacles/schema_statements/abstract_adapter"
2
2
 
3
3
  module Spectacles
4
4
  module SchemaStatements
5
5
  module SQLServerAdapter
6
6
  include Spectacles::SchemaStatements::AbstractAdapter
7
-
8
- def views(name = nil) #:nodoc:
7
+
8
+ def views(name = nil) # :nodoc:
9
9
  select_values("SELECT table_name FROM information_schema.views", name)
10
10
  end
11
11
 
12
12
  def view_build_query(view, name = nil)
13
- q =<<-ENDSQL
13
+ q = <<-ENDSQL
14
14
  SELECT view_definition FROM information_schema.views
15
15
  WHERE table_name = '#{view}'
16
16
  ENDSQL
17
17
 
18
18
  q = select_value(q, name) or raise "No view called #{view} found"
19
- q.gsub(/CREATE VIEW .*? AS/i, "")
19
+ q.gsub(/CREATE VIEW .*? AS/i, "")
20
20
  end
21
21
  end
22
22
  end
@@ -1,23 +1,23 @@
1
- require 'spectacles/schema_statements/abstract_adapter'
1
+ require "spectacles/schema_statements/abstract_adapter"
2
2
 
3
3
  module Spectacles
4
4
  module SchemaStatements
5
5
  module VerticaAdapter
6
6
  include Spectacles::SchemaStatements::AbstractAdapter
7
-
7
+
8
8
  def views(name = nil)
9
9
  q = <<-SQL
10
10
  SELECT table_name FROM v_catalog.views
11
11
  SQL
12
-
13
- execute(q, name).map { |row| row['table_name'] }
12
+
13
+ execute(q, name).map { |row| row["table_name"] }
14
14
  end
15
15
 
16
16
  def view_build_query(view, name = nil)
17
17
  q = <<-SQL
18
18
  SELECT view_definition FROM v_catalog.views WHERE table_name = '#{view}'
19
19
  SQL
20
-
20
+
21
21
  select_value(q, name) or raise "No view called #{view} found"
22
22
  end
23
23
  end
@@ -1,7 +1,7 @@
1
- require 'spectacles/schema_statements/abstract_adapter'
1
+ require "spectacles/schema_statements/abstract_adapter"
2
2
 
3
3
  module Spectacles
4
- SUPPORTED_ADAPTERS = %w( Mysql Mysql2 PostgreSQL SQLServer SQLite SQLite3 Vertica )
4
+ SUPPORTED_ADAPTERS = %w[Mysql2 PostgreSQL SQLServer SQLite SQLite3 Vertica]
5
5
 
6
6
  def self.load_adapters
7
7
  SUPPORTED_ADAPTERS.each do |db|
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Spectacles
2
- VERSION = "6.0.0"
4
+ VERSION = "7.1.0"
3
5
  end
@@ -7,7 +7,7 @@ module Spectacles
7
7
  end
8
8
 
9
9
  def self.view_exists?
10
- self.connection.view_exists?(self.view_name)
10
+ connection.view_exists?(view_name)
11
11
  end
12
12
 
13
13
  class << self
@@ -15,11 +15,11 @@ module Spectacles
15
15
  alias_method :view_name, :table_name
16
16
  end
17
17
 
18
- def ==(comparison_object)
18
+ def ==(other)
19
19
  super ||
20
- comparison_object.instance_of?(self.class) &&
21
- attributes.present? &&
22
- comparison_object.attributes == attributes
20
+ other.instance_of?(self.class) &&
21
+ attributes.present? &&
22
+ other.attributes == attributes
23
23
  end
24
24
 
25
25
  def persisted?
data/lib/spectacles.rb CHANGED
@@ -1,14 +1,16 @@
1
- require 'active_record'
2
- require 'active_support/core_ext'
3
- require 'spectacles/schema_statements'
4
- require 'spectacles/schema_dumper'
5
- require 'spectacles/view'
6
- require 'spectacles/materialized_view'
7
- require 'spectacles/version'
8
- require 'spectacles/configuration'
9
- require 'spectacles/abstract_adapter_override'
10
-
11
- require 'spectacles/railtie' if defined?(Rails)
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record"
4
+ require "active_support/core_ext"
5
+ require "spectacles/schema_statements"
6
+ require "spectacles/schema_dumper"
7
+ require "spectacles/view"
8
+ require "spectacles/materialized_view"
9
+ require "spectacles/version"
10
+ require "spectacles/configuration"
11
+ require "spectacles/abstract_adapter_override"
12
+
13
+ require "spectacles/railtie" if defined?(Rails)
12
14
 
13
15
  module Spectacles
14
16
  def self.configuration
@@ -34,4 +36,4 @@ ActiveRecord::SchemaDumper.class_eval do
34
36
  end
35
37
  end
36
38
 
37
- Spectacles::load_adapters
39
+ Spectacles.load_adapters
metadata CHANGED
@@ -1,55 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spectacles
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0
4
+ version: 7.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Hutchison, Brandon Dewitt
8
- autorequire:
9
- bindir: bin
8
+ autorequire:
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2022-02-21 00:00:00.000000000 Z
11
+ date: 2024-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: 3.2.0
20
17
  - - "~>"
21
18
  - !ruby/object:Gem::Version
22
- version: 6.1.0
19
+ version: 7.1.0
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: 3.2.0
30
24
  - - "~>"
31
25
  - !ruby/object:Gem::Version
32
- version: 6.1.0
26
+ version: 7.1.0
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: activesupport
35
29
  requirement: !ruby/object:Gem::Requirement
36
30
  requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: 3.2.0
40
31
  - - "~>"
41
32
  - !ruby/object:Gem::Version
42
- version: 6.1.0
33
+ version: 7.1.0
43
34
  type: :runtime
44
35
  prerelease: false
45
36
  version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 7.1.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
46
44
  requirements:
47
45
  - - ">="
48
46
  - !ruby/object:Gem::Version
49
- version: 3.2.0
50
- - - "~>"
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
51
53
  - !ruby/object:Gem::Version
52
- version: 6.1.0
54
+ version: '5.0'
53
55
  - !ruby/object:Gem::Dependency
54
56
  name: rake
55
57
  requirement: !ruby/object:Gem::Requirement
@@ -65,7 +67,7 @@ dependencies:
65
67
  - !ruby/object:Gem::Version
66
68
  version: '0'
67
69
  - !ruby/object:Gem::Dependency
68
- name: minitest
70
+ name: standard
69
71
  requirement: !ruby/object:Gem::Requirement
70
72
  requirements:
71
73
  - - ">="
@@ -86,12 +88,13 @@ executables: []
86
88
  extensions: []
87
89
  extra_rdoc_files: []
88
90
  files:
89
- - ".gitignore"
90
- - ".travis.yml"
91
- - Gemfile
92
- - LICENSE
91
+ - ".rubocop.yml"
92
+ - ".standard.yml"
93
+ - CHANGELOG.md
94
+ - CODE_OF_CONDUCT.md
95
+ - LICENSE.txt
96
+ - README.md
93
97
  - Rakefile
94
- - Readme.rdoc
95
98
  - lib/spectacles.rb
96
99
  - lib/spectacles/abstract_adapter_override.rb
97
100
  - lib/spectacles/configuration.rb
@@ -107,23 +110,14 @@ files:
107
110
  - lib/spectacles/schema_statements/vertica_adapter.rb
108
111
  - lib/spectacles/version.rb
109
112
  - lib/spectacles/view.rb
110
- - specs/adapters/mysql2_adapter_spec.rb
111
- - specs/adapters/postgresql_adapter_spec.rb
112
- - specs/adapters/sqlite3_adapter_spec.rb
113
- - specs/spec_helper.rb
114
- - specs/spectacles/abstract_adapter_override_spec.rb
115
- - specs/spectacles/schema_statements/abstract_adapter_spec.rb
116
- - specs/spectacles/view_spec.rb
117
- - specs/support/minitest_matchers.rb
118
- - specs/support/minitest_shared.rb
119
- - specs/support/schema_statement_examples.rb
120
- - specs/support/view_examples.rb
121
- - spectacles.gemspec
122
113
  homepage: http://github.com/liveh2o/spectacles
123
114
  licenses:
124
115
  - MIT
125
- metadata: {}
126
- post_install_message:
116
+ metadata:
117
+ homepage_uri: http://github.com/liveh2o/spectacles
118
+ source_code_uri: http://github.com/liveh2o/spectacles
119
+ changelog_uri: http://github.com/liveh2o/spectacles/blob/main/CHANGELOG.md
120
+ post_install_message:
127
121
  rdoc_options: []
128
122
  require_paths:
129
123
  - lib
@@ -131,16 +125,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
131
125
  requirements:
132
126
  - - ">="
133
127
  - !ruby/object:Gem::Version
134
- version: 2.2.0
128
+ version: 2.7.0
135
129
  required_rubygems_version: !ruby/object:Gem::Requirement
136
130
  requirements:
137
131
  - - ">="
138
132
  - !ruby/object:Gem::Version
139
133
  version: '0'
140
134
  requirements: []
141
- rubygems_version: 3.3.6
142
- signing_key:
135
+ rubygems_version: 3.4.22
136
+ signing_key:
143
137
  specification_version: 4
144
- summary: Spectacles (derived from RailsSQLViews) adds database view functionality
145
- to ActiveRecord.
138
+ summary: Spectacles adds database view functionality to ActiveRecord.
146
139
  test_files: []
data/.gitignore DELETED
@@ -1,8 +0,0 @@
1
- .DS_Store
2
- *.gem
3
- .bundle
4
- .rvmrc
5
- Gemfile.lock
6
- pkg/*
7
- specs/*.db
8
- coverage
data/.travis.yml DELETED
@@ -1,14 +0,0 @@
1
- language: ruby
2
- jdk:
3
- - openjdk8
4
- rvm:
5
- - 2.2
6
- - 2.3
7
- - 2.4
8
- - 2.5
9
- - 2.6
10
- - jruby
11
- cache: bundler
12
- services:
13
- - mysql
14
- - postgresql
data/Gemfile DELETED
@@ -1,20 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in spectacles.gemspec
4
- gemspec
5
-
6
- platforms :jruby do
7
- gem "activerecord-jdbcmysql-adapter"
8
- gem "activerecord-jdbcpostgresql-adapter"
9
- gem "activerecord-jdbcsqlite3-adapter"
10
- end
11
-
12
- platforms :ruby do
13
- gem "mysql2"
14
- gem "pg"
15
- gem "sqlite3"
16
- end
17
-
18
- group :test do
19
- gem 'simplecov', :require => false
20
- end
data/LICENSE DELETED
@@ -1,20 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2012-2019 Adam Hutchison, Brandon Dewitt
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy of
6
- this software and associated documentation files (the "Software"), to deal in
7
- the Software without restriction, including without limitation the rights to
8
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
- the Software, and to permit persons to whom the Software is furnished to do so,
10
- subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Readme.rdoc DELETED
@@ -1,120 +0,0 @@
1
- {<img src="https://travis-ci.org/liveh2o/spectacles.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/liveh2o/spectacles] {<img src="https://badge.fury.io/rb/spectacles.svg" alt="Gem Version" />}[https://badge.fury.io/rb/spectacles]
2
-
3
- = Spectacles
4
-
5
- Spectacles adds database view functionality to ActiveRecord. It is heavily inspired by Rails SQL Views (created by https://github.com/aeden but no longer maintained) and built from the ground up to work with Rails 3.2+.
6
-
7
- Spectacles provides the ability to create views in migrations using a similar format to creating tables. It also provides an abstract view class that inherits from ActiveRecord::Base that can be used to create view-backed models.
8
-
9
- It currently works with the SQLite, MySQL, MySQL2, PostgreSQL, and Vertica drivers.
10
-
11
- = Using Spectacles
12
- Install it
13
- gem install spectacles # => OR include it in your Gemfile
14
-
15
- == Migrations
16
-
17
- Create a migration from an query string:
18
-
19
- create_view :product_users do
20
- "SELECT name AS product_name, first_name AS username FROM
21
- products JOIN users ON users.id = products.user_id"
22
- end
23
-
24
-
25
- Create a migration from an ARel object:
26
-
27
- create_view :product_users do
28
- Product.select("products.name AS product_name).
29
- select("users.first_name AS username").
30
- join(:users)
31
- end
32
-
33
- == Models
34
-
35
- class ProductUser < Spectacles::View
36
- # Add relationships
37
-
38
- # Use scopes
39
-
40
- # Your fancy methods
41
- end
42
-
43
- == Materialized Views
44
-
45
- *This feature is only supported for PostgreSQL backends.*
46
- These are essentially views that cache their result set. In this way
47
- they are kind of a cross between tables (which persist data) and views
48
- (which are windows onto other tables).
49
-
50
- create_materialized_view :product_users do
51
- <<-SQL.squish
52
- SELECT name AS product_name, first_name AS username
53
- FROM products
54
- JOIN users ON users.id = products.user_id
55
- SQL
56
- end
57
-
58
- class ProductUser < Spectacles::MaterializedView
59
- # just like Spectacles::View
60
- end
61
-
62
- Because materialized views cache a snapshot of the data as it
63
- exists at a point in time (typically when the view was created), you
64
- need to manually _refresh_ the view when new data is added to the
65
- original tables. You can do this with the +#refresh!+ method on
66
- the +Spectacles::MaterializedView+ subclass:
67
-
68
- User.create(first_name: "Bob", email: "bob@example.com")
69
- ProductUser.refresh!
70
-
71
- Also, you can specify a few different options to +create_materialized_view+
72
- to affect how the new view is created:
73
-
74
- * +:force+ - if +false+ (the default), the create will fail if a
75
- materialized view with the given name already exists. If +true+,
76
- any materialized view with that name will be dropped before the
77
- create runs.
78
-
79
- create_materialized_view :product_users, force: true do
80
- # ...
81
- end
82
-
83
- * +:data+ - if +true+ (the default), the view is immediately populated
84
- with the corresponding data. If +false+, the view will be empty initially,
85
- and must be populated by invoking the +#refresh!+ method.
86
-
87
- create_materialized_view :product_users, data: false do
88
- # ...
89
- end
90
-
91
- * +:columns+ - an optional array of names to give the columns in the view.
92
- By default, columns in the view will use the names given in the query.
93
-
94
- create_materialized_view :product_users, columns: %i(product_name username) do
95
- <<-SQL.squish
96
- SELECT products.name, users.first_name
97
- FROM products
98
- JOIN users ON users.id = products.user_id
99
- SQL
100
- end
101
-
102
- * +:tablespace+ - an optional identifier (string or symbol) indicating
103
- which namespace the materialized view ought to be created in.
104
-
105
- create_materialized_view :product_users, tablespace: "awesomesauce" do
106
- # ...
107
- end
108
-
109
- * +:storage+ - an optional hash of (database-specific) storage parameters to
110
- optimize how the materialized view is stored. (See
111
- http://www.postgresql.org/docs/9.4/static/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS
112
- for details.)
113
-
114
- create_materialized_view :product_users, storage: { fillfactor: 70 } do
115
- # ...
116
- end
117
-
118
- = License
119
-
120
- Spectacles is licensed under MIT license (Read the LICENSE file for full license)
@@ -1,16 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "Spectacles::SchemaStatements::Mysql2Adapter" do
4
- config = {
5
- :adapter => "mysql2",
6
- :host => "localhost",
7
- :username => "root"
8
- }
9
-
10
- configure_database(config)
11
- recreate_database("spectacles_test")
12
- load_schema
13
-
14
- it_behaves_like "an adapter", "Mysql2Adapter"
15
- it_behaves_like "a view model"
16
- end