diff --git a/xflaim/csharp/cstest/cstest.cs b/xflaim/csharp/cstest/cstest.cs index d09405a..53487f9 100644 --- a/xflaim/csharp/cstest/cstest.cs +++ b/xflaim/csharp/cstest/cstest.cs @@ -359,6 +359,46 @@ namespace cstest return( true); } + //-------------------------------------------------------------------------- + // Rebuild database test. + //-------------------------------------------------------------------------- + static bool rebuildDbTest( + string sSrcDbName, + string sDestDbName, + DbSystem dbSystem) + { + MyDbRebuildStatus dbRebuildStatus = null; + CREATE_OPTS createOpts = null; + + // Try restoring the database + + beginTest( "Rebuild Database Test (" + sSrcDbName + " to " + sDestDbName + ")"); + + dbRebuildStatus = new MyDbRebuildStatus(); + createOpts = new CREATE_OPTS(); + + createOpts.uiBlockSize = 8192; + createOpts.uiVersionNum = (uint)DBVersions.XFLM_CURRENT_VERSION_NUM; + createOpts.uiMinRflFileSize = 2000000; + createOpts.uiMaxRflFileSize = 20000000; + createOpts.bKeepRflFiles = 1; + createOpts.bLogAbortedTransToRfl = 1; + createOpts.uiDefaultLanguage = (uint)Languages.FLM_DE_LANG; + try + { + dbSystem.dbRebuild( sSrcDbName, null, sDestDbName, null, null, + null, null, createOpts, dbRebuildStatus); + } + catch (XFlaimException ex) + { + endTest( dbRebuildStatus.outputLines(), ex, "rebuilding database"); + return( false); + } + + endTest( true, true); + return( true); + } + //-------------------------------------------------------------------------- // Remove database test. //-------------------------------------------------------------------------- @@ -460,6 +500,13 @@ namespace cstest return; } + // Database rebuild test + + if (!rebuildDbTest( RESTORE_DB_NAME, REBUILD_DB_NAME, dbSystem)) + { + return; + } + // Database check test if (!checkDbTest( CREATE_DB_NAME, dbSystem)) @@ -478,6 +525,10 @@ namespace cstest { return; } + if (!checkDbTest( REBUILD_DB_NAME, dbSystem)) + { + return; + } // Database remove test @@ -497,6 +548,10 @@ namespace cstest { return; } + if (!removeDbTest( dbSystem, REBUILD_DB_NAME)) + { + return; + } } } @@ -859,6 +914,43 @@ namespace cstest } } + public class PrintCorruption + { + public static void printCorruption( + XFLM_CORRUPT_INFO corruptInfo) + { + System.Console.WriteLine( "\nCorruption Found: {0}, Locale: {1}", + corruptInfo.eErrCode, corruptInfo.eErrLocale); + if (corruptInfo.uiErrLfNumber != 0) + { + System.Console.WriteLine( " Logical File Number...... {0} ({1})", + corruptInfo.uiErrLfNumber, corruptInfo.eErrLfType); + System.Console.WriteLine( " B-Tree Level............. {0}", + corruptInfo.uiErrBTreeLevel); + } + if (corruptInfo.uiErrBlkAddress != 0) + { + System.Console.WriteLine( " Block Address............ {0:X})", + corruptInfo.uiErrBlkAddress); + } + if (corruptInfo.uiErrParentBlkAddress != 0) + { + System.Console.WriteLine( " Parent Block Address..... {0:X})", + corruptInfo.uiErrParentBlkAddress); + } + if (corruptInfo.uiErrElmOffset != 0) + { + System.Console.WriteLine( " Element Offset........... {0})", + corruptInfo.uiErrElmOffset); + } + if (corruptInfo.ulErrNodeId != 0) + { + System.Console.WriteLine( " Node ID.................. {0})", + corruptInfo.ulErrNodeId); + } + } + } + public class MyDbCheckStatus : DbCheckStatus { public MyDbCheckStatus() @@ -891,35 +983,44 @@ namespace cstest public RCODE reportCheckErr( XFLM_CORRUPT_INFO corruptInfo) { - System.Console.WriteLine( "\nCorruption Found: {0}, Locale: {1}", - corruptInfo.eErrCode, corruptInfo.eErrLocale); - if (corruptInfo.uiErrLfNumber != 0) + PrintCorruption.printCorruption( corruptInfo); + m_bOutputLines = true; + return( RCODE.NE_XFLM_OK); + } + + public bool outputLines() + { + return( m_bOutputLines); + } + + private bool m_bOutputLines; + } + + public class MyDbRebuildStatus : DbRebuildStatus + { + public MyDbRebuildStatus() + { + m_bOutputLines = false; + System.Console.Write( "\n"); + } + + public RCODE reportRebuild( + XFLM_REBUILD_INFO rebuildInfo) + { + if (rebuildInfo.bStartFlag != 0) { - System.Console.WriteLine( " Logical File Number...... {0} ({1})", - corruptInfo.uiErrLfNumber, corruptInfo.eErrLfType); - System.Console.WriteLine( " B-Tree Level............. {0}", - corruptInfo.uiErrBTreeLevel); - } - if (corruptInfo.uiErrBlkAddress != 0) - { - System.Console.WriteLine( " Block Address............ {0:X})", - corruptInfo.uiErrBlkAddress); - } - if (corruptInfo.uiErrParentBlkAddress != 0) - { - System.Console.WriteLine( " Parent Block Address..... {0:X})", - corruptInfo.uiErrParentBlkAddress); - } - if (corruptInfo.uiErrElmOffset != 0) - { - System.Console.WriteLine( " Element Offset........... {0})", - corruptInfo.uiErrElmOffset); - } - if (corruptInfo.ulErrNodeId != 0) - { - System.Console.WriteLine( " Node ID.................. {0})", - corruptInfo.ulErrNodeId); + System.Console.WriteLine( "\nRebuild Phase: {0}", rebuildInfo.eDoingFlag); } + System.Console.Write( "Bytes To Do {0}, Bytes Done: {1}\r", + rebuildInfo.ulDatabaseSize, rebuildInfo.ulBytesExamined); + m_bOutputLines = true; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportRebuildErr( + XFLM_CORRUPT_INFO corruptInfo) + { + PrintCorruption.printCorruption( corruptInfo); m_bOutputLines = true; return( RCODE.NE_XFLM_OK); } diff --git a/xflaim/csharp/xflaim/DbSystem.cpp b/xflaim/csharp/xflaim/DbSystem.cpp index 2feb784..5f2d4cc 100644 --- a/xflaim/csharp/xflaim/DbSystem.cpp +++ b/xflaim/csharp/xflaim/DbSystem.cpp @@ -881,3 +881,92 @@ Exit: return( rc); } + +typedef RCODE (FLMAPI * DB_REBUILD_STATUS)( + FLMBOOL bHaveRebuildInfo, + XFLM_REBUILD_INFO * pRebuildInfo, + XFLM_CORRUPT_INFO * pCorruptInfo); + +/**************************************************************************** +Desc: +****************************************************************************/ +class CS_DbRebuildStatus : public IF_DbRebuildStatus +{ +public: + + CS_DbRebuildStatus( + DB_REBUILD_STATUS fnDbRebuildStatus) + { + m_fnDbRebuildStatus = fnDbRebuildStatus; + } + + virtual ~CS_DbRebuildStatus() + { + } + + RCODE FLMAPI reportRebuild( + XFLM_REBUILD_INFO * pRebuildInfo) + { + return( m_fnDbRebuildStatus( TRUE, pRebuildInfo, NULL)); + } + + RCODE FLMAPI reportRebuildErr( + XFLM_CORRUPT_INFO * pCorruptInfo) + { + return( m_fnDbRebuildStatus( FALSE, NULL, pCorruptInfo)); + } + +private: + + DB_REBUILD_STATUS m_fnDbRebuildStatus; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMEXTC FLMEXP RCODE FLMAPI xflaim_DbSystem_dbRebuild( + FLMUINT64 ui64This, + const char * pszSourceDbPath, + const char * pszSourceDataDir, + const char * pszDestDbPath, + const char * pszDestDataDir, + const char * pszDestRflDir, + const char * pszDictPath, + const char * pszPassword, + XFLM_CREATE_OPTS * pCreateOpts, + DB_REBUILD_STATUS fnRebuildStatus) +{ + RCODE rc = NE_XFLM_OK; + IF_DbSystem * pDbSystem = ((IF_DbSystem *)(FLMUINT)ui64This); + IF_DbRebuildStatus * pDbRebuildStatus = NULL; + FLMUINT64 ui64TotNodes; + FLMUINT64 ui64NodesRecov; + FLMUINT64 ui64DiscardedDocs; + + if (fnRebuildStatus) + { + if ((pDbRebuildStatus = f_new CS_DbRebuildStatus( fnRebuildStatus)) == NULL) + { + rc = RC_SET( NE_XFLM_MEM); + goto Exit; + } + } + + if (RC_BAD( rc = pDbSystem->dbRebuild( pszSourceDbPath, pszSourceDataDir, + pszDestDbPath, pszDestDataDir, pszDestRflDir, + pszDictPath, pszPassword, pCreateOpts, + &ui64TotNodes, &ui64NodesRecov, &ui64DiscardedDocs, + pDbRebuildStatus))) + { + goto Exit; + } + +Exit: + + if (pDbRebuildStatus) + { + pDbRebuildStatus->Release(); + } + + return( rc); +} diff --git a/xflaim/csharp/xflaim/DbSystem.cs b/xflaim/csharp/xflaim/DbSystem.cs index 900181f..4365df1 100644 --- a/xflaim/csharp/xflaim/DbSystem.cs +++ b/xflaim/csharp/xflaim/DbSystem.cs @@ -282,6 +282,10 @@ namespace xflaim return m_pDbSystem; } +//----------------------------------------------------------------------------- +// dbCreate +//----------------------------------------------------------------------------- + /// /// Creates a new XFlaim database. /// @@ -350,8 +354,12 @@ namespace xflaim return( db); } +//----------------------------------------------------------------------------- +// dbOpen +//----------------------------------------------------------------------------- + /// - /// Creates a new XFlaim database. + /// Opens an existing XFlaim database. /// /// /// See documentation on . @@ -396,6 +404,10 @@ namespace xflaim return( db); } +//----------------------------------------------------------------------------- +// dbRemove +//----------------------------------------------------------------------------- + /// /// Removes (deletes) an XFlaim database. /// @@ -427,6 +439,10 @@ namespace xflaim } } +//----------------------------------------------------------------------------- +// dbRestore +//----------------------------------------------------------------------------- + /// /// Restores a previously backed up database. The parameter /// and the parameter are mutually exclusive. If the @@ -720,6 +736,10 @@ namespace xflaim private RestoreStatus m_restoreStatus; } +//----------------------------------------------------------------------------- +// dbCheck +//----------------------------------------------------------------------------- + /// /// Check for physical and logical corruptions on the specified database. /// @@ -819,6 +839,10 @@ namespace xflaim private DbCheckStatus m_dbCheckStatus; } +//----------------------------------------------------------------------------- +// dbCopy +//----------------------------------------------------------------------------- + /// /// Makes a copy of an existing database. /// @@ -916,6 +940,10 @@ namespace xflaim private DbCopyStatus m_dbCopyStatus; } +//----------------------------------------------------------------------------- +// dbRename +//----------------------------------------------------------------------------- + /// /// Rename a database. /// @@ -991,7 +1019,124 @@ namespace xflaim private DbRenameStatus m_dbRenameStatus; } - // PRIVATE METHODS THAT ARE IMPLEMENTED IN C AND C++ +//----------------------------------------------------------------------------- +// dbRebuild +//----------------------------------------------------------------------------- + + /// + /// Rebuild a database. + /// + /// + /// The name of the control file of the database that is to be rebuilt. + /// + /// + /// The data file directory. See for more information. + /// + /// + /// The name of the control file of the destination + /// database that is to be built from the source database. + /// + /// + /// The destination database's data file directory. See for + /// more information. + /// + /// + /// The destination database's roll-forward log + /// directory. See for more information. + /// + /// + /// The name of a file containing dictionary definitions that + /// are to be put into the destination database when it is created. + /// May be null. + /// + /// + /// Password for opening the source database. This is only needed + /// if the database key is currently wrapped in a password instead of the + /// local NICI storage key. May be null. + /// + /// + /// A object that contains several parameters that + /// are used in the creation of the destination database. + /// + /// + /// If non-null this is an object that implements the + /// interface. It is a callback object that is used to report rebuild progress. + /// + public void dbRebuild( + string sSourceDbPath, + string sSourceDataDir, + string sDestDbPath, + string sDestDataDir, + string sDestRflDir, + string sDictPath, + string sPassword, + CREATE_OPTS createOpts, + DbRebuildStatus rebuildStatus) + { + int rc; + DbRebuildStatusDelegate dbRebuildStatus = null; + DbRebuildStatusCallback fnDbRebuildStatus = null; + + if (rebuildStatus != null) + { + dbRebuildStatus = new DbRebuildStatusDelegate( rebuildStatus); + fnDbRebuildStatus = new DbRebuildStatusCallback( dbRebuildStatus.funcDbRebuildStatus); + } + + if ((rc = xflaim_DbSystem_dbRebuild( m_pDbSystem, sSourceDbPath, sSourceDataDir, sDestDbPath, + sDestDataDir, sDestRflDir, sDictPath, sPassword, + createOpts, fnDbRebuildStatus)) != 0) + { + throw new XFlaimException( rc); + } + } + + private delegate RCODE DbRebuildStatusCallback( + int bHaveRebuildInfo, + IntPtr pRebuildInfo, + IntPtr pCorruptInfo); + + private class DbRebuildStatusDelegate + { + public DbRebuildStatusDelegate( + DbRebuildStatus dbRebuildStatus) + { + m_dbRebuildStatus = dbRebuildStatus; + } + + ~DbRebuildStatusDelegate() + { + } + + public RCODE funcDbRebuildStatus( + int bHaveRebuildInfo, + IntPtr pRebuildInfo, + IntPtr pCorruptInfo) + { + RCODE rc = RCODE.NE_XFLM_OK; + + if (bHaveRebuildInfo != 0) + { + rc = m_dbRebuildStatus.reportRebuild( + (XFLM_REBUILD_INFO)Marshal.PtrToStructure( pRebuildInfo, + typeof( XFLM_REBUILD_INFO))); + } + else + { + XFLM_CORRUPT_INFO corruptInfo = new XFLM_CORRUPT_INFO(); + rc = m_dbRebuildStatus.reportRebuildErr( + (XFLM_CORRUPT_INFO)Marshal.PtrToStructure( pCorruptInfo, + typeof( XFLM_CORRUPT_INFO))); + } + return( rc); + } + + private DbRebuildStatus m_dbRebuildStatus; + } + +//----------------------------------------------------------------------------- +// PRIVATE METHODS THAT ARE IMPLEMENTED IN C AND C++ +//----------------------------------------------------------------------------- [DllImport("xflaim")] private static extern int xflaim_DbSystem_createDbSystem( @@ -1073,6 +1218,19 @@ namespace xflaim int bOverwriteDestOk, DbRenameStatusCallback fnDbRenameStatus); + [DllImport("xflaim",CharSet=CharSet.Ansi)] + private static extern int xflaim_DbSystem_dbRebuild( + ulong pDbSystem, + [MarshalAs(UnmanagedType.LPStr)] string pszSourceDbPath, + [MarshalAs(UnmanagedType.LPStr)] string pszSourceDataDir, + [MarshalAs(UnmanagedType.LPStr)] string pszDestDbPath, + [MarshalAs(UnmanagedType.LPStr)] string pszDestDataDir, + [MarshalAs(UnmanagedType.LPStr)] string pszDestRflDir, + [MarshalAs(UnmanagedType.LPStr)] string pszDictPath, + [MarshalAs(UnmanagedType.LPStr)] string pszPassword, + CREATE_OPTS pCreateOpts, + DbRebuildStatusCallback fnDbRebuildStatus); + private ulong m_pDbSystem; } } diff --git a/xflaim/csharp/xflaim/dbCheck.cs b/xflaim/csharp/xflaim/dbCheck.cs index 459071a..21da7ac 100644 --- a/xflaim/csharp/xflaim/dbCheck.cs +++ b/xflaim/csharp/xflaim/dbCheck.cs @@ -369,12 +369,10 @@ namespace xflaim /// /// Indicates whether we are just starting this phase of the operation. Value /// will be non-zero if just starting, zero otherwise. - /// is currently in. /// public int bStartFlag; /// /// Total number of bytes in the database. - /// is currently in. /// public ulong ulDatabaseSize; /// diff --git a/xflaim/csharp/xflaim/dbRebuild.cs b/xflaim/csharp/xflaim/dbRebuild.cs new file mode 100644 index 0000000..6a1caf6 --- /dev/null +++ b/xflaim/csharp/xflaim/dbRebuild.cs @@ -0,0 +1,123 @@ +//------------------------------------------------------------------------------ +// Desc: Db Rebuild Status +// +// Tabs: 3 +// +// Copyright (c) 2006 Novell, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of version 2 of the GNU General Public +// License as published by the Free Software Foundation. +// +// 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, contact Novell, Inc. +// +// To contact Novell about this file by physical or electronic mail, +// you may find current contact information at www.novell.com +// +// $Id$ +//------------------------------------------------------------------------------ + +using System; +using System.Runtime.InteropServices; + +namespace xflaim +{ + + /// + /// Phases of a rebuild operation. + /// + public enum RebuildPhase + { + /// Determining block size + REBUILD_GET_BLK_SIZ = 1, + /// Recovering the dictionary + REBUILD_RECOVER_DICT = 2, + /// Recovering non-dictionary data + REBUILD_RECOVER_DATA = 3 + } + + /// + /// Class that reports progress information for a operation. + /// It is returned in the method. + /// IMPORTANT NOTE: This structure needs to stay in sync with the XFLM_REBUILD_INFO + /// structure defined in xflaim.h + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public class XFLM_REBUILD_INFO + { + /// Current phase of the rebuild operation + public RebuildPhase eDoingFlag; + /// + /// Indicates whether we are just starting this phase of the operation. Value + /// will be non-zero if just starting, zero otherwise. + /// + public int bStartFlag; + /// + /// Size of the database in bytes. + /// + public ulong ulDatabaseSize; + /// + /// Total bytes read so far. + /// + public ulong ulBytesExamined; + /// + /// Total DOM nodes found so far. + /// + public ulong ulTotNodes; + /// + /// Total DOM nodes recovered. + /// + public ulong ulNodesRecov; + /// + /// Total DOM nodes discarded. + /// + public ulong ulDiscardedDocs; + } + + /// + /// This interface allows XFlaim to periodically pass information back to the + /// client about the status of an ongoing database rebuild operation. The + /// implementor may do anything it wants with the information, such as write + /// it to a log file or display it on the screen. + /// + public interface DbRebuildStatus + { + + /// + /// Called by to report progress of the + /// rebuild operation. + /// + /// + /// This object contains information about the progress of the + /// rebuild operation. + /// + /// + /// If the implementation object returns anything but RCODE.NE_XFLM_OK + /// the operation will abort and throw an + /// + /// + RCODE reportRebuild( + XFLM_REBUILD_INFO rebuildInfo); + + /// + /// Called by to report corruptions found by the + /// rebuild operation. + /// + /// + /// Information about the corruption is contained in this object. + /// + /// + /// If the implementation object returns anything but RCODE.NE_XFLM_OK + /// the operation will abort and throw an + /// + /// + RCODE reportRebuildErr( + XFLM_CORRUPT_INFO corruptInfo); + } +}