active_record_query_fixer 0.0.10 → 0.0.15

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6fc75b0466693604d010e4489ac07fd724b21d3f5199b6379b92c3733c342cb4
4
- data.tar.gz: bf0a66c2fb45fdcb762058c3749d13fe6273f0eba822462c4c112f7fece00b71
3
+ metadata.gz: 5faf0cd7f5d3fa4a60edd9a520032fc2d2c1d21f017c1bb5e8701d62cc341d1c
4
+ data.tar.gz: 7863addd51c71f1a5799cbac6ed94e1987742b19efb9a218f954384222f723b3
5
5
  SHA512:
6
- metadata.gz: 00f4f4cbaf9d3e81e82c27e1a78a43867b8f511b29d398ff84624d462b7fef370a51b8e15d46e8462791222feb46e7d9a51718cafbec275aecb9a9da224e7c89
7
- data.tar.gz: 92b877b63ae9e03d15d79ff9611091935aa94983fb7676b8d34a478919c67fc64e108e8f7615662dea586a16b49c2c1569a1880fdac72784b3917c2cc800b267
6
+ metadata.gz: a61caaae41ab19741b1837df67332e6a882625f8b7cd64c4ca5480c1e0c99bffd9ccf9d332004539e827c023db37a86f390fee502a093b9cdc0172b4ebca5df0
7
+ data.tar.gz: 6b76c2ba3b64bec72a0fb49f0ac17c71524c6d2cd48188fceb8c445fbc84485d98ea2c91dd13c719f7468e4d6bea97a6a16b4339ca31069644774f2edf12ae87
@@ -1,5 +1,4 @@
1
1
  require "dig_bang"
2
- require "pg_query"
3
2
 
4
3
  class ActiveRecordQueryFixer
5
4
  autoload :RelationExtentions, "#{__dir__}/active_record_query_fixer/relation_extentions"
@@ -19,25 +18,25 @@ class ActiveRecordQueryFixer
19
18
  fix_reference_group if fix_reference_group?
20
19
  fix_order_group if fix_order_group?
21
20
  fix_order_select_distinct if fix_order_select_distinct?
22
- fix_select_group if @query.values[:select] && @query.values[:group]
21
+ fix_select_group if query.values[:select] && query.values[:group]
23
22
 
24
23
  self
25
24
  end
26
25
 
27
26
  def fix_select_group
28
27
  select_targets.each do |select_target|
29
- fields = select_target.dig!("ResTarget", "val", "ColumnRef", "fields")
30
- next if fields.length != 2
28
+ fields = select_target.dig!("ResTarget", "val").dig("ColumnRef", "fields")
29
+ next if !fields || fields.length != 2
31
30
 
32
31
  table = fields[0].dig("String", "str")
33
32
  column = fields[1].dig("String", "str")
34
33
 
35
34
  if column
36
35
  # A table and a column has been selected - make sure to group by that
37
- @query = @query.group("#{table}.#{column}")
36
+ @query = query.group("#{table}.#{column}")
38
37
  elsif fields[1].key?("A_Star")
39
38
  # A table and a star has been selected - assume the primary key is called "id" and group by that
40
- @query = @query.group("#{table}.id")
39
+ @query = query.group("#{table}.id")
41
40
  end
42
41
  end
43
42
 
@@ -45,7 +44,7 @@ class ActiveRecordQueryFixer
45
44
  end
46
45
 
47
46
  def fix_order_group
48
- @query = @query.group(@query.model.arel_table[@query.model.primary_key])
47
+ @query = query.group(query.model.arel_table[query.model.primary_key])
49
48
 
50
49
  sort_targets.each do |sort_target|
51
50
  fields = sort_target.dig("SortBy", "node", "ColumnRef", "fields")
@@ -54,14 +53,14 @@ class ActiveRecordQueryFixer
54
53
  table = fields.dig(0, "String", "str")
55
54
  column = fields.dig(1, "String", "str")
56
55
 
57
- @query = @query.group("#{table}.#{column}") if table && column
56
+ @query = query.group("#{table}.#{column}") if table && column
58
57
  end
59
58
 
60
59
  self
61
60
  end
62
61
 
