query_helper 0.2.26 → 0.2.28

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
  SHA256:
3
- metadata.gz: b424d779be28de32e24c3ec31668d775915e0053ddc7099691b51f48ecb1edf4
4
- data.tar.gz: 43c360e9e47dd3b5b410632f91e58ded247c9ab20848d43eea510ce4c1ba3665
3
+ metadata.gz: c635a27696eb10b152787a3b66132760bf79e3b2e695037bf6dcc2b06b39e9b9
4
+ data.tar.gz: bfc80f15f647d447a6115423308368c39a2f034938731eb94f91d23a7f4c1f53
5
5
  SHA512:
6
- metadata.gz: 8cd9187f8a136f15b5ab1f27cd5ba184531f1976a91a7f72149f1b4e1efb3ba8627ed4a8083a6e71420f45d3bf7c58ffdd05099e4cedc43d94ebbb0875b6fe5d
7
- data.tar.gz: 4beaf1b6c5dffecfe84bf1e7a7caf174c29defe585e3cd6cf195c2b39e045f1fd6900d1e40119c8e6a61f997a6fb7b80c8c126d18d4f45705ec4ade868237e52
6
+ metadata.gz: d61105466f4cadc1b111ed38afd7e764c3d3fde76fb4db786029654516fb893df43ccf02e2b6f07693dd118ceabbc15ffa9281b2c1c7dbc388091a4f65b9e300
7
+ data.tar.gz: b3c6b12c6594e1a3f068ce0d1de484f3e49bc53e1da5c99c6b7c68b27fc9c1f90e334e653b711281f0d93334a2ee95dc666d1d620a17de67ca378117e3e4c806
@@ -0,0 +1,24 @@
1
+ name: CI
2
+
3
+ on: [push]
4
+
5
+ env:
6
+ RAILS_ENV: test
7
+ GEMFILE_RUBY_VERSION: 2.7.2
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v2
14
+
15
+ - name: Set up Ruby 2.7.2
16
+ uses: ruby/setup-ruby@v1
17
+ with:
18
+ # Not needed with a .ruby-version file
19
+ ruby-version: 2.7.2
20
+ # runs 'bundle install' and caches installed gems automatically
21
+ bundler-cache: true
22
+
23
+ - name: Run tests
24
+ run: bundle exec rspec spec
data/CODE_OF_CONDUCT.md CHANGED
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
55
55
  ## Enforcement
56
56
 
57
57
  Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
- reported by contacting the project team at eamigo13@gmail.com. All
58
+ reported by contacting the project team at opensource@pattern.com. All
59
59
  complaints will be reviewed and investigated and will result in a response that
60
60
  is deemed necessary and appropriate to the circumstances. The project team is
61
61
  obligated to maintain confidentiality with regard to the reporter of an incident.
data/Gemfile.lock CHANGED
@@ -1,9 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- query_helper (0.2.26)
4
+ query_helper (0.2.28)
5
5
  activerecord (> 5)
6
6
  activesupport (> 5)
7
+ sqlite3
7
8
 
8
9
  GEM
9
10
  remote: https://rubygems.org/
@@ -46,12 +47,12 @@ GEM
46
47
  crass (~> 1.0.2)
47
48
  nokogiri (>= 1.5.9)
48
49
  method_source (1.0.0)
49
- mini_portile2 (2.6.1)
50
+ mini_portile2 (2.8.0)
50
51
  minitest (5.14.4)
51
- nokogiri (1.12.4)
52
- mini_portile2 (~> 2.6.1)
52
+ nokogiri (1.13.3)
53
+ mini_portile2 (~> 2.8.0)
53
54
  racc (~> 1.4)
54
- racc (1.5.2)
55
+ racc (1.6.0)
55
56
  rack (2.2.3)
56
57
  rack-test (1.1.0)
57
58
  rack (>= 1.0, < 3)
