Added backup and restore operations to C# bindings. Also added unit test for backup and restore.

git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@861 0109f412-320b-0410-ab79-c3e0c5ffbbe6
This commit is contained in:
dsandersoremutah
2006-09-19 16:13:38 +00:00
parent 1fdf4361cf
commit 433218bb22
10 changed files with 1182 additions and 56 deletions

View File

@@ -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);
}
}
}

View File

@@ -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());
}

View File

@@ -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
{
/// <summary>
/// This class provides methods to backup an XFLAIM database.
/// </summary>
public class Backup
{
/// <summary>
/// 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 <see cref="Db.backupBegin"/>
/// </summary>
/// <param name="pBackup">
/// This is a pointer to the IF_Backup object in C++.
/// </param>
/// <param name="db">
/// 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.
/// </param>
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()");
}
}
/// <summary>
/// Destructor
/// </summary>
~Backup()
{
if (m_pBackup != 0)
{
xflaim_Backup_Release( m_pBackup);
m_pBackup = 0;
}
m_db = null;
}
/// <summary>
/// Get the transaction ID for this backup operation.
/// </summary>
/// <returns>Returns the transaction ID for this backup operation.</returns>
public ulong getBackupTransId()
{
return( xflaim_Backup_getBackupTransId( m_pBackup));
}
/// <summary>
/// Gets the transaction ID for the last backup job run on this database.
/// </summary>
/// <returns>
/// Returns the transaction ID for the last backup job run on the
/// database associated with this Backup object.
/// </returns>
public ulong getLastBackupTransId()
{
return( xflaim_Backup_getLastBackupTransId( m_pBackup));
}
/// <summary>
/// Performs the backup operation. The <paramref name="sBackupPath"/> and
/// <paramref name="backupClient"/> 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.
/// </summary>
/// <param name="sBackupPath">
/// The full pathname where the backup set is to be created. This parameter
/// is ignored if the backupClient parameter is non-null.
/// </param>
/// <param name="sPassword">
/// 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.
/// </param>
/// <param name="backupClient">
/// 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.
/// </param>
/// <param name="backupStatus">
/// If non-null, the backupStatus object provides an interface that this method
/// calls to report backup progress.
/// </param>
/// <returns>
/// Returns a sequence number for this backup. This is for informational
/// purposes only. For instance, users can use it to label their backup tapes.
/// </returns>
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;
}
/// <summary>
/// Ends the backup operation.
/// </summary>
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;
}
}

View File

@@ -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
{
/// <summary>
/// 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 <see cref="Backup.backup"/>. The object determines
/// where backup data will be saved.
/// </summary>
public interface BackupClient
{
/// <summary>
/// This method is called by the <see cref="Backup.backup"/> 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.
/// </summary>
/// <param name="pvData">
/// Pointer to data that is to be written out.
/// </param>
/// <param name="uiDataLen">
/// Length of data to be written out.
/// </param>
/// <returns>
/// Returns an <see cref="RCODE"/>. Note that returning anything
/// other than RCODE.NE_XFLM_OK will cause the backup operation to abort. It
/// will throw an <see cref="XFlaimException"/>
/// </returns>
RCODE writeData(
IntPtr pvData,
uint uiDataLen);
}
}

View File

@@ -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
{
/// <summary>
/// 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.
/// </summary>
public interface BackupStatus
{
/// <summary>
/// This method is called by the <see cref="Backup.backup"/> method to
/// report progress of a backup.
/// </summary>
/// <param name="ulBytesToDo">
/// Total bytes that are to be backed up.
/// </param>
/// <param name="ulBytesDone">
/// Bytes written out so far.
/// </param>
/// <returns>
/// Returns an <see cref="RCODE"/>. Note that returning anything
/// other than RCODE.NE_XFLM_OK will cause the backup operation to abort. It
/// will throw an <see cref="XFlaimException"/>
/// </returns>
RCODE backupStatus(
ulong ulBytesToDo,
ulong ulBytesDone);
}
}

View File

@@ -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);
}

View File

@@ -40,22 +40,22 @@ namespace xflaim
/// <summary>
/// Db constructor.
/// </summary>
/// <param name="cs_dbRef">
/// <param name="pDb">
/// Reference to an IF_Db object.
/// </param>
/// <param name="dbSystem">
/// DbSystem object that this Db object is associated with.
/// </param>
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();
}
/// <summary>
/// Return the pointer to the IF_Db object.
/// </summary>
/// <returns>Returns a pointer to the IF_Db object.</returns>
public ulong getDb()
{
return( m_pDb);
}
/// <summary>
/// Close this database.
/// </summary>
@@ -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;
}
/// <summary>
/// Sets up a backup operation.
/// </summary>
/// <param name="bFullBackup">
/// Specifies whether the backup is to be a full backup (true) or an incremental backup (false).
/// </param>
/// <param name="bLockDb">
/// Specifies whether the database should be locked during the back (a "warm" backup)
/// or unlocked (a "hot" backup).
/// </param>
/// <param name="uiMaxLockWait">
/// This parameter is only used if the bLockDb parameter is true. It specifies the maximum
/// number of seconds to wait to obtain a lock.
/// </param>
/// <returns>
/// If successful, this method returns a <see cref="Backup"/> 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.
/// </returns>
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);
/// <summary>
/// Reference to C++ IF_Db object.
/// </summary>
public ulong m_this;
public ulong m_pDb;
private DbSystem m_dbSystem;
}
}

View File

@@ -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
/// </summary>
~DbSystem()
{
xflaim_DbSystem_Release( m_this);
m_this = 0;
xflaim_DbSystem_Release( m_pDbSystem);
m_pDbSystem = 0;
}
/// <summary>
/// Called by <see cref="Db"/> class to silence compiler warning.
/// Has no other important use!
/// </summary>
public ulong getRef()
public ulong getDbSystem()
{
return m_this;
return m_pDbSystem;
}
/// <summary>
@@ -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;
}
}

View File

@@ -31,7 +31,7 @@ namespace xflaim
/// <summary>
/// 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 cref="DbSystem.dbRestore"/>
/// See the documentation regarding Backup/Restore operations for more details. * @see DefaultRestoreClient
/// </summary>

View File

@@ -48,7 +48,7 @@ namespace xflaim
}
/// <summary>
/// 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