n_1_finder 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 53d31e40235f5510cee7b906ce2c83f76d681eb3
4
- data.tar.gz: bc1cf15f6593999d87e9f4f10c9e1ab2fcc1cc54
3
+ metadata.gz: 961ceb11825e90ca10011fb5d9be594976e31d30
4
+ data.tar.gz: 2223479f079ca9e0c1e1384243e76ad249babf64
5
5
  SHA512:
6
- metadata.gz: bf40aa00184ebd40ae71ad11e7d19d70af0a7dbd9d3795afe3f9c30cfd9c00246287bf7da75ab975493b839b5630595e83ffe95664542a97f043a9f2ac2b0e2d
7
- data.tar.gz: 7ea778e457f4de2dc18d74e48c8d5755722254a76046682eeff1606324a577d4d74f66b70559e05639f5ab4f74332557f5ef3f9d6a5a02e47f82e41436452874
6
+ metadata.gz: a15d14a85b1293769a7f11b77ff2fd0009b15e43502c8b1bb3ca3393d4f8682bfe71eceab4a5064e7470879498d835b6c4d8a3da7d73556a06089f03d98e0930
7
+ data.tar.gz: d5814f4732a51d49a1fde41f3a2d5ef7b9125910aae695ea686a959d6b02e0d531a0d0bc572fa20e11998bbd2de6f552e6830a122a61ea7d4ef2fba1174cc2ce
data/Readme.md CHANGED
@@ -2,6 +2,7 @@
2
2
  [![Gem Version](https://badge.fury.io/rb/n_1_finder.svg)](https://badge.fury.io/rb/n_1_finder)
3
3
  [![Build Status](https://api.travis-ci.org/aglushkov/n1_finder.svg?branch=master)](https://travis-ci.org/aglushkov/n1_finder)
4
4
  [![Inline docs](http://inch-ci.org/github/aglushkov/n1_finder.svg?branch=master)](http://inch-ci.org/github/aglushkov/n1_finder)
5
+ [![Code Climate](https://codeclimate.com/github/aglushkov/n1_finder/badges/gpa.svg)](https://codeclimate.com/github/aglushkov/n1_finder)
5
6
 
6
7
  This gem helps to find N+1 queries.
7
8
 
@@ -12,27 +13,6 @@
12
13
  ## Installation
13
14
  `gem 'n_1_finder', group: :development`
14
15
 
15
- ## Configuration
16
- ### Logger
17
- Default is `Logger.new(STDOUT)`
18
-
19
- Logger can be any instance of `Logger` class.
20
-
21
- ```ruby
22
- N1Finder.logger = Logger.new('log/n1.log')
23
- ```
24
-
25
- ### ORM
26
- Default is `:active_record` if you have activerecord gem installed.
27
-
28
- Default is `:sequel` if you have sequel gem installed.
29
-
30
- Allowed values are `:active_record` and `:sequel`
31
-
32
- ```ruby
33
- N1Finder.orm = :active_record
34
- ```
35
-
36
16
  ## Using
37
17
  Include middleware to your Rack app:
38
18
  ```ruby
@@ -68,6 +48,27 @@ N+1 QUERY DETECTED:
68
48
  SELECT "comments".* FROM "comments" WHERE "comments"."user_id" = $1, user_id = 947
69
49
  ```
70
50
 
51
+ ## Configuration
52
+ ### Logger
53
+ Default is `Logger.new(STDOUT)`
54
+
55
+ Logger can be any instance of `Logger` class.
56
+
57
+ ```ruby
58
+ N1Finder.logger = Logger.new('log/n1.log')
59
+ ```
60
+
61
+ ### ORM
62
+ Default is `:active_record` if you have activerecord gem installed.
63
+
64
+ Default is `:sequel` if you have sequel gem installed.
65
+
66
+ Allowed values are `:active_record` and `:sequel`
67
+
68
+ ```ruby
69
+ N1Finder.orm = :active_record
70
+ ```
71
+
71
72
  ## Running tests
72
73
  - Copy `spec/.env.example` file to `spec/.env` and set database credentials.
73
74
  ```bash
data/lib/n_1_finder.rb CHANGED
@@ -1,32 +1,7 @@
1
- require 'n_1_finder/logger'
2
- require 'n_1_finder/middleware'
3
- require 'n_1_finder/query'
4
- require 'n_1_finder/n_1_query'
5
- require 'n_1_finder/storage'
6
- require 'n_1_finder/adapters/base_adapter'
7
- require 'n_1_finder/adapters/active_record_adapter'
8
- require 'n_1_finder/adapters/sequel_adapter'
9
- require 'n_1_finder/adapters/null_adapter'
10
-
11
1
  # Main class
12
2
  class N1Finder
13
- # Base error
14
- # @api private
15
- class Invalid < StandardError; end
16
-
17
- # Raised when specifying invalid ORM
18
- # @api private
19
- class InvalidORM < Invalid; end
20
-
21
- # Raised when specifying invalid logger
22
- # @api private
23
- class InvalidLogger < Invalid; end
24
-
25
3
  # Supported ORM adapters
26
- ORM_ADAPTERS = {
27
- active_record: N1Finder::Adapters::ActiveRecordAdapter,
28
- sequel: N1Finder::Adapters::SequelAdapter
29
- }.freeze
4
+ ORM_ADAPTERS = [:active_record, :sequel].freeze
30
5
 
31
6
  class << self
32
7
  # Supported ORM adapters
@@ -37,10 +12,10 @@ class N1Finder
37
12
  #
38
13
  # @return [void] result of block call
39
14
  def find
40
- storage = N1Finder::Storage.new
15
+ storage = Storage.new
41
16
  result = catch_queries(storage) { yield }
42
- n1_queries = N1Finder::N1Query.generate_by(storage.queries)
43
- N1Finder::Logger.new.log(n1_queries)
17
+ n1_queries = N1Query.generate_by(storage.queries)
18
+ Logger.new.log(n1_queries)
44
19
 
45
20
  result
46
21
  end
@@ -59,11 +34,11 @@ class N1Finder
59
34
  # @param [Logger] custom_logger
60
35
  # Must be instance of `Logger`
61
36
  #
62
- # @raise [N1Finder::InvalidLogger] If custom_logger is not an instance of `Logger`.
37
+ # @raise [N1Finder::Errors::InvalidLogger] If custom_logger is not an instance of `Logger`.
63
38
  #
64
39
  # @return [Logger]
65
40
  def logger=(custom_logger)
66
- raise N1Finder::InvalidLogger unless custom_logger.is_a?(::Logger)
41
+ raise Errors::InvalidLogger unless custom_logger.is_a?(::Logger)
67
42
 
68
43
  @logger = custom_logger
69
44
  end
@@ -75,12 +50,11 @@ class N1Finder
75
50
  #
76
51
  # @return [Symbol, nil]
77
52
  def orm
78
- @orm ||=
79
- if defined?(ActiveRecord)
80
- :active_record
81
- elsif defined?(Sequel)
82
- :sequel
83
- end
53
+ @orm ||= if defined?(ActiveRecord)
54
+ :active_record
55
+ elsif defined?(Sequel)
56
+ :sequel
57
+ end
84
58
  end
85
59
 
86
60
  # Configure ORM
@@ -88,11 +62,11 @@ class N1Finder
88
62
  # @param [Symbol] custom_orm
89
63
  # Must be `:active_record` or `:sequel`
90
64
  #
91
- # @raise [N1Finder::InvalidORM] If custom_orm is not in allowed list.
65
+ # @raise [N1Finder::Errors::InvalidORM] If custom_orm is not in allowed list.
92
66
  #
93
67
  # @return [Symbol]
94
68
  def orm=(custom_orm)
95
- raise N1Finder::InvalidORM unless ORM_ADAPTERS.keys.include?(custom_orm)
69
+ raise Errors::InvalidORM unless ORM_ADAPTERS.include?(custom_orm)
96
70
 
97
71
  @orm = custom_orm
98
72
  end
@@ -100,12 +74,22 @@ class N1Finder
100
74
  private
101
75
 
102
76
  def catch_queries(storage)
103
- adapter = adapter_class.new(storage)
77
+ adapter = Adapters::Factory.get(orm, storage)
104
78
  adapter.exec(&Proc.new)
105
79
  end
106
-
107
- def adapter_class
108
- ORM_ADAPTERS[orm] || N1Finder::Adapters::NullAdapter
109
- end
110
80
  end
111
81
  end
82
+
83
+ require 'n_1_finder/logger'
84
+ require 'n_1_finder/middleware'
85
+ require 'n_1_finder/query'
86
+ require 'n_1_finder/n_1_query'
87
+ require 'n_1_finder/storage'
88
+ require 'n_1_finder/adapters/factory'
89
+ require 'n_1_finder/adapters/base_adapter'
90
+ require 'n_1_finder/adapters/active_record_adapter'
91
+ require 'n_1_finder/adapters/sequel_adapter'
92
+ require 'n_1_finder/adapters/null_adapter'
93
+ require 'n_1_finder/errors/base'
94
+ require 'n_1_finder/errors/invalid_orm'
95
+ require 'n_1_finder/errors/invalid_logger'
@@ -1,46 +1,43 @@
1
1
  ##
2
- # Combine ORM adapters
2
+ # Adds common functionality to other adapters
3
3
  #
4
- module N1Finder::Adapters
5
- # Adds common functionality to other adapters
6
- class BaseAdapter
7
- # An alias that we create for MAIN_METHOD function
8
- MAIN_METHOD_ALIAS = :main_method_alias
4
+ class N1Finder::Adapters::BaseAdapter
5
+ # An alias that we create for MAIN_METHOD function
6
+ MAIN_METHOD_ALIAS = :main_method_alias
9
7
 
10
- # @!attribute [r] storage
11
- # Storage that stores queries
12
- attr_reader :storage
8
+ # @!attribute [r] storage
9
+ # Storage that stores queries
10
+ attr_reader :storage
13
11
 
14
- def initialize(storage)
15
- @storage = storage
16
- end
12
+ def initialize(storage)
13
+ @storage = storage
14
+ end
17
15
 
18
- # Replaces original query execution function (defined in MAIN_METHOD)
19
- # with our function that collects all queries and calls original function.
20
- # After passed block yileds, replaces our function with origianal and
21
- # removes our function.
22
- #
23
- # @yield passed block
24
- #
25
- # @return passed block execution result
26
- def exec
27
- set_trap
28
- yield
29
- ensure
30
- remove_trap
31
- end
16
+ # Replaces original query execution function (defined in MAIN_METHOD)
17
+ # with our function that collects all queries and calls original function.
18
+ # After passed block yileds, replaces our function with origianal and
19
+ # removes our function.
20
+ #
21
+ # @yield passed block
22
+ #
23
+ # @return passed block execution result
24
+ def exec
25
+ set_trap
26
+ yield
27
+ ensure
28
+ remove_trap
29
+ end
32
30
 
33
- private
31
+ private
34
32
 
35
- def remove_trap
36
- main_query_method = self.class::MAIN_METHOD
37
- main_method_alias = MAIN_METHOD_ALIAS
33
+ def remove_trap
34
+ main_query_method = self.class::MAIN_METHOD
35
+ main_method_alias = MAIN_METHOD_ALIAS
38
36
 
39
- database_class.class_eval do
40
- remove_method(main_query_method)
41
- alias_method main_query_method, main_method_alias
42
- remove_method(main_method_alias)
43
- end
37
+ database_class.class_eval do
38
+ remove_method(main_query_method)
39
+ alias_method main_query_method, main_method_alias
40
+ remove_method(main_method_alias)
44
41
  end
45
42
  end
46
43
  end
@@ -0,0 +1,16 @@
1
+ # Combine ORM adapters
2
+ module N1Finder::Adapters
3
+ # Adapters factory
4
+ class Factory
5
+ # Constructs new instance of adapter
6
+ def self.get(key, storage)
7
+ adapter_class = case key
8
+ when :active_record then N1Finder::Adapters::ActiveRecordAdapter
9
+ when :sequel then N1Finder::Adapters::SequelAdapter
10
+ else N1Finder::Adapters::NullAdapter
11
+ end
12
+
13
+ adapter_class.new(storage)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,7 @@
1
+ # Errors module
2
+ # @api private
3
+ module N1Finder::Errors
4
+ # Base error class
5
+ class Base < StandardError
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ # Raised when specifying invalid logger
2
+ # @api private
3
+ class N1Finder::Errors::InvalidLogger < N1Finder::Errors::Base
4
+ end
@@ -0,0 +1,4 @@
1
+ # Raised when specifying invalid ORM
2
+ # @api private
3
+ class N1Finder::Errors::InvalidORM < N1Finder::Errors::Base
4
+ end
@@ -1,4 +1,4 @@
1
1
  class N1Finder
2
2
  # Gem version
3
- VERSION = '0.0.4'.freeze
3
+ VERSION = '0.0.5'.freeze
4
4
  end
@@ -0,0 +1,36 @@
1
+ RSpec.describe N1Finder::Adapters::Factory do
2
+ describe '.get' do
3
+ let(:storage) { 'STORAGE' }
4
+ subject { described_class.get(key, storage) }
5
+
6
+ context 'getting active_record' do
7
+ let(:key) { :active_record }
8
+ it 'returns active_record adapter' do
9
+ expect(subject).to be_a(N1Finder::Adapters::ActiveRecordAdapter)
10
+ end
11
+ it 'sets storage' do
12
+ expect(subject.storage).to eq storage
13
+ end
14
+ end
15
+
16
+ context 'getting sequel' do
17
+ let(:key) { :sequel }
18
+ it 'returns sequel adapter' do
19
+ expect(subject).to be_a(N1Finder::Adapters::SequelAdapter)
20
+ end
21
+ it 'sets storage' do
22
+ expect(subject.storage).to eq storage
23
+ end
24
+ end
25
+
26
+ context 'getting other adapter' do
27
+ let(:key) { :other }
28
+ it 'returns sequel adapter' do
29
+ expect(subject).to be_a(N1Finder::Adapters::NullAdapter)
30
+ end
31
+ it 'sets storage' do
32
+ expect(subject.storage).to eq storage
33
+ end
34
+ end
35
+ end
36
+ end
@@ -42,7 +42,7 @@ RSpec.describe N1Finder do
42
42
  context 'when logger is not a Logger' do
43
43
  let(:logger) { nil }
44
44
  it 'raises error' do
45
- expect { subject }.to raise_error described_class::InvalidLogger
45
+ expect { subject }.to raise_error described_class::Errors::InvalidLogger
46
46
  end
47
47
  end
48
48
  end
@@ -50,7 +50,7 @@ RSpec.describe N1Finder do
50
50
  describe '#orm=' do
51
51
  subject { described_class.orm = orm }
52
52
  context 'when provided supported orm' do
53
- let(:orm) { described_class::ORM_ADAPTERS.keys.sample }
53
+ let(:orm) { described_class::ORM_ADAPTERS.sample }
54
54
  it 'sets orm' do
55
55
  subject
56
56
  expect(described_class.orm).to eq orm
@@ -60,7 +60,7 @@ RSpec.describe N1Finder do
60
60
  context 'when orm is not supported' do
61
61
  let(:orm) { :mongo }
62
62
  it 'raises error' do
63
- expect { subject }.to raise_error N1Finder::InvalidORM
63
+ expect { subject }.to raise_error described_class::Errors::InvalidORM
64
64
  end
65
65
  end
66
66
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: n_1_finder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Glushkov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-29 00:00:00.000000000 Z
11
+ date: 2016-07-01 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Finds N+1 queries
14
14
  email: aglushkov@shakuro.com
@@ -20,8 +20,12 @@ files:
20
20
  - lib/n_1_finder.rb
21
21
  - lib/n_1_finder/adapters/active_record_adapter.rb
22
22
  - lib/n_1_finder/adapters/base_adapter.rb
23
+ - lib/n_1_finder/adapters/factory.rb
23
24
  - lib/n_1_finder/adapters/null_adapter.rb
24
25
  - lib/n_1_finder/adapters/sequel_adapter.rb
26
+ - lib/n_1_finder/errors/base.rb
27
+ - lib/n_1_finder/errors/invalid_logger.rb
28
+ - lib/n_1_finder/errors/invalid_orm.rb
25
29
  - lib/n_1_finder/logger.rb
26
30
  - lib/n_1_finder/middleware.rb
27
31
  - lib/n_1_finder/n_1_query.rb
@@ -30,6 +34,7 @@ files:
30
34
  - lib/n_1_finder/version.rb
31
35
  - spec/.env.example
32
36
  - spec/n_1_finder/adapters/active_record_adapter_spec.rb
37
+ - spec/n_1_finder/adapters/factory_spec.rb
33
38
  - spec/n_1_finder/adapters/null_adapter_spec.rb
34
39
  - spec/n_1_finder/adapters/sequel_adapter_spec.rb
35
40
  - spec/n_1_finder/features/active_record_mysql_spec.rb