# # Sonar, entreprise quality control tool. # Copyright (C) 2008-2012 SonarSource # mailto:contact AT sonarsource DOT com # # Sonar is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 3 of the License, or (at your option) any later version. # # Sonar is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with Sonar; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 # # # Class that centralizes the management the DB migration # require 'singleton' require 'thread' class DatabaseMigrationManager # mixin the singleton module to ensure we have only one instance of the class # it will be accessible with "DatabaseMigrationManager.instance" include Singleton # the status of the migration @status MIGRATION_NEEDED = "MIGRATION_NEEDED" MIGRATION_RUNNING = "MIGRATION_RUNNING" MIGRATION_FAILED = "MIGRATION_FAILED" MIGRATION_SUCCEEDED = "MIGRATION_SUCCEEDED" NO_MIGRATION = "NO_MIGRATION" # the corresponding message that can be given to the user @message # the time when the migration was started @start_time def initialize if !ActiveRecord::Base.connected? @status = MIGRATION_FAILED @message = "Not connected to database." elsif DatabaseVersion.uptodate? @status = NO_MIGRATION @message = "Database is up-to-date, no migration needed." else if DatabaseVersion.production? @status = MIGRATION_NEEDED @message = "Migration required." else @status = MIGRATION_FAILED @message = "Upgrade is not supported. Please use a production-ready database." end end end def message @message end def status @status end def requires_migration? @status==MIGRATION_NEEDED end def migration_running? @status==MIGRATION_RUNNING end def migration_failed? @status==MIGRATION_FAILED end def is_sonar_access_allowed? @status==NO_MIGRATION || @status==MIGRATION_SUCCEEDED end def migration_start_time @start_time end def start_migration # Use an exclusive block of code to ensure that only 1 thread will be able to proceed with the migration can_start_migration = false Thread.exclusive do if requires_migration? @status = MIGRATION_RUNNING @message = "Database migration is currently running." can_start_migration = true end end if can_start_migration # launch the upgrade begin @start_time = Time.now DatabaseVersion.upgrade_and_start @status = MIGRATION_SUCCEEDED @message = "The migration succeeded." rescue Exception => e @status = MIGRATION_FAILED @message = "The migration failed: " + e.clean_message + ".
Please check the logs." # rethrow the exception so that it is logged and so that the whole system knows that a problem occured raise end end end end