namespace :wiki do desc 'Wiki 移行' task migrate: :environment do require 'digest' require 'gollum-lib' wiki = Gollum::Wiki.new(Rails.root.join('wiki').to_s) WikiPage.where.missing(:wiki_revisions).find_each do |wiki_page| page = wiki.page("#{ wiki_page.id }.md") next unless page versions = page.versions next if versions.blank? base_revision_id = nil versions.reverse_each do |version| pg = wiki.page("#{ wiki_page.id }.md", version.id) raw = pg&.raw_data next unless raw lines = raw.force_encoding('UTF-8').split("\n") line_shas = lines.map { |l| Digest::SHA256.hexdigest(l) } tree_sha = Digest::SHA256.hexdigest(line_shas.join(',')) at = version.authored_date line_id_by_sha = WikiLine.where(sha256: line_shas).pluck(:sha256, :id).to_h missing_rows = [] line_shas.each_with_index do |sha, i| next if line_id_by_sha.key?(sha) missing_rows << { sha256: sha, body: lines[i], created_at: at, updated_at: at } end if missing_rows.any? WikiLine.upsert_all(missing_rows) line_id_by_sha = WikiLine.where(sha256: line_shas).pluck(:sha256, :id).to_h end line_ids = line_shas.map { |sha| line_id_by_sha.fetch(sha) } rev = nil ActiveRecord::Base.transaction do wiki_page.lock! rev = WikiRevision.create!( wiki_page:, base_revision_id:, created_user_id: (Integer(version.author.name) rescue 2), kind: :content, redirect_page_id: nil, message: nil, lines_count: lines.length, tree_sha256: tree_sha, created_at: at, updated_at: at) rows = line_ids.each_with_index.map do |line_id, pos| { wiki_revision_id: rev.id, wiki_line_id: line_id, position: pos } end WikiRevisionLine.insert_all!(rows) end base_revision_id = rev.id end end end end