HsSVN-0.4.3.2: Subversion/FileSystem.hsc
{-# LANGUAGE
DeriveDataTypeable
, EmptyDataDecls
, ForeignFunctionInterface
#-}
{-# OPTIONS_HADDOCK prune #-}
-- |An interface to the Subversion filesystem.
#include "HsSVN.h"
module Subversion.FileSystem
( -- * Type
FileSystem
, SVN_FS_T -- private
, wrapFS -- private
, withFSPtr -- private
, touchFS -- private
-- * Information of the libsvn_fs itself
, fsVersion
-- * Filesystem creation, opening and destruction
, createFileSystem
, fsConfigFSType
, fsTypeBDB
, fsTypeFSFS
, openFileSystem
, deleteFileSystem
, hotCopyFileSystem
-- * Accessors
, getFileSystemType
, getFileSystemPath
, getYoungestRev
)
where
import Foreign.C.String
import Foreign.ForeignPtr
import Foreign.Ptr
import Foreign.Marshal.Alloc
import Foreign.Storable
import GHC.ForeignPtr as GF
import Subversion.Error
import Subversion.Hash
import Subversion.Pool
import Subversion.Types
-- |@'FileSystem'@ is an opaque object representing a Subversion
-- filesystem.
newtype FileSystem = FileSystem (ForeignPtr SVN_FS_T)
data SVN_FS_T
foreign import ccall "svn_fs_version"
_version :: IO (Ptr SVN_VERSION_T)
foreign import ccall "svn_fs_create"
_create :: Ptr (Ptr SVN_FS_T) -> CString -> Ptr APR_HASH_T -> Ptr APR_POOL_T -> IO (Ptr SVN_ERROR_T)
foreign import ccall "svn_fs_open"
_open :: Ptr (Ptr SVN_FS_T) -> CString -> Ptr APR_HASH_T -> Ptr APR_POOL_T -> IO (Ptr SVN_ERROR_T)
foreign import ccall "svn_fs_delete_fs"
_delete_fs :: CString -> Ptr APR_POOL_T -> IO (Ptr SVN_ERROR_T)
foreign import ccall "svn_fs_hotcopy"
_hotcopy :: CString -> CString -> SVN_BOOLEAN_T -> Ptr APR_POOL_T -> IO (Ptr SVN_ERROR_T)
foreign import ccall "svn_fs_type"
_type :: Ptr CString -> CString -> Ptr APR_POOL_T -> IO (Ptr SVN_ERROR_T)
foreign import ccall "svn_fs_path"
_path :: Ptr SVN_FS_T -> Ptr APR_POOL_T -> IO CString
foreign import ccall "svn_fs_youngest_rev"
_youngest_rev :: Ptr SVN_REVNUM_T -> Ptr SVN_FS_T -> Ptr APR_POOL_T -> IO (Ptr SVN_ERROR_T)
wrapFS :: IO () -> Ptr SVN_FS_T -> IO FileSystem
wrapFS finalizer fsPtr
= do fs <- newForeignPtr_ fsPtr
GF.addForeignPtrConcFinalizer fs finalizer
return $ FileSystem fs
withFSPtr :: FileSystem -> (Ptr SVN_FS_T -> IO a) -> IO a
withFSPtr (FileSystem fs) = withForeignPtr fs
touchFS :: FileSystem -> IO ()
touchFS (FileSystem fs) = touchForeignPtr fs
-- |@fsVersion@ returns the version number of the libsvn_fs.
fsVersion :: IO Version
fsVersion = _version >>= peekVersion
-- |@'fsConfigFSType'@ is a config key to choose a filesystem
-- back-end.
fsConfigFSType :: String
fsConfigFSType = #const_str SVN_FS_CONFIG_FS_TYPE
-- |@'fsTypeBDB'@ is a config value representing the Berkeley-DB
-- back-end.
fsTypeBDB :: String
fsTypeBDB = #const_str SVN_FS_TYPE_BDB
-- |@'fsTypeFSFS'@ is a config value representing the
-- Native-filesystem back-end.
fsTypeFSFS :: String
fsTypeFSFS = #const_str SVN_FS_TYPE_FSFS
-- |@'createFileSystem'@ creates a new, empty Subversion
-- filesystem. Note that creating a raw filesystem and creating a
-- repository is not the same thing. If you want a new repository, use
-- 'Subversion.Repository.createRepository' instead.
createFileSystem
:: FilePath -- ^ Where to create the filesystem. The
-- path most not currently exist, but its
-- parent must exist.
-> [(String, String)] -- ^ A list of @(key, value)@ tuples which
-- modifies the behavior of the
-- filesystem. The interpretation of it is
-- up to the filesystem back-end.
--
-- If the list contains a value for
-- 'fsConfigFSType', that value determines
-- the filesystem type for the new
-- filesystem. These values are currently
-- defined:
--
-- ['fsTypeBDB'] Berkeley-DB implementation
--
-- ['fsTypeFSFS'] Native-filesystem
-- implementation
--
-- If the list does not contain
-- 'fsConfigFSType' then the default
-- filesystem type will be used. This will
-- typically be BDB for version 1.1 and
-- FSFS for later versions, though you
-- should not rely upon any particular
-- default value if you want a filesystem
-- of specific type.
-> IO FileSystem -- ^ The new filesystem.
createFileSystem path configPairs
= do pool <- newPool
alloca $ \ fsPtrPtr ->
withCString path $ \ pathPtr ->
withPoolPtr pool $ \ poolPtr ->
do config <- pairsToHash configPairs
svnErr $ _create fsPtrPtr pathPtr (unsafeHashToPtr config) poolPtr
fs <- wrapFS (touchPool pool) =<< peek fsPtrPtr
-- We want config to be alive until the fs dies.
GF.addForeignPtrConcFinalizer (case fs of FileSystem x -> x)
$ touchHash config
return fs
-- |@'openFileSystem'@ opens a Subversion filesystem. Note that you
-- probably don't want to use this directly. Take a look at
-- 'Subversion.Repository.openRepository' instead.
openFileSystem
:: FilePath -- ^ Where the filesystem located on.
-> [(String, String)] -- ^ A list of @(key, value)@ tuples which
-- modifies the behavior of the
-- filesystem. The interpretation of it is
-- up to the filesystem back-end.
-> IO FileSystem
openFileSystem path configPairs
= do pool <- newPool
alloca $ \ fsPtrPtr ->
withCString path $ \ pathPtr ->
withPoolPtr pool $ \ poolPtr ->
do config <- pairsToHash configPairs
svnErr $ _open fsPtrPtr pathPtr (unsafeHashToPtr config) poolPtr
fs <- wrapFS (touchPool pool) =<< peek fsPtrPtr
-- We want config to be alive until the fs dies.
GF.addForeignPtrConcFinalizer (case fs of FileSystem x -> x)
$ touchHash config
return fs
-- |@'deleteFileSystem'@ deletes a Subversion filesystem. Note that
-- you probably don't want to use this directly. Take a look at
-- 'Subversion.Repository.deleteRepository' instead.
deleteFileSystem :: FilePath -> IO ()
deleteFileSystem path
= do pool <- newPool
withCString path $ \ pathPtr ->
withPoolPtr pool $ \ poolPtr ->
svnErr $ _delete_fs pathPtr poolPtr
-- |@'hotCopyFileSystem'@ copies a possibly live Subversion filesystem
-- from one location to another.
hotCopyFileSystem :: FilePath -- ^ Source
-> FilePath -- ^ Destination
-> Bool -- ^ If 'True', @'hotCopyFileSystem'@
-- performs cleanup on the source
-- filesystem as part of the copy
-- opeation; currently, this means
-- deleting copied, unused logfiles
-- for a Berkeley DB source
-- filesystem.
-> IO ()
hotCopyFileSystem src dest clean
= do pool <- newPool
withCString src $ \ srcPath ->
withCString dest $ \ destPath ->
withPoolPtr pool $ \ poolPtr ->
svnErr $ _hotcopy srcPath destPath (marshalBool clean) poolPtr
-- |@'getFileSystemPath' fsPath@ returns a string identifying the
-- back-end type of the Subversion filesystem located on @fsPath@. The
-- string should be equal to one of the @fsType*@ defined constants,
-- unless the filesystem is a new back-end type added in a later
-- version of Subversion.
--
-- In general, the type should make no difference in the filesystem's
-- semantics, but there are a few situations (such as backups) where
-- it might matter.
getFileSystemType :: FilePath -> IO String
getFileSystemType path
= do pool <- newPool
alloca $ \ typePtrPtr ->
withCString path $ \ pathPtr ->
withPoolPtr pool $ \ poolPtr ->
do svnErr $ _type typePtrPtr pathPtr poolPtr
peekCString =<< peek typePtrPtr
-- |@'getFileSystemPath' fs@ returns the path to @fs@'s
-- repository. Note that this is what was passed to 'createFileSystem'
-- or 'openFileSystem'; might be absolute, might be not.
getFileSystemPath :: FileSystem -> IO FilePath
getFileSystemPath fs
= do pool <- newPool
withFSPtr fs $ \ fsPtr ->
withPoolPtr pool $ \ poolPtr ->
do path <- peekCString =<< _path fsPtr poolPtr
touchPool pool
return path
-- |@'getYoungestRev' fs@ returns the youngest revision number in
-- filesystem @fs@. The revision number starts from zero.
getYoungestRev :: FileSystem -> IO RevNum
getYoungestRev fs
= do pool <- newPool
alloca $ \ revNumPtr ->
withFSPtr fs $ \ fsPtr ->
withPoolPtr pool $ \ poolPtr ->
do svnErr $ _youngest_rev revNumPtr fsPtr poolPtr
return . fromIntegral =<< peek revNumPtr