このコミットが含まれているのは:
@@ -0,0 +1,54 @@
|
|||||||
|
class CreateExternalTags < ActiveRecord::Migration[8.0]
|
||||||
|
def up
|
||||||
|
create_table :external_tags do |t|
|
||||||
|
t.string :platform, limit: 16, null: false
|
||||||
|
t.string :name, limit: 255, null: false
|
||||||
|
t.integer :post_count, null: false, default: 0
|
||||||
|
t.datetime :created_at, null: false
|
||||||
|
|
||||||
|
t.index [:platform, :name], unique: true
|
||||||
|
end
|
||||||
|
|
||||||
|
execute <<~SQL
|
||||||
|
INSERT INTO
|
||||||
|
external_tags(id, platform, name, post_count, created_at)
|
||||||
|
SELECT
|
||||||
|
t.id
|
||||||
|
, 'nico' AS platform
|
||||||
|
, SUBSTR(tn.name, 6) AS name
|
||||||
|
, t.post_count
|
||||||
|
, t.created_at
|
||||||
|
FROM
|
||||||
|
tags t
|
||||||
|
INNER JOIN
|
||||||
|
tag_names tn
|
||||||
|
ON
|
||||||
|
tn.id = t.tag_name_id
|
||||||
|
AND t.category = 'nico'
|
||||||
|
SQL
|
||||||
|
|
||||||
|
execute <<~SQL
|
||||||
|
INSERT INTO
|
||||||
|
external_tags(id, platform, name, post_count, created_at)
|
||||||
|
SELECT
|
||||||
|
ntv.tag_id
|
||||||
|
, 'nico' AS platform
|
||||||
|
, SUBSTR(ntv.name, 6) AS name
|
||||||
|
, 0 AS post_count
|
||||||
|
, ntv.created_at
|
||||||
|
FROM
|
||||||
|
nico_tag_versions ntv
|
||||||
|
LEFT JOIN
|
||||||
|
external_tags et
|
||||||
|
ON
|
||||||
|
et.id = ntv.tag_id
|
||||||
|
WHERE
|
||||||
|
ntv.version_no = 1
|
||||||
|
AND et.id IS NULL
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
drop_table :external_tags
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
class CreatePostExternalTags < ActiveRecord::Migration[8.0]
|
||||||
|
def up
|
||||||
|
create_table :post_external_tags, primary_key: [:post_id, :external_tag_id] do |t|
|
||||||
|
t.references :post, null: false, index: false, foreign_key: true
|
||||||
|
t.references :external_tag, null: false, foreign_key: true
|
||||||
|
t.datetime :created_at, null: false
|
||||||
|
end
|
||||||
|
|
||||||
|
execute <<~SQL
|
||||||
|
INSERT INTO
|
||||||
|
post_external_tags(post_id, external_tag_id, created_at)
|
||||||
|
SELECT
|
||||||
|
pt.post_id
|
||||||
|
, pt.tag_id AS external_tag_id
|
||||||
|
, pt.created_at
|
||||||
|
FROM
|
||||||
|
post_tags pt
|
||||||
|
INNER JOIN
|
||||||
|
tags t
|
||||||
|
ON
|
||||||
|
pt.tag_id = t.id
|
||||||
|
AND t.category = 'nico'
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
drop_table :post_external_tags
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
class ChangeForeignKeyOnNicoTagRelations < ActiveRecord::Migration[8.0]
|
||||||
|
def change
|
||||||
|
remove_foreign_key :nico_tag_relations, :tags, column: :nico_tag_id
|
||||||
|
add_foreign_key :nico_tag_relations, :external_tags, column: :nico_tag_id
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,199 @@
|
|||||||
|
class MigrateExternalTags < ActiveRecord::Migration[8.0]
|
||||||
|
class MigrationPostVersion < ActiveRecord::Base
|
||||||
|
self.table_name = 'post_versions'
|
||||||
|
end
|
||||||
|
|
||||||
|
def up
|
||||||
|
x = connection.select_value(<<~SQL)
|
||||||
|
SELECT
|
||||||
|
COUNT(0)
|
||||||
|
FROM
|
||||||
|
post_tag_sections pts
|
||||||
|
INNER JOIN
|
||||||
|
tags t
|
||||||
|
ON
|
||||||
|
t.id = pts.tag_id
|
||||||
|
WHERE
|
||||||
|
t.category = 'nico'
|
||||||
|
SQL
|
||||||
|
if x > 0
|
||||||
|
raise "post_tag_sections に #{ x } 件のチンカスがあります!"
|
||||||
|
end
|
||||||
|
|
||||||
|
x = connection.select_value(<<~SQL)
|
||||||
|
SELECT
|
||||||
|
COUNT(0)
|
||||||
|
FROM
|
||||||
|
materials m
|
||||||
|
INNER JOIN
|
||||||
|
tags t
|
||||||
|
ON
|
||||||
|
t.id = m.tag_id
|
||||||
|
WHERE
|
||||||
|
t.category = 'nico'
|
||||||
|
SQL
|
||||||
|
if x > 0
|
||||||
|
raise "materials に #{ x } 件のチンカスがあります!"
|
||||||
|
end
|
||||||
|
|
||||||
|
x = connection.select_value(<<~SQL)
|
||||||
|
SELECT
|
||||||
|
COUNT(0)
|
||||||
|
FROM
|
||||||
|
tag_implications ti
|
||||||
|
INNER JOIN
|
||||||
|
tags t
|
||||||
|
ON
|
||||||
|
t.id = ti.tag_id
|
||||||
|
OR t.id = ti.parent_tag_id
|
||||||
|
WHERE
|
||||||
|
t.category = 'nico'
|
||||||
|
SQL
|
||||||
|
if x > 0
|
||||||
|
raise "tag_implications に #{ x } 件のチンカスがあります!"
|
||||||
|
end
|
||||||
|
|
||||||
|
execute <<~SQL
|
||||||
|
DELETE
|
||||||
|
ts
|
||||||
|
FROM
|
||||||
|
tag_similarities ts
|
||||||
|
INNER JOIN
|
||||||
|
tags t
|
||||||
|
ON
|
||||||
|
t.category = 'nico'
|
||||||
|
AND (t.id = ts.tag_id
|
||||||
|
OR t.id = ts.target_tag_id)
|
||||||
|
SQL
|
||||||
|
|
||||||
|
execute <<~SQL
|
||||||
|
DELETE
|
||||||
|
tset
|
||||||
|
FROM
|
||||||
|
theatre_skip_event_tags tset
|
||||||
|
INNER JOIN
|
||||||
|
tags t
|
||||||
|
ON
|
||||||
|
t.category = 'nico'
|
||||||
|
AND t.id = tset.tag_id
|
||||||
|
SQL
|
||||||
|
|
||||||
|
remove_check_constraint :post_versions, name: 'chk_post_versions_tags_json_schema'
|
||||||
|
|
||||||
|
say_with_time 'Migrate post_versions.tags_json' do
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
MigrationPostVersion.find_each(batch_size: 500) do |version|
|
||||||
|
tags = version.tags_json.map do |tag|
|
||||||
|
if tag.fetch('category') == 'nico'
|
||||||
|
{ 'external_tag_id' => tag.fetch('id') }
|
||||||
|
else
|
||||||
|
{ 'tag_id' => tag.fetch('id'),
|
||||||
|
'version_no' => tag.fetch('version_no'),
|
||||||
|
'name' => tag.fetch('name'),
|
||||||
|
'category' => tag.fetch('category'),
|
||||||
|
'sections' => tag.fetch('sections') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
version.update_columns(tags_json: tags)
|
||||||
|
count += 1
|
||||||
|
end
|
||||||
|
|
||||||
|
count
|
||||||
|
end
|
||||||
|
|
||||||
|
add_tags_json_constraint!
|
||||||
|
|
||||||
|
tag_name_ids = connection.select_values(<<~SQL)
|
||||||
|
SELECT
|
||||||
|
tag_name_id
|
||||||
|
FROM
|
||||||
|
tags
|
||||||
|
WHERE
|
||||||
|
category = 'nico'
|
||||||
|
SQL
|
||||||
|
|
||||||
|
connection.transaction do
|
||||||
|
execute <<~SQL
|
||||||
|
DELETE
|
||||||
|
pt
|
||||||
|
FROM
|
||||||
|
post_tags pt
|
||||||
|
INNER JOIN
|
||||||
|
tags t
|
||||||
|
ON
|
||||||
|
t.category = 'nico'
|
||||||
|
AND t.id = pt.tag_id
|
||||||
|
SQL
|
||||||
|
|
||||||
|
execute <<~SQL
|
||||||
|
DELETE
|
||||||
|
FROM
|
||||||
|
tags
|
||||||
|
WHERE
|
||||||
|
category = 'nico'
|
||||||
|
SQL
|
||||||
|
|
||||||
|
unless tag_name_ids.empty?
|
||||||
|
execute <<~SQL
|
||||||
|
DELETE
|
||||||
|
FROM
|
||||||
|
tag_names
|
||||||
|
WHERE
|
||||||
|
id IN (#{ tag_name_ids.join(', ') })
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
raise ActiveRecord::IrreversibleMigration, '戻せません.'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def add_tags_json_constraint!
|
||||||
|
schema = { type: 'array',
|
||||||
|
items: { oneOf: [internal_tag_schema, external_tag_schema] } }
|
||||||
|
|
||||||
|
quoted_schema = connection.quote(JSON.generate(schema))
|
||||||
|
|
||||||
|
add_check_constraint :post_versions,
|
||||||
|
"JSON_SCHEMA_VALID(#{ quoted_schema }, tags_json)",
|
||||||
|
name: 'chk_post_versions_tags_json_schema'
|
||||||
|
end
|
||||||
|
|
||||||
|
def internal_tag_schema
|
||||||
|
{ type: 'object',
|
||||||
|
properties: { tag_id: { type: 'integer', minimum: 1 },
|
||||||
|
version_no: { type: 'integer', minimum: 1 },
|
||||||
|
name: { type: 'string', minLength: 1 },
|
||||||
|
category: { type: 'string',
|
||||||
|
enum: ['deerjikist',
|
||||||
|
'meme',
|
||||||
|
'character',
|
||||||
|
'general',
|
||||||
|
'material',
|
||||||
|
'meta'] },
|
||||||
|
sections: sections_schema },
|
||||||
|
required: ['tag_id', 'version_no', 'sections'],
|
||||||
|
additionalProperties: false }
|
||||||
|
end
|
||||||
|
|
||||||
|
def external_tag_schema
|
||||||
|
{ type: 'object',
|
||||||
|
properties: { external_tag_id: { type: 'integer', minimum: 1 } },
|
||||||
|
required: ['external_tag_id'],
|
||||||
|
additionalProperties: false }
|
||||||
|
end
|
||||||
|
|
||||||
|
def sections_schema
|
||||||
|
{ type: 'array',
|
||||||
|
items: { type: 'object',
|
||||||
|
properties: { begin_ms: { type: 'integer', minimum: 0 },
|
||||||
|
end_ms: { type: ['integer', 'null'], minimum: 0 } },
|
||||||
|
required: ['begin_ms', 'end_ms'],
|
||||||
|
additionalProperties: false } }
|
||||||
|
end
|
||||||
|
end
|
||||||
新しいイシューから参照
ユーザーをブロックする