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.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/.standard.yml +4 -0
- data/CHANGELOG.md +58 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +21 -0
- data/README.md +136 -0
- data/Rakefile +15 -15
- data/lib/spectacles/abstract_adapter_override.rb +3 -3
- data/lib/spectacles/materialized_view.rb +7 -7
- data/lib/spectacles/railtie.rb +3 -3
- data/lib/spectacles/schema_dumper.rb +1 -1
- data/lib/spectacles/schema_statements/abstract_adapter.rb +15 -9
- data/lib/spectacles/schema_statements/mysql2_adapter.rb +6 -26
- data/lib/spectacles/schema_statements/postgresql_adapter.rb +31 -33
- data/lib/spectacles/schema_statements/sqlite3_adapter.rb +5 -20
- data/lib/spectacles/schema_statements/sqlserver_adapter.rb +5 -5
- data/lib/spectacles/schema_statements/vertica_adapter.rb +5 -5
- data/lib/spectacles/schema_statements.rb +2 -2
- data/lib/spectacles/version.rb +3 -1
- data/lib/spectacles/view.rb +5 -5
- data/lib/spectacles.rb +14 -12
- metadata +37 -44
- data/.gitignore +0 -8
- data/.travis.yml +0 -14
- data/Gemfile +0 -20
- data/LICENSE +0 -20
- data/Readme.rdoc +0 -120
- data/specs/adapters/mysql2_adapter_spec.rb +0 -16
- data/specs/adapters/postgresql_adapter_spec.rb +0 -68
- data/specs/adapters/sqlite3_adapter_spec.rb +0 -14
- data/specs/spec_helper.rb +0 -53
- data/specs/spectacles/abstract_adapter_override_spec.rb +0 -14
- data/specs/spectacles/schema_statements/abstract_adapter_spec.rb +0 -82
- data/specs/spectacles/view_spec.rb +0 -7
- data/specs/support/minitest_matchers.rb +0 -5
- data/specs/support/minitest_shared.rb +0 -20
- data/specs/support/schema_statement_examples.rb +0 -241
- data/specs/support/view_examples.rb +0 -62
- data/spectacles.gemspec +0 -33
@@ -1,21 +1,21 @@
|
|
1
|
-
require
|
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)
|
8
|
+
def views(name = nil) # :nodoc:
|
9
9
|
q = <<-SQL
|
10
|
-
SELECT t.table_name
|
11
|
-
FROM information_schema.
|
12
|
-
INNER JOIN pg_class AS c ON c.relname = t.table_name
|
13
|
-
WHERE t.table_schema = ANY(current_schemas(
|
14
|
-
AND
|
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[
|
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[
|
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 ==
|
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
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
79
|
+
"(" + options[:columns].map { |c| quote_column_name(c) }.join(",") + ")"
|
80
|
+
else
|
81
|
+
""
|
82
|
+
end
|
84
83
|
|
85
|
-
storage = if options[:storage]
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
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
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
91
|
+
"TABLESPACE #{quote_table_name(options[:tablespace])}"
|
92
|
+
else
|
93
|
+
""
|
94
|
+
end
|
96
95
|
|
97
96
|
with_data = if options.fetch(:data, true)
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
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(
|
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
|
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
|
16
|
+
def views # :nodoc:
|
32
17
|
sql = generate_view_query(:name)
|
33
18
|
|
34
19
|
exec_query(sql, "SCHEMA").map do |row|
|
35
|
-
row[
|
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[
|
29
|
+
row["sql"].gsub(/CREATE VIEW .*? AS/i, "")
|
45
30
|
end
|
46
31
|
end
|
47
32
|
end
|
@@ -1,22 +1,22 @@
|
|
1
|
-
require
|
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)
|
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
|
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
|
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[
|
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
|
1
|
+
require "spectacles/schema_statements/abstract_adapter"
|
2
2
|
|
3
3
|
module Spectacles
|
4
|
-
SUPPORTED_ADAPTERS = %w
|
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|
|
data/lib/spectacles/version.rb
CHANGED
data/lib/spectacles/view.rb
CHANGED
@@ -7,7 +7,7 @@ module Spectacles
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def self.view_exists?
|
10
|
-
|
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 ==(
|
18
|
+
def ==(other)
|
19
19
|
super ||
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
|
11
|
-
require
|
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
|
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:
|
4
|
+
version: 7.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Hutchison, Brandon Dewitt
|
8
|
-
autorequire:
|
9
|
-
bindir:
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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
|
-
- ".
|
90
|
-
- ".
|
91
|
-
-
|
92
|
-
-
|
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
|
-
|
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.
|
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.
|
142
|
-
signing_key:
|
135
|
+
rubygems_version: 3.4.22
|
136
|
+
signing_key:
|
143
137
|
specification_version: 4
|
144
|
-
summary: Spectacles
|
145
|
-
to ActiveRecord.
|
138
|
+
summary: Spectacles adds database view functionality to ActiveRecord.
|
146
139
|
test_files: []
|
data/.gitignore
DELETED
data/.travis.yml
DELETED
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
|