/**************************************************************************/
/*!

  @file         Kernel_Migration.hpp
  @author       UweH
  @brief        This implements the class Kernel_Migration.
  @since        2003-06-30
*/
/*!
\if EMIT_LICENCE

  copyright:    (c) 2001-2004 SAP AG


    ========== licence begin  GPL
    Copyright (c) 2001-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end



\endif
*/
#ifndef KERNEL_MIGRATION_HPP
#define KERNEL_MIGRATION_HPP

#include "KernelCommon/Kernel_Version.hpp"

/// maximum of persistent change list
#define MAX_CHANGE_INFO     10
#define INVALID_CHANGE_INFO MAX_CHANGE_INFO - 1

/*!
    @brief        This class bundles the migration of persistent structures within the kernel.
    @ingroup      KernelCommon
*/
class Kernel_Migration
{
    public:
        
        /// These components independently check migration needs and compatibility
        enum PersistentComponent
        {
            data    = 0,
            log     = 1,
            catalog = 2,
            MaxPersistentComponent_do_not_use = 3
        };
        
        struct ChangeInfo
        {
            const SAPDB_Char*         changeTitle;
            const PersistentComponent component;
            const bool                livecacheOnly;
            const Kernel_Version      changedInVersion;
            bool                      migrationEnabled;
            
            ChangeInfo(const SAPDB_Char*         newChangeTitle,
                       const PersistentComponent newComponent,
                       const bool                newLivecacheOnly,
                       const Kernel_Version      newChangedInVersion)
            : changeTitle      (newChangeTitle),
              component        (newComponent),
              livecacheOnly    (newLivecacheOnly),
              changedInVersion (newChangedInVersion),
              migrationEnabled (false)
            {}

            ChangeInfo()
            : changeTitle      (0),
              component        (data),
              livecacheOnly    (false),
              changedInVersion (Kernel_Version()),
              migrationEnabled (false)
            {}
            
            bool IsValid() const
            {
                return changeTitle != 0;
            }

            bool IsEnabled() const
            {
                return IsValid() && migrationEnabled;
            }
        };
        
        /// Compatibility of persistent data is checked.
        /// false is returned if the software version is older then the checkVersion.
        bool CheckCompatibility(PersistentComponent   checkComponent,
                                const Kernel_Version &checkVersion);

        /// Search for a named persistent change.
        /// If it is not found the returns ChangeInfo is invalid.
        /// changeTitle must be given as a 0 terminated ascii string.
        ChangeInfo & SearchForChangeInfo (const SAPDB_Char * changeTitle);
        /// the constan variant
        const ChangeInfo & SearchForChangeInfo (const SAPDB_Char * changeTitle) const;
        
        /// This compares all changes and returns the latest change version.
        static Kernel_Version GetOldestCompatibleVersion();
        
        static void Test(); ///< Self Test

    private:

        static void        ResetAllEnabledMigrationFlags();
        static SAPDB_Char* PersistentComponentStrings [MaxPersistentComponent_do_not_use];
        static ChangeInfo  m_ChangeInfos              [MAX_CHANGE_INFO];
};
#endif