@@ -88,7 +89,7 @@ GEM
88
89
  rspec-mocks (~> 3.10)
89
90
  rspec-support (~> 3.10)
90
91
  rspec-support (3.10.2)
91
- sqlite3 (1.3.13)
92
+ sqlite3 (1.4.2)
92
93
  thor (1.1.0)
93
94
  tzinfo (2.0.4)
94
95
  concurrent-ruby (~> 1.0)
@@ -107,7 +108,6 @@ DEPENDENCIES
107
108
  rake (~> 13.0)
108
109
  rspec (~> 3.0)
109
110
  rspec-rails
110
- sqlite3 (~> 1.3.6)
111
111
 
112
112
  BUNDLED WITH
113
- 2.2.27
113
+ 2.2.29
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # QueryHelper
2
2
  [![Gem Version](https://badge.fury.io/rb/query_helper.svg)](https://badge.fury.io/rb/query_helper)
3
+ [![CI](https://github.com/patterninc/query_helper/actions/workflows/ci.yml/badge.svg)](https://github.com/patterninc/query_helper/actions)
3
4
 
4
5
  QueryHelper is a ruby gem used to paginate, sort, and filter your API calls in Ruby on Rails using URL params in your HTTP requests. It currently only supports Postgres.
5
6
 
@@ -3,18 +3,20 @@ require "query_helper/invalid_query_error"
3
3
  class QueryHelper
4
4
  class Filter
5
5
 
6
- attr_accessor :operator, :criterion, :comparate, :operator_code, :bind_variable, :aggregate
6
+ attr_accessor :operator, :criterion, :comparate, :operator_code, :bind_variable, :aggregate, :qualify_clause
7
7
 
8
8
  def initialize(
9
9
  operator_code:,
10
10
  criterion:,
11
11
  comparate:,
12
- aggregate: false
12
+ aggregate: false,
13
+ qualify_clause: false
13
14
  )
14
15
  @operator_code = operator_code
15
16
  @criterion = criterion # Converts to a string to be inserted into sql.
16
17
  @comparate = comparate
17
18
  @aggregate = aggregate
19
+ @qualify_clause = qualify_clause
18
20
  @bind_variable = ('a'..'z').to_a.shuffle[0,20].join.to_sym
19
21
 
20
22
  translate_operator_code()
@@ -3,11 +3,13 @@ require "query_helper/invalid_query_error"
3
3
  class QueryHelper
4
4
  class SqlFilter
5
5
 
6
- attr_accessor :filter_values, :column_maps
6
+ attr_accessor :filter_values, :column_maps, :options, :qualify_filters
7
7
 
8
- def initialize(filter_values: [], column_maps: [])
8
+ def initialize(filter_values: [], column_maps: [], qualify_filters: [], options: {})
9
9
  @column_maps = column_maps
10
10
  @filter_values = filter_values
11
+ @options = options
12
+ @qualify_filters = qualify_filters
11
13
  end
12
14
 
13
15
  def create_filters
@@ -23,13 +25,22 @@ class QueryHelper
23
25
  operator_code: criteria.keys.first,
24
26
  criterion: criteria.values.first,
25
27
  comparate: map.sql_expression,
26
- aggregate: map.aggregate
28
+ aggregate: map.aggregate,
29
+ qualify_clause: aggregated_attribute?(comparate: map.sql_expression)
27
30
  )
28
31
  end
29
32
  end
30
33
 
34
+ def aggregated_attribute?(comparate:)
35
+ @options['qualify_clause'] && qualify_filters.include?(comparate)
36
+ end
37
+
38
+ def qualify_clauses
39
+ @filters.select{ |f| aggregated_attribute?(comparate: f.comparate) }.map(&:sql_string)
40
+ end
41
+
31
42
  def where_clauses
32
- @filters.select{ |f| f.aggregate == false }.map(&:sql_string)
43
+ @filters.select{ |f| f.aggregate == false && !f.qualify_clause }.map(&:sql_string)
33
44
  end
34
45
 
35
46
  def having_clauses
@@ -9,14 +9,17 @@ class QueryHelper
9
9
  sql:,
10
10
  where_clauses: nil,
11
11
  having_clauses: nil,
12
+ qualify_clauses: nil,
12
13
  order_by_clauses: nil,
13
14
  include_limit_clause: false,
14
15
  additional_select_clauses: []
15
16
  )
17
+ sql = remove_qualified_count(sql)
16
18
  @parser = SqlParser.new(sql)
17
19
  @sql = @parser.sql.dup
18
20
  @where_clauses = where_clauses
19
21
  @having_clauses = having_clauses
22
+ @qualify_clauses = qualify_clauses
20
23
  @order_by_clauses = order_by_clauses
21
24
  @include_limit_clause = include_limit_clause
22
25
  @additional_select_clauses = additional_select_clauses
@@ -24,28 +27,69 @@ class QueryHelper
24
27
 
25
28
  def build
26
29
  insert_having_clauses()
30
+ insert_qualify_clauses()
27
31
  insert_where_clauses()
28
32
  insert_select_clauses()
29
33
  insert_order_by_and_limit_clause()
34
+ insert_qualified_count_clauses if (qualify_clause_applicable? || @qualify_present) && @include_limit_clause
35
+
30
36
  @sql.squish
31
37
  end
32
38
 
33
39
  private
34
40
 
35
41
  def insert_select_clauses
36
- total_count_clause = "count(*) over () as _query_full_count"
37
- @additional_select_clauses << total_count_clause if @include_limit_clause
42
+ @additional_select_clauses << count_sql if @include_limit_clause && !(qualify_clause_applicable? || @qualify_present)
38
43
  @sql.insert(@parser.insert_select_index, " , #{@additional_select_clauses.join(", ")} ") if @additional_select_clauses.length > 0
39
44
  end
40
45
 
46
+ def count_sql
47
+ "count(*) over () as _query_full_count"
48
+ end
49
+
50
+ def qualify_clauses(index)
51
+ if index == 0
52
+ "qualified_results AS ( "
53
+ else
54
+ ", qualified_results AS ( "
55
+ end
56
+ end
57
+
58
+ # If modifying something please check remove_qualified_count method too
59
+ def insert_qualified_count_clauses
60
+ @sql.insert(@parser.select_index, qualify_clauses(@parser.select_index))
61
+ @sql.insert(@sql.length, ") SELECT qualified_results.*, #{count_sql} FROM qualified_results")
62
+ end
63
+
64
+ # If modifying something please check insert_qualified_count_clauses method too
65
+ def remove_qualified_count(unparsed_sql)
66
+ @qualify_present = unparsed_sql.include?("qualified_results") || unparsed_sql.include?(" qualify ")
67
+ return unparsed_sql unless @qualify_present
68
+
69
+ unparsed_sql = unparsed_sql.gsub(/[\,\s]?qualified_results AS \( /, '')
70
+ unparsed_sql = unparsed_sql.gsub(") SELECT qualified_results.*, count(*) over () as _query_full_count FROM qualified_results", '')
71
+ unparsed_sql
72
+ end
73
+
41
74
  def insert_where_clauses
42
75
  return unless @where_clauses.length > 0
43
76
  begin_string = @parser.where_included? ? "and" : "where"
44
77
  filter_string = @where_clauses.join(" and ")
45
- " #{begin_string} #{filter_string} "
46
78
  @sql.insert(@parser.insert_where_index, " #{begin_string} #{filter_string} ")
47
79
  end
48
80
 
81
+ def insert_qualify_clauses
82
+ return unless qualify_clause_applicable?
83
+
84
+ begin_string = @parser.qualify_included? ? "and" : "qualify"
85
+ filter_string = @qualify_clauses.join(" and ")
86
+ @sql.insert(@parser.insert_where_index, " #{begin_string} #{filter_string} ")
87
+ end
88
+
89
+ def qualify_clause_applicable?
90
+ @qualify_clauses.length > 0
91
+ end
92
+
49
93
  def insert_having_clauses
50
94
  return unless @having_clauses.length > 0
51
95
  begin_string = @parser.having_included? ? "and" : "having"
@@ -48,6 +48,11 @@ class QueryHelper
48
48
  find_index(regex, position)
49
49
  end
50
50
 
51
+ def qualify_index(position=:start)
52
+ regex = / [Qq][Uu][Aa][Ll][Ii][Ff][Yy] /
53
+ find_index(regex, position)
54
+ end
55
+
51
56
  def group_by_index(position=:start)
52
57
  regex = / [Gg][Rr][Oo][Uu][Pp] [Bb][Yy] /
53
58
  find_index(regex, position)
@@ -80,6 +85,10 @@ class QueryHelper
80
85
  !where_index.nil?
81
86
  end
82
87
 
88
+ def qualify_included?
89
+ !qualify_index.nil?
90
+ end
91
+
83
92
  def group_by_included?
84
93
  !group_by_index.nil?
85
94
  end
@@ -59,14 +59,12 @@ class QueryHelper
59
59
  sql_strings << "#{sql_expression} #{direction}"
60
60
  end
61
61
  end
62
- sql_strings << parse_custom_sort_string
62
+ sql_strings << parse_custom_sort_string if @column_sort_order.present? && @column_sort_order[:sort_values].present?
63
63
  sql_strings
64
64
  end
65
65
 
66
66
  # This method is used for sorting enum based column
67
67
  def parse_custom_sort_string
68
- return '' if @column_sort_order.blank? || @column_sort_order[:sort_values].blank?
69
-
70
68
  sort_column = @column_sort_order[:column_name]
71
69
  sort_values = @column_sort_order[:sort_values]
72
70
  direction = @column_sort_order[:direction]
@@ -1,3 +1,3 @@
1
1
  class QueryHelper
2
- VERSION = "0.2.26"
2
+ VERSION = "0.2.28"
3
3
  end
data/lib/query_helper.rb CHANGED
@@ -121,6 +121,7 @@ class QueryHelper
121
121
 
122
122
  having_clauses = @sql_filter.having_clauses
123
123
  where_clauses = @sql_filter.where_clauses
124
+ qualify_clauses = @sql_filter.qualify_clauses
124
125
 
125
126
  if @search_string
126
127
  search_filter = search_filter(column_maps)
@@ -140,6 +141,7 @@ class QueryHelper
140
141
  sql: @query,
141
142
  where_clauses: where_clauses,
142
143
  having_clauses: having_clauses,
144
+ qualify_clauses: qualify_clauses,
143
145
  order_by_clauses: @sql_sort.parse_sort_string,
144
146
  include_limit_clause: @page && @per_page ? true : false,
145
147
  additional_select_clauses: @sql_sort.select_strings
data/query_helper.gemspec CHANGED
@@ -6,12 +6,12 @@ require "query_helper/version"
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "query_helper"
8
8
  spec.version = QueryHelper::VERSION
9
- spec.authors = ["Patterninc"]
10
- spec.email = ["tech@pattern.com"]
9
+ spec.authors = ["Evan McDaniel"]
10
+ spec.email = ["eamigo13@gmail.com"]
11
11
 
12
12
  spec.summary = %q{Ruby Gem to help with pagination and data formatting at Pattern, Inc.}
13
13
  spec.description = %q{Ruby gem developed to help with pagination, filtering, sorting, and including associations on both active record queries and custom sql queries}
14
- spec.homepage = "https://github.com/patterninc/query_helper"
14
+ spec.homepage = "https://github.com/iserve-products/query_helper"
15
15
  spec.license = "MIT"
16
16
 
17
17
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
@@ -35,11 +35,11 @@ Gem::Specification.new do |spec|
35
35
  spec.bindir = "exe"
36
36
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
37
37
  spec.require_paths = ["lib"]
38
+ spec.required_ruby_version = ">= 2.6.0"
38
39
 
39
40
  spec.add_development_dependency "bundler", "~> 2.2.27"
40
41
  spec.add_development_dependency "rake", "~> 13.0"
41
42
  spec.add_development_dependency "rspec", "~> 3.0"
42
- spec.add_development_dependency "sqlite3", "~> 1.3.6"
43
43
  spec.add_development_dependency "faker", "~> 1.9.3"
44
44
  spec.add_development_dependency "byebug"
45
45
  spec.add_development_dependency 'rspec-rails'
@@ -48,4 +48,5 @@ Gem::Specification.new do |spec|
48
48
 
49
49
  spec.add_dependency "activerecord", "> 5"
50
50
  spec.add_dependency "activesupport", "> 5"
51
+ spec.add_dependency "sqlite3"
51
52
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: query_helper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.26
4
+ version: 0.2.28
5
5
  platform: ruby
6
6
  authors:
7
- - Patterninc
7
+ - Evan McDaniel
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-02-15 00:00:00.000000000 Z
11
+ date: 2022-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,20 +52,6 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
- - !ruby/object:Gem::Dependency
56
- name: sqlite3
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: 1.3.6
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: 1.3.6
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: faker
71
57
  requirement: !ruby/object:Gem::Requirement
@@ -164,15 +150,29 @@ dependencies:
164
150
  - - ">"
165
151
  - !ruby/object:Gem::Version
166
152
  version: '5'
153
+ - !ruby/object:Gem::Dependency
154
+ name: sqlite3
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
167
  description: Ruby gem developed to help with pagination, filtering, sorting, and including
168
168
  associations on both active record queries and custom sql queries
169
169
  email:
170
- - tech@pattern.com
170
+ - eamigo13@gmail.com
171
171
  executables: []
172
172
  extensions: []
173
173
  extra_rdoc_files: []
174
174
  files:
175
- - ".github/actions/publish_rubygems.yml"
175
+ - ".github/workflows/ci.yml"
176
176
  - ".gitignore"
177
177
  - ".rspec"
178
178
  - CODE_OF_CONDUCT.md
@@ -195,7 +195,7 @@ files:
195
195
  - lib/query_helper/sql_sort.rb
196
196
  - lib/query_helper/version.rb
197
197
  - query_helper.gemspec
198
- homepage: https://github.com/patterninc/query_helper
198
+ homepage: https://github.com/iserve-products/query_helper
199
199
  licenses:
200
200
  - MIT
201
201
  metadata: {}
@@ -207,14 +207,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
207
207
  requirements:
208
208
  - - ">="
209
209
  - !ruby/object:Gem::Version
210
- version: '0'
210
+ version: 2.6.0
211
211
  required_rubygems_version: !ruby/object:Gem::Requirement
212
212
  requirements:
213
213
  - - ">="
214
214
  - !ruby/object:Gem::Version
215
215
  version: '0'
216
216
  requirements: []
217
- rubygems_version: 3.2.26
217
+ rubygems_version: 3.1.4
218
218
  signing_key:
219
219
  specification_version: 4
220
220
  summary: Ruby Gem to help with pagination and data formatting at Pattern, Inc.
@@ -1,20 +0,0 @@
1
- name: Publish Gem
2
-
3
- on:
4
- push:
5
- tags:
6
- - v*
7
- jobs:
8
- build:
9
- runs-on: ubuntu-latest
10
-
11
- steps:
12
- - uses: actions/checkout@v1
13
-
14
- - name: Release Gem
15
- if: contains(github.ref, 'refs/tags/v')
16
- uses: cadwallion/publish-rubygems-action@master
17
- env:
18
- GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
19
- RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_API_KEY}}
20
- RELEASE_COMMAND: rake release