diff --git a/xflaim/csharp/cstest/cstest.cs b/xflaim/csharp/cstest/cstest.cs index 3c17db0..0b613d9 100644 --- a/xflaim/csharp/cstest/cstest.cs +++ b/xflaim/csharp/cstest/cstest.cs @@ -35,8 +35,8 @@ namespace cstest private const string COPY_DB_NAME = "copy.db"; private const string RENAME_DB_NAME = "rename.db"; private const string RESTORE_DB_NAME = "restore.db"; - private const string REBUILD_DB_NAME = "rebuild.db"; private const string BACKUP_PATH = "backup"; + private const string REBUILD_DB_NAME = "rebuild.db"; //-------------------------------------------------------------------------- // Begin a test. @@ -51,8 +51,13 @@ namespace cstest // End a test. //-------------------------------------------------------------------------- static void endTest( + bool bWriteLine, bool bPassed) { + if (bWriteLine) + { + System.Console.Write( "\n"); + } if (bPassed) { System.Console.WriteLine( "PASS"); @@ -67,10 +72,11 @@ namespace cstest // End a test with an exception //-------------------------------------------------------------------------- static void endTest( + bool bWriteLine, XFlaimException ex, string sWhat) { - endTest( false); + endTest( bWriteLine, false); System.Console.Write( "Error {0}: ", sWhat); if (ex.getRCode() == RCODE.NE_XFLM_OK) { @@ -115,7 +121,7 @@ namespace cstest if (rc != RCODE.NE_XFLM_FILE_EXISTS) { - endTest( ex, "creating database"); + endTest( false, ex, "creating database"); return( false); } } @@ -132,7 +138,7 @@ namespace cstest } catch (XFlaimException ex) { - endTest( ex, "removing database"); + endTest( false, ex, "removing database"); return( false); } } @@ -141,7 +147,7 @@ namespace cstest db.close(); db = null; } - endTest( true); + endTest( false, true); return( true); } @@ -161,7 +167,7 @@ namespace cstest } catch (XFlaimException ex) { - endTest( ex, "opening database"); + endTest( false, ex, "opening database"); return( false); } if (db != null) @@ -169,7 +175,7 @@ namespace cstest db.close(); db = null; } - endTest( true); + endTest( false, true); return( true); } @@ -191,10 +197,106 @@ namespace cstest } catch (XFlaimException ex) { - endTest( ex, "copying database"); + endTest( copyStatus.outputLines(), ex, "copying database"); return( false); } - endTest( true); + endTest( copyStatus.outputLines(), true); + return( true); + } + + //-------------------------------------------------------------------------- + // Backup database test. + //-------------------------------------------------------------------------- + static bool backupDbTest( + DbSystem dbSystem) + { + Db db = null; + Backup backup = null; + MyBackupStatus backupStatus = null; + uint uiSeqNum; + + // Try backing up the database + + beginTest( "Backup Database Test (" + COPY_DB_NAME + " to directory \"" + BACKUP_PATH + "\")"); + + try + { + db = dbSystem.dbOpen( COPY_DB_NAME, null, null, null, false); + } + catch (XFlaimException ex) + { + endTest( false, ex, "opening database"); + return( false); + } + + // Backup the database + + try + { + backup = db.backupBegin( true, false, 0); + } + catch (XFlaimException ex) + { + endTest( false, ex, "calling backupBegin"); + return( false); + } + + // Perform the backup + + backupStatus = new MyBackupStatus(); + try + { + uiSeqNum = backup.backup( BACKUP_PATH, null, null, backupStatus); + } + catch (XFlaimException ex) + { + endTest( backupStatus.outputLines(), ex, "calling backup"); + return( false); + } + + // End the backup + + try + { + backup.endBackup(); + } + catch (XFlaimException ex) + { + endTest( backupStatus.outputLines(), ex, "calling endBackup"); + return( false); + } + + db.close(); + db = null; + endTest( backupStatus.outputLines(), true); + return( true); + } + + //-------------------------------------------------------------------------- + // Restore database test. + //-------------------------------------------------------------------------- + static bool restoreDbTest( + DbSystem dbSystem) + { + MyRestoreStatus restoreStatus = null; + + // Try restoring the database + + beginTest( "Restore Database Test (from directory \"" + BACKUP_PATH + "\" to " + RESTORE_DB_NAME + ")"); + + restoreStatus = new MyRestoreStatus(); + try + { + dbSystem.dbRestore( RESTORE_DB_NAME, null, null, BACKUP_PATH, null, + null, restoreStatus); + } + catch (XFlaimException ex) + { + endTest( restoreStatus.outputLines(), ex, "restoring database"); + return( false); + } + + endTest( restoreStatus.outputLines(), true); return( true); } @@ -212,10 +314,10 @@ namespace cstest } catch (XFlaimException ex) { - endTest( ex, "removing database"); + endTest( false, ex, "removing database"); return( false); } - endTest( true); + endTest( false, true); return( true); } @@ -247,6 +349,20 @@ namespace cstest return; } + // Database backup test + + if (!backupDbTest( dbSystem)) + { + return; + } + + // Database restore test + + if (!restoreDbTest( dbSystem)) + { + return; + } + // Database remove test if (!removeDbTest( dbSystem, CREATE_DB_NAME)) @@ -257,15 +373,23 @@ namespace cstest { return; } + if (!removeDbTest( dbSystem, RESTORE_DB_NAME)) + { + return; + } } } - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public class MyDbCopyStatus : DbCopyStatus { + public MyDbCopyStatus() + { + m_bOutputLines = false; + } + public RCODE dbCopyStatus( - ulong uiBytesToCopy, - ulong uiBytesCopied, + ulong ulBytesToCopy, + ulong ulBytesCopied, string sSrcFileName, string sDestFileName) { @@ -273,9 +397,345 @@ namespace cstest { System.Console.WriteLine( "\nSrc File: {0}, Dest File {1}", sSrcFileName, sDestFileName); } - System.Console.Write( "Bytes To Copy: {0}, Bytes Copied: {1}\r", uiBytesToCopy, uiBytesCopied); + System.Console.Write( "Bytes To Copy: {0}, Bytes Copied: {1}\r", ulBytesToCopy, ulBytesCopied); + m_bOutputLines = true; + return( RCODE.NE_XFLM_OK); + } + + public bool outputLines() + { + return( m_bOutputLines); + } + + private bool m_bOutputLines; + } + + public class MyBackupStatus : BackupStatus + { + public MyBackupStatus() + { + System.Console.WriteLine( " "); + m_bOutputLines = false; + } + + public RCODE backupStatus( + ulong ulBytesToDo, + ulong ulBytesDone) + { + System.Console.Write( "Bytes To Backup: {0}, Bytes Backed Up: {1}\r", ulBytesToDo, ulBytesDone); + m_bOutputLines = true; + return( RCODE.NE_XFLM_OK); + } + + public bool outputLines() + { + return( m_bOutputLines); + } + + private bool m_bOutputLines; + } + + public class MyRestoreStatus : RestoreStatus + { + private ulong m_ulNumTransCommitted; + private ulong m_ulNumTransAborted; + private bool m_bOutputLines; + + public MyRestoreStatus() + { + m_ulNumTransCommitted = 0; + m_ulNumTransAborted = 0; + System.Console.WriteLine( " "); + m_bOutputLines = false; + } + + public bool outputLines() + { + return( m_bOutputLines); + } + + public RCODE reportProgress( + ref RestoreAction peRestoreAction, + ulong ulBytesToDo, + ulong ulBytesDone) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + + System.Console.Write( "Bytes To Restore: {0}, Bytes Restored: {1}, TRCmit: {2}, TRAbrt: {3}\r", + ulBytesToDo, ulBytesDone, m_ulNumTransCommitted, m_ulNumTransAborted); + m_bOutputLines = true; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportError( + ref RestoreAction peRestoreAction, + RCODE rcErr) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + + System.Console.WriteLine( "\nError reported: {0}", rcErr); + m_bOutputLines = true; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportBeginTrans( + ref RestoreAction peRestoreAction, + ulong ulTransId) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportCommitTrans( + ref RestoreAction peRestoreAction, + ulong ulTransId) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + m_ulNumTransCommitted++; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportAbortTrans( + ref RestoreAction peRestoreAction, + ulong ulTransId) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + m_ulNumTransAborted++; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportBlockChainFree( + ref RestoreAction peRestoreAction, + ulong ulTransId, + ulong ulMaintDocNum, + uint uiStartBlkAddr, + uint uiEndBlkAddr, + uint uiCount) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportIndexSuspend( + ref RestoreAction peRestoreAction, + ulong ulTransId, + uint uiIndexNum) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportIndexResume( + ref RestoreAction peRestoreAction, + ulong ulTransId, + uint uiIndexNum) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportReduce( + ref RestoreAction peRestoreAction, + ulong ulTransId, + uint uiCount) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportUpgrade( + ref RestoreAction peRestoreAction, + ulong ulTransId, + uint uiOldDbVersion, + uint uiNewDbVersion) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportOpenRflFile( + ref RestoreAction peRestoreAction, + uint uiFileNum) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportRflRead( + ref RestoreAction peRestoreAction, + uint uiFileNum, + uint uiBytesRead) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportEnableEncryption( + ref RestoreAction peRestoreAction, + ulong ulTransId) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportWrapKey( + ref RestoreAction peRestoreAction, + ulong ulTransId) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportSetNextNodeId( + ref RestoreAction peRestoreAction, + ulong ulTransId, + uint uiCollection, + ulong ulNextNodeId) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportNodeSetMetaValue( + ref RestoreAction peRestoreAction, + ulong ulTransId, + uint uiCollection, + ulong ulNodeId, + ulong ulMetaValue) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportNodeSetPrefixId( + ref RestoreAction peRestoreAction, + ulong ulTransId, + uint uiCollection, + ulong ulNodeId, + uint uiAttrNameId, + uint uiPrefixId) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportNodeFlagsUpdate( + ref RestoreAction peRestoreAction, + ulong ulTransId, + uint uiCollection, + ulong ulNodeId, + uint uiFlags, + bool bAdd) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportAttributeSetValue( + ref RestoreAction peRestoreAction, + ulong ulTransId, + uint uiCollection, + ulong ulElementNodeId, + uint uiAttrNameId) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportNodeSetValue( + ref RestoreAction peRestoreAction, + ulong ulTransId, + uint uiCollection, + ulong ulNodeId) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportNodeUpdate( + ref RestoreAction peRestoreAction, + ulong ulTransId, + uint uiCollection, + ulong ulNodeId) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportInsertBefore( + ref RestoreAction peRestoreAction, + ulong ulTransId, + uint uiCollection, + ulong ulParentId, + ulong ulNewChildId, + ulong ulRefChildId) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportNodeCreate( + ref RestoreAction peRestoreAction, + ulong ulTransId, + uint uiCollection, + ulong ulRefNodeId, + eDomNodeType eNodeType, + uint uiNameId, + eNodeInsertLoc eLocation) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportNodeChildrenDelete( + ref RestoreAction peRestoreAction, + ulong ulTransId, + uint uiCollection, + ulong ulNodeId, + uint uiNameId) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportAttributeDelete( + ref RestoreAction peRestoreAction, + ulong ulTransId, + uint uiCollection, + ulong ulElementNodeId, + uint uiAttrNameId) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportNodeDelete( + ref RestoreAction peRestoreAction, + ulong ulTransId, + uint uiCollection, + ulong ulNodeId) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportDocumentDone( + ref RestoreAction peRestoreAction, + ulong ulTransId, + uint uiCollection, + ulong ulDocumentId) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; + return( RCODE.NE_XFLM_OK); + } + + public RCODE reportRollOverDbKey( + ref RestoreAction peRestoreAction, + ulong ulTransId) + { + peRestoreAction = RestoreAction.XFLM_RESTORE_ACTION_CONTINUE; return( RCODE.NE_XFLM_OK); } } } - diff --git a/xflaim/csharp/xflaim/Backup.cpp b/xflaim/csharp/xflaim/Backup.cpp new file mode 100644 index 0000000..6a46cce --- /dev/null +++ b/xflaim/csharp/xflaim/Backup.cpp @@ -0,0 +1,192 @@ +//------------------------------------------------------------------------------ +// Desc: +// +// 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$ +//------------------------------------------------------------------------------ + +#include "xflaim.h" + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMEXTC FLMEXP void FLMAPI xflaim_Backup_Release( + FLMUINT64 ui64This) +{ + IF_Backup * pBackup = ((IF_Backup *)(FLMUINT)ui64This); + + if (pBackup) + { + pBackup->Release(); + } +} + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMEXTC FLMEXP FLMUINT64 FLMAPI xflaim_Backup_getBackupTransId( + FLMUINT64 ui64This) +{ + IF_Backup * pBackup = ((IF_Backup *)(FLMUINT)ui64This); + + return( pBackup->getBackupTransId()); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMEXTC FLMEXP FLMUINT64 FLMAPI xflaim_Backup_getLastBackupTransId( + FLMUINT64 ui64This) +{ + IF_Backup * pBackup = ((IF_Backup *)(FLMUINT)ui64This); + + return( pBackup->getLastBackupTransId()); +} + +typedef RCODE (FLMAPI * BACKUP_CLIENT)( + const void * pvData, + FLMUINT uiDataLen); + +/**************************************************************************** +Desc: +****************************************************************************/ +class CS_BackupClient : public IF_BackupClient +{ +public: + + CS_BackupClient( + BACKUP_CLIENT fnBackupClient) + { + m_fnBackupClient = fnBackupClient; + } + + virtual ~CS_BackupClient() + { + } + + RCODE FLMAPI WriteData( + const void * pvBuffer, + FLMUINT uiBytesToWrite) + { + return( m_fnBackupClient( pvBuffer, uiBytesToWrite)); + } + +private: + + BACKUP_CLIENT m_fnBackupClient; +}; + +typedef RCODE (FLMAPI * BACKUP_STATUS)( + FLMUINT64 ui64BytesToDo, + FLMUINT64 ui64BytesDone); + +/**************************************************************************** +Desc: +****************************************************************************/ +class CS_BackupStatus : public IF_BackupStatus +{ +public: + + CS_BackupStatus( + BACKUP_STATUS fnBackupStatus) + { + m_fnBackupStatus = fnBackupStatus; + } + + virtual ~CS_BackupStatus() + { + } + + RCODE FLMAPI backupStatus( + FLMUINT64 ui64BytesToDo, + FLMUINT64 ui64BytesDone) + { + return( m_fnBackupStatus( ui64BytesToDo, ui64BytesDone)); + } + +private: + + BACKUP_STATUS m_fnBackupStatus; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMEXTC FLMEXP RCODE FLMAPI xflaim_Backup_backup( + FLMUINT64 ui64This, + const char * pszBackupPath, + const char * pszPassword, + FLMUINT * puiSeqNum, + BACKUP_CLIENT fnBackupClient, + BACKUP_STATUS fnBackupStatus) +{ + RCODE rc = NE_XFLM_OK; + IF_Backup * pBackup = (IF_Backup *)((FLMUINT)ui64This); + IF_BackupClient * pBackupClient = NULL; + IF_BackupStatus * pBackupStatus = NULL; + + if (fnBackupClient) + { + if ((pBackupClient = f_new CS_BackupClient( fnBackupClient)) == NULL) + { + rc = RC_SET( NE_XFLM_MEM); + goto Exit; + } + } + if (fnBackupStatus) + { + if ((pBackupStatus = f_new CS_BackupStatus( fnBackupStatus)) == NULL) + { + rc = RC_SET( NE_XFLM_MEM); + goto Exit; + } + } + if (RC_BAD( rc = pBackup->backup( pszBackupPath, pszPassword, pBackupClient, + pBackupStatus, puiSeqNum))) + { + goto Exit; + } + +Exit: + + if (pBackupClient) + { + pBackupClient->Release(); + } + + if (pBackupStatus) + { + pBackupStatus->Release(); + } + + return( rc); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMEXTC FLMEXP RCODE FLMAPI xflaim_Backup_endBackup( + FLMUINT64 ui64This) +{ + IF_Backup * pBackup = ((IF_Backup *)(FLMUINT)ui64This); + + return( pBackup->endBackup()); +} diff --git a/xflaim/csharp/xflaim/Backup.cs b/xflaim/csharp/xflaim/Backup.cs new file mode 100644 index 0000000..ddf4b2b --- /dev/null +++ b/xflaim/csharp/xflaim/Backup.cs @@ -0,0 +1,269 @@ +//------------------------------------------------------------------------------ +// Desc: Backup +// +// 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: Backup.java 3109 2006-01-19 13:07:07 -0700 (Thu, 19 Jan 2006) dsanders $ +//------------------------------------------------------------------------------ + +using System; +using System.Runtime.InteropServices; + +namespace xflaim +{ + + /// + /// This class provides methods to backup an XFLAIM database. + /// + public class Backup + { + + /// + /// This constructor doesn't need to do much of anything; it's here mostly + /// to ensure that Backup does NOT have a public constructor. (The + /// application is not supposed to call new on Backup; Backup objects + /// are created by calling + /// + /// + /// This is a pointer to the IF_Backup object in C++. + /// + /// + /// This is the database object this backup object is associated with. + /// We keep a reference to the database object so that it won't go away + /// in the middle of a backup. + /// + public Backup( + ulong pBackup, + Db db) + { + if ((m_pBackup = pBackup) == 0) + { + throw new XFlaimException( "Invalid IF_Backup pointer passed into Backup constructor"); + } + + if ((m_db = db) == null) + { + throw new XFlaimException( "Invalid Db object passed into Backup constructor"); + } + + // Must call something inside of Db. Otherwise, the + // m_db object gets a compiler warning on linux because + // it is not used anywhere. Other than that, there is really + // no need to make the following call. + if (m_db.getDb() == 0) + { + throw new XFlaimException( "Invalid Db.getRef()"); + } + } + + /// + /// Destructor + /// + ~Backup() + { + if (m_pBackup != 0) + { + xflaim_Backup_Release( m_pBackup); + m_pBackup = 0; + } + + m_db = null; + } + + /// + /// Get the transaction ID for this backup operation. + /// + /// Returns the transaction ID for this backup operation. + public ulong getBackupTransId() + { + return( xflaim_Backup_getBackupTransId( m_pBackup)); + } + + /// + /// Gets the transaction ID for the last backup job run on this database. + /// + /// + /// Returns the transaction ID for the last backup job run on the + /// database associated with this Backup object. + /// + public ulong getLastBackupTransId() + { + return( xflaim_Backup_getLastBackupTransId( m_pBackup)); + } + + /// + /// Performs the backup operation. The and + /// parameters are mutually exclusive. If + /// backupClient is null, then the backup will be created on disk in the + /// location specified by sBackupPath. If backupClient is non-null, the + /// sBackupPath parameter is ignored. + /// + /// + /// The full pathname where the backup set is to be created. This parameter + /// is ignored if the backupClient parameter is non-null. + /// + /// + /// Password to be used for the backup. A non-empty password allows the backup + /// to be restored on a machine other than the one where the database exists. The + /// database's encryption key (if encryption is enabled) will be wrapped in the + /// specified password so that the backup can be restored to a different machine. + /// + /// + /// If non-null, the backupClient is an object the provides interfaces for storing + /// backup data to disk, tape, or other media. If null, the backup data is stored + /// to a file set specified by the sBackupPath parameter. + /// + /// + /// If non-null, the backupStatus object provides an interface that this method + /// calls to report backup progress. + /// + /// + /// Returns a sequence number for this backup. This is for informational + /// purposes only. For instance, users can use it to label their backup tapes. + /// + public uint backup( + string sBackupPath, + string sPassword, + BackupClient backupClient, + BackupStatus backupStatus) + { + int rc; + uint uiSeqNum; + BackupClientDelegate backupClientDelegate = null; + BackupClientCallback fnBackupClient = null; + BackupStatusDelegate backupStatusDelegate = null; + BackupStatusCallback fnBackupStatus = null; + + if (backupClient != null) + { + backupClientDelegate = new BackupClientDelegate( backupClient); + fnBackupClient = new BackupClientCallback( backupClientDelegate.funcBackupClient); + } + if (backupStatus != null) + { + backupStatusDelegate = new BackupStatusDelegate( backupStatus); + fnBackupStatus = new BackupStatusCallback( backupStatusDelegate.funcBackupStatus); + } + + if ((rc = xflaim_Backup_backup( m_pBackup, sBackupPath, sPassword, out uiSeqNum, + fnBackupClient, fnBackupStatus)) != 0) + { + throw new XFlaimException( rc); + } + return( uiSeqNum); + } + + private delegate RCODE BackupClientCallback( + IntPtr pvData, + uint uiDataLen); + + private class BackupClientDelegate + { + public BackupClientDelegate( + BackupClient backupClient) + { + m_backupClient = backupClient; + } + + ~BackupClientDelegate() + { + } + + public RCODE funcBackupClient( + IntPtr pvData, + uint uiDataLen) + { + return( m_backupClient.writeData( pvData, uiDataLen)); + } + + private BackupClient m_backupClient; + } + + private delegate RCODE BackupStatusCallback( + ulong ulBytesToDo, + ulong ulBytesDone); + + private class BackupStatusDelegate + { + public BackupStatusDelegate( + BackupStatus backupStatus) + { + m_backupStatus = backupStatus; + } + + ~BackupStatusDelegate() + { + } + + public RCODE funcBackupStatus( + ulong ulBytesToDo, + ulong ulBytesDone) + { + return( m_backupStatus.backupStatus( ulBytesToDo, ulBytesDone)); + } + + private BackupStatus m_backupStatus; + } + + /// + /// Ends the backup operation. + /// + public void endBackup() + { + int rc; + + if ((rc = xflaim_Backup_endBackup( m_pBackup)) != 0) + { + throw new XFlaimException( rc); + } + } + + // PRIVATE METHODS THAT ARE IMPLEMENTED IN C AND C++ + + [DllImport("xflaim")] + private static extern int xflaim_Backup_Release( + ulong pBackup); + + [DllImport("xflaim")] + private static extern ulong xflaim_Backup_getBackupTransId( + ulong pBackup); + + [DllImport("xflaim")] + private static extern ulong xflaim_Backup_getLastBackupTransId( + ulong pBackup); + + [DllImport("xflaim")] + private static extern int xflaim_Backup_backup( + ulong pBackup, + [MarshalAs(UnmanagedType.LPStr)] string sBackupPath, + [MarshalAs(UnmanagedType.LPStr)] string sPassword, + out uint uiSeqNum, + BackupClientCallback fnBackupClient, + BackupStatusCallback fnBackupStatus); + + [DllImport("xflaim")] + private static extern int xflaim_Backup_endBackup( + ulong pBackup); + + private ulong m_pBackup; + private Db m_db; + } +} + diff --git a/xflaim/csharp/xflaim/BackupClient.cs b/xflaim/csharp/xflaim/BackupClient.cs new file mode 100644 index 0000000..63449cc --- /dev/null +++ b/xflaim/csharp/xflaim/BackupClient.cs @@ -0,0 +1,60 @@ +//------------------------------------------------------------------------------ +// Desc: Backup Client +// +// 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 +{ + + /// + /// This interface defines the client side interface to XFlaim's backup + /// subsystem. Clients may pass an object that implements this interface + /// into the call to . The object determines + /// where backup data will be saved. + /// + public interface BackupClient + { + + /// + /// This method is called by the method to + /// write out data that needs to be backed up. It is the responsibility + /// of this method to write that data out - to disk, tape, etc. + /// + /// + /// Pointer to data that is to be written out. + /// + /// + /// Length of data to be written out. + /// + /// + /// Returns an . Note that returning anything + /// other than RCODE.NE_XFLM_OK will cause the backup operation to abort. It + /// will throw an + /// + RCODE writeData( + IntPtr pvData, + uint uiDataLen); + } +} diff --git a/xflaim/csharp/xflaim/BackupStatus.cs b/xflaim/csharp/xflaim/BackupStatus.cs new file mode 100644 index 0000000..578303d --- /dev/null +++ b/xflaim/csharp/xflaim/BackupStatus.cs @@ -0,0 +1,60 @@ +//------------------------------------------------------------------------------ +// Desc: Backup 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 +{ + + /// + /// This interface allows XFlaim's backup subsystem to periodicly pass + /// information about the status of a backup operation (bytes completed and + /// bytes remaining) while the operation is running. The implementor may do + /// anything it wants with the information, such as using it to update a + /// progress bar or simply ignoring it. + /// + public interface BackupStatus + { + + /// + /// This method is called by the method to + /// report progress of a backup. + /// + /// + /// Total bytes that are to be backed up. + /// + /// + /// Bytes written out so far. + /// + /// + /// Returns an . Note that returning anything + /// other than RCODE.NE_XFLM_OK will cause the backup operation to abort. It + /// will throw an + /// + RCODE backupStatus( + ulong ulBytesToDo, + ulong ulBytesDone); + } +} diff --git a/xflaim/csharp/xflaim/Db.cpp b/xflaim/csharp/xflaim/Db.cpp index 24ee973..f05434f 100644 --- a/xflaim/csharp/xflaim/Db.cpp +++ b/xflaim/csharp/xflaim/Db.cpp @@ -38,3 +38,35 @@ FLMEXTC FLMEXP void FLMAPI xflaim_Db_Release( pDb->Release(); } } + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMEXTC FLMEXP RCODE FLMAPI xflaim_Db_backupBegin( + FLMUINT64 ui64This, + FLMBOOL bFullBackup, + FLMBOOL bLockDb, + FLMUINT uiMaxLockWait, + FLMUINT64 * pui64BackupRef) +{ + RCODE rc = NE_XFLM_OK; + IF_Db * pDb = ((IF_Db *)(FLMUINT)ui64This); + IF_Backup * pBackup = NULL; + + if (RC_BAD( rc = pDb->backupBegin( + (eDbBackupType)(bFullBackup + ? XFLM_FULL_BACKUP + : XFLM_INCREMENTAL_BACKUP), + (eDbTransType)(bLockDb + ? XFLM_READ_TRANS + : XFLM_UPDATE_TRANS), + uiMaxLockWait, &pBackup))) + { + goto Exit; + } + +Exit: + + *pui64BackupRef = (FLMUINT64)((FLMUINT)pBackup); + return( rc); +} diff --git a/xflaim/csharp/xflaim/Db.cs b/xflaim/csharp/xflaim/Db.cs index 4660a47..6eee3d4 100644 --- a/xflaim/csharp/xflaim/Db.cs +++ b/xflaim/csharp/xflaim/Db.cs @@ -40,22 +40,22 @@ namespace xflaim /// /// Db constructor. /// - /// + /// /// Reference to an IF_Db object. /// /// /// DbSystem object that this Db object is associated with. /// public Db( - ulong cs_dbRef, + ulong pDb, DbSystem dbSystem) { - if (cs_dbRef == 0) + if (pDb == 0) { throw new XFlaimException( "Invalid IF_Db reference"); } - m_this = cs_dbRef; + m_pDb = pDb; if (dbSystem == null) { @@ -68,7 +68,7 @@ namespace xflaim // m_dbSystem object gets a compiler warning on linux because // it is not used anywhere. Other than that, there is really // no need to make the following call. - if (m_dbSystem.getRef() == 0) + if (m_dbSystem.getDbSystem() == 0) { throw new XFlaimException( "Invalid DbSystem.getRef()"); } @@ -82,6 +82,15 @@ namespace xflaim close(); } + /// + /// Return the pointer to the IF_Db object. + /// + /// Returns a pointer to the IF_Db object. + public ulong getDb() + { + return( m_pDb); + } + /// /// Close this database. /// @@ -89,10 +98,10 @@ namespace xflaim { // Release the native pDb! - if (m_this != 0) + if (m_pDb != 0) { - xflaim_Db_Release( m_this); - m_this = 0; + xflaim_Db_Release( m_pDb); + m_pDb = 0; } // Remove our reference to the dbSystem so it can be released. @@ -100,16 +109,60 @@ namespace xflaim m_dbSystem = null; } + /// + /// Sets up a backup operation. + /// + /// + /// Specifies whether the backup is to be a full backup (true) or an incremental backup (false). + /// + /// + /// Specifies whether the database should be locked during the back (a "warm" backup) + /// or unlocked (a "hot" backup). + /// + /// + /// This parameter is only used if the bLockDb parameter is true. It specifies the maximum + /// number of seconds to wait to obtain a lock. + /// + /// + /// If successful, this method returns a object which can then be used + /// to perform the backup operation. The database will be locked if bLockDb was specified. + /// Otherwise, a read transaction will have been started to perform the backup. + /// + public Backup backupBegin( + bool bFullBackup, + bool bLockDb, + uint uiMaxLockWait) + { + int rc = 0; + ulong pBackup; + + if ((rc = xflaim_Db_backupBegin( m_pDb, (bFullBackup ? 1 : 0), + (bLockDb ? 1 : 0), uiMaxLockWait, out pBackup)) != 0) + { + throw new XFlaimException( rc); + } + + return( new Backup( pBackup, this)); + } + // PRIVATE METHODS THAT ARE IMPLEMENTED IN C AND C++ [DllImport("xflaim")] private static extern int xflaim_Db_Release( - ulong ui64This); + ulong pDb); + + [DllImport("xflaim")] + private static extern int xflaim_Db_backupBegin( + ulong pDb, + int bFullBackup, + int bLockDb, + uint uiMaxLockWait, + out ulong ulBackupRef); /// /// Reference to C++ IF_Db object. /// - public ulong m_this; + public ulong m_pDb; private DbSystem m_dbSystem; } } diff --git a/xflaim/csharp/xflaim/DbSystem.cs b/xflaim/csharp/xflaim/DbSystem.cs index ddb7758..21b418d 100644 --- a/xflaim/csharp/xflaim/DbSystem.cs +++ b/xflaim/csharp/xflaim/DbSystem.cs @@ -244,7 +244,7 @@ namespace xflaim { int rc = 0; - if (( rc = xflaim_DbSystem_createDbSystem( out m_this)) != 0) + if (( rc = xflaim_DbSystem_createDbSystem( out m_pDbSystem)) != 0) { throw new XFlaimException( rc); } @@ -255,17 +255,17 @@ namespace xflaim /// ~DbSystem() { - xflaim_DbSystem_Release( m_this); - m_this = 0; + xflaim_DbSystem_Release( m_pDbSystem); + m_pDbSystem = 0; } /// /// Called by class to silence compiler warning. /// Has no other important use! /// - public ulong getRef() + public ulong getDbSystem() { - return m_this; + return m_pDbSystem; } /// @@ -320,18 +320,18 @@ namespace xflaim CREATE_OPTS createOpts) { Db db = null; - ulong pulDbRef; + ulong pDb; int rc; - if ((rc = xflaim_DbSystem_dbCreate( m_this, sDbFileName, sDataDir, sRflDir, - sDictFileName, sDictBuf, createOpts, out pulDbRef)) != 0) + if ((rc = xflaim_DbSystem_dbCreate( m_pDbSystem, sDbFileName, sDataDir, sRflDir, + sDictFileName, sDictBuf, createOpts, out pDb)) != 0) { throw new XFlaimException( rc); } - if (pulDbRef != 0) + if (pDb != 0) { - db = new Db( pulDbRef, this); + db = new Db( pDb, this); } return( db); } @@ -366,18 +366,18 @@ namespace xflaim bool bAllowLimited) { Db db = null; - ulong pulDbRef; + ulong pDb; int rc; - if ((rc = xflaim_DbSystem_dbOpen( m_this, sDbFileName, sDataDir, sRflDir, - sPassword, (int)(bAllowLimited ? 1 : 0), out pulDbRef)) != 0) + if ((rc = xflaim_DbSystem_dbOpen( m_pDbSystem, sDbFileName, sDataDir, sRflDir, + sPassword, (int)(bAllowLimited ? 1 : 0), out pDb)) != 0) { throw new XFlaimException( rc); } - if (pulDbRef != 0) + if (pDb != 0) { - db = new Db( pulDbRef, this); + db = new Db( pDb, this); } return( db); } @@ -406,7 +406,7 @@ namespace xflaim { int rc; - if ((rc = xflaim_DbSystem_dbRemove( m_this, sDbFileName, sDataDir, sRflDir, + if ((rc = xflaim_DbSystem_dbRemove( m_pDbSystem, sDbFileName, sDataDir, sRflDir, (int)(bRemoveRflFiles ? 1 : 0))) != 0) { throw new XFlaimException( rc); @@ -477,7 +477,7 @@ namespace xflaim fnRestoreStatus = new RestoreStatusCallback( restoreStatusDelegate.funcRestoreStatus); } - if ((rc = xflaim_DbSystem_dbRestore( m_this, sDbPath, sDataDir, sRflDir, sBackupPath, + if ((rc = xflaim_DbSystem_dbRestore( m_pDbSystem, sDbPath, sDataDir, sRflDir, sBackupPath, sPassword, fnRestoreClient, fnRestoreStatus)) != 0) { throw new XFlaimException( rc); @@ -753,7 +753,7 @@ namespace xflaim dbCopyStatus = new DbCopyStatusDelegate( copyStatus); fnDbCopyStatus = new DbCopyStatusCallback( dbCopyStatus.funcDbCopyStatus); } - if ((rc = xflaim_DbSystem_dbCopy( m_this, sSrcDbName, sSrcDataDir, sSrcRflDir, + if ((rc = xflaim_DbSystem_dbCopy( m_pDbSystem, sSrcDbName, sSrcDataDir, sSrcRflDir, sDestDbName, sDestDataDir, sDestRflDir, fnDbCopyStatus)) != 0) { throw new XFlaimException( rc); @@ -807,36 +807,36 @@ namespace xflaim [DllImport("xflaim")] private static extern int xflaim_DbSystem_createDbSystem( - out ulong pulDbSystemRef); + out ulong ppDbSystem); [DllImport("xflaim")] private static extern int xflaim_DbSystem_Release( - ulong ulThis); + ulong pDbSystem); [DllImport("xflaim",CharSet=CharSet.Ansi)] private static extern int xflaim_DbSystem_dbCreate( - ulong ulThis, + ulong pDbSystem, [MarshalAs(UnmanagedType.LPStr)] string pszDbFileName, [MarshalAs(UnmanagedType.LPStr)] string pszDataDir, [MarshalAs(UnmanagedType.LPStr)] string pszRflDir, [MarshalAs(UnmanagedType.LPStr)] string pszDictFileName, [MarshalAs(UnmanagedType.LPStr)] string pszDictBuf, CREATE_OPTS pCreateOpts, - out ulong pulDbRef); + out ulong ppDb); [DllImport("xflaim",CharSet=CharSet.Ansi)] private static extern int xflaim_DbSystem_dbOpen( - ulong ulThis, + ulong pDbSystem, [MarshalAs(UnmanagedType.LPStr)] string pszDbFileName, [MarshalAs(UnmanagedType.LPStr)] string pszDataDir, [MarshalAs(UnmanagedType.LPStr)] string pszRflDir, [MarshalAs(UnmanagedType.LPStr)] string pszPassword, int bAllowLimited, - out ulong pulDbRef); + out ulong ppDb); [DllImport("xflaim",CharSet=CharSet.Ansi)] private static extern int xflaim_DbSystem_dbRemove( - ulong ulThis, + ulong pDbSystem, [MarshalAs(UnmanagedType.LPStr)] string pszDbFileName, [MarshalAs(UnmanagedType.LPStr)] string pszDataDir, [MarshalAs(UnmanagedType.LPStr)] string pszRflDir, @@ -844,7 +844,7 @@ namespace xflaim [DllImport("xflaim",CharSet=CharSet.Ansi)] private static extern int xflaim_DbSystem_dbRestore( - ulong ulThis, + ulong pDbSystem, [MarshalAs(UnmanagedType.LPStr)] string pszDbFileName, [MarshalAs(UnmanagedType.LPStr)] string pszDataDir, [MarshalAs(UnmanagedType.LPStr)] string pszRflDir, @@ -855,7 +855,7 @@ namespace xflaim [DllImport("xflaim",CharSet=CharSet.Ansi)] private static extern int xflaim_DbSystem_dbCopy( - ulong ulThis, + ulong pDbSystem, [MarshalAs(UnmanagedType.LPStr)] string pszSrcDbName, [MarshalAs(UnmanagedType.LPStr)] string pszSrcDataDir, [MarshalAs(UnmanagedType.LPStr)] string pszSrcRflDir, @@ -864,6 +864,6 @@ namespace xflaim [MarshalAs(UnmanagedType.LPStr)] string pszDestRflDir, DbCopyStatusCallback fnDbCopyStatus); - private ulong m_this; + private ulong m_pDbSystem; } } diff --git a/xflaim/csharp/xflaim/RestoreClient.cs b/xflaim/csharp/xflaim/RestoreClient.cs index f539841..bc0f9ac 100644 --- a/xflaim/csharp/xflaim/RestoreClient.cs +++ b/xflaim/csharp/xflaim/RestoreClient.cs @@ -31,7 +31,7 @@ namespace xflaim /// /// This interface defines the client side interface to XFlaim's restore - /// subsystem. Clients must pass an object that implements this interface + /// subsystem. Clients may pass an object that implements this interface /// into the call to /// See the documentation regarding Backup/Restore operations for more details. * @see DefaultRestoreClient /// diff --git a/xflaim/csharp/xflaim/RestoreStatus.cs b/xflaim/csharp/xflaim/RestoreStatus.cs index bbf2394..26053f7 100644 --- a/xflaim/csharp/xflaim/RestoreStatus.cs +++ b/xflaim/csharp/xflaim/RestoreStatus.cs @@ -48,7 +48,7 @@ namespace xflaim } /// - /// This interface allows XFlaim's backup subsystem to periodicly pass + /// This interface allows XFlaim's restore subsystem to periodicly pass /// information about the status of a restore operation (bytes completed and /// bytes remaining) while the operation is running. The implementor may do /// anything it wants with the information, such as using it to update a