63
62
  def fix_order_select_distinct
64
- changed = false
63
+ select_appends = []
65
64
 
66
65
  sort_targets.each do |sort_target|
67
66
  fields = sort_target.dig("SortBy", "node", "ColumnRef", "fields")
@@ -72,21 +71,25 @@ class ActiveRecordQueryFixer
72
71
 
73
72
  next if !table || !column
74
73
 
75
- @query = @query.select("#{table}.#{column} AS active_record_query_fixer_#{@count_select}")
76
- changed = true
74
+ select_appends << "#{table}.#{column} AS active_record_query_fixer_#{@count_select}"
77
75
  @count_select += 1
78
76
  end
79
77
 
80
- @query = @query.select("#{@query.table_name}.*") if changed
78
+ # Start by prepending a wild-card select before doing the fix-selects to avoid any issues with `DISTINCT COUNT`
79
+ prepend_table_wildcard if !table_wildcard_prepended? && select_appends.any? && query.values[:select].blank?
80
+
81
+ select_appends.each do |select_append|
82
+ @query = query.select(select_append)
83
+ end
81
84
 
82
85
  self
83
86
  end
84
87
 
85
88
  def fix_reference_group
86
- @query = @query.group(@query.model.arel_table[@query.model.primary_key])
89
+ @query = query.group(query.model.arel_table[query.model.primary_key])
87
90
 
88
- @query.values[:references].each do |reference|
89
- @query = @query.group("#{reference}.id")
91
+ query.values[:references].each do |reference|
92
+ @query = query.group("#{reference}.id")
90
93
  end
91
94
 
92
95
  self
@@ -95,20 +98,41 @@ class ActiveRecordQueryFixer
95
98
  private
96
99
 
97
100
  def fix_order_group?
98
- @query.values[:joins].blank? && @query.values[:distinct].present? && @query.values[:order].present? ||
99
- @query.values[:group].present? && @query.values[:order].present?
101
+ query.values[:joins].blank? && query.values[:distinct].present? && query.values[:order].present? ||
102
+ query.values[:group].present? && query.values[:order].present?
100
103
  end
101
104
 
102
105
  def fix_order_select_distinct?
103
- @query.values[:distinct].present? && @query.values[:order].present?
106
+ query.values[:distinct].present? && query.values[:order].present?
104
107
  end
105
108
 
106
109
  def fix_reference_group?
107
- @query.values[:references].present? && @query.values[:group].present?
110
+ query.values[:references].present? && query.values[:group].present?
108
111
  end
109
112
 
110
113
  def parsed_query
111
- @parsed_query ||= PgQuery.parse(@query.to_sql)
114
+ require "pg_query" unless defined?(PgQuery)
115
+ @parsed_query ||= PgQuery.parse(query.to_sql)
116
+ end
117
+
118
+ # Prepends 'table_name.*' to the query. It needs to be pre-pended in case a `COUNT` or another aggregate function has been added to work with `DISTINCT`.
119
+ def prepend_table_wildcard
120
+ old_select = query.values[:select]&.clone || []
121
+ old_select = old_select.keep_if { |select_statement| select_statement != select_table_wildcard_sql }
122
+
123
+ @query = query.except(:select).select(select_table_wildcard_sql)
124
+
125
+ old_select.each do |select_statement|
126
+ @query = query.select(select_statement)
127
+ end
128
+ end
129
+
130
+ def select_table_wildcard_sql
131
+ @select_table_wildcard_sql ||= "#{query.table_name}.*"
132
+ end
133
+
134
+ def table_wildcard_prepended?
135
+ query.values[:select]&.first == select_table_wildcard_sql
112
136
  end
113
137
 
114
138
  def select_statement
@@ -1,3 +1,3 @@
1
1
  class ActiveRecordQueryFixer
2
- VERSION = "0.0.10".freeze
2
+ VERSION = "0.0.15".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_query_fixer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - kaspernj
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-21 00:00:00.000000000 Z
11
+ date: 2021-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dig_bang
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: pg_query
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
27
  description: A library for automatically added `.select` on a column used for `.distinct`
42
28
  or automatically adding `.group` for a column used for order.
43
29
  email: