active_record_query_fixer 0.0.10 → 0.0.15

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: 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: