{-# LANGUAGE BlockArguments #-}
module Database.DuckDB.Simple.Catalog (
CatalogEntry (..),
catalogTypeName,
lookupCatalogEntry,
) where
import Control.Exception (bracket)
import Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.Text.Foreign as TextForeign
import Database.DuckDB.FFI
import Database.DuckDB.Simple.Internal (Connection, withClientContext)
import Foreign.C.String (CString, peekCString)
import Foreign.Marshal.Alloc (alloca)
import Foreign.Ptr (nullPtr)
import Foreign.Storable (poke)
data CatalogEntry = CatalogEntry
{ CatalogEntry -> Text
catalogEntryName :: !Text
, CatalogEntry -> DuckDBCatalogEntryType
catalogEntryType :: !DuckDBCatalogEntryType
}
deriving (CatalogEntry -> CatalogEntry -> Bool
(CatalogEntry -> CatalogEntry -> Bool)
-> (CatalogEntry -> CatalogEntry -> Bool) -> Eq CatalogEntry
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CatalogEntry -> CatalogEntry -> Bool
== :: CatalogEntry -> CatalogEntry -> Bool
$c/= :: CatalogEntry -> CatalogEntry -> Bool
/= :: CatalogEntry -> CatalogEntry -> Bool
Eq, Int -> CatalogEntry -> ShowS
[CatalogEntry] -> ShowS
CatalogEntry -> String
(Int -> CatalogEntry -> ShowS)
-> (CatalogEntry -> String)
-> ([CatalogEntry] -> ShowS)
-> Show CatalogEntry
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CatalogEntry -> ShowS
showsPrec :: Int -> CatalogEntry -> ShowS
$cshow :: CatalogEntry -> String
show :: CatalogEntry -> String
$cshowList :: [CatalogEntry] -> ShowS
showList :: [CatalogEntry] -> ShowS
Show)
catalogTypeName :: Connection -> Text -> IO (Maybe Text)
catalogTypeName :: Connection -> Text -> IO (Maybe Text)
catalogTypeName Connection
conn Text
catalogName =
Connection
-> (DuckDBClientContext -> IO (Maybe Text)) -> IO (Maybe Text)
forall a. Connection -> (DuckDBClientContext -> IO a) -> IO a
withClientContext Connection
conn \DuckDBClientContext
ctx ->
Text -> (CString -> IO (Maybe Text)) -> IO (Maybe Text)
forall a. Text -> (CString -> IO a) -> IO a
TextForeign.withCString Text
catalogName \CString
cName ->
DuckDBClientContext
-> CString -> (DuckDBCatalog -> IO (Maybe Text)) -> IO (Maybe Text)
forall a.
DuckDBClientContext
-> CString -> (DuckDBCatalog -> IO (Maybe a)) -> IO (Maybe a)
withMaybeCatalog DuckDBClientContext
ctx CString
cName \DuckDBCatalog
catalog -> do
namePtr <- DuckDBCatalog -> IO CString
c_duckdb_catalog_get_type_name DuckDBCatalog
catalog
if namePtr == nullPtr
then pure Nothing
else Just . Text.pack <$> peekCString namePtr
lookupCatalogEntry :: Connection -> Text -> Text -> Text -> DuckDBCatalogEntryType -> IO (Maybe CatalogEntry)
lookupCatalogEntry :: Connection
-> Text
-> Text
-> Text
-> DuckDBCatalogEntryType
-> IO (Maybe CatalogEntry)
lookupCatalogEntry Connection
conn Text
catalogName Text
schemaName Text
entryName DuckDBCatalogEntryType
entryType =
Connection
-> (DuckDBClientContext -> IO (Maybe CatalogEntry))
-> IO (Maybe CatalogEntry)
forall a. Connection -> (DuckDBClientContext -> IO a) -> IO a
withClientContext Connection
conn \DuckDBClientContext
ctx ->
Text
-> (CString -> IO (Maybe CatalogEntry)) -> IO (Maybe CatalogEntry)
forall a. Text -> (CString -> IO a) -> IO a
TextForeign.withCString Text
catalogName \CString
cCatalog ->
Text
-> (CString -> IO (Maybe CatalogEntry)) -> IO (Maybe CatalogEntry)
forall a. Text -> (CString -> IO a) -> IO a
TextForeign.withCString Text
schemaName \CString
cSchema ->
Text
-> (CString -> IO (Maybe CatalogEntry)) -> IO (Maybe CatalogEntry)
forall a. Text -> (CString -> IO a) -> IO a
TextForeign.withCString Text
entryName \CString
cEntry ->
DuckDBClientContext
-> CString
-> (DuckDBCatalog -> IO (Maybe CatalogEntry))
-> IO (Maybe CatalogEntry)
forall a.
DuckDBClientContext
-> CString -> (DuckDBCatalog -> IO (Maybe a)) -> IO (Maybe a)
withMaybeCatalog DuckDBClientContext
ctx CString
cCatalog \DuckDBCatalog
catalog ->
DuckDBCatalog
-> DuckDBClientContext
-> DuckDBCatalogEntryType
-> CString
-> CString
-> (DuckDBCatalogEntry -> IO (Maybe CatalogEntry))
-> IO (Maybe CatalogEntry)
forall a.
DuckDBCatalog
-> DuckDBClientContext
-> DuckDBCatalogEntryType
-> CString
-> CString
-> (DuckDBCatalogEntry -> IO (Maybe a))
-> IO (Maybe a)
withMaybeCatalogEntry DuckDBCatalog
catalog DuckDBClientContext
ctx DuckDBCatalogEntryType
entryType CString
cSchema CString
cEntry \DuckDBCatalogEntry
entry -> do
typ <- DuckDBCatalogEntry -> IO DuckDBCatalogEntryType
c_duckdb_catalog_entry_get_type DuckDBCatalogEntry
entry
namePtr <- c_duckdb_catalog_entry_get_name entry
if namePtr == nullPtr
then pure Nothing
else do
name <- Text.pack <$> peekCString namePtr
pure (Just CatalogEntry{catalogEntryName = name, catalogEntryType = typ})
destroyCatalog :: DuckDBCatalog -> IO ()
destroyCatalog :: DuckDBCatalog -> IO ()
destroyCatalog DuckDBCatalog
catalog =
(Ptr DuckDBCatalog -> IO ()) -> IO ()
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca \Ptr DuckDBCatalog
ptr -> Ptr DuckDBCatalog -> DuckDBCatalog -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr DuckDBCatalog
ptr DuckDBCatalog
catalog IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Ptr DuckDBCatalog -> IO ()
c_duckdb_destroy_catalog Ptr DuckDBCatalog
ptr
destroyCatalogEntry :: DuckDBCatalogEntry -> IO ()
destroyCatalogEntry :: DuckDBCatalogEntry -> IO ()
destroyCatalogEntry DuckDBCatalogEntry
entry =
(Ptr DuckDBCatalogEntry -> IO ()) -> IO ()
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca \Ptr DuckDBCatalogEntry
ptr -> Ptr DuckDBCatalogEntry -> DuckDBCatalogEntry -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr DuckDBCatalogEntry
ptr DuckDBCatalogEntry
entry IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Ptr DuckDBCatalogEntry -> IO ()
c_duckdb_destroy_catalog_entry Ptr DuckDBCatalogEntry
ptr
withMaybeCatalog :: DuckDBClientContext -> CString -> (DuckDBCatalog -> IO (Maybe a)) -> IO (Maybe a)
withMaybeCatalog :: forall a.
DuckDBClientContext
-> CString -> (DuckDBCatalog -> IO (Maybe a)) -> IO (Maybe a)
withMaybeCatalog DuckDBClientContext
ctx CString
name DuckDBCatalog -> IO (Maybe a)
action = do
catalog <- DuckDBClientContext -> CString -> IO DuckDBCatalog
c_duckdb_client_context_get_catalog DuckDBClientContext
ctx CString
name
if catalog == nullPtr
then pure Nothing
else bracket (pure catalog) destroyCatalog action
withMaybeCatalogEntry ::
DuckDBCatalog ->
DuckDBClientContext ->
DuckDBCatalogEntryType ->
CString ->
CString ->
(DuckDBCatalogEntry -> IO (Maybe a)) ->
IO (Maybe a)
withMaybeCatalogEntry :: forall a.
DuckDBCatalog
-> DuckDBClientContext
-> DuckDBCatalogEntryType
-> CString
-> CString
-> (DuckDBCatalogEntry -> IO (Maybe a))
-> IO (Maybe a)
withMaybeCatalogEntry DuckDBCatalog
catalog DuckDBClientContext
ctx DuckDBCatalogEntryType
entryType CString
schemaName CString
entryName DuckDBCatalogEntry -> IO (Maybe a)
action = do
entry <- DuckDBCatalog
-> DuckDBClientContext
-> DuckDBCatalogEntryType
-> CString
-> CString
-> IO DuckDBCatalogEntry
c_duckdb_catalog_get_entry DuckDBCatalog
catalog DuckDBClientContext
ctx DuckDBCatalogEntryType
entryType CString
schemaName CString
entryName
if entry == nullPtr
then pure Nothing
else bracket (pure entry) destroyCatalogEntry action