Module: RuboCop::Cop::Isucon::Correctors::NPlusOneQueryCorrector::ReplaceMethods
- Defined in:
- lib/rubocop/cop/isucon/correctors/n_plus_one_query_corrector/replace_methods.rb
Overview
replace ast
Instance Method Summary collapse
- #generate_each_with_object ⇒ String
- #generate_second_line ⇒ String
- #indent_level(node) ⇒ Integer
- #instance_var_name ⇒ String
- #replace ⇒ Object
-
#replace_chained_method_to_each_with_object ⇒ Object
Replace
.first
->.each_with_object({}) { |v, hash| hash[v[:id]] = v }
. -
#replace_to_2_lines ⇒ Object
Split line.
- #replace_to_2_lines_for_1st_line ⇒ Object
- #replace_to_2_lines_for_2nd_line ⇒ Object
-
#replace_where_condition_in_sql ⇒ Object
Replace where condition in SQL (e.g.
id = ?
->id IN (?)
). -
#replace_xquery_2nd_arg ⇒ Object
Replace 2nd arg in db.xquery (e.g.
course[:teacher_id]
->courses.map { |course| course[:teacher_id] }
).
Instance Method Details
#generate_each_with_object ⇒ String
53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/rubocop/cop/isucon/correctors/n_plus_one_query_corrector/replace_methods.rb', line 53 def generate_each_with_object hash_key = case xquery_arg.node_parts[2].type when :sym ":#{where_column_without_quote}" when :str %("#{where_column_without_quote}") end "each_with_object({}) { |v, hash| hash[v[#{hash_key}]] = v }" end |
#generate_second_line ⇒ String
117 118 119 120 121 |
# File 'lib/rubocop/cop/isucon/correctors/n_plus_one_query_corrector/replace_methods.rb', line 117 def generate_second_line object_source = xquery_arg.node_parts[0].source symbol_source = xquery_arg.node_parts[2].source "#{xquery_lvar.node_parts[0]} = #{instance_var_name}[#{object_source}[#{symbol_source}]]\n" end |
#indent_level(node) ⇒ Integer
106 107 108 109 110 111 |
# File 'lib/rubocop/cop/isucon/correctors/n_plus_one_query_corrector/replace_methods.rb', line 106 def indent_level(node) node.loc.expression.source_line =~ /^(\s+)/ return 0 unless Regexp.last_match(1) Regexp.last_match(1).length end |
#instance_var_name ⇒ String
91 92 93 |
# File 'lib/rubocop/cop/isucon/correctors/n_plus_one_query_corrector/replace_methods.rb', line 91 def instance_var_name "@#{gda.table_names[0]}_by_#{where_column_without_quote}" end |
#replace ⇒ Object
10 11 12 13 14 15 |
# File 'lib/rubocop/cop/isucon/correctors/n_plus_one_query_corrector/replace_methods.rb', line 10 def replace replace_where_condition_in_sql replace_xquery_2nd_arg replace_chained_method_to_each_with_object replace_to_2_lines end |
#replace_chained_method_to_each_with_object ⇒ Object
Replace .first
-> .each_with_object({}) { |v, hash| hash[v[:id]] = v }
39 40 41 42 43 44 45 46 47 |
# File 'lib/rubocop/cop/isucon/correctors/n_plus_one_query_corrector/replace_methods.rb', line 39 def replace_chained_method_to_each_with_object xquery_chained_method_begin_pos = current_node.loc.end.end_pos + 1 xquery_chained_method_range = Parser::Source::Range.new(current_node.loc.expression.source_buffer, xquery_chained_method_begin_pos, xquery_chained_method_begin_pos + xquery_chained_method.length) corrector.replace(xquery_chained_method_range, generate_each_with_object) end |
#replace_to_2_lines ⇒ Object
Split line
75 76 77 78 79 80 |
# File 'lib/rubocop/cop/isucon/correctors/n_plus_one_query_corrector/replace_methods.rb', line 75 def replace_to_2_lines # rubocop:enable Layout/LineLength replace_to_2_lines_for_1st_line replace_to_2_lines_for_2nd_line end |
#replace_to_2_lines_for_1st_line ⇒ Object
82 83 84 85 86 87 88 |
# File 'lib/rubocop/cop/isucon/correctors/n_plus_one_query_corrector/replace_methods.rb', line 82 def replace_to_2_lines_for_1st_line range = Parser::Source::Range.new(current_node.loc.expression.source_buffer, xquery_lvar.loc.expression.begin_pos, current_node.loc.expression.begin_pos) corrector.replace(range, "#{instance_var_name} ||= ") end |
#replace_to_2_lines_for_2nd_line ⇒ Object
95 96 97 98 99 100 101 102 |
# File 'lib/rubocop/cop/isucon/correctors/n_plus_one_query_corrector/replace_methods.rb', line 95 def replace_to_2_lines_for_2nd_line indent_level = indent_level(current_node) pos = xquery_lvar.loc.expression.end_pos + 1 range = Parser::Source::Range.new(current_node.loc.expression.source_buffer, pos, pos) corrector.replace(range, "#{' ' * indent_level}#{generate_second_line}") end |
#replace_where_condition_in_sql ⇒ Object
Replace where condition in SQL (e.g. id = ?
-> id IN (?)
)
18 19 20 21 22 23 |
# File 'lib/rubocop/cop/isucon/correctors/n_plus_one_query_corrector/replace_methods.rb', line 18 def replace_where_condition_in_sql loc = offense_location(type: type, node: current_node, gda_location: where_condition_gda_loc) return unless loc corrector.replace(loc, "#{where_column} IN (?)") end |
#replace_xquery_2nd_arg ⇒ Object
Replace 2nd arg in db.xquery (e.g. course[:teacher_id]
-> courses.map { |course| course[:teacher_id] }
)
26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/rubocop/cop/isucon/correctors/n_plus_one_query_corrector/replace_methods.rb', line 26 def replace_xquery_2nd_arg object_source = xquery_arg.node_parts[0].source symbol_source = xquery_arg.node_parts[2].source corrector.replace( xquery_arg.loc.expression, # e.g. # courses.map { |course| course[:teacher_id] } "#{parent_receiver.source}.map { |#{object_source}| #{object_source}[#{symbol_source}] }", ) end |