hsgubert/rails-sharding

View on GitHub
lib/rails/sharding/connection_handler.rb

Summary

Maintainability
A
25 mins
Test Coverage

Assignment Branch Condition size for establish_connection is too high. [24.1/15]
Open

    def self.establish_connection(shard_group, shard_name, environment=nil)
      self.setup unless defined? @@connection_handler

      configurations = (environment.nil? ? Core.configurations : Core.configurations(environment))

This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric

Method has too many lines. [16/10]
Open

    def self.establish_connection(shard_group, shard_name, environment=nil)
      self.setup unless defined? @@connection_handler

      configurations = (environment.nil? ? Core.configurations : Core.configurations(environment))

This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.

Method has too many lines. [14/10]
Open

    def self.add_shard_tag_to_connection_log(connection, shard_tag)
      # avoids modifing connection twice
      if connection.respond_to? :shard_tag
        connection.shard_tag = shard_tag
        return connection

This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.

Method establish_connection has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring.
Open

    def self.establish_connection(shard_group, shard_name, environment=nil)
      self.setup unless defined? @@connection_handler

      configurations = (environment.nil? ? Core.configurations : Core.configurations(environment))

Severity: Minor
Found in lib/rails/sharding/connection_handler.rb - About 25 mins to fix

Cognitive Complexity

Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

A method's cognitive complexity is based on a few simple rules:

  • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
  • Code is considered more complex for each "break in the linear flow of the code"
  • Code is considered more complex when "flow breaking structures are nested"

Further reading

Avoid parameter lists longer than 5 parameters. [6/5]
Open

        def log(sql, name="SQL", binds=[], type_casted_binds=[], statement_name=nil, &block)

This cop checks for methods with too many parameters. The maximum number of parameters is configurable. Keyword arguments can optionally be excluded from the total count.

Indent access modifiers like private.
Open

  private

Modifiers should be indented as deep as method definitions, or as deep as the class/module keyword, depending on configuration.

Example: EnforcedStyle: indent (default)

# bad
class Plumbus
private
  def smooth; end
end

# good
class Plumbus
  private
  def smooth; end
end

Example: EnforcedStyle: outdent

# bad
class Plumbus
  private
  def smooth; end
end

# good
class Plumbus
private
  def smooth; end
end

Surrounding space missing in default value assignment.
Open

    def self.establish_connection(shard_group, shard_name, environment=nil)

Checks that the equals signs in parameter default assignments have or don't have surrounding space depending on configuration.

Example:

# bad
def some_method(arg1=:default, arg2=nil, arg3=[])
  # do something...
end

# good
def some_method(arg1 = :default, arg2 = nil, arg3 = [])
  # do something...
end

Useless private access modifier.
Open

  private

This cop checks for redundant access modifiers, including those with no code, those which are repeated, and leading public modifiers in a class or module body. Conditionally-defined methods are considered as always being defined, and thus access modifiers guarding such methods are not redundant.

Example:

class Foo
  public # this is redundant (default access is public)

  def method
  end

  private # this is not redundant (a method is defined)
  def method2
  end

  private # this is redundant (no following methods are defined)
end

Example:

class Foo
  # The following is not redundant (conditionally defined methods are
  # considered as always defining a method)
  private

  if condition?
    def method
    end
  end

  protected # this is not redundant (method is defined)

  define_method(:method2) do
  end

  protected # this is redundant (repeated from previous modifier)

  [1,2,3].each do |i|
    define_method("foo#{i}") do
    end
  end

  # The following is redundant (methods defined on the class'
  # singleton class are not affected by the public modifier)
  public

  def self.method3
  end
end

Example:

# Lint/UselessAccessModifier:
#   ContextCreatingMethods:
#     - concerning
require 'active_support/concern'
class Foo
  concerning :Bar do
    def some_public_method
    end

    private

    def some_private_method
    end
  end

  # this is not redundant because `concerning` created its own context
  private

  def some_other_private_method
  end
end

Example:

# Lint/UselessAccessModifier:
#   MethodCreatingMethods:
#     - delegate
require 'active_support/core_ext/module/delegation'
class Foo
  # this is not redundant because `delegate` creates methods
  private

  delegate :method_a, to: :method_b
end

Line is too long. [82/80]
Open

      # database.yml) and it notifies subscribers of a event that does not concern

Use == if you meant to do a comparison or wrap the expression in parentheses to indicate you meant to assign in a condition.
Open

      if connection_pool = connection_handler.retrieve_connection_pool(connection_name(shard_group, shard_name))

This cop checks for assignments in the conditions of if/while/until.

Example:

# bad

if some_var = true
  do_something
end

Example:

# good

if some_var == true
  do_something
end

Line is too long. [98/80]
Open

      configurations = (environment.nil? ? Core.configurations : Core.configurations(environment))

private (on line 94) does not make singleton methods private. Use private_class_method or private inside a class << self block instead.
Open

    def self.connection_name(shard_group, shard_name)

This cop checks for private or protected access modifiers which are applied to a singleton method. These access modifiers do not make singleton methods private/protected. private_class_method can be used for that.

Example:

# bad

class C
  private

  def self.method
    puts 'hi'
  end
end

Example:

# good

class C
  def self.method
    puts 'hi'
  end

  private_class_method :method
end

Example:

# good

class C
  class << self
    private

    def method
      puts 'hi'
    end
  end
end

Line is too long. [84/80]
Open

      @@connection_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new

Line is too long. [118/80]
Open

      raise Errors::UninitializedError, 'Shards::ConnectionHandler was not setup' unless defined? @@connection_handler

Line is too long. [84/80]
Open

      # it has become simpler than reusing the one from rails. And it will not break

Extra empty line detected at class body beginning.
Open


    # Establishes connections to all shards in all shard groups.

This cops checks if empty lines around the bodies of classes match the configuration.

Example: EnforcedStyle: empty_lines

# good

class Foo

  def bar
    # ...
  end

end

Example: EnforcedStyle: emptylinesexcept_namespace

# good

class Foo
  class Bar

    # ...

  end
end

Example: EnforcedStyle: emptylinesspecial

# good
class Foo

  def bar; end

end

Example: EnforcedStyle: noemptylines (default)

# good

class Foo
  def bar
    # ...
  end
end

private (on line 94) does not make singleton methods private. Use private_class_method or private inside a class << self block instead.
Open

    def self.connection_handler

This cop checks for private or protected access modifiers which are applied to a singleton method. These access modifiers do not make singleton methods private/protected. private_class_method can be used for that.

Example:

# bad

class C
  private

  def self.method
    puts 'hi'
  end
end

Example:

# good

class C
  def self.method
    puts 'hi'
  end

  private_class_method :method
end

Example:

# good

class C
  class << self
    private

    def method
      puts 'hi'
    end
  end
end

Use nested module/class definitions instead of compact style.
Open

module Rails::Sharding

This cop checks the style of children definitions at classes and modules. Basically there are two different styles:

Example: EnforcedStyle: nested (default)

# good
# have each child on its own line
class Foo
  class Bar
  end
end

Example: EnforcedStyle: compact

# good
# combine definitions as much as possible
class Foo::Bar
end

The compact style is only forced for classes/modules with one child.

Missing magic comment # frozen_string_literal: true.
Open

module Rails::Sharding

This cop is designed to help upgrade to Ruby 3.0. It will add the comment # frozen_string_literal: true to the top of files to enable frozen string literals. Frozen string literals may be default in Ruby 3.0. The comment will be added below a shebang and encoding comment. The frozen string literal comment is only valid in Ruby 2.3+.

Example: EnforcedStyle: when_needed (default)

# The `when_needed` style will add the frozen string literal comment
# to files only when the `TargetRubyVersion` is set to 2.3+.
# bad
module Foo
  # ...
end

# good
# frozen_string_literal: true

module Foo
  # ...
end

Example: EnforcedStyle: always

# The `always` style will always add the frozen string literal comment
# to a file, regardless of the Ruby version or if `freeze` or `<<` are
# called on a string literal.
# bad
module Bar
  # ...
end

# good
# frozen_string_literal: true

module Bar
  # ...
end

Example: EnforcedStyle: never

# The `never` will enforce that the frozen string literal comment does
# not exist in a file.
# bad
# frozen_string_literal: true

module Baz
  # ...
end

# good
module Baz
  # ...
end

Line is too long. [81/80]
Open

    # Adds a shard tag to the log of all queries executed through this connection

Line is too long. [92/80]
Open

        def log(sql, name="SQL", binds=[], type_casted_binds=[], statement_name=nil, &block)

Line is too long. [208/80]
Open

        raise Errors::ConfigNotFoundError, "Cannot find configuration for shard '#{shard_group}:#{shard_name}' in environment '#{environment}' in #{Config.shards_config_file}, or it does not specify :adapter"

Line is too long. [84/80]
Open

      connection_handler.remove_connection(connection_name(shard_group, shard_name))

Line is too long. [116/80]
Open

      resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(shard_group_configurations)

Line is too long. [150/80]
Open

      raise ActiveRecord::ConnectionNotEstablished, "No connection pool for shard #{connection_name(shard_group, shard_name)}" if connection_pool.nil?

Redundant self detected.
Open

      self.setup unless defined? @@connection_handler

This cop checks for redundant uses of self.

The usage of self is only needed when:

  • Sending a message to same object with zero arguments in presence of a method name clash with an argument or a local variable.

  • Calling an attribute writer to prevent an local variable assignment.

Note, with using explicit self you can only send messages with public or protected scope, you cannot send private messages this way.

Note we allow uses of self with operators because it would be awkward otherwise.

Example:

# bad
def foo(bar)
  self.baz
end

# good
def foo(bar)
  self.bar  # Resolves name clash with the argument.
end

def foo
  bar = 1
  self.bar  # Resolves name clash with the local variable.
end

def foo
  %w[x y z].select do |bar|
    self.bar == bar  # Resolves name clash with argument of the block.
  end
end

Prefer single-quoted strings when you don't need string interpolation or special symbols.
Open

        def log(sql, name="SQL", binds=[], type_casted_binds=[], statement_name=nil, &block)

Checks if uses of quotes match the configured preference.

Example: EnforcedStyle: single_quotes (default)

# bad
"No special symbols"
"No string interpolation"
"Just text"

# good
'No special symbols'
'No string interpolation'
'Just text'
"Wait! What's #{this}!"

Example: EnforcedStyle: double_quotes

# bad
'Just some text'
'No special chars or interpolation'

# good
"Just some text"
"No special chars or interpolation"
"Every string in #{project} uses double_quotes"

Line is too long. [85/80]
Open

        # key you used to retrieve it from the resolver, in this case the shard_name.

Replace class var @@connection_handler with a class instance var.
Open

      @@connection_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new

This cop checks for uses of class variables. Offenses are signaled only on assignment to class variables to reduce the number of offenses that would be reported.

private (on line 94) does not make singleton methods private. Use private_class_method or private inside a class << self block instead.
Open

    def self.setup

This cop checks for private or protected access modifiers which are applied to a singleton method. These access modifiers do not make singleton methods private/protected. private_class_method can be used for that.

Example:

# bad

class C
  private

  def self.method
    puts 'hi'
  end
end

Example:

# good

class C
  def self.method
    puts 'hi'
  end

  private_class_method :method
end

Example:

# good

class C
  class << self
    private

    def method
      puts 'hi'
    end
  end
end

Line is too long. [167/80]
Open

        raise Errors::ConfigNotFoundError, "Cannot find configuration for shard_group '#{shard_group}' in environment '#{environment}' in #{Config.shards_config_file}"

