このコミットが含まれているのは:
@@ -1,6 +1,7 @@
|
||||
# Common entrypoint for six version resources; legacy endpoints keep their contracts.
|
||||
class CountsTableQuery
|
||||
SQL_HINTS = ['MAX_EXECUTION_TIME(10000)',
|
||||
SQL_TIMEOUT_SECONDS = 30
|
||||
SQL_HINTS = ["MAX_EXECUTION_TIME(#{ SQL_TIMEOUT_SECONDS * 1000 })",
|
||||
"SET_VAR(optimizer_switch='semijoin=off')"].freeze
|
||||
MAX_COLUMNS = 100
|
||||
class TooManyColumns < ArgumentError; end
|
||||
@@ -176,7 +177,7 @@ class CountsTableQuery
|
||||
end
|
||||
|
||||
def details
|
||||
query = population.scope.select(Arel.sql(
|
||||
query = population.scope.optimizer_hints(*SQL_HINTS).select(Arel.sql(
|
||||
"(#{ population.current_latest_sql }) AS counts_latest"))
|
||||
order = sort_sql { detail_expression(_1) }
|
||||
query = query.order(Arel.sql((order + ['v.id ASC']).join(', ')))
|
||||
@@ -373,7 +374,9 @@ class CountsTableQuery
|
||||
return "#{ column } IS NULL ASC, (#{ column } <=> #{ masked }) ASC, " +
|
||||
"#{ expression } #{ direction.upcase }"
|
||||
end
|
||||
if field == 'category'
|
||||
if field == 'event_type'
|
||||
expression = event_order_sql(column)
|
||||
elsif field == 'category'
|
||||
# Tag's enum preserves the same category order as TagsController.
|
||||
cases = Tag.categories.keys.each_with_index.map { |category, index|
|
||||
"WHEN #{ @connection.quote(category) } THEN #{ index }"
|
||||
@@ -398,6 +401,7 @@ class CountsTableQuery
|
||||
|
||||
def detail_expression(key)
|
||||
return "(#{ population.current_latest_sql })" if key == 'latest'
|
||||
return event_order_sql(@definition.expression(key)) if key == 'event_type'
|
||||
return @definition.name_expression(key) if @definition.resource == 'tags' &&
|
||||
@definition.name_column(key)
|
||||
aliases = { 'tags' => 'tags_json', 'parents' => @definition.resource == 'posts' ?
|
||||
@@ -409,6 +413,11 @@ class CountsTableQuery
|
||||
"CAST(#{ expression } AS CHAR) COLLATE utf8mb4_bin"
|
||||
end
|
||||
|
||||
def event_order_sql(expression)
|
||||
"CASE #{ expression } WHEN 'create' THEN 0 WHEN 'update' THEN 1 " +
|
||||
"WHEN 'discard' THEN 2 WHEN 'restore' THEN 3 ELSE 4 END"
|
||||
end
|
||||
|
||||
def sort_sql
|
||||
@sort.flat_map do |key, direction|
|
||||
expression = yield key
|
||||
@@ -423,6 +432,7 @@ class CountsTableQuery
|
||||
values = conditions.map { _1['value'] }.compact.uniq
|
||||
labels = case field
|
||||
when 'tags' then tag_labels(values)
|
||||
when 'parent_tag_ids' then parent_tag_labels(values)
|
||||
when 'user'
|
||||
actors = HistoryAccess.visible(population.scope, 'v').except(:select, :order)
|
||||
.select('v.created_by_user_id')
|
||||
@@ -452,6 +462,7 @@ class CountsTableQuery
|
||||
labels = tag_labels(values)
|
||||
@axis_names["a#{ index }"] = @tag_names
|
||||
labels
|
||||
when 'parent_tag_ids' then parent_tag_labels(values)
|
||||
else {}
|
||||
end
|
||||
result["a#{ index }"] = labels
|
||||
@@ -459,6 +470,17 @@ class CountsTableQuery
|
||||
result
|
||||
end
|
||||
|
||||
def parent_tag_labels(values)
|
||||
ids = values.flat_map { _1.to_s.split }.uniq
|
||||
tag_labels(ids.map { "internal:#{ _1 }" })
|
||||
values.to_h do |value|
|
||||
names = value.to_s.split.map do |id|
|
||||
@tag_names.fetch("internal:#{ id }", {}).dig(locale.language_code, 'name')
|
||||
end
|
||||
[value.to_s, names.compact.join(' ')]
|
||||
end
|
||||
end
|
||||
|
||||
def tag_labels(values)
|
||||
internal = values.grep(/\Ainternal:/).map { _1.split(':').last.to_i }
|
||||
external = values.grep(/\Aexternal:/).map { _1.split(':').last.to_i }
|
||||
|
||||
新しいイシューから参照
ユーザーをブロックする