spectacles 6.0.0 → 7.0.0

Sign up to get free protection for your applications and to get access to all the features.
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 +54 -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 +3 -3
  15. data/lib/spectacles/schema_statements/postgresql_adapter.rb +31 -33
  16. data/lib/spectacles/schema_statements/sqlite3_adapter.rb +7 -7
  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,4 +1,4 @@
1
- require 'spectacles/schema_statements/abstract_adapter'
1
+ require "spectacles/schema_statements/abstract_adapter"
2
2
 
3
3
  module Spectacles
4
4
  module SchemaStatements
@@ -15,24 +15,24 @@ module Spectacles
15
15
  SQL
16
16
  sql << " AND name = #{quote_table_name(table_name)}" if table_name
17
17
 
18
- exec_query(sql, 'SCHEMA').map do |row|
19
- row['name']
18
+ exec_query(sql, "SCHEMA").map do |row|
19
+ row["name"]
20
20
  end
21
21
  end
22
22
 
23
23
  def generate_view_query(*columns)
24
24
  <<-SQL
25
- SELECT #{columns.join(',')}
25
+ SELECT #{columns.join(",")}
26
26
  FROM sqlite_master
27
27
  WHERE type = 'view'
28
28
  SQL
29
29
  end
30
30
 
31
- def views #:nodoc:
31
+ def views # :nodoc:
32
32
  sql = generate_view_query(:name)
33
33
 
34
34
  exec_query(sql, "SCHEMA").map do |row|
35
- row['name']
35
+ row["name"]
36
36
  end
37
37
  end
38
38
 
@@ -41,7 +41,7 @@ module Spectacles
41
41
  sql << " AND name = #{quote_table_name(table_name)}"
42
42
 
43
43
  row = exec_query(sql, "SCHEMA").first
44
- row['sql'].gsub(/CREATE VIEW .*? AS/i, "")
44
+ row["sql"].gsub(/CREATE VIEW .*? AS/i, "")
45
45
  end
46
46
  end
47
47
  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.0.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.0.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.0.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.0.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.0.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.0.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.6
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