Line is too long. [82/80]
Open

        # since Rails 5.1 connection_spec already comes with :name set to whatever

Line is too long. [85/80]
Open

    # Obs: connection inherits from ActiveRecord::ConnectionAdapters::AbstractAdapter

Missing top-level class documentation comment.
Open

  class ConnectionHandler

This cop checks for missing top-level documentation of classes and modules. Classes with no body are exempt from the check and so are namespace modules - modules that have nothing in their bodies except classes, other modules, or constant definitions.

The documentation requirement is annulled if the class or module has a "#:nodoc:" comment next to it. Likewise, "#:nodoc: all" does the same for all its children.

Example:

# bad
class Person
  # ...
end

# good
# Description/Explanation of Person class
class Person
  # ...
end

private (on line 94) does not make singleton methods private. Use private_class_method or private inside a class << self block instead.
Open

    def self.add_shard_tag_to_connection_log(connection, shard_tag)

This cop checks for private or protected access modifiers which are applied to a singleton method. These access modifiers do not make singleton methods private/protected. private_class_method can be used for that.

Example:

# bad

class C
  private

  def self.method
    puts 'hi'
  end
end

Example:

# good

class C
  def self.method
    puts 'hi'
  end

  private_class_method :method
end

Example:

# good

class C
  class << self
    private

    def method
      puts 'hi'
    end
  end
end

Line is too long. [83/80]
Open

          original_log(sql, name, binds, type_casted_binds, statement_name, &block)

Surrounding space missing in default value assignment.
Open

        def log(sql, name="SQL", binds=[], type_casted_binds=[], statement_name=nil, &block)

Checks that the equals signs in parameter default assignments have or don't have surrounding space depending on configuration.

Example:

# bad
def some_method(arg1=:default, arg2=nil, arg3=[])
  # do something...
end

# good
def some_method(arg1 = :default, arg2 = nil, arg3 = [])
  # do something...
end

Line is too long. [139/80]
Open

      connection_handler.send(:owner_to_pool)[connection_spec.name] = ActiveRecord::ConnectionAdapters::ConnectionPool.new(connection_spec)

Line is too long. [84/80]
Open

      # Note: we should consider writting our connection handler from scratch, since

Line is too long. [112/80]
Open

      if connection_pool = connection_handler.retrieve_connection_pool(connection_name(shard_group, shard_name))

Surrounding space missing in default value assignment.
Open

        def log(sql, name="SQL", binds=[], type_casted_binds=[], statement_name=nil, &block)

Checks that the equals signs in parameter default assignments have or don't have surrounding space depending on configuration.

Example:

# bad
def some_method(arg1=:default, arg2=nil, arg3=[])
  # do something...
end

# good
def some_method(arg1 = :default, arg2 = nil, arg3 = [])
  # do something...
end

Surrounding space missing in default value assignment.
Open

        def log(sql, name="SQL", binds=[], type_casted_binds=[], statement_name=nil, &block)

Checks that the equals signs in parameter default assignments have or don't have surrounding space depending on configuration.

Example:

# bad
def some_method(arg1=:default, arg2=nil, arg3=[])
  # do something...
end

# good
def some_method(arg1 = :default, arg2 = nil, arg3 = [])
  # do something...
end

Line is too long. [86/80]
Open

      # Since Rails 5.1 we cannot use connection_handler.establish_connection anymore,

Surrounding space missing in default value assignment.
Open

        def log(sql, name="SQL", binds=[], type_casted_binds=[], statement_name=nil, &block)

Checks that the equals signs in parameter default assignments have or don't have surrounding space depending on configuration.

Example:

# bad
def some_method(arg1=:default, arg2=nil, arg3=[])
  # do something...
end

# good
def some_method(arg1 = :default, arg2 = nil, arg3 = [])
  # do something...
end

There are no issues that match your filters.

Category
Status