//------------------------------------------------------------------------------ // Desc: This file contains the F_DbSystem::dbRemove method. // Tabs: 3 // // Copyright (c) 2001-2007 Novell, Inc. All Rights Reserved. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; version 2.1 // of the License. // // This library 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 // Library Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; 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 "flaimsys.h" /**************************************************************************** Desc: Deletes all files of a database ****************************************************************************/ RCODE F_DbSystem::dbRemove( const char * pszDbName, // [IN] Name of source database to be deleted. const char * pszDataDir, // [IN] Directory where data files are located. const char * pszRflDir, // [IN] RFL directory of database. NULL can be // passed to indicate that the log files are located // in the same directory as the other database files. FLMBOOL bRemoveRflFiles) { RCODE rc = NE_XFLM_OK; FLMUINT uiFileNumber; char * pszTmpName = NULL; char * pszRflDirName; char * pszDataName; char * pszBaseName; char * pszExt; char * pszDataExt; IF_DirHdl * pDirHdl = NULL; // Cannot handle empty database name. if( !pszDbName || !(*pszDbName)) { rc = RC_SET( NE_FLM_IO_INVALID_FILENAME); goto Exit; } // Allocate memory, so as to not consume stack. if( RC_BAD( rc = f_alloc( F_PATH_MAX_SIZE * 3 + F_FILENAME_SIZE, &pszTmpName))) { goto Exit; } pszRflDirName = pszTmpName + F_PATH_MAX_SIZE; pszDataName = pszRflDirName + F_PATH_MAX_SIZE; pszBaseName = pszDataName + F_PATH_MAX_SIZE; // First make sure we have closed this database and gotten rid of // it from our internal memory tables - in case it had been open. if (RC_BAD( rc = checkDatabaseClosed( pszDbName, pszDataDir))) { goto Exit; } // Close all unused file handles if( gv_XFlmSysData.pFileHdlCache) { gv_XFlmSysData.pFileHdlCache->closeUnusedFiles(); } if (pszDataDir && *pszDataDir) { if (RC_BAD( rc = gv_XFlmSysData.pFileSystem->pathReduce( pszDbName, pszDataName, pszBaseName))) { goto Exit; } f_strcpy( pszDataName, pszDataDir); if (RC_BAD( rc = gv_XFlmSysData.pFileSystem->pathAppend( pszDataName, pszBaseName))) { goto Exit; } } else { f_strcpy( pszDataName, pszDbName); } f_strcpy( pszTmpName, pszDbName); // Start deleting files, beginning with the main DB file. if (RC_BAD( rc = gv_XFlmSysData.pFileSystem->deleteFile( pszDbName))) { if (rc == NE_FLM_IO_PATH_NOT_FOUND || rc == NE_FLM_IO_INVALID_FILENAME) { rc = NE_XFLM_OK; } else { goto Exit; } } // Find where the extension of the database name is pszExt = pszTmpName + f_strlen( pszTmpName) - 1; pszDataExt = pszDataName + f_strlen( pszDataName) - 1; while (pszExt != pszTmpName && *pszExt != '.') { pszExt--; // Both the db name and data name have the same // base name, so we can decrement pszDataExt // at the same time we decrement pszExt. pszDataExt--; } if (*pszExt != '.') { pszExt = pszTmpName + f_strlen( pszTmpName); pszDataExt = pszDataName + f_strlen( pszDataName); } // Delete the .lck file, if any f_strcpy( pszExt, ".lck"); if (RC_BAD( rc = gv_XFlmSysData.pFileSystem->deleteFile( pszTmpName))) { if (rc == NE_FLM_IO_PATH_NOT_FOUND || rc == NE_FLM_IO_INVALID_FILENAME) { rc = NE_XFLM_OK; } else { goto Exit; } } // Delete block (data) files. uiFileNumber = 1; for (;;) { F_SuperFileClient::bldSuperFileExtension( uiFileNumber, pszDataExt); if (RC_BAD( rc = gv_XFlmSysData.pFileSystem->deleteFile( pszDataName))) { if (rc == NE_FLM_IO_PATH_NOT_FOUND || rc == NE_FLM_IO_INVALID_FILENAME) { rc = NE_XFLM_OK; break; } else { goto Exit; } } if (uiFileNumber == MAX_DATA_BLOCK_FILE_NUMBER) { break; } uiFileNumber++; } // Delete rollback log files. uiFileNumber = FIRST_LOG_BLOCK_FILE_NUMBER; for (;;) { F_SuperFileClient::bldSuperFileExtension( uiFileNumber, pszExt); if (RC_BAD( rc = gv_XFlmSysData.pFileSystem->deleteFile( pszTmpName))) { if (rc == NE_FLM_IO_PATH_NOT_FOUND || rc == NE_FLM_IO_INVALID_FILENAME) { rc = NE_XFLM_OK; break; } else { goto Exit; } } if (uiFileNumber == MAX_LOG_BLOCK_FILE_NUMBER) { break; } uiFileNumber++; } if (bRemoveRflFiles) { // Delete roll-forward log files. FLMBOOL bCanDeleteDir; // Scan the RFL directory for RFL files. if (RC_BAD( rc = rflGetDirAndPrefix( pszDbName, pszRflDir, pszRflDirName))) { goto Exit; } // See if the directory exists. If not, we are done. if (!gv_XFlmSysData.pFileSystem->isDir( pszRflDirName)) { goto Exit; // Should return NE_XFLM_OK } // Open the directory and scan for RFL files. // NOTE: DO NOT just call removeDir. There may be other // things in the directory that we do not want to delete. // Look specifically for files that match our expected // name format for RFL files. if (RC_BAD( rc = gv_XFlmSysData.pFileSystem->openDir( pszRflDirName, "*", &pDirHdl))) { goto Exit; } // Assume that we can delete the directory. This will only // be set to FALSE if we can't delete all of the files in // the directory - i.e., some don't look like RFL log files. bCanDeleteDir = TRUE; for (;;) { if (RC_BAD( rc = pDirHdl->next())) { if (rc == NE_FLM_IO_NO_MORE_FILES) { rc = NE_XFLM_OK; break; } else { goto Exit; } } pDirHdl->currentItemPath( pszTmpName); if (pDirHdl->currentItemIsDir()) { bCanDeleteDir = FALSE; } else if (!rflGetFileNum( pszTmpName, &uiFileNumber)) { bCanDeleteDir = FALSE; } else { if( RC_BAD( rc = gv_XFlmSysData.pFileSystem->deleteFile( pszTmpName))) { if (rc == NE_FLM_IO_PATH_NOT_FOUND || rc == NE_FLM_IO_INVALID_FILENAME) { rc = NE_XFLM_OK; } else { goto Exit; } } } } // Attempt to delete the directory - if allowed. if (bCanDeleteDir) { // Need to release the directory handle so the // directory will be closed when we try to delete it // below. if (pDirHdl) { pDirHdl->Release(); pDirHdl = NULL; } if (RC_BAD( rc = gv_XFlmSysData.pFileSystem->removeDir( pszRflDirName))) { if (rc == NE_FLM_IO_PATH_NOT_FOUND || rc == NE_FLM_IO_INVALID_FILENAME) { rc = NE_XFLM_OK; } goto Exit; } } } Exit: if( pszTmpName) { f_free( &pszTmpName); } if( pDirHdl) { pDirHdl->Release(); } return( rc); }