# frozen_string_literal: true class DisallowMultiLevelsThemeComponents < ActiveRecord::Migration[5.2] def up @handled = [] top_parents = DB.query( " SELECT parent_theme_id, child_theme_id FROM child_themes WHERE parent_theme_id NOT IN (SELECT child_theme_id FROM child_themes) ", ) top_parents.each { |top_parent| migrate_child(top_parent, top_parent) } if @handled.size > 0 execute( " DELETE FROM child_themes WHERE parent_theme_id NOT IN (#{top_parents.map(&:parent_theme_id).join(", ")}) ", ) end execute( " UPDATE themes SET user_selectable = false FROM child_themes WHERE themes.id = child_themes.child_theme_id AND themes.user_selectable = true ", ) default = DB.query_single("SELECT value FROM site_settings WHERE name = 'default_theme_id'").first if default default_child = DB.query( "SELECT 1 AS one FROM child_themes WHERE child_theme_id = ?", default.to_i, ).present? execute("DELETE FROM site_settings WHERE name = 'default_theme_id'") if default_child end end def down raise ActiveRecord::IrreversibleMigration end private def migrate_child(parent, top_parent) unless already_exists?(top_parent.parent_theme_id, parent.child_theme_id) execute( " INSERT INTO child_themes (parent_theme_id, child_theme_id, created_at, updated_at) VALUES (#{top_parent.parent_theme_id}, #{parent.child_theme_id}, now(), now()) ", ) end @handled << [top_parent.parent_theme_id, parent.parent_theme_id, parent.child_theme_id] children = DB.query( " SELECT parent_theme_id, child_theme_id FROM child_themes WHERE parent_theme_id = :child", child: parent.child_theme_id, ) children.each do |child| if @handled.exclude?( [top_parent.parent_theme_id, child.parent_theme_id, child.child_theme_id], ) migrate_child(child, top_parent) end end end def already_exists?(parent, child) DB.query( "SELECT 1 AS one FROM child_themes WHERE child_theme_id = :child AND parent_theme_id = :parent", child: child, parent: parent, ).present? end end