diff --git a/.rubocop.yml b/.rubocop.yml index 2447a73d..b066a573 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -11,7 +11,7 @@ Bundler/OrderedGems: Gemspec/OrderedDependencies: Enabled: false -Layout/AlignParameters: +Layout/ParameterAlignment: Enabled: true EnforcedStyle: with_fixed_indentation Layout/ConditionPosition: @@ -20,7 +20,7 @@ Layout/DotPosition: EnforcedStyle: leading Layout/ExtraSpacing: Enabled: true -Layout/IndentAssignment: +Layout/AssignmentIndentation: Enabled: False Layout/MultilineOperationIndentation: Enabled: true @@ -33,7 +33,7 @@ Lint/AmbiguousOperator: Enabled: true Lint/AmbiguousRegexpLiteral: Enabled: true -Lint/DuplicatedKey: +Lint/DuplicateHashKey: Enabled: true Metrics/ClassLength: diff --git a/lib/generators/scenic/materializable.rb b/lib/generators/scenic/materializable.rb index 7e7a6cdf..1cf9badb 100644 --- a/lib/generators/scenic/materializable.rb +++ b/lib/generators/scenic/materializable.rb @@ -6,20 +6,20 @@ module Materializable included do class_option :materialized, - type: :boolean, - required: false, - desc: "Makes the view materialized", - default: false + type: :boolean, + required: false, + desc: "Makes the view materialized", + default: false class_option :no_data, - type: :boolean, - required: false, - desc: "Adds WITH NO DATA when materialized view creates/updates", - default: false + type: :boolean, + required: false, + desc: "Adds WITH NO DATA when materialized view creates/updates", + default: false class_option :replace, - type: :boolean, - required: false, - desc: "Uses replace_view instead of update_view", - default: false + type: :boolean, + required: false, + desc: "Uses replace_view instead of update_view", + default: false end private diff --git a/lib/generators/scenic/model/model_generator.rb b/lib/generators/scenic/model/model_generator.rb index 41627fcc..c2680e41 100644 --- a/lib/generators/scenic/model/model_generator.rb +++ b/lib/generators/scenic/model/model_generator.rb @@ -12,16 +12,17 @@ class ModelGenerator < Rails::Generators::NamedBase def invoke_rails_model_generator invoke "model", - [file_path.singularize], - options.merge( - fixture_replacement: false, - migration: false, - ) + [file_path.singularize], + options.merge( + fixture_replacement: false, + migration: false, + ) end def inject_model_methods if materialized? && generating? - inject_into_class "app/models/#{file_path.singularize}.rb", class_name do + inject_into_class "app/models/#{file_path.singularize}.rb", + class_name do evaluate_template("model.erb") end end diff --git a/lib/scenic/adapters/postgres.rb b/lib/scenic/adapters/postgres.rb index 6c4775c9..83ff5ada 100644 --- a/lib/scenic/adapters/postgres.rb +++ b/lib/scenic/adapters/postgres.rb @@ -60,9 +60,10 @@ def views # # @return [void] def create_view(name, sql_definition, if_not_exists: false) - if if_not_exists - return if views.any? { |view| view.name == name } + if if_not_exists && views.any? { |view| view.name == name } + return end + execute "CREATE VIEW #{quote_table_name(name)} AS #{sql_definition};" end @@ -142,7 +143,8 @@ def drop_view(name, if_exists: false) # in use does not support materialized views. # # @return [void] - def create_materialized_view(name, sql_definition, no_data: false, if_not_exists: false) + def create_materialized_view(name, sql_definition, no_data: false, + if_not_exists: false) raise_unless_materialized_views_supported definition_if_not_exists = if_not_exists ? "IF NOT EXISTS " : "" @@ -239,6 +241,7 @@ def refresh_materialized_view(name, concurrently: false, cascade: false) private attr_reader :connectable + delegate :execute, :quote_table_name, to: :connection def connection diff --git a/lib/scenic/adapters/postgres/index_reapplication.rb b/lib/scenic/adapters/postgres/index_reapplication.rb index 59ab5add..96a26843 100644 --- a/lib/scenic/adapters/postgres/index_reapplication.rb +++ b/lib/scenic/adapters/postgres/index_reapplication.rb @@ -56,7 +56,7 @@ def with_savepoint(name) yield connection.execute("RELEASE SAVEPOINT #{name}") true - rescue + rescue StandardError connection.execute("ROLLBACK TO SAVEPOINT #{name}") false end diff --git a/lib/scenic/adapters/postgres/indexes.rb b/lib/scenic/adapters/postgres/indexes.rb index 8ce36de6..74d13c27 100644 --- a/lib/scenic/adapters/postgres/indexes.rb +++ b/lib/scenic/adapters/postgres/indexes.rb @@ -20,6 +20,7 @@ def on(name) private attr_reader :connection + delegate :quote_table_name, to: :connection def indexes_on(name) diff --git a/lib/scenic/schema_dumper.rb b/lib/scenic/schema_dumper.rb index 68aab1b2..df9d9bf4 100644 --- a/lib/scenic/schema_dumper.rb +++ b/lib/scenic/schema_dumper.rb @@ -35,7 +35,8 @@ def ignored?(table_name) when String then remove_prefix_and_suffix(table_name) == ignored when Regexp then remove_prefix_and_suffix(table_name) =~ ignored else - raise StandardError, "ActiveRecord::SchemaDumper.ignore_tables accepts an array of String and / or Regexp values." + raise StandardError, + "ActiveRecord::SchemaDumper.ignore_tables accepts an array of String and / or Regexp values." end end end diff --git a/lib/scenic/statements.rb b/lib/scenic/statements.rb index 6acf6a36..a43af466 100644 --- a/lib/scenic/statements.rb +++ b/lib/scenic/statements.rb @@ -24,7 +24,8 @@ module Statements # SELECT * FROM users WHERE users.active = 't' # SQL # - def create_view(name, version: nil, sql_definition: nil, materialized: false, if_not_exists: false) + def create_view(name, version: nil, sql_definition: nil, + materialized: false, if_not_exists: false) if version.present? && sql_definition.present? raise( ArgumentError, @@ -46,7 +47,8 @@ def create_view(name, version: nil, sql_definition: nil, materialized: false, if if_not_exists: if_not_exists, ) else - Scenic.database.create_view(name, sql_definition, if_not_exists: if_not_exists) + Scenic.database.create_view(name, sql_definition, + if_not_exists: if_not_exists) end end @@ -65,7 +67,8 @@ def create_view(name, version: nil, sql_definition: nil, materialized: false, if # @example Drop a view, rolling back to version 3 on rollback # drop_view(:users_who_recently_logged_in, revert_to_version: 3) # - def drop_view(name, revert_to_version: nil, materialized: false, if_exists: false) + def drop_view(name, revert_to_version: nil, materialized: false, + if_exists: false) if materialized Scenic.database.drop_materialized_view(name, if_exists: if_exists) else @@ -93,7 +96,8 @@ def drop_view(name, revert_to_version: nil, materialized: false, if_exists: fals # @example # update_view :engagement_reports, version: 3, revert_to_version: 2 # - def update_view(name, version: nil, sql_definition: nil, revert_to_version: nil, materialized: false) + def update_view(name, version: nil, sql_definition: nil, + revert_to_version: nil, materialized: false) if version.blank? && sql_definition.blank? raise( ArgumentError, @@ -137,7 +141,8 @@ def update_view(name, version: nil, sql_definition: nil, revert_to_version: nil, # @example # replace_view :engagement_reports, version: 3, revert_to_version: 2 # - def replace_view(name, version: nil, revert_to_version: nil, materialized: false) + def replace_view(name, version: nil, revert_to_version: nil, + materialized: false) if version.blank? raise ArgumentError, "version is required" end diff --git a/spec/scenic/adapters/postgres_spec.rb b/spec/scenic/adapters/postgres_spec.rb index 00ff1e15..78f728b1 100644 --- a/spec/scenic/adapters/postgres_spec.rb +++ b/spec/scenic/adapters/postgres_spec.rb @@ -15,7 +15,8 @@ module Adapters it "successfully creates a view with :if_not_exists if view does not exist" do adapter = Postgres.new - adapter.create_view("greetings", "SELECT text 'hi' AS greeting", if_not_exists: true) + adapter.create_view("greetings", "SELECT text 'hi' AS greeting", + if_not_exists: true) expect(adapter.views.map(&:name)).to include("greetings") end @@ -24,7 +25,10 @@ module Adapters adapter = Postgres.new adapter.create_view("greetings", "SELECT text 'hi' AS greeting") - expect { adapter.create_view("greetings", "SELECT text 'hi' AS greeting", if_not_exists: true) } + expect { + adapter.create_view("greetings", "SELECT text 'hi' AS greeting", + if_not_exists: true) + } .not_to raise_error end end @@ -106,7 +110,9 @@ module Adapters it "does not raise error with :if_exists if view does not exist" do adapter = Postgres.new - expect { adapter.drop_view("greetings", if_exists: true) }.not_to raise_error + expect { + adapter.drop_view("greetings", if_exists: true) + }.not_to raise_error end end @@ -138,7 +144,10 @@ module Adapters it "does not raise error with :if_exists if view does not exist" do adapter = Postgres.new - expect { adapter.drop_materialized_view("greetings", if_exists: true) }.not_to raise_error + expect { + adapter.drop_materialized_view("greetings", + if_exists: true) + }.not_to raise_error end it "raises an exception if the version of PostgreSQL is too old" do diff --git a/spec/scenic/command_recorder_spec.rb b/spec/scenic/command_recorder_spec.rb index edc1016f..484ab9bd 100644 --- a/spec/scenic/command_recorder_spec.rb +++ b/spec/scenic/command_recorder_spec.rb @@ -24,7 +24,7 @@ recorder.revert { recorder.create_view :greetings, materialized: true } expect(recorder.commands).to eq [ - [:drop_view, [:greetings, materialized: true]], + [:drop_view, [:greetings, { materialized: true }]], ] end end diff --git a/spec/scenic/schema_dumper_spec.rb b/spec/scenic/schema_dumper_spec.rb index 893dd9f9..ccdd1a20 100644 --- a/spec/scenic/schema_dumper_spec.rb +++ b/spec/scenic/schema_dumper_spec.rb @@ -44,7 +44,8 @@ class SearchInAHaystack < ActiveRecord::Base it "dumps a create_view for a materialized view in the database" do view_definition = "SELECT 'needle'::text AS haystack" - Search.connection.create_view :searches, materialized: true, sql_definition: view_definition + Search.connection.create_view :searches, materialized: true, + sql_definition: view_definition stream = StringIO.new ActiveRecord::SchemaDumper.dump(Search.connection, stream) @@ -59,7 +60,8 @@ class SearchInAHaystack < ActiveRecord::Base it "dumps a create_view including namespace for a view in the database" do view_definition = "SELECT 'needle'::text AS haystack" Search.connection.execute "CREATE SCHEMA scenic; SET search_path TO scenic, public" - Search.connection.create_view :"scenic.searches", sql_definition: view_definition + Search.connection.create_view :"scenic.searches", + sql_definition: view_definition stream = StringIO.new ActiveRecord::SchemaDumper.dump(Search.connection, stream) @@ -74,7 +76,8 @@ class SearchInAHaystack < ActiveRecord::Base it "handles active record table name prefixes and suffixes" do with_affixed_tables(prefix: "a_", suffix: "_z") do view_definition = "SELECT 'needle'::text AS haystack" - Search.connection.create_view :a_searches_z, sql_definition: view_definition + Search.connection.create_view :a_searches_z, + sql_definition: view_definition stream = StringIO.new ActiveRecord::SchemaDumper.dump(Search.connection, stream) @@ -102,7 +105,8 @@ class SearchInAHaystack < ActiveRecord::Base context "with views using unexpected characters in name" do it "dumps a create_view for a view in the database" do view_definition = "SELECT 'needle'::text AS haystack" - Search.connection.create_view '"search in a haystack"', sql_definition: view_definition + Search.connection.create_view '"search in a haystack"', + sql_definition: view_definition stream = StringIO.new ActiveRecord::SchemaDumper.dump(Search.connection, stream) @@ -126,7 +130,7 @@ class SearchInAHaystack < ActiveRecord::Base "CREATE SCHEMA scenic; SET search_path TO scenic, public", ) Search.connection.create_view 'scenic."search in a haystack"', - sql_definition: view_definition + sql_definition: view_definition stream = StringIO.new ActiveRecord::SchemaDumper.dump(Search.connection, stream) diff --git a/spec/scenic/statements_spec.rb b/spec/scenic/statements_spec.rb index 97bab4bd..bbda3e42 100644 --- a/spec/scenic/statements_spec.rb +++ b/spec/scenic/statements_spec.rb @@ -83,7 +83,8 @@ module Scenic definition = instance_double("Scenic::Definition", to_sql: "definition") allow(Definition).to receive(:new).and_return(definition) - connection.create_view(:views, version: 1, materialized: true, if_not_exists: true) + connection.create_view(:views, version: 1, materialized: true, + if_not_exists: true) expect(Scenic.database).to have_received(:create_materialized_view) .with(:views, definition.to_sql, no_data: false, if_not_exists: true) @@ -94,7 +95,8 @@ module Scenic it "removes a view from the database" do connection.drop_view :name - expect(Scenic.database).to have_received(:drop_view).with(:name, if_exists: false) + expect(Scenic.database).to have_received(:drop_view).with(:name, + if_exists: false) end it "removes a view from the database if it exists" do diff --git a/spec/support/generator_spec_setup.rb b/spec/support/generator_spec_setup.rb index fdeaa9d1..ead31fc6 100644 --- a/spec/support/generator_spec_setup.rb +++ b/spec/support/generator_spec_setup.rb @@ -1,6 +1,6 @@ require "rspec/rails" -require "ammeter/rspec/generator/example.rb" -require "ammeter/rspec/generator/matchers.rb" +require "ammeter/rspec/generator/example" +require "ammeter/rspec/generator/matchers" require "ammeter/init" RSpec.configure do |config|