@@ -72,14 +72,70 @@ module ActiveRecord
72
72
#
73
73
# config.active_record.cache_query_log_tags = true
74
74
module QueryLogs
75
- mattr_accessor :taggings , instance_accessor : false , default : { }
76
- mattr_accessor :tags , instance_accessor : false , default : [ :application ]
77
- mattr_accessor :prepend_comment , instance_accessor : false , default : false
78
- mattr_accessor :cache_query_log_tags , instance_accessor : false , default : false
79
- mattr_accessor :tags_formatter , instance_accessor : false
75
+ class GetKeyHandler # :nodoc:
76
+ def initialize ( name )
77
+ @name = name
78
+ end
79
+
80
+ def call ( context )
81
+ context [ @name ]
82
+ end
83
+ end
84
+
85
+ class IdentityHandler # :nodoc:
86
+ def initialize ( value )
87
+ @value = value
88
+ end
89
+
90
+ def call ( _context )
91
+ @value
92
+ end
93
+ end
94
+
95
+ class ZeroArityHandler # :nodoc:
96
+ def initialize ( proc )
97
+ @proc = proc
98
+ end
99
+
100
+ def call ( _context )
101
+ @proc . call
102
+ end
103
+ end
104
+
105
+ @taggings = { }
106
+ @tags = [ :application ]
107
+ @prepend_comment = false
108
+ @cache_query_log_tags = false
109
+ @tags_formatter = false
110
+
80
111
thread_mattr_accessor :cached_comment , instance_accessor : false
81
112
82
113
class << self
114
+ attr_reader :tags , :taggings , :tags_formatter # :nodoc:
115
+ attr_accessor :prepend_comment , :cache_query_log_tags # :nodoc:
116
+
117
+ def taggings = ( taggings ) # :nodoc:
118
+ @taggings = taggings
119
+ @handlers = rebuild_handlers
120
+ end
121
+
122
+ def tags = ( tags ) # :nodoc:
123
+ @tags = tags
124
+ @handlers = rebuild_handlers
125
+ end
126
+
127
+ def tags_formatter = ( format ) # :nodoc:
128
+ @tags_formatter = format
129
+ @formatter = case format
130
+ when :legacy
131
+ LegacyFormatter
132
+ when :sqlcommenter
133
+ SQLCommenter
134
+ else
135
+ raise ArgumentError , "Formatter is unsupported: #{ format } "
136
+ end
137
+ end
138
+
83
139
def call ( sql , connection ) # :nodoc:
84
140
comment = self . comment ( connection )
85
141
@@ -96,19 +152,6 @@ def clear_cache # :nodoc:
96
152
self . cached_comment = nil
97
153
end
98
154
99
- # Updates the formatter to be what the passed in format is.
100
- def update_formatter ( format )
101
- self . tags_formatter =
102
- case format
103
- when :legacy
104
- LegacyFormatter . new
105
- when :sqlcommenter
106
- SQLCommenter . new
107
- else
108
- raise ArgumentError , "Formatter is unsupported: #{ formatter } "
109
- end
110
- end
111
-
112
155
if Thread . respond_to? ( :each_caller_location )
113
156
def query_source_location # :nodoc:
114
157
Thread . each_caller_location do |location |
@@ -126,6 +169,36 @@ def query_source_location # :nodoc:
126
169
ActiveSupport ::ExecutionContext . after_change { ActiveRecord ::QueryLogs . clear_cache }
127
170
128
171
private
172
+ def rebuild_handlers
173
+ handlers = [ ]
174
+ @tags . each do |i |
175
+ if i . is_a? ( Hash )
176
+ i . each do |k , v |
177
+ handlers << [ k , build_handler ( k , v ) ]
178
+ end
179
+ else
180
+ handlers << [ i , build_handler ( i ) ]
181
+ end
182
+ end
183
+ handlers . sort_by! { |( key , _ ) | key . to_s }
184
+ handlers
185
+ end
186
+
187
+ def build_handler ( name , handler = nil )
188
+ handler ||= @taggings [ name ]
189
+ if handler . nil?
190
+ GetKeyHandler . new ( name )
191
+ elsif handler . respond_to? ( :call )
192
+ if handler . arity == 0
193
+ ZeroArityHandler . new ( handler )
194
+ else
195
+ handler
196
+ end
197
+ else
198
+ IdentityHandler . new ( handler )
199
+ end
200
+ end
201
+
129
202
# Returns an SQL comment +String+ containing the query log tags.
130
203
# Sets and returns a cached comment if <tt>cache_query_log_tags</tt> is +true+.
131
204
def comment ( connection )
@@ -136,10 +209,6 @@ def comment(connection)
136
209
end
137
210
end
138
211
139
- def formatter
140
- self . tags_formatter || self . update_formatter ( :legacy )
141
- end
142
-
143
212
def uncached_comment ( connection )
144
213
content = tag_content ( connection )
145
214
@@ -165,25 +234,15 @@ def tag_content(connection)
165
234
context = ActiveSupport ::ExecutionContext . to_h
166
235
context [ :connection ] ||= connection
167
236
168
- pairs = tags . flat_map { |i | [ *i ] } . filter_map do |tag |
169
- key , handler = tag
170
- handler ||= taggings [ key ]
171
-
172
- val = if handler . nil?
173
- context [ key ]
174
- elsif handler . respond_to? ( :call )
175
- if handler . arity == 0
176
- handler . call
177
- else
178
- handler . call ( context )
179
- end
180
- else
181
- handler
182
- end
183
- [ key , val ] unless val . nil?
237
+ pairs = @handlers . filter_map do |( key , handler ) |
238
+ val = handler . call ( context )
239
+ @formatter . format ( key , val ) unless val . nil?
184
240
end
185
- self . formatter . format ( pairs )
241
+ @ formatter. join ( pairs )
186
242
end
187
243
end
244
+
245
+ @handlers = rebuild_handlers
246
+ self . tags_formatter = :legacy
188
247
end
189
248
end
0 commit comments