このコミットが含まれているのは:
2026-10-28 20:34:11 +09:00
コミット cb3f4c600a
14個のファイルの変更、208行の追加、33行の削除
+34 -7
ファイルの表示
@@ -112,19 +112,29 @@ class CountsResourceDefinition
def field_label(key) = LABELS.fetch(key, "counts:attributes.#{ key }")
def self.name_key(code) = "name_#{ code.to_s.downcase.tr('-', '_') }"
def self.aliases_key(code) = "aliases_#{ code.to_s.downcase.tr('-', '_') }"
def name_columns
@name_columns ||= Locale.order(:code).map do |locale|
{ key: self.class.name_key(locale.code), label: 'counts:localeName',
label_values: { locale: locale.name },
name_locale: { code: locale.code, language_code: locale.language_code,
script_code: locale.script_code } }
@name_columns ||= Locale.select(:code, :language_code, :script_code).order(:code)
.flat_map do |locale|
codes = { code: locale.code, language_code: locale.language_code,
script_code: locale.script_code }
[{ key: self.class.name_key(locale.code), label: 'counts:localeName', name_locale: codes },
{ key: self.class.aliases_key(locale.code), label: 'counts:localeAliases',
name_locale: codes, multiple_values: true }]
end
end
def name_column(key) = name_columns.find { _1[:key] == key }
def name_expression(key, row = 'v')
if key.start_with?('aliases_')
source, value = alias_source(key, row)
return "CAST(COALESCE((SELECT JSON_ARRAYAGG(#{ value }) OVER (" +
'ORDER BY locale_alias.ordinal ROWS BETWEEN UNBOUNDED PRECEDING ' +
"AND UNBOUNDED FOLLOWING) FROM #{ source } WHERE #{ value } IS NOT NULL " +
'LIMIT 1), JSON_ARRAY()) AS CHAR) COLLATE utf8mb4_bin'
end
locale = name_column(key).fetch(:name_locale)
connection = model.connection
path = connection.quote("$.#{ locale[:language_code].to_json }")
@@ -135,6 +145,19 @@ class CountsResourceDefinition
"CONCAT(#{ path }, '.name')), CAST('null' AS JSON))) END"
end
def alias_source(key, row = 'v')
locale = name_column(key).fetch(:name_locale)
connection = model.connection
path = connection.quote("$.#{ locale[:language_code].to_json }.aliases[*]")
script = connection.quote(locale[:script_code])
source = "JSON_TABLE(COALESCE(#{ row }.names, JSON_OBJECT()), #{ path } " +
"COLUMNS (ordinal FOR ORDINALITY, name TEXT PATH '$.name', " +
"script TEXT PATH '$.script_code')) locale_alias"
value = "CASE WHEN LOWER(locale_alias.script) = LOWER(#{ script }) " +
'THEN locale_alias.name END'
[source, value]
end
def output_fields
content = case resource
when 'posts'
@@ -149,6 +172,7 @@ class CountsResourceDefinition
keys.flat_map do |key|
next name_columns if key == 'name' && resource == 'tags'
next [] if key == 'names' && resource == 'tags'
next [] if key == 'aliases' && resource == 'tags'
label = if key == 'parents'
resource == 'tags' ? 'tags:parents' : 'shared:labels.parentPosts'
else field_label(key)
@@ -174,6 +198,7 @@ class CountsResourceDefinition
else []
end
keys.flat_map do |child|
next [] if child == 'aliases' && key == 'tags'
if child == 'name' && ['tags', 'parents'].include?(key)
next [{ key: child, label: CHILD_LABELS.fetch(child) }, *name_columns]
end
@@ -194,14 +219,16 @@ class CountsResourceDefinition
fields = output_fields
if resource == 'tags'
fields += [{ key: 'name', label: 'counts:columns.name' },
{ key: 'names', label: 'counts:columns.names', children: child_fields('names') }]
{ key: 'names', label: 'counts:columns.names', children: child_fields('names') },
{ key: 'aliases', label: 'tags:aliases', children: child_fields('aliases') }]
end
if resource == 'posts'
fields = fields.map do |field|
next field unless field[:key] == 'tags'
field.merge(children: field[:children] + [
{ key: 'names', label: 'counts:columns.names', children: child_fields('names') }])
{ key: 'names', label: 'counts:columns.names', children: child_fields('names') },
{ key: 'aliases', label: 'tags:aliases', children: child_fields('aliases') }])
end
end
fields