├── .gitmodules ├── scripts ├── list-sources.sh └── format.sh ├── src └── Database │ ├── DuckDB.hs │ └── DuckDB │ ├── Internal.hs │ ├── Connection.hs │ ├── Query.hs │ ├── Appender.hs │ ├── Value.hs │ └── Internal │ └── FFI.hsc ├── .gitignore ├── test ├── Main.hs └── Database │ └── DuckDB │ └── Tests │ ├── Connection.hs │ ├── Appender.hs │ └── Query.hs ├── cbits ├── duckdb-c-api.h └── duckdb-c-api.cpp ├── LICENSE ├── fourmolu.yaml ├── .hlint.yaml ├── .github └── workflows │ └── ci.yaml └── README.md /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "duckdb"] 2 | path = duckdb 3 | url = https://github.com/duckdb/duckdb.git 4 | -------------------------------------------------------------------------------- /scripts/list-sources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 6 | 7 | pushd ${SCRIPT_DIR}/.. > /dev/null 8 | 9 | pushd duckdb > /dev/null 10 | python3 scripts/amalgamation.py --list-sources | xargs -I{} echo duckdb/{} | sort 11 | popd 12 | 13 | popd 14 | -------------------------------------------------------------------------------- /src/Database/DuckDB.hs: -------------------------------------------------------------------------------- 1 | module Database.DuckDB 2 | ( module Database.DuckDB.Connection 3 | , module Database.DuckDB.Query 4 | , module Database.DuckDB.Value 5 | ) 6 | where 7 | 8 | import Database.DuckDB.Appender 9 | import Database.DuckDB.Connection 10 | import Database.DuckDB.Query 11 | import Database.DuckDB.Value 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | dist-* 3 | cabal-dev 4 | *.o 5 | *.hi 6 | *.hie 7 | *.chi 8 | *.chs.h 9 | *.dyn_o 10 | *.dyn_hi 11 | .hpc 12 | .hsenv 13 | .cabal-sandbox/ 14 | cabal.sandbox.config 15 | *.prof 16 | *.aux 17 | *.hp 18 | *.eventlog 19 | .stack-work/ 20 | cabal.project.local 21 | cabal.project.local~ 22 | .HTF/ 23 | .ghc.environment.* 24 | -------------------------------------------------------------------------------- /scripts/format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eu 4 | 5 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 6 | 7 | pushd ${SCRIPT_DIR}/.. > /dev/null 8 | 9 | echo "Formatting hs files ..." 10 | git ls-files -z '*.hs' | xargs -P 12 -0 fourmolu --mode inplace 11 | 12 | echo "Formatting hsc files ..." 13 | git ls-files -z '*.hsc' | xargs -P 12 -0 fourmolu --mode inplace 14 | 15 | popd > /dev/null 16 | -------------------------------------------------------------------------------- /test/Main.hs: -------------------------------------------------------------------------------- 1 | module Main (main) where 2 | 3 | import Database.DuckDB.Tests.Appender 4 | import Database.DuckDB.Tests.Connection 5 | import Database.DuckDB.Tests.Query 6 | import Test.Tasty 7 | 8 | main :: IO () 9 | main = defaultMain tests 10 | 11 | tests :: TestTree 12 | tests = 13 | testGroup 14 | "Tests" 15 | [ connectionTests 16 | , appenderTests 17 | , queryTests 18 | ] 19 | -------------------------------------------------------------------------------- /cbits/duckdb-c-api.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "duckdb.h" 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | DUCKDB_API duckdb_data_chunk duckdb_result_get_chunk_capi(duckdb_result *result, idx_t chunk_index); 10 | 11 | DUCKDB_API bool duckdb_result_is_streaming_capi(duckdb_result *result); 12 | 13 | DUCKDB_API idx_t duckdb_result_chunk_count_capi(duckdb_result *result); 14 | 15 | DUCKDB_API duckdb_data_chunk duckdb_stream_fetch_chunk_capi(duckdb_result *result); 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | -------------------------------------------------------------------------------- /test/Database/DuckDB/Tests/Connection.hs: -------------------------------------------------------------------------------- 1 | module Database.DuckDB.Tests.Connection 2 | ( connectionTests 3 | ) 4 | where 5 | 6 | import Database.DuckDB.Connection 7 | import Test.Tasty 8 | import Test.Tasty.HUnit 9 | 10 | connectionTests :: TestTree 11 | connectionTests = testGroup "ConnectionTest" [defaultConnectionTest] 12 | 13 | defaultConnectionTest :: TestTree 14 | defaultConnectionTest = testCase "Setup the default duckdb database" $ do 15 | r <- runDuckDB $ do 16 | (conn, db) <- defaultConnection 17 | close (conn, db) 18 | r @?= Right () 19 | -------------------------------------------------------------------------------- /cbits/duckdb-c-api.cpp: -------------------------------------------------------------------------------- 1 | #include "duckdb-c-api.h" 2 | 3 | DUCKDB_API duckdb_data_chunk duckdb_result_get_chunk_capi(duckdb_result *result, idx_t chunk_index) { 4 | return duckdb_result_get_chunk(*result, chunk_index); 5 | } 6 | 7 | DUCKDB_API bool duckdb_result_is_streaming_capi(duckdb_result *result) { 8 | return duckdb_result_is_streaming(*result); 9 | } 10 | 11 | DUCKDB_API idx_t duckdb_result_chunk_count_capi(duckdb_result *result) { 12 | return duckdb_result_chunk_count(*result); 13 | } 14 | 15 | DUCKDB_API duckdb_data_chunk duckdb_stream_fetch_chunk_capi(duckdb_result *result) { 16 | return duckdb_stream_fetch_chunk(*result); 17 | } 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Tao He 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/Database/DuckDB/Internal.hs: -------------------------------------------------------------------------------- 1 | module Database.DuckDB.Internal 2 | ( -- * Error reporting 3 | DuckDBError 4 | , isDuckDBError 5 | 6 | -- * Monad 7 | , DuckDBMonad (..) 8 | , liftIO 9 | , liftIOEither 10 | , runDuckDB 11 | 12 | -- * Version 13 | , version 14 | ) 15 | where 16 | 17 | import Control.Monad 18 | import Control.Monad.Except 19 | import Control.Monad.IO.Class 20 | import Database.DuckDB.Internal.FFI (DuckDBState) 21 | import Database.DuckDB.Internal.FFI qualified as FFI 22 | import Foreign.C.String 23 | 24 | type DuckDBError = String 25 | 26 | isDuckDBError :: DuckDBState -> Bool 27 | isDuckDBError FFI.DuckDBSuccess = False 28 | isDuckDBError _ = True 29 | 30 | newtype DuckDBMonad a = DuckDBMonad {runDuckDBMonad :: ExceptT DuckDBError IO a} 31 | deriving (Functor, Applicative, Monad, MonadIO, MonadError DuckDBError) 32 | 33 | liftIOEither :: IO (Either DuckDBError a) -> DuckDBMonad a 34 | liftIOEither = liftEither <=< liftIO 35 | 36 | runDuckDB :: DuckDBMonad a -> IO (Either DuckDBError a) 37 | runDuckDB = runExceptT . runDuckDBMonad 38 | 39 | version :: DuckDBMonad String 40 | version = liftIO $ do 41 | p <- FFI.duckdb_library_version 42 | peekCString p 43 | -------------------------------------------------------------------------------- /fourmolu.yaml: -------------------------------------------------------------------------------- 1 | # Number of spaces per indentation step 2 | indentation: 4 3 | 4 | # Max line length for automatic line breaking 5 | column-limit: 80 6 | 7 | # Styling of arrows in type signatures (choices: trailing, leading, or leading-args) 8 | function-arrows: leading 9 | 10 | # How to place commas in multi-line lists, records, etc. (choices: leading or trailing) 11 | comma-style: leading 12 | 13 | # Styling of import/export lists (choices: leading, trailing, or diff-friendly) 14 | import-export-style: leading 15 | 16 | # Whether to full-indent or half-indent 'where' bindings past the preceding body 17 | indent-wheres: false 18 | 19 | # Whether to leave a space before an opening record brace 20 | record-brace-space: true 21 | 22 | # Number of spaces between top-level declarations 23 | newlines-between-decls: 1 24 | 25 | # How to print Haddock comments (choices: single-line, multi-line, or multi-line-compact) 26 | haddock-style: single-line 27 | 28 | # How to print module docstring 29 | haddock-style-module: single-line 30 | 31 | # Styling of let blocks (choices: auto, inline, newline, or mixed) 32 | let-style: inline 33 | 34 | # How to align the 'in' keyword with respect to the 'let' keyword (choices: left-align, right-align, or no-space) 35 | in-style: right-align 36 | 37 | # Whether to put parentheses around a single constraint (choices: auto, always, or never) 38 | single-constraint-parens: never 39 | 40 | # Output Unicode syntax (choices: detect, always, or never) 41 | unicode: never 42 | 43 | # Give the programmer more choice on where to insert blank lines 44 | respectful: false 45 | 46 | # Fixity information for operators 47 | fixities: [] 48 | 49 | # Module reexports Fourmolu should know about 50 | reexports: [] 51 | -------------------------------------------------------------------------------- /test/Database/DuckDB/Tests/Appender.hs: -------------------------------------------------------------------------------- 1 | module Database.DuckDB.Tests.Appender 2 | ( appenderTests 3 | ) 4 | where 5 | 6 | import Control.Monad 7 | import Data.Vector.Storable qualified as Vec 8 | import Database.DuckDB.Appender 9 | import Database.DuckDB.Connection 10 | import Database.DuckDB.Query 11 | import Foreign.ForeignPtr 12 | import Test.Tasty 13 | import Test.Tasty.HUnit 14 | 15 | appenderTests :: TestTree 16 | appenderTests = 17 | testGroup 18 | "AppendTableTest" 19 | [ appenderTableTest 20 | ] 21 | 22 | appenderTableTest :: TestTree 23 | appenderTableTest = testCase "Create table, append data and query" $ do 24 | r <- runDuckDB $ withDefaultConnection $ \(_db, conn) -> do 25 | _ <- query conn "CREATE TABLE integers (i INTEGER, j INTEGER)" 26 | 27 | withAppender conn "" "integers" $ \app -> 28 | forM_ [1 .. 100] $ \i -> withAppenderRow app $ do 29 | appendInt32 app i 30 | appendInt32 app (i + 99) 31 | 32 | r <- query conn "SELECT i, j FROM integers" 33 | 34 | nchk <- chunkCount r 35 | liftIO $ nchk @?= 1 36 | 37 | chk <- chunkAt r 0 38 | columns <- getChunkColumnCount chk 39 | liftIO $ columns @?= 2 40 | 41 | rows <- getChunkSize chk 42 | liftIO $ rows @?= 100 43 | 44 | getChunkVector chk 0 >>= getVectorData >>= \pointer -> 45 | liftIO $ do 46 | vec <- 47 | Vec.unsafeFromForeignPtr0 <$> newForeignPtr_ pointer <*> (pure rows) 48 | :: IO (Vec.Vector Int32) 49 | vec @?= Vec.fromList [1 .. 100] 50 | 51 | getChunkVector chk 1 >>= getVectorData >>= \pointer -> 52 | liftIO $ do 53 | vec <- 54 | Vec.unsafeFromForeignPtr0 <$> newForeignPtr_ pointer <*> (pure rows) 55 | :: IO (Vec.Vector Int32) 56 | vec @?= Vec.fromList [100 .. 199] 57 | 58 | r @?= Right () 59 | -------------------------------------------------------------------------------- /test/Database/DuckDB/Tests/Query.hs: -------------------------------------------------------------------------------- 1 | module Database.DuckDB.Tests.Query 2 | ( queryTests 3 | ) 4 | where 5 | 6 | import Data.Vector.Storable qualified as Vec 7 | import Database.DuckDB.Connection 8 | import Database.DuckDB.Query 9 | import Foreign.ForeignPtr 10 | import Test.Tasty 11 | import Test.Tasty.HUnit 12 | 13 | queryTests :: TestTree 14 | queryTests = 15 | testGroup 16 | "QueryTest" 17 | [ query42Test 18 | , queryCreateTableTest 19 | , queryDataVector 20 | ] 21 | 22 | query42Test :: TestTree 23 | query42Test = testCase "Query the constant (42)" $ do 24 | r <- runDuckDB $ withDefaultConnection $ \(_db, conn) -> do 25 | r <- query conn "select 42;" 26 | v <- valueInt32 r 0 0 27 | liftIO $ v @?= 42 28 | r @?= Right () 29 | 30 | queryCreateTableTest :: TestTree 31 | queryCreateTableTest = testCase "Create table and query" $ do 32 | r <- runDuckDB $ withDefaultConnection $ \(_db, conn) -> do 33 | _ <- query conn "CREATE TABLE integers (i INTEGER)" 34 | _ <- query conn "INSERT INTO integers VALUES (1), (2), (3), (999)" 35 | r <- query conn "SELECT i FROM integers" 36 | valueInt32 r 0 0 >>= \v -> liftIO $ v @?= 1 37 | valueInt32 r 0 1 >>= \v -> liftIO $ v @?= 2 38 | valueInt32 r 0 2 >>= \v -> liftIO $ v @?= 3 39 | valueInt32 r 0 3 >>= \v -> liftIO $ v @?= 999 40 | r @?= Right () 41 | 42 | queryDataVector :: TestTree 43 | queryDataVector = testCase "Create table and query as efficient vectors" $ do 44 | r <- runDuckDB $ withDefaultConnection $ \(_db, conn) -> do 45 | _ <- query conn "CREATE TABLE integers (i INTEGER)" 46 | _ <- query conn "INSERT INTO integers VALUES (1), (2), (3), (999)" 47 | r <- query conn "SELECT i FROM integers" 48 | 49 | nchk <- chunkCount r 50 | liftIO $ nchk @?= 1 51 | 52 | chk <- chunkAt r 0 53 | columns <- getChunkColumnCount chk 54 | liftIO $ columns @?= 1 55 | 56 | rows <- getChunkSize chk 57 | liftIO $ rows @?= 4 58 | 59 | pointer <- getVectorData =<< getChunkVector chk 0 60 | 61 | liftIO $ do 62 | vec <- 63 | Vec.unsafeFromForeignPtr0 <$> newForeignPtr_ pointer <*> (pure rows) 64 | :: IO (Vec.Vector Int32) 65 | vec @?= Vec.fromList [1, 2, 3, 999] 66 | r @?= Right () 67 | -------------------------------------------------------------------------------- /.hlint.yaml: -------------------------------------------------------------------------------- 1 | # HLint configuration file 2 | # https://github.com/ndmitchell/hlint 3 | ########################## 4 | 5 | # This file contains a template configuration file, which is typically 6 | # placed as .hlint.yaml in the root of your project 7 | 8 | 9 | # Warnings currently triggered by your code 10 | - ignore: {name: "Redundant $"} # 2 hints 11 | - ignore: {name: "Redundant bracket"} # 3 hints 12 | - ignore: {name: "Redundant return"} # 6 hints 13 | - ignore: {name: "Unused LANGUAGE pragma"} # 3 hints 14 | - ignore: {name: "Use forM_"} # 1 hint 15 | - ignore: {name: "Use null"} # 1 hint 16 | - ignore: {name: "Redundant return"} 17 | 18 | # Specify additional command line arguments 19 | # 20 | # - arguments: [--color, --cpp-simple, -XQuasiQuotes] 21 | 22 | 23 | # Control which extensions/flags/modules/functions can be used 24 | # 25 | # - extensions: 26 | # - default: false # all extension are banned by default 27 | # - name: [PatternGuards, ViewPatterns] # only these listed extensions can be used 28 | # - {name: CPP, within: CrossPlatform} # CPP can only be used in a given module 29 | # 30 | # - flags: 31 | # - {name: -w, within: []} # -w is allowed nowhere 32 | # 33 | # - modules: 34 | # - {name: [Data.Set, Data.HashSet], as: Set} # if you import Data.Set qualified, it must be as 'Set' 35 | # - {name: Control.Arrow, within: []} # Certain modules are banned entirely 36 | # 37 | # - functions: 38 | # - {name: unsafePerformIO, within: []} # unsafePerformIO can only appear in no modules 39 | 40 | 41 | # Add custom hints for this project 42 | # 43 | # Will suggest replacing "wibbleMany [myvar]" with "wibbleOne myvar" 44 | # - error: {lhs: "wibbleMany [x]", rhs: wibbleOne x} 45 | 46 | # The hints are named by the string they display in warning messages. 47 | # For example, if you see a warning starting like 48 | # 49 | # Main.hs:116:51: Warning: Redundant == 50 | # 51 | # You can refer to that hint with `{name: Redundant ==}` (see below). 52 | 53 | # Turn on hints that are off by default 54 | # 55 | # Ban "module X(module X) where", to require a real export list 56 | # - warn: {name: Use explicit module export list} 57 | # 58 | # Replace a $ b $ c with a . b $ c 59 | # - group: {name: dollar, enabled: true} 60 | # 61 | # Generalise map to fmap, ++ to <> 62 | # - group: {name: generalise, enabled: true} 63 | # 64 | # Warn on use of partial functions 65 | # - group: {name: partial, enabled: true} 66 | 67 | 68 | # Ignore some builtin hints 69 | # - ignore: {name: Use let} 70 | # - ignore: {name: Use const, within: SpecialModule} # Only within certain modules 71 | 72 | 73 | # Define some custom infix operators 74 | # - fixity: infixr 3 ~^#^~ 75 | 76 | 77 | # To generate a suitable file for HLint do: 78 | # $ hlint --default > .hlint.yaml 79 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | concurrency: 6 | group: ${{ github.repository }}-${{ github.event.number || github.head_ref || github.sha }}-${{ github.workflow }} 7 | cancel-in-progress: true 8 | 9 | jobs: 10 | ci: 11 | runs-on: ${{ matrix.os }} 12 | strategy: 13 | matrix: 14 | os: [ubuntu-20.04] 15 | ghc-version: ['9.8'] 16 | steps: 17 | - uses: actions/checkout@v3 18 | with: 19 | submodules: true 20 | 21 | - name: Set up GHC ${{ matrix.ghc-version }} 22 | uses: haskell/actions/setup@v2 23 | id: setup 24 | with: 25 | ghc-version: ${{ matrix.ghc-version }} 26 | cabal-version: 'latest' 27 | cabal-update: true 28 | 29 | - name: Configure the build 30 | run: | 31 | cabal configure --enable-tests --enable-benchmarks --disable-documentation 32 | cabal build --dry-run 33 | # The last step generates dist-newstyle/cache/plan.json for the cache key. 34 | 35 | - name: Restore cached dependencies 36 | uses: actions/cache/restore@v3 37 | id: cache 38 | env: 39 | key: ${{ runner.os }}-ghc-${{ steps.setup.outputs.ghc-version }}-cabal-${{ steps.setup.outputs.cabal-version }} 40 | with: 41 | path: ${{ steps.setup.outputs.cabal-store }} 42 | key: ${{ env.key }}-plan-${{ hashFiles('**/plan.json') }} 43 | restore-keys: ${{ env.key }}- 44 | 45 | - name: Install dependencies 46 | run: cabal build all --only-dependencies 47 | 48 | # Cache dependencies already here, so that we do not have to rebuild them should the subsequent steps fail. 49 | - name: Save cached dependencies 50 | uses: actions/cache/save@v3 51 | # Caches are immutable, trying to save with the same key would error. 52 | if: ${{ steps.cache.outputs.cache-primary-key != steps.cache.outputs.cache-matched-key }} 53 | with: 54 | path: ${{ steps.setup.outputs.cabal-store }} 55 | key: ${{ steps.cache.outputs.cache-primary-key }} 56 | 57 | - name: SDist 58 | run: | 59 | cabal sdist 60 | mkdir -p $HOME/test-against-sdist 61 | tar -xf dist-newstyle/sdist/*.tar.gz -C $HOME/test-against-sdist --strip-components=1 62 | 63 | - name: Build 64 | run: | 65 | cd $HOME/test-against-sdist 66 | cabal build all 67 | 68 | - name: Run tests 69 | run: | 70 | cd $HOME/test-against-sdist 71 | cabal test all 72 | 73 | - name: Check cabal file 74 | run: | 75 | cd $HOME/test-against-sdist 76 | cabal check 77 | 78 | - name: Build documentation 79 | run: | 80 | cd $HOME/test-against-sdist 81 | cabal haddock all 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # duckdb-haskell 2 | 3 | Full-featured Haskell bindings for [DuckDB](https://duckdb.org). 4 | 5 | ## Installation 6 | 7 | The library is available on [Hackage](https://hackage.haskell.org/package/duckdb-haskell). 8 | 9 | ## Usage 10 | 11 | - `Database.DuckDB.Internal.FFI`: fully FFI bindings to [the DuckDB C API](https://github.com/duckdb/duckdb/blob/main/src/include/duckdb.h) 12 | - `Database.DuckDB.Connection`: connection management 13 | - `Database.DuckDB.Query`: query execution 14 | - `Database.DuckDB.Appender`: bulk data loading 15 | 16 | ### Connection 17 | 18 | - Connect to a database: 19 | 20 | ```haskell 21 | defaultConnectionTest :: TestTree 22 | defaultConnectionTest = testCase "Setup the default duckdb database" $ do 23 | r <- runDuckDB $ do 24 | (conn, db) <- defaultConnection 25 | close (conn, db) 26 | r @?= Right () 27 | ``` 28 | 29 | ### Query results 30 | 31 | - Query from the database: 32 | 33 | ```haskell 34 | query42Test :: TestTree 35 | query42Test = testCase "Query the constant (42)" $ do 36 | r <- runDuckDB $ withDefaultConnection $ \(_db, conn) -> do 37 | r <- query conn "select 42;" 38 | v <- valueInt32 r 0 0 39 | liftIO $ v @?= 42 40 | r @?= Right () 41 | ``` 42 | 43 | - Query from the database, more complex example: 44 | 45 | ```haskell 46 | queryCreateTableTest :: TestTree 47 | queryCreateTableTest = testCase "Create table and query" $ do 48 | r <- runDuckDB $ withDefaultConnection $ \(_db, conn) -> do 49 | _ <- query conn "CREATE TABLE integers (i INTEGER)" 50 | _ <- query conn "INSERT INTO integers VALUES (1), (2), (3), (999)" 51 | r <- query conn "SELECT i FROM integers" 52 | valueInt32 r 0 0 >>= \v -> liftIO $ v @?= 1 53 | valueInt32 r 0 1 >>= \v -> liftIO $ v @?= 2 54 | valueInt32 r 0 2 >>= \v -> liftIO $ v @?= 3 55 | valueInt32 r 0 3 >>= \v -> liftIO $ v @?= 999 56 | r @?= Right () 57 | ``` 58 | 59 | - Query from the database, inspecting the value using [`Data.Vector.Storable`](https://hackage.haskell.org/package/vector): 60 | 61 | ``` 62 | queryDataVector :: TestTree 63 | queryDataVector = testCase "Create table and query as efficient vectors" $ do 64 | r <- runDuckDB $ withDefaultConnection $ \(_db, conn) -> do 65 | _ <- query conn "CREATE TABLE integers (i INTEGER)" 66 | _ <- query conn "INSERT INTO integers VALUES (1), (2), (3), (999)" 67 | r <- query conn "SELECT i FROM integers" 68 | 69 | nchk <- chunkCount r 70 | liftIO $ nchk @?= 1 71 | 72 | chk <- chunkAt r 0 73 | columns <- getChunkColumnCount chk 74 | liftIO $ columns @?= 1 75 | 76 | rows <- getChunkSize chk 77 | liftIO $ rows @?= 4 78 | 79 | pointer <- getVectorData =<< getChunkVector chk 0 80 | 81 | liftIO $ do 82 | vec <- 83 | Vec.unsafeFromForeignPtr0 <$> newForeignPtr_ pointer <*> (pure rows) 84 | :: IO (Vec.Vector Int32) 85 | vec @?= Vec.fromList [1, 2, 3, 999] 86 | r @?= Right () 87 | ``` 88 | 89 | ### Bulk data loading 90 | 91 | - Efficiently loading data using appenders: 92 | 93 | ```haskell 94 | appenderTableTest :: TestTree 95 | appenderTableTest = testCase "Create table, append data and query" $ do 96 | r <- runDuckDB $ withDefaultConnection $ \(_db, conn) -> do 97 | _ <- query conn "CREATE TABLE integers (i INTEGER, j INTEGER)" 98 | 99 | withAppender conn "" "integers" $ \app -> 100 | forM_ [1 .. 100] $ \i -> withAppenderRow app $ do 101 | appendInt32 app i 102 | appendInt32 app (i + 99) 103 | 104 | r <- query conn "SELECT i, j FROM integers" 105 | 106 | liftIO $ chunkCount r >>= print 107 | ``` 108 | -------------------------------------------------------------------------------- /src/Database/DuckDB/Connection.hs: -------------------------------------------------------------------------------- 1 | module Database.DuckDB.Connection 2 | ( -- * Error reporting 3 | DuckDBError 4 | , isDuckDBError 5 | 6 | -- * Monad 7 | , DuckDBMonad (..) 8 | , liftIO 9 | , liftIOEither 10 | , runDuckDB 11 | 12 | -- * Version 13 | , version 14 | 15 | -- * Database and Connection 16 | , open 17 | , configure 18 | , configCount 19 | , getConfigFlag 20 | , setConfig 21 | , destroyConfig 22 | , openExt 23 | , connect 24 | , defaultConnection 25 | , withDefaultConnection 26 | , close 27 | , closeConnection 28 | , closeDatabase 29 | ) 30 | where 31 | 32 | import Control.Monad 33 | import Control.Monad.Except 34 | import Control.Monad.IO.Class 35 | import Database.DuckDB.Internal 36 | import Database.DuckDB.Internal.FFI 37 | ( DuckDBConfig 38 | , DuckDBConnection 39 | , DuckDBDatabase 40 | ) 41 | import Database.DuckDB.Internal.FFI qualified as FFI 42 | import Foreign.C.String 43 | import Foreign.Marshal.Alloc 44 | import Foreign.Storable 45 | 46 | open :: String -> DuckDBMonad DuckDBDatabase 47 | open path = do 48 | db <- liftIOEither $ withCString path $ \path' -> runDuckDB $ do 49 | liftIOEither $ alloca $ \db' -> runDuckDB $ do 50 | err <- liftIO $ FFI.duckdb_open path' db' 51 | when (isDuckDBError err) $ 52 | throwError "duckdb_open failed" 53 | liftIO $ peek db' 54 | return db 55 | 56 | configure :: DuckDBMonad DuckDBConfig 57 | configure = do 58 | config <- liftIOEither $ alloca $ \config' -> runDuckDB $ do 59 | err <- liftIO $ FFI.duckdb_create_config config' 60 | when (isDuckDBError err) $ 61 | throwError "duckdb_create_config failed" 62 | liftIO $ peek config' 63 | return config 64 | 65 | configCount :: DuckDBMonad Int 66 | configCount = do 67 | count <- liftIO $ FFI.duckdb_config_count 68 | return (fromIntegral count) 69 | 70 | getConfigFlag 71 | :: Int 72 | -> DuckDBMonad 73 | ( String 74 | , -- \^ name 75 | String 76 | ) 77 | -- \^ description 78 | 79 | getConfigFlag index = do 80 | (name, description) <- liftIOEither $ alloca $ \name' -> alloca $ \description' -> runDuckDB $ do 81 | err <- 82 | liftIO $ FFI.duckdb_get_config_flag (fromIntegral index) name' description' 83 | when (isDuckDBError err) $ 84 | throwError "duckdb_config_get_flag failed" 85 | liftIO $ 86 | (,) <$> (peek name' >>= peekCString) <*> (peek description' >>= peekCString) 87 | return (name, description) 88 | 89 | setConfig 90 | :: DuckDBConfig 91 | -> String 92 | -- ^ name 93 | -> String 94 | -- ^ option 95 | -> DuckDBMonad () 96 | setConfig config name option = do 97 | liftIOEither $ withCString name $ \name' -> withCString option $ \option' -> runDuckDB $ do 98 | err <- liftIO $ FFI.duckdb_set_config config name' option' 99 | when (isDuckDBError err) $ 100 | throwError "duckdb_set_config failed" 101 | 102 | destroyConfig :: DuckDBConfig -> DuckDBMonad () 103 | destroyConfig config = do 104 | liftIO $ alloca $ \config' -> do 105 | poke config' config 106 | FFI.duckdb_destroy_config config' 107 | 108 | openExt :: String -> DuckDBConfig -> DuckDBMonad DuckDBDatabase 109 | openExt path config = do 110 | db <- liftIOEither $ withCString path $ \path' -> runDuckDB $ do 111 | liftIOEither $ alloca $ \db' -> 112 | alloca $ \err' -> runDuckDB $ do 113 | err <- liftIO $ FFI.duckdb_open_ext path' db' config err' 114 | when (isDuckDBError err) $ do 115 | message <- liftIO $ do 116 | p <- peek err' 117 | m <- peekCString p 118 | FFI.duckdb_free p 119 | return m 120 | throwError $ "duckdb_open failed: " ++ message 121 | liftIO $ peek db' 122 | return db 123 | 124 | connect :: DuckDBDatabase -> DuckDBMonad DuckDBConnection 125 | connect db = do 126 | conn <- liftIOEither $ alloca $ \conn' -> runDuckDB $ do 127 | err <- liftIO $ FFI.duckdb_connect db conn' 128 | when (isDuckDBError err) $ 129 | throwError "duckdb_connect failed" 130 | liftIO $ peek conn' 131 | return conn 132 | 133 | defaultConnection :: DuckDBMonad (DuckDBDatabase, DuckDBConnection) 134 | defaultConnection = do 135 | db <- open ":memory:" 136 | conn <- connect db 137 | return (db, conn) 138 | 139 | withDefaultConnection 140 | :: ((DuckDBDatabase, DuckDBConnection) -> DuckDBMonad a) -> DuckDBMonad a 141 | withDefaultConnection f = do 142 | (db, conn) <- defaultConnection 143 | r <- f (db, conn) 144 | close (db, conn) 145 | return r 146 | 147 | close :: (DuckDBDatabase, DuckDBConnection) -> DuckDBMonad () 148 | close (db, conn) = do 149 | closeConnection conn 150 | closeDatabase db 151 | 152 | closeConnection :: DuckDBConnection -> DuckDBMonad () 153 | closeConnection conn = do 154 | liftIO $ alloca $ \conn' -> do 155 | poke conn' conn 156 | FFI.duckdb_disconnect conn' 157 | 158 | closeDatabase :: DuckDBDatabase -> DuckDBMonad () 159 | closeDatabase db = do 160 | liftIO $ alloca $ \db' -> do 161 | poke db' db 162 | FFI.duckdb_close db' 163 | -------------------------------------------------------------------------------- /src/Database/DuckDB/Query.hs: -------------------------------------------------------------------------------- 1 | module Database.DuckDB.Query 2 | ( module Database.DuckDB.Value 3 | 4 | -- * Query 5 | , query 6 | 7 | -- * Prepare statement 8 | , prepare 9 | , destroyPrepare 10 | , executePrepared 11 | 12 | -- * Prepare statement parameters 13 | , bindBool 14 | , bindInt8 15 | , bindInt16 16 | , bindInt32 17 | , bindInt64 18 | , bindUint8 19 | , bindUint16 20 | , bindUint32 21 | , bindUint64 22 | , bindFloat 23 | , bindDouble 24 | , bindDate 25 | , bindTime 26 | , bindTimestamp 27 | , bindVarChar 28 | , bindNull 29 | ) 30 | where 31 | 32 | import Control.Monad 33 | import Control.Monad.Except 34 | import Control.Monad.IO.Class 35 | import Data.Int 36 | import Data.Word 37 | import Database.DuckDB.Internal 38 | import Database.DuckDB.Internal.FFI 39 | ( DuckDBConnection 40 | , DuckDBPreparedStatement 41 | ) 42 | import Database.DuckDB.Internal.FFI qualified as FFI 43 | import Database.DuckDB.Value 44 | import Foreign.C.String 45 | import Foreign.Marshal.Alloc 46 | import Foreign.Ptr 47 | import Foreign.Storable 48 | 49 | query :: DuckDBConnection -> String -> DuckDBMonad DuckDBResult 50 | query conn q = do 51 | result <- liftIOEither $ withCString q $ \q' -> runDuckDB $ do 52 | result <- 53 | liftIO $ 54 | FFI.duckdb_malloc (fromIntegral $ sizeOf (undefined :: FFI.DuckDBResult)) 55 | when (result == nullPtr) $ 56 | throwError "duckdb_malloc failed" 57 | err <- liftIO $ FFI.duckdb_query conn q' result 58 | when (isDuckDBError err) $ do 59 | message <- liftIO $ do 60 | p <- FFI.duckdb_result_error result 61 | peekCString p 62 | liftIO $ do 63 | FFI.duckdb_destroy_result result 64 | FFI.duckdb_free result 65 | throwError $ "duckdb_query failed: " ++ message 66 | return result 67 | return result 68 | 69 | prepare :: DuckDBConnection -> String -> DuckDBMonad DuckDBPreparedStatement 70 | prepare conn q = do 71 | stmt <- liftIOEither $ withCString q $ \q' -> alloca $ \stmt' -> runDuckDB $ do 72 | err <- liftIO $ FFI.duckdb_prepare conn q' stmt' 73 | when (isDuckDBError err) $ do 74 | message <- liftIO $ do 75 | stmt <- peek stmt' 76 | p <- FFI.duckdb_prepare_error stmt 77 | peekCString p 78 | liftIO $ FFI.duckdb_destroy_prepare stmt' 79 | throwError $ "duckdb_prepare failed: " ++ message 80 | liftIO $ peek stmt' 81 | return stmt 82 | 83 | destroyPrepare :: DuckDBPreparedStatement -> DuckDBMonad () 84 | destroyPrepare stmt = do 85 | liftIO $ alloca $ \stmt' -> do 86 | poke stmt' stmt 87 | FFI.duckdb_destroy_prepare stmt' 88 | 89 | prepareParameters :: DuckDBPreparedStatement -> DuckDBMonad Int 90 | prepareParameters stmt = do 91 | count <- liftIO $ FFI.duckdb_nparams stmt 92 | return (fromIntegral count) 93 | 94 | prepareParamType :: DuckDBPreparedStatement -> Int -> DuckDBMonad DuckDBType 95 | prepareParamType stmt idx = liftIO $ FFI.duckdb_param_type stmt (fromIntegral idx) 96 | 97 | prepareClearBindings :: DuckDBPreparedStatement -> DuckDBMonad () 98 | prepareClearBindings stmt = do 99 | err <- liftIO $ FFI.duckdb_clear_bindings stmt 100 | when (isDuckDBError err) $ 101 | throwError "duckdb_clear_bindings failed" 102 | 103 | executePrepared :: DuckDBPreparedStatement -> DuckDBMonad DuckDBResult 104 | executePrepared stmt = do 105 | result <- 106 | liftIO $ 107 | FFI.duckdb_malloc (fromIntegral $ sizeOf (undefined :: FFI.DuckDBResult)) 108 | when (result == nullPtr) $ 109 | throwError "duckdb_malloc failed" 110 | err <- liftIO $ FFI.duckdb_execute_prepared stmt result 111 | when (isDuckDBError err) $ do 112 | message <- liftIO $ do 113 | p <- FFI.duckdb_result_error result 114 | peekCString p 115 | liftIO $ do 116 | FFI.duckdb_destroy_result result 117 | FFI.duckdb_free result 118 | throwError $ "duckdb_execute_prepared failed: " ++ message 119 | return result 120 | 121 | bindBool 122 | :: DuckDBPreparedStatement -> Int -> Bool -> DuckDBMonad () 123 | bindBool stmt idx val = do 124 | err <- liftIO $ FFI.duckdb_bind_boolean stmt (fromIntegral idx) val 125 | when (isDuckDBError err) $ 126 | throwError "duckdb_bind_boolean failed" 127 | 128 | bindInt8 :: DuckDBPreparedStatement -> Int -> Int8 -> DuckDBMonad () 129 | bindInt8 stmt idx val = do 130 | err <- liftIO $ FFI.duckdb_bind_int8 stmt (fromIntegral idx) val 131 | when (isDuckDBError err) $ 132 | throwError "duckdb_bind_int8 failed" 133 | 134 | bindInt16 :: DuckDBPreparedStatement -> Int -> Int16 -> DuckDBMonad () 135 | bindInt16 stmt idx val = do 136 | err <- liftIO $ FFI.duckdb_bind_int16 stmt (fromIntegral idx) val 137 | when (isDuckDBError err) $ 138 | throwError "duckdb_bind_int16 failed" 139 | 140 | bindInt32 :: DuckDBPreparedStatement -> Int -> Int32 -> DuckDBMonad () 141 | bindInt32 stmt idx val = do 142 | err <- liftIO $ FFI.duckdb_bind_int32 stmt (fromIntegral idx) val 143 | when (isDuckDBError err) $ 144 | throwError "duckdb_bind_int32 failed" 145 | 146 | bindInt64 :: DuckDBPreparedStatement -> Int -> Int64 -> DuckDBMonad () 147 | bindInt64 stmt idx val = do 148 | err <- liftIO $ FFI.duckdb_bind_int64 stmt (fromIntegral idx) val 149 | when (isDuckDBError err) $ 150 | throwError "duckdb_bind_int64 failed" 151 | 152 | bindUint8 :: DuckDBPreparedStatement -> Int -> Word8 -> DuckDBMonad () 153 | bindUint8 stmt idx val = do 154 | err <- liftIO $ FFI.duckdb_bind_uint8 stmt (fromIntegral idx) val 155 | when (isDuckDBError err) $ 156 | throwError "duckdb_bind_uint8 failed" 157 | 158 | bindUint16 :: DuckDBPreparedStatement -> Int -> Word16 -> DuckDBMonad () 159 | bindUint16 stmt idx val = do 160 | err <- liftIO $ FFI.duckdb_bind_uint16 stmt (fromIntegral idx) val 161 | when (isDuckDBError err) $ 162 | throwError "duckdb_bind_uint16 failed" 163 | 164 | bindUint32 :: DuckDBPreparedStatement -> Int -> Word32 -> DuckDBMonad () 165 | bindUint32 stmt idx val = do 166 | err <- liftIO $ FFI.duckdb_bind_uint32 stmt (fromIntegral idx) val 167 | when (isDuckDBError err) $ 168 | throwError "duckdb_bind_uint32 failed" 169 | 170 | bindUint64 :: DuckDBPreparedStatement -> Int -> Word64 -> DuckDBMonad () 171 | bindUint64 stmt idx val = do 172 | err <- liftIO $ FFI.duckdb_bind_uint64 stmt (fromIntegral idx) val 173 | when (isDuckDBError err) $ 174 | throwError "duckdb_bind_uint64 failed" 175 | 176 | bindFloat :: DuckDBPreparedStatement -> Int -> Float -> DuckDBMonad () 177 | bindFloat stmt idx val = do 178 | err <- liftIO $ FFI.duckdb_bind_float stmt (fromIntegral idx) val 179 | when (isDuckDBError err) $ 180 | throwError "duckdb_bind_float failed" 181 | 182 | bindDouble :: DuckDBPreparedStatement -> Int -> Double -> DuckDBMonad () 183 | bindDouble stmt idx val = do 184 | err <- liftIO $ FFI.duckdb_bind_double stmt (fromIntegral idx) val 185 | when (isDuckDBError err) $ 186 | throwError "duckdb_bind_double failed" 187 | 188 | bindDate :: DuckDBPreparedStatement -> Int -> DuckDBDate -> DuckDBMonad () 189 | bindDate stmt idx val = do 190 | err <- liftIO $ FFI.duckdb_bind_date stmt (fromIntegral idx) val 191 | when (isDuckDBError err) $ 192 | throwError "duckdb_bind_date failed" 193 | 194 | bindTime :: DuckDBPreparedStatement -> Int -> DuckDBTime -> DuckDBMonad () 195 | bindTime stmt idx val = do 196 | err <- liftIO $ FFI.duckdb_bind_time stmt (fromIntegral idx) val 197 | when (isDuckDBError err) $ 198 | throwError "duckdb_bind_time failed" 199 | 200 | bindTimestamp 201 | :: DuckDBPreparedStatement -> Int -> DuckDBTimestamp -> DuckDBMonad () 202 | bindTimestamp stmt idx val = do 203 | err <- liftIO $ FFI.duckdb_bind_timestamp stmt (fromIntegral idx) val 204 | when (isDuckDBError err) $ 205 | throwError "duckdb_bind_timestamp failed" 206 | 207 | bindVarChar :: DuckDBPreparedStatement -> Int -> String -> DuckDBMonad () 208 | bindVarChar stmt idx val = do 209 | liftIOEither $ withCString val $ \val' -> runDuckDB $ do 210 | err <- liftIO $ FFI.duckdb_bind_varchar stmt (fromIntegral idx) val' 211 | when (isDuckDBError err) $ 212 | throwError "duckdb_bind_varchar failed" 213 | 214 | bindNull :: DuckDBPreparedStatement -> Int -> DuckDBMonad () 215 | bindNull stmt idx = do 216 | err <- liftIO $ FFI.duckdb_bind_null stmt (fromIntegral idx) 217 | when (isDuckDBError err) $ 218 | throwError "duckdb_bind_null failed" 219 | -------------------------------------------------------------------------------- /src/Database/DuckDB/Appender.hs: -------------------------------------------------------------------------------- 1 | module Database.DuckDB.Appender 2 | ( module Database.DuckDB.Value 3 | 4 | -- * Appender 5 | , appender 6 | , flushAppender 7 | , closeAppender 8 | , destroyAppender 9 | , withAppender 10 | 11 | -- * Appending 12 | , appenderBeginRow 13 | , appenderEndRow 14 | , withAppenderRow 15 | , appendBool 16 | , appendBoolUnsafe 17 | , appendInt8 18 | , appendInt8Unsafe 19 | , appendInt16 20 | , appendInt16Unsafe 21 | , appendInt32 22 | , appendInt32Unsafe 23 | , appendInt64 24 | , appendInt64Unsafe 25 | , appendWord8 26 | , appendWord8Unsafe 27 | , appendWord16 28 | , appendWord16Unsafe 29 | , appendWord32 30 | , appendWord32Unsafe 31 | , appendWord64 32 | , appendWord64Unsafe 33 | , appendFloat 34 | , appendFloatUnsafe 35 | , appendDouble 36 | , appendDoubleUnsafe 37 | , appendDate 38 | , appendDateUnsafe 39 | , appendTime 40 | , appendTimeUnsafe 41 | , appendTimestamp 42 | , appendTimestampUnsafe 43 | , appendString 44 | , appendStringUnsafe 45 | , appendNull 46 | , appendNullUnsafe 47 | , appendDataChunk 48 | ) 49 | where 50 | 51 | import Control.Monad 52 | import Control.Monad.Except 53 | import Control.Monad.IO.Class 54 | import Data.Int 55 | import Data.Word 56 | import Database.DuckDB.Internal 57 | ( DuckDBMonad 58 | , isDuckDBError 59 | , liftIOEither 60 | , runDuckDB 61 | ) 62 | import Database.DuckDB.Internal.FFI 63 | ( DuckDBAppender 64 | , DuckDBConnection 65 | ) 66 | import Database.DuckDB.Internal.FFI qualified as FFI 67 | import Database.DuckDB.Value 68 | import Foreign.C.String 69 | import Foreign.Marshal.Alloc 70 | import Foreign.Ptr 71 | import Foreign.Storable 72 | 73 | appender 74 | :: DuckDBConnection 75 | -> String 76 | -- ^ schema, null (empty) for default schema 77 | -> String 78 | -- ^ table name 79 | -> DuckDBMonad DuckDBAppender 80 | appender conn schema table = do 81 | app <- liftIOEither $ withCString schema $ \schema' -> withCString table $ \table' -> do 82 | alloca $ \appender' -> runDuckDB $ do 83 | let schema'' = 84 | if null schema 85 | then nullPtr 86 | else schema' 87 | err <- liftIO $ FFI.duckdb_appender_create conn schema'' table' appender' 88 | when (isDuckDBError err) $ do 89 | message <- liftIO $ do 90 | app <- peek appender' 91 | p <- FFI.duckdb_appender_error app 92 | peekCString p 93 | _ <- liftIO $ FFI.duckdb_appender_destroy appender' 94 | throwError $ "duckdb_appender_create failed: " ++ message 95 | liftIO $ peek appender' 96 | return app 97 | 98 | flushAppender :: DuckDBAppender -> DuckDBMonad () 99 | flushAppender app = do 100 | err <- liftIO $ FFI.duckdb_appender_flush app 101 | when (isDuckDBError err) $ do 102 | message <- liftIO $ do 103 | p <- FFI.duckdb_appender_error app 104 | peekCString p 105 | throwError $ "duckdb_appender_flush failed: " ++ message 106 | 107 | closeAppender :: DuckDBAppender -> DuckDBMonad () 108 | closeAppender app = do 109 | err <- liftIO $ FFI.duckdb_appender_close app 110 | when (isDuckDBError err) $ do 111 | message <- liftIO $ do 112 | p <- FFI.duckdb_appender_error app 113 | peekCString p 114 | throwError $ "duckdb_appender_close failed: " ++ message 115 | 116 | destroyAppender :: DuckDBAppender -> DuckDBMonad () 117 | destroyAppender app = do 118 | err <- liftIO $ alloca $ \appender' -> do 119 | poke appender' app 120 | FFI.duckdb_appender_destroy appender' 121 | when (isDuckDBError err) $ do 122 | message <- liftIO $ do 123 | p <- FFI.duckdb_appender_error app 124 | peekCString p 125 | throwError $ "duckdb_appender_destroy failed: " ++ message 126 | 127 | withAppender 128 | :: DuckDBConnection 129 | -> String 130 | -- ^ schema, null (empty) for default schema 131 | -> String 132 | -- ^ table name 133 | -> (DuckDBAppender -> DuckDBMonad a) 134 | -> DuckDBMonad a 135 | withAppender conn schema table f = do 136 | app <- appender conn schema table 137 | r <- f app 138 | destroyAppender app 139 | return r 140 | 141 | appenderBeginRow :: DuckDBAppender -> DuckDBMonad () 142 | appenderBeginRow app = do 143 | err <- liftIO $ FFI.duckdb_appender_begin_row app 144 | when (isDuckDBError err) $ do 145 | message <- liftIO $ do 146 | p <- FFI.duckdb_appender_error app 147 | peekCString p 148 | throwError $ "duckdb_appender_begin_row failed: " ++ message 149 | 150 | appenderEndRow :: DuckDBAppender -> DuckDBMonad () 151 | appenderEndRow app = do 152 | err <- liftIO $ FFI.duckdb_appender_end_row app 153 | when (isDuckDBError err) $ do 154 | message <- liftIO $ do 155 | p <- FFI.duckdb_appender_error app 156 | peekCString p 157 | throwError $ "duckdb_appender_end_row failed: " ++ message 158 | 159 | withAppenderRow :: DuckDBAppender -> DuckDBMonad a -> DuckDBMonad a 160 | withAppenderRow app f = do 161 | appenderBeginRow app 162 | r <- f 163 | appenderEndRow app 164 | return r 165 | 166 | appendBool :: DuckDBAppender -> Bool -> DuckDBMonad () 167 | appendBool app b = do 168 | err <- liftIO $ FFI.duckdb_append_bool app b 169 | when (isDuckDBError err) $ do 170 | message <- liftIO $ do 171 | p <- FFI.duckdb_appender_error app 172 | peekCString p 173 | throwError $ "duckdb_append_bool failed: " ++ message 174 | 175 | appendBoolUnsafe :: DuckDBAppender -> Bool -> DuckDBMonad () 176 | appendBoolUnsafe app b = liftIO $ void $ FFI.duckdb_append_bool app b 177 | 178 | appendInt8 :: DuckDBAppender -> Int8 -> DuckDBMonad () 179 | appendInt8 app i = do 180 | err <- liftIO $ FFI.duckdb_append_int8 app i 181 | when (isDuckDBError err) $ do 182 | message <- liftIO $ do 183 | p <- FFI.duckdb_appender_error app 184 | peekCString p 185 | throwError $ "duckdb_append_int8 failed: " ++ message 186 | 187 | appendInt8Unsafe :: DuckDBAppender -> Int8 -> DuckDBMonad () 188 | appendInt8Unsafe app i = liftIO $ void $ FFI.duckdb_append_int8 app i 189 | 190 | appendInt16 :: DuckDBAppender -> Int16 -> DuckDBMonad () 191 | appendInt16 app i = do 192 | err <- liftIO $ FFI.duckdb_append_int16 app i 193 | when (isDuckDBError err) $ do 194 | message <- liftIO $ do 195 | p <- FFI.duckdb_appender_error app 196 | peekCString p 197 | throwError $ "duckdb_append_int16 failed: " ++ message 198 | 199 | appendInt16Unsafe :: DuckDBAppender -> Int16 -> DuckDBMonad () 200 | appendInt16Unsafe app i = liftIO $ void $ FFI.duckdb_append_int16 app i 201 | 202 | appendInt32 :: DuckDBAppender -> Int32 -> DuckDBMonad () 203 | appendInt32 app i = do 204 | err <- liftIO $ FFI.duckdb_append_int32 app i 205 | when (isDuckDBError err) $ do 206 | message <- liftIO $ do 207 | p <- FFI.duckdb_appender_error app 208 | peekCString p 209 | throwError $ "duckdb_append_int32 failed: " ++ message 210 | 211 | appendInt32Unsafe :: DuckDBAppender -> Int32 -> DuckDBMonad () 212 | appendInt32Unsafe app i = liftIO $ void $ FFI.duckdb_append_int32 app i 213 | 214 | appendInt64 :: DuckDBAppender -> Int64 -> DuckDBMonad () 215 | appendInt64 app i = do 216 | err <- liftIO $ FFI.duckdb_append_int64 app i 217 | when (isDuckDBError err) $ do 218 | message <- liftIO $ do 219 | p <- FFI.duckdb_appender_error app 220 | peekCString p 221 | throwError $ "duckdb_append_int64 failed: " ++ message 222 | 223 | appendInt64Unsafe :: DuckDBAppender -> Int64 -> DuckDBMonad () 224 | appendInt64Unsafe app i = liftIO $ void $ FFI.duckdb_append_int64 app i 225 | 226 | appendWord8 :: DuckDBAppender -> Word8 -> DuckDBMonad () 227 | appendWord8 app i = do 228 | err <- liftIO $ FFI.duckdb_append_uint8 app i 229 | when (isDuckDBError err) $ do 230 | message <- liftIO $ do 231 | p <- FFI.duckdb_appender_error app 232 | peekCString p 233 | throwError $ "duckdb_append_uint8 failed: " ++ message 234 | 235 | appendWord8Unsafe :: DuckDBAppender -> Word8 -> DuckDBMonad () 236 | appendWord8Unsafe app i = liftIO $ void $ FFI.duckdb_append_uint8 app i 237 | 238 | appendWord16 :: DuckDBAppender -> Word16 -> DuckDBMonad () 239 | appendWord16 app i = do 240 | err <- liftIO $ FFI.duckdb_append_uint16 app i 241 | when (isDuckDBError err) $ do 242 | message <- liftIO $ do 243 | p <- FFI.duckdb_appender_error app 244 | peekCString p 245 | throwError $ "duckdb_append_uint16 failed: " ++ message 246 | 247 | appendWord16Unsafe :: DuckDBAppender -> Word16 -> DuckDBMonad () 248 | appendWord16Unsafe app i = liftIO $ void $ FFI.duckdb_append_uint16 app i 249 | 250 | appendWord32 :: DuckDBAppender -> Word32 -> DuckDBMonad () 251 | appendWord32 app i = do 252 | err <- liftIO $ FFI.duckdb_append_uint32 app i 253 | when (isDuckDBError err) $ do 254 | message <- liftIO $ do 255 | p <- FFI.duckdb_appender_error app 256 | peekCString p 257 | throwError $ "duckdb_append_uint32 failed: " ++ message 258 | 259 | appendWord32Unsafe :: DuckDBAppender -> Word32 -> DuckDBMonad () 260 | appendWord32Unsafe app i = liftIO $ void $ FFI.duckdb_append_uint32 app i 261 | 262 | appendWord64 :: DuckDBAppender -> Word64 -> DuckDBMonad () 263 | appendWord64 app i = do 264 | err <- liftIO $ FFI.duckdb_append_uint64 app i 265 | when (isDuckDBError err) $ do 266 | message <- liftIO $ do 267 | p <- FFI.duckdb_appender_error app 268 | peekCString p 269 | throwError $ "duckdb_append_uint64 failed: " ++ message 270 | 271 | appendWord64Unsafe :: DuckDBAppender -> Word64 -> DuckDBMonad () 272 | appendWord64Unsafe app i = liftIO $ void $ FFI.duckdb_append_uint64 app i 273 | 274 | appendFloat :: DuckDBAppender -> Float -> DuckDBMonad () 275 | appendFloat app f = do 276 | err <- liftIO $ FFI.duckdb_append_float app f 277 | when (isDuckDBError err) $ do 278 | message <- liftIO $ do 279 | p <- FFI.duckdb_appender_error app 280 | peekCString p 281 | throwError $ "duckdb_append_float failed: " ++ message 282 | 283 | appendFloatUnsafe :: DuckDBAppender -> Float -> DuckDBMonad () 284 | appendFloatUnsafe app f = liftIO $ void $ FFI.duckdb_append_float app f 285 | 286 | appendDouble :: DuckDBAppender -> Double -> DuckDBMonad () 287 | appendDouble app d = do 288 | err <- liftIO $ FFI.duckdb_append_double app d 289 | when (isDuckDBError err) $ do 290 | message <- liftIO $ do 291 | p <- FFI.duckdb_appender_error app 292 | peekCString p 293 | throwError $ "duckdb_append_double failed: " ++ message 294 | 295 | appendDoubleUnsafe :: DuckDBAppender -> Double -> DuckDBMonad () 296 | appendDoubleUnsafe app d = liftIO $ void $ FFI.duckdb_append_double app d 297 | 298 | appendDate :: DuckDBAppender -> Int32 -> DuckDBMonad () 299 | appendDate app d = do 300 | err <- liftIO $ FFI.duckdb_append_date app d 301 | when (isDuckDBError err) $ do 302 | message <- liftIO $ do 303 | p <- FFI.duckdb_appender_error app 304 | peekCString p 305 | throwError $ "duckdb_append_date failed: " ++ message 306 | 307 | appendDateUnsafe :: DuckDBAppender -> Int32 -> DuckDBMonad () 308 | appendDateUnsafe app d = liftIO $ void $ FFI.duckdb_append_date app d 309 | 310 | appendTime :: DuckDBAppender -> Int64 -> DuckDBMonad () 311 | appendTime app t = do 312 | err <- liftIO $ FFI.duckdb_append_time app t 313 | when (isDuckDBError err) $ do 314 | message <- liftIO $ do 315 | p <- FFI.duckdb_appender_error app 316 | peekCString p 317 | throwError $ "duckdb_append_time failed: " ++ message 318 | 319 | appendTimeUnsafe :: DuckDBAppender -> Int64 -> DuckDBMonad () 320 | appendTimeUnsafe app t = liftIO $ void $ FFI.duckdb_append_time app t 321 | 322 | appendTimestamp :: DuckDBAppender -> Int64 -> DuckDBMonad () 323 | appendTimestamp app t = do 324 | err <- liftIO $ FFI.duckdb_append_timestamp app t 325 | when (isDuckDBError err) $ do 326 | message <- liftIO $ do 327 | p <- FFI.duckdb_appender_error app 328 | peekCString p 329 | throwError $ "duckdb_append_timestamp failed: " ++ message 330 | 331 | appendTimestampUnsafe :: DuckDBAppender -> Int64 -> DuckDBMonad () 332 | appendTimestampUnsafe app t = liftIO $ void $ FFI.duckdb_append_timestamp app t 333 | 334 | appendString :: DuckDBAppender -> String -> DuckDBMonad () 335 | appendString app s = do 336 | err <- liftIO $ withCString s $ \s' -> FFI.duckdb_append_varchar app s' 337 | when (isDuckDBError err) $ do 338 | message <- liftIO $ do 339 | p <- FFI.duckdb_appender_error app 340 | peekCString p 341 | throwError $ "duckdb_append_varchar failed: " ++ message 342 | 343 | appendStringUnsafe :: DuckDBAppender -> String -> DuckDBMonad () 344 | appendStringUnsafe app s = liftIO $ void $ withCString s $ \s' -> FFI.duckdb_append_varchar app s' 345 | 346 | appendNull :: DuckDBAppender -> DuckDBMonad () 347 | appendNull app = do 348 | err <- liftIO $ FFI.duckdb_append_null app 349 | when (isDuckDBError err) $ do 350 | message <- liftIO $ do 351 | p <- FFI.duckdb_appender_error app 352 | peekCString p 353 | throwError $ "duckdb_append_null failed: " ++ message 354 | 355 | appendNullUnsafe :: DuckDBAppender -> DuckDBMonad () 356 | appendNullUnsafe app = liftIO $ void $ FFI.duckdb_append_null app 357 | 358 | appendDataChunk :: DuckDBAppender -> DuckDBDataChunk -> DuckDBMonad () 359 | appendDataChunk app chk = do 360 | err <- liftIO $ FFI.duckdb_append_data_chunk app chk 361 | when (isDuckDBError err) $ do 362 | message <- liftIO $ do 363 | p <- FFI.duckdb_appender_error app 364 | peekCString p 365 | throwError $ "duckdb_append_chunk failed: " ++ message 366 | -------------------------------------------------------------------------------- /src/Database/DuckDB/Value.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE PatternSynonyms #-} 2 | 3 | module Database.DuckDB.Value 4 | ( -- * Query result 5 | DuckDBResult 6 | , DuckDBDataChunk 7 | , DuckDBVector 8 | , DuckDBType 9 | , DuckDBLogicalType 10 | , destroy 11 | 12 | -- * Data types 13 | , pattern FFI.DUCKDB_TYPE_INVALID 14 | , pattern FFI.DUCKDB_TYPE_BOOLEAN 15 | , pattern FFI.DUCKDB_TYPE_TINYINT 16 | , pattern FFI.DUCKDB_TYPE_SMALLINT 17 | , pattern FFI.DUCKDB_TYPE_INTEGER 18 | , pattern FFI.DUCKDB_TYPE_BIGINT 19 | , pattern FFI.DUCKDB_TYPE_UTINYINT 20 | , pattern FFI.DUCKDB_TYPE_USMALLINT 21 | , pattern FFI.DUCKDB_TYPE_UINTEGER 22 | , pattern FFI.DUCKDB_TYPE_UBIGINT 23 | , pattern FFI.DUCKDB_TYPE_FLOAT 24 | , pattern FFI.DUCKDB_TYPE_DOUBLE 25 | , pattern FFI.DUCKDB_TYPE_TIMESTAMP 26 | , pattern FFI.DUCKDB_TYPE_DATE 27 | , pattern FFI.DUCKDB_TYPE_TIME 28 | , pattern FFI.DUCKDB_TYPE_INTERVAL 29 | , pattern FFI.DUCKDB_TYPE_HUGEINT 30 | , pattern FFI.DUCKDB_TYPE_VARCHAR 31 | , pattern FFI.DUCKDB_TYPE_BLOB 32 | , pattern FFI.DUCKDB_TYPE_DECIMAL 33 | , pattern FFI.DUCKDB_TYPE_TIMESTAMP_S 34 | , pattern FFI.DUCKDB_TYPE_TIMESTAMP_MS 35 | , pattern FFI.DUCKDB_TYPE_TIMESTAMP_NS 36 | , pattern FFI.DUCKDB_TYPE_ENUM 37 | , pattern FFI.DUCKDB_TYPE_LIST 38 | , pattern FFI.DUCKDB_TYPE_STRUCT 39 | , pattern FFI.DUCKDB_TYPE_MAP 40 | , pattern FFI.DUCKDB_TYPE_UUID 41 | , pattern FFI.DUCKDB_TYPE_UNION 42 | , pattern FFI.DUCKDB_TYPE_BIT 43 | , typeRep 44 | , Int8 45 | , Int16 46 | , Int32 47 | , Int64 48 | , Word8 49 | , Word16 50 | , Word32 51 | , Word64 52 | , DuckDBDate 53 | , DuckDBTime 54 | , DuckDBTimestamp 55 | 56 | -- * Columns 57 | , columnName 58 | , columnType 59 | , columnLogicalType 60 | , columnCount 61 | , rowCount 62 | , rowsChanged 63 | , columnData 64 | , nullmaskData 65 | 66 | -- * Data chunks 67 | , chunkAt 68 | , isStreaming 69 | , chunkCount 70 | , createChunk 71 | , destroyChunk 72 | , resetChunk 73 | , getChunkColumnCount 74 | , getChunkVector 75 | , getChunkSize 76 | , setChunkSize 77 | , getVectorType 78 | , getVectorData 79 | , getVectorValidity 80 | , ensureVectorValidityWritable 81 | , setVectorStringValue 82 | , isValidityRowValid 83 | , setValidityRow 84 | , setValidityRowInvalid 85 | , setValidityRowValid 86 | 87 | -- * Element values 88 | , valueBoolean 89 | , valueInt8 90 | , valueInt16 91 | , valueInt32 92 | , valueInt64 93 | , valueUint8 94 | , valueUint16 95 | , valueUint32 96 | , valueUint64 97 | , valueFloat 98 | , valueDouble 99 | , valueDate 100 | , valueTime 101 | , valueTimestamp 102 | , valueVarChar 103 | , valueVarCharInternal 104 | , valueIsNull 105 | ) 106 | where 107 | 108 | import Control.Monad 109 | import Control.Monad.Except 110 | import Control.Monad.IO.Class 111 | import Data.Coerce 112 | import Data.Int 113 | import Data.Typeable (TypeRep, typeOf) 114 | import Data.Word 115 | import Database.DuckDB.Internal 116 | import Database.DuckDB.Internal.FFI 117 | ( DuckDBDataChunk 118 | , DuckDBDate 119 | , DuckDBLogicalType 120 | , DuckDBTime 121 | , DuckDBTimestamp 122 | , DuckDBType 123 | , DuckDBVector 124 | ) 125 | import Database.DuckDB.Internal.FFI qualified as FFI 126 | import Foreign.C.String 127 | import Foreign.Marshal.Alloc 128 | import Foreign.Marshal.Array 129 | import Foreign.Ptr 130 | import Foreign.Storable 131 | 132 | type DuckDBResult = Ptr FFI.DuckDBResult 133 | 134 | destroy :: DuckDBResult -> DuckDBMonad () 135 | destroy result = liftIO $ do 136 | FFI.duckdb_destroy_result result 137 | FFI.duckdb_free result 138 | 139 | typeRep :: DuckDBType -> TypeRep 140 | typeRep FFI.DUCKDB_TYPE_INVALID = typeOf () 141 | typeRep FFI.DUCKDB_TYPE_BOOLEAN = typeOf (undefined :: Bool) 142 | typeRep FFI.DUCKDB_TYPE_TINYINT = typeOf (undefined :: Int8) 143 | typeRep FFI.DUCKDB_TYPE_SMALLINT = typeOf (undefined :: Int16) 144 | typeRep FFI.DUCKDB_TYPE_INTEGER = typeOf (undefined :: Int32) 145 | typeRep FFI.DUCKDB_TYPE_BIGINT = typeOf (undefined :: Int64) 146 | typeRep FFI.DUCKDB_TYPE_UTINYINT = typeOf (undefined :: Word8) 147 | typeRep FFI.DUCKDB_TYPE_USMALLINT = typeOf (undefined :: Word16) 148 | typeRep FFI.DUCKDB_TYPE_UINTEGER = typeOf (undefined :: Word32) 149 | typeRep FFI.DUCKDB_TYPE_UBIGINT = typeOf (undefined :: Word64) 150 | typeRep FFI.DUCKDB_TYPE_FLOAT = typeOf (undefined :: Float) 151 | typeRep FFI.DUCKDB_TYPE_DOUBLE = typeOf (undefined :: Double) 152 | typeRep FFI.DUCKDB_TYPE_TIMESTAMP = typeOf (undefined :: Int64) 153 | typeRep FFI.DUCKDB_TYPE_DATE = typeOf (undefined :: Int32) 154 | typeRep FFI.DUCKDB_TYPE_TIME = typeOf (undefined :: Int64) 155 | typeRep FFI.DUCKDB_TYPE_INTERVAL = typeOf (undefined :: Int64) 156 | typeRep FFI.DUCKDB_TYPE_HUGEINT = typeOf (undefined :: Int64) 157 | typeRep FFI.DUCKDB_TYPE_VARCHAR = typeOf (undefined :: String) 158 | typeRep FFI.DUCKDB_TYPE_BLOB = typeOf (undefined :: String) 159 | typeRep FFI.DUCKDB_TYPE_DECIMAL = typeOf (undefined :: Double) 160 | typeRep FFI.DUCKDB_TYPE_TIMESTAMP_S = typeOf (undefined :: Int64) 161 | typeRep FFI.DUCKDB_TYPE_TIMESTAMP_MS = typeOf (undefined :: Int64) 162 | typeRep FFI.DUCKDB_TYPE_TIMESTAMP_NS = typeOf (undefined :: Int64) 163 | typeRep FFI.DUCKDB_TYPE_ENUM = typeOf (undefined :: Int32) 164 | typeRep FFI.DUCKDB_TYPE_LIST = typeOf (undefined :: Int64) 165 | typeRep FFI.DUCKDB_TYPE_STRUCT = typeOf (undefined :: Int64) 166 | typeRep FFI.DUCKDB_TYPE_MAP = typeOf (undefined :: Int64) 167 | typeRep FFI.DUCKDB_TYPE_UUID = typeOf (undefined :: Int64) 168 | typeRep FFI.DUCKDB_TYPE_UNION = typeOf (undefined :: Int64) 169 | typeRep FFI.DUCKDB_TYPE_BIT = typeOf (undefined :: Int64) 170 | typeRep ty = error ("impossible: unknown duckdb type enumeration: " ++ show ty) 171 | 172 | columnName :: DuckDBResult -> Int -> DuckDBMonad String 173 | columnName result idx = do 174 | name' <- liftIO $ FFI.duckdb_column_name result (fromIntegral idx) 175 | when (name' == nullPtr) $ 176 | throwError "duckdb_column_name failed" 177 | liftIO $ peekCString name' 178 | 179 | columnType :: DuckDBResult -> Int -> DuckDBMonad DuckDBType 180 | columnType result idx = do 181 | ty <- liftIO $ FFI.duckdb_column_type result (fromIntegral idx) 182 | when (ty == FFI.DUCKDB_TYPE_INVALID) $ 183 | throwError "duckdb_column_type failed" 184 | return ty 185 | 186 | columnLogicalType :: DuckDBResult -> Int -> DuckDBMonad DuckDBLogicalType 187 | columnLogicalType result idx = do 188 | ty <- liftIO $ FFI.duckdb_column_logical_type result (fromIntegral idx) 189 | when (coerce ty == nullPtr) $ 190 | throwError "duckdb_column_logical_type failed" 191 | return ty 192 | 193 | columnCount :: DuckDBResult -> DuckDBMonad Int 194 | columnCount result = do 195 | count <- liftIO $ FFI.duckdb_column_count result 196 | return (fromIntegral count) 197 | 198 | rowCount :: DuckDBResult -> DuckDBMonad Int 199 | rowCount result = do 200 | count <- liftIO $ FFI.duckdb_row_count result 201 | return (fromIntegral count) 202 | 203 | rowsChanged :: DuckDBResult -> DuckDBMonad Int 204 | rowsChanged result = do 205 | count <- liftIO $ FFI.duckdb_rows_changed result 206 | return (fromIntegral count) 207 | 208 | columnData :: DuckDBResult -> Int -> DuckDBMonad (Ptr a) 209 | columnData result idx = do 210 | data' <- liftIO $ FFI.duckdb_column_data result (fromIntegral idx) 211 | when (data' == nullPtr) $ 212 | throwError "duckdb_column_data failed" 213 | return data' 214 | 215 | nullmaskData :: DuckDBResult -> Int -> DuckDBMonad (Ptr Bool) 216 | nullmaskData result idx = do 217 | data' <- liftIO $ FFI.duckdb_nullmask_data result (fromIntegral idx) 218 | when (data' == nullPtr) $ 219 | throwError "duckdb_nullmask_data failed" 220 | return data' 221 | 222 | chunkAt :: DuckDBResult -> Int -> DuckDBMonad DuckDBDataChunk 223 | chunkAt result idx = do 224 | chk <- liftIO $ do 225 | FFI.duckdb_result_get_chunk result (fromIntegral idx) 226 | return chk 227 | 228 | isStreaming :: DuckDBResult -> DuckDBMonad Bool 229 | isStreaming result = do 230 | streaming <- liftIO $ do 231 | FFI.duckdb_result_is_streaming result 232 | return streaming 233 | 234 | chunkCount :: DuckDBResult -> DuckDBMonad Int 235 | chunkCount result = do 236 | count <- liftIO $ do 237 | FFI.duckdb_result_chunk_count result 238 | return (fromIntegral count) 239 | 240 | createChunk 241 | :: [DuckDBLogicalType] 242 | -> Int 243 | -- ^ column count 244 | -> DuckDBMonad DuckDBDataChunk 245 | createChunk tys colCount = do 246 | chk <- liftIO $ withArray tys $ \tys' -> FFI.duckdb_create_data_chunk tys' (fromIntegral colCount) 247 | when (coerce chk == nullPtr) $ 248 | throwError "duckdb_create_data_chunk failed" 249 | return chk 250 | 251 | destroyChunk :: DuckDBDataChunk -> DuckDBMonad () 252 | destroyChunk chk = liftIO $ alloca $ \chk' -> do 253 | poke chk' chk 254 | FFI.duckdb_destroy_data_chunk chk' 255 | 256 | resetChunk :: DuckDBDataChunk -> DuckDBMonad () 257 | resetChunk chk = liftIO $ FFI.duckdb_data_chunk_reset chk 258 | 259 | getChunkColumnCount :: DuckDBDataChunk -> DuckDBMonad Int 260 | getChunkColumnCount chk = do 261 | count <- liftIO $ FFI.duckdb_data_chunk_get_column_count chk 262 | return (fromIntegral count) 263 | 264 | getChunkVector :: DuckDBDataChunk -> Int -> DuckDBMonad DuckDBVector 265 | getChunkVector chk idx = do 266 | vec <- liftIO $ FFI.duckdb_data_chunk_get_vector chk (fromIntegral idx) 267 | when (coerce vec == nullPtr) $ 268 | throwError "duckdb_data_chunk_get_vector failed" 269 | return vec 270 | 271 | getChunkSize :: DuckDBDataChunk -> DuckDBMonad Int 272 | getChunkSize chk = do 273 | size <- liftIO $ FFI.duckdb_data_chunk_get_size chk 274 | return (fromIntegral size) 275 | 276 | setChunkSize :: DuckDBDataChunk -> Int -> DuckDBMonad () 277 | setChunkSize chk size = liftIO $ FFI.duckdb_data_chunk_set_size chk (fromIntegral size) 278 | 279 | getVectorType :: DuckDBVector -> DuckDBMonad DuckDBLogicalType 280 | getVectorType vec = liftIO $ FFI.duckdb_vector_get_column_type vec 281 | 282 | getVectorData :: DuckDBVector -> DuckDBMonad (Ptr a) 283 | getVectorData vec = liftIO $ FFI.duckdb_vector_get_data vec 284 | 285 | getVectorValidity :: DuckDBVector -> DuckDBMonad (Ptr Word64) 286 | getVectorValidity vec = liftIO $ FFI.duckdb_vector_get_validity vec 287 | 288 | ensureVectorValidityWritable :: DuckDBVector -> DuckDBMonad () 289 | ensureVectorValidityWritable vec = liftIO $ FFI.duckdb_vector_ensure_validity_writable vec 290 | 291 | setVectorStringValue :: DuckDBVector -> Int -> String -> DuckDBMonad () 292 | setVectorStringValue vec idx value = liftIO $ withCString value $ \value' -> 293 | FFI.duckdb_vector_assign_string_element vec (fromIntegral idx) value' 294 | 295 | isValidityRowValid :: Ptr Word64 -> Int -> DuckDBMonad Bool 296 | isValidityRowValid vec idx = liftIO $ FFI.duckdb_validity_row_is_valid vec (fromIntegral idx) 297 | 298 | setValidityRow :: Ptr Word64 -> Int -> Bool -> DuckDBMonad () 299 | setValidityRow vec idx valid = liftIO $ FFI.duckdb_validity_set_row_validity vec (fromIntegral idx) valid 300 | 301 | setValidityRowInvalid :: Ptr Word64 -> Int -> DuckDBMonad () 302 | setValidityRowInvalid vec idx = liftIO $ FFI.duckdb_validity_set_row_invalid vec (fromIntegral idx) 303 | 304 | setValidityRowValid :: Ptr Word64 -> Int -> DuckDBMonad () 305 | setValidityRowValid vec idx = liftIO $ FFI.duckdb_validity_set_row_valid vec (fromIntegral idx) 306 | 307 | valueBoolean 308 | :: DuckDBResult 309 | -> Int 310 | -- ^ column 311 | -> Int 312 | -- ^ row 313 | -> DuckDBMonad Bool 314 | valueBoolean result col row = 315 | liftIO $ FFI.duckdb_value_boolean result (fromIntegral col) (fromIntegral row) 316 | 317 | valueInt8 318 | :: DuckDBResult 319 | -> Int 320 | -- ^ column 321 | -> Int 322 | -- ^ row 323 | -> DuckDBMonad Int8 324 | valueInt8 result col row = liftIO $ FFI.duckdb_value_int8 result (fromIntegral col) (fromIntegral row) 325 | 326 | valueInt16 327 | :: DuckDBResult 328 | -> Int 329 | -- ^ column 330 | -> Int 331 | -- ^ row 332 | -> DuckDBMonad Int16 333 | valueInt16 result col row = liftIO $ FFI.duckdb_value_int16 result (fromIntegral col) (fromIntegral row) 334 | 335 | valueInt32 336 | :: DuckDBResult 337 | -> Int 338 | -- ^ column 339 | -> Int 340 | -- ^ row 341 | -> DuckDBMonad Int32 342 | valueInt32 result col row = liftIO $ FFI.duckdb_value_int32 result (fromIntegral col) (fromIntegral row) 343 | 344 | valueInt64 345 | :: DuckDBResult 346 | -> Int 347 | -- ^ column 348 | -> Int 349 | -- ^ row 350 | -> DuckDBMonad Int64 351 | valueInt64 result col row = liftIO $ FFI.duckdb_value_int64 result (fromIntegral col) (fromIntegral row) 352 | 353 | valueUint8 354 | :: DuckDBResult 355 | -> Int 356 | -- ^ column 357 | -> Int 358 | -- ^ row 359 | -> DuckDBMonad Word8 360 | valueUint8 result col row = liftIO $ FFI.duckdb_value_uint8 result (fromIntegral col) (fromIntegral row) 361 | 362 | valueUint16 363 | :: DuckDBResult 364 | -> Int 365 | -- ^ column 366 | -> Int 367 | -- ^ row 368 | -> DuckDBMonad Word16 369 | valueUint16 result col row = liftIO $ FFI.duckdb_value_uint16 result (fromIntegral col) (fromIntegral row) 370 | 371 | valueUint32 372 | :: DuckDBResult 373 | -> Int 374 | -- ^ column 375 | -> Int 376 | -- ^ row 377 | -> DuckDBMonad Word32 378 | valueUint32 result col row = liftIO $ FFI.duckdb_value_uint32 result (fromIntegral col) (fromIntegral row) 379 | 380 | valueUint64 381 | :: DuckDBResult 382 | -> Int 383 | -- ^ column 384 | -> Int 385 | -- ^ row 386 | -> DuckDBMonad Word64 387 | valueUint64 result col row = liftIO $ FFI.duckdb_value_uint64 result (fromIntegral col) (fromIntegral row) 388 | 389 | valueFloat 390 | :: DuckDBResult 391 | -> Int 392 | -- ^ column 393 | -> Int 394 | -- ^ row 395 | -> DuckDBMonad Float 396 | valueFloat result col row = liftIO $ FFI.duckdb_value_float result (fromIntegral col) (fromIntegral row) 397 | 398 | valueDouble 399 | :: DuckDBResult 400 | -> Int 401 | -- ^ column 402 | -> Int 403 | -- ^ row 404 | -> DuckDBMonad Double 405 | valueDouble result col row = liftIO $ FFI.duckdb_value_double result (fromIntegral col) (fromIntegral row) 406 | 407 | valueDate 408 | :: DuckDBResult 409 | -> Int 410 | -- ^ column 411 | -> Int 412 | -- ^ row 413 | -> DuckDBMonad DuckDBDate 414 | valueDate result col row = liftIO $ FFI.duckdb_value_date result (fromIntegral col) (fromIntegral row) 415 | 416 | valueTime 417 | :: DuckDBResult 418 | -> Int 419 | -- ^ column 420 | -> Int 421 | -- ^ row 422 | -> DuckDBMonad DuckDBTime 423 | valueTime result col row = liftIO $ FFI.duckdb_value_time result (fromIntegral col) (fromIntegral row) 424 | 425 | valueTimestamp 426 | :: DuckDBResult 427 | -> Int 428 | -- ^ column 429 | -> Int 430 | -- ^ row 431 | -> DuckDBMonad DuckDBTimestamp 432 | valueTimestamp result col row = 433 | liftIO $ FFI.duckdb_value_timestamp result (fromIntegral col) (fromIntegral row) 434 | 435 | valueVarChar 436 | :: DuckDBResult 437 | -> Int 438 | -- ^ column 439 | -> Int 440 | -- ^ row 441 | -> DuckDBMonad String 442 | valueVarChar result col row = do 443 | value <- 444 | liftIO $ FFI.duckdb_value_varchar result (fromIntegral col) (fromIntegral row) 445 | when (value == nullPtr) $ 446 | throwError "duckdb_value_varchar failed" 447 | liftIO $ peekCString value 448 | 449 | valueVarCharInternal 450 | :: DuckDBResult 451 | -> Int 452 | -- ^ column 453 | -> Int 454 | -- ^ row 455 | -> DuckDBMonad CString 456 | valueVarCharInternal result col row = 457 | liftIO $ 458 | FFI.duckdb_value_varchar_internal result (fromIntegral col) (fromIntegral row) 459 | 460 | valueIsNull 461 | :: DuckDBResult 462 | -> Int 463 | -- ^ column 464 | -> Int 465 | -- ^ row 466 | -> DuckDBMonad Bool 467 | valueIsNull result col row = 468 | liftIO $ FFI.duckdb_value_is_null result (fromIntegral col) (fromIntegral row) 469 | -------------------------------------------------------------------------------- /src/Database/DuckDB/Internal/FFI.hsc: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DuplicateRecordFields #-} 2 | {-# LANGUAGE PatternSynonyms #-} 3 | 4 | module Database.DuckDB.Internal.FFI where 5 | 6 | import Data.Int 7 | import Data.Word 8 | import Foreign.C.String 9 | import Foreign.C.Types 10 | import Foreign.Ptr 11 | import Foreign.Storable 12 | 13 | {- FOURMOLU_DISABLE -} 14 | 15 | #include "duckdb.h" 16 | #include "duckdb-c-api.h" 17 | 18 | {- FOURMOLU_ENABLE -} 19 | 20 | type DuckDBIndexType = Word64 21 | 22 | type DuckDBType = Int32 23 | 24 | pattern DUCKDB_TYPE_INVALID :: DuckDBType 25 | pattern DUCKDB_TYPE_INVALID = 0 26 | 27 | pattern DUCKDB_TYPE_BOOLEAN :: DuckDBType 28 | pattern DUCKDB_TYPE_BOOLEAN = 1 29 | 30 | pattern DUCKDB_TYPE_TINYINT :: DuckDBType 31 | pattern DUCKDB_TYPE_TINYINT = 2 32 | 33 | pattern DUCKDB_TYPE_SMALLINT :: DuckDBType 34 | pattern DUCKDB_TYPE_SMALLINT = 3 35 | 36 | pattern DUCKDB_TYPE_INTEGER :: DuckDBType 37 | pattern DUCKDB_TYPE_INTEGER = 4 38 | 39 | pattern DUCKDB_TYPE_BIGINT :: DuckDBType 40 | pattern DUCKDB_TYPE_BIGINT = 5 41 | 42 | pattern DUCKDB_TYPE_UTINYINT :: DuckDBType 43 | pattern DUCKDB_TYPE_UTINYINT = 6 44 | 45 | pattern DUCKDB_TYPE_USMALLINT :: DuckDBType 46 | pattern DUCKDB_TYPE_USMALLINT = 7 47 | 48 | pattern DUCKDB_TYPE_UINTEGER :: DuckDBType 49 | pattern DUCKDB_TYPE_UINTEGER = 8 50 | 51 | pattern DUCKDB_TYPE_UBIGINT :: DuckDBType 52 | pattern DUCKDB_TYPE_UBIGINT = 9 53 | 54 | pattern DUCKDB_TYPE_FLOAT :: DuckDBType 55 | pattern DUCKDB_TYPE_FLOAT = 10 56 | 57 | pattern DUCKDB_TYPE_DOUBLE :: DuckDBType 58 | pattern DUCKDB_TYPE_DOUBLE = 11 59 | 60 | pattern DUCKDB_TYPE_TIMESTAMP :: DuckDBType 61 | pattern DUCKDB_TYPE_TIMESTAMP = 12 62 | 63 | pattern DUCKDB_TYPE_DATE :: DuckDBType 64 | pattern DUCKDB_TYPE_DATE = 13 65 | 66 | pattern DUCKDB_TYPE_TIME :: DuckDBType 67 | pattern DUCKDB_TYPE_TIME = 14 68 | 69 | pattern DUCKDB_TYPE_INTERVAL :: DuckDBType 70 | pattern DUCKDB_TYPE_INTERVAL = 15 71 | 72 | pattern DUCKDB_TYPE_HUGEINT :: DuckDBType 73 | pattern DUCKDB_TYPE_HUGEINT = 16 74 | 75 | pattern DUCKDB_TYPE_VARCHAR :: DuckDBType 76 | pattern DUCKDB_TYPE_VARCHAR = 17 77 | 78 | pattern DUCKDB_TYPE_BLOB :: DuckDBType 79 | pattern DUCKDB_TYPE_BLOB = 18 80 | 81 | pattern DUCKDB_TYPE_DECIMAL :: DuckDBType 82 | pattern DUCKDB_TYPE_DECIMAL = 19 83 | 84 | pattern DUCKDB_TYPE_TIMESTAMP_S :: DuckDBType 85 | pattern DUCKDB_TYPE_TIMESTAMP_S = 20 86 | 87 | pattern DUCKDB_TYPE_TIMESTAMP_MS :: DuckDBType 88 | pattern DUCKDB_TYPE_TIMESTAMP_MS = 21 89 | 90 | pattern DUCKDB_TYPE_TIMESTAMP_NS :: DuckDBType 91 | pattern DUCKDB_TYPE_TIMESTAMP_NS = 22 92 | 93 | pattern DUCKDB_TYPE_ENUM :: DuckDBType 94 | pattern DUCKDB_TYPE_ENUM = 23 95 | 96 | pattern DUCKDB_TYPE_LIST :: DuckDBType 97 | pattern DUCKDB_TYPE_LIST = 24 98 | 99 | pattern DUCKDB_TYPE_STRUCT :: DuckDBType 100 | pattern DUCKDB_TYPE_STRUCT = 25 101 | 102 | pattern DUCKDB_TYPE_MAP :: DuckDBType 103 | pattern DUCKDB_TYPE_MAP = 26 104 | 105 | pattern DUCKDB_TYPE_UUID :: DuckDBType 106 | pattern DUCKDB_TYPE_UUID = 27 107 | 108 | pattern DUCKDB_TYPE_UNION :: DuckDBType 109 | pattern DUCKDB_TYPE_UNION = 28 110 | 111 | pattern DUCKDB_TYPE_BIT :: DuckDBType 112 | pattern DUCKDB_TYPE_BIT = 29 113 | 114 | {-# COMPLETE 115 | DUCKDB_TYPE_INVALID 116 | , DUCKDB_TYPE_BOOLEAN 117 | , DUCKDB_TYPE_TINYINT 118 | , DUCKDB_TYPE_SMALLINT 119 | , DUCKDB_TYPE_INTEGER 120 | , DUCKDB_TYPE_BIGINT 121 | , DUCKDB_TYPE_UTINYINT 122 | , DUCKDB_TYPE_USMALLINT 123 | , DUCKDB_TYPE_UINTEGER 124 | , DUCKDB_TYPE_UBIGINT 125 | , DUCKDB_TYPE_FLOAT 126 | , DUCKDB_TYPE_DOUBLE 127 | , DUCKDB_TYPE_TIMESTAMP 128 | , DUCKDB_TYPE_DATE 129 | , DUCKDB_TYPE_TIME 130 | , DUCKDB_TYPE_INTERVAL 131 | , DUCKDB_TYPE_HUGEINT 132 | , DUCKDB_TYPE_VARCHAR 133 | , DUCKDB_TYPE_BLOB 134 | , DUCKDB_TYPE_DECIMAL 135 | , DUCKDB_TYPE_TIMESTAMP_S 136 | , DUCKDB_TYPE_TIMESTAMP_MS 137 | , DUCKDB_TYPE_TIMESTAMP_NS 138 | , DUCKDB_TYPE_ENUM 139 | , DUCKDB_TYPE_LIST 140 | , DUCKDB_TYPE_STRUCT 141 | , DUCKDB_TYPE_MAP 142 | , DUCKDB_TYPE_UUID 143 | , DUCKDB_TYPE_UNION 144 | , DUCKDB_TYPE_BIT :: 145 | DuckDBType 146 | #-} 147 | 148 | type DuckDBDate = Int32 -- days 149 | 150 | data DuckDBDateStruct = DuckDBDateStruct 151 | { year :: Int32 152 | , month :: Int8 153 | , day :: Int8 154 | } 155 | deriving (Eq, Show) 156 | 157 | {- FOURMOLU_DISABLE -} 158 | 159 | instance Storable DuckDBDateStruct where 160 | sizeOf _ = (#size duckdb_date_struct) 161 | alignment _ = alignment (undefined :: CInt) 162 | peek ptr = 163 | DuckDBDateStruct 164 | <$> (#peek duckdb_date_struct, year) ptr 165 | <*> (#peek duckdb_date_struct, month) ptr 166 | <*> (#peek duckdb_date_struct, day) ptr 167 | poke ptr (DuckDBDateStruct year month day) = do 168 | (#poke duckdb_date_struct, year) ptr year 169 | (#poke duckdb_date_struct, month) ptr month 170 | (#poke duckdb_date_struct, day) ptr day 171 | 172 | {- FOURMOLU_ENABLE -} 173 | 174 | type DuckDBTime = Int64 -- microseconds 175 | 176 | data DuckDBTimeStruct = DuckDBTimeStruct 177 | { hour :: Int8 178 | , min :: Int8 179 | , sec :: Int8 180 | , micros :: Int32 181 | } 182 | deriving (Eq, Show) 183 | 184 | {- FOURMOLU_DISABLE -} 185 | 186 | instance Storable DuckDBTimeStruct where 187 | sizeOf _ = (#size duckdb_time_struct) 188 | alignment _ = alignment (undefined :: CInt) 189 | peek ptr = 190 | DuckDBTimeStruct 191 | <$> (#peek duckdb_time_struct, hour) ptr 192 | <*> (#peek duckdb_time_struct, min) ptr 193 | <*> (#peek duckdb_time_struct, sec) ptr 194 | <*> (#peek duckdb_time_struct, micros) ptr 195 | poke ptr (DuckDBTimeStruct hour minute sec micros) = do 196 | (#poke duckdb_time_struct, hour) ptr hour 197 | (#poke duckdb_time_struct, min) ptr minute 198 | (#poke duckdb_time_struct, sec) ptr sec 199 | (#poke duckdb_time_struct, micros) ptr micros 200 | 201 | {- FOURMOLU_ENABLE -} 202 | 203 | type DuckDBTimestamp = Int64 -- microseconds 204 | 205 | data DuckDBTimestampStruct = DuckDBTimestampStruct 206 | { date :: DuckDBDateStruct 207 | , time :: DuckDBTimeStruct 208 | } 209 | deriving (Eq, Show) 210 | 211 | {- FOURMOLU_DISABLE -} 212 | 213 | instance Storable DuckDBTimestampStruct where 214 | sizeOf _ = (#size duckdb_timestamp_struct) 215 | alignment _ = alignment (undefined :: CInt) 216 | peek ptr = 217 | DuckDBTimestampStruct 218 | <$> (#peek duckdb_timestamp_struct, date) ptr 219 | <*> (#peek duckdb_timestamp_struct, time) ptr 220 | poke ptr (DuckDBTimestampStruct date time) = do 221 | (#poke duckdb_timestamp_struct, date) ptr date 222 | (#poke duckdb_timestamp_struct, time) ptr time 223 | 224 | {- FOURMOLU_ENABLE -} 225 | 226 | data DuckDBIntervalStruct = DuckDBIntervalStruct 227 | { months :: Int32 228 | , days :: Int32 229 | , micros :: Int64 230 | } 231 | deriving (Eq, Show) 232 | 233 | {- FOURMOLU_DISABLE -} 234 | 235 | instance Storable DuckDBIntervalStruct where 236 | sizeOf _ = (#size duckdb_interval) 237 | alignment _ = alignment (undefined :: CInt) 238 | peek ptr = 239 | DuckDBIntervalStruct 240 | <$> (#peek duckdb_interval, months) ptr 241 | <*> (#peek duckdb_interval, days) ptr 242 | <*> (#peek duckdb_interval, micros) ptr 243 | poke ptr (DuckDBIntervalStruct months days micros) = do 244 | (#poke duckdb_interval, months) ptr months 245 | (#poke duckdb_interval, days) ptr days 246 | (#poke duckdb_interval, micros) ptr micros 247 | 248 | {- FOURMOLU_ENABLE -} 249 | 250 | data DuckDBHugeIntStruct = DuckDBHugeIntStruct 251 | { lower :: Word64 252 | , upper :: Int64 253 | } 254 | deriving (Eq, Show) 255 | 256 | {- FOURMOLU_DISABLE -} 257 | 258 | instance Storable DuckDBHugeIntStruct where 259 | sizeOf _ = (#size duckdb_hugeint) 260 | alignment _ = alignment (undefined :: CInt) 261 | peek ptr = 262 | DuckDBHugeIntStruct 263 | <$> (#peek duckdb_hugeint, lower) ptr 264 | <*> (#peek duckdb_hugeint, upper) ptr 265 | poke ptr (DuckDBHugeIntStruct lower upper) = do 266 | (#poke duckdb_hugeint, lower) ptr lower 267 | (#poke duckdb_hugeint, upper) ptr upper 268 | 269 | {- FOURMOLU_ENABLE -} 270 | 271 | data DuckDBDecimalStruct = DuckDBDecimalStruct 272 | { width :: Word8 273 | , scale :: Word8 274 | , value :: DuckDBHugeIntStruct 275 | } 276 | deriving (Eq, Show) 277 | 278 | {- FOURMOLU_DISABLE -} 279 | 280 | instance Storable DuckDBDecimalStruct where 281 | sizeOf _ = (#size duckdb_decimal) 282 | alignment _ = alignment (undefined :: CInt) 283 | peek ptr = 284 | DuckDBDecimalStruct 285 | <$> (#peek duckdb_decimal, width) ptr 286 | <*> (#peek duckdb_decimal, scale) ptr 287 | <*> (#peek duckdb_decimal, value) ptr 288 | poke ptr (DuckDBDecimalStruct width scale value) = do 289 | (#poke duckdb_decimal, width) ptr width 290 | (#poke duckdb_decimal, scale) ptr scale 291 | (#poke duckdb_decimal, value) ptr value 292 | 293 | {- FOURMOLU_ENABLE -} 294 | 295 | data DuckDBStringStruct = DuckDBStringStruct 296 | { data_ :: CString 297 | , size :: DuckDBIndexType 298 | } 299 | deriving (Eq, Show) 300 | 301 | {- FOURMOLU_DISABLE -} 302 | 303 | instance Storable DuckDBStringStruct where 304 | sizeOf _ = (#size duckdb_string) 305 | alignment _ = alignment (undefined :: CInt) 306 | peek ptr = 307 | DuckDBStringStruct 308 | <$> (#peek duckdb_string, data) ptr 309 | <*> (#peek duckdb_string, size) ptr 310 | poke ptr (DuckDBStringStruct data_ size) = do 311 | (#poke duckdb_string, data) ptr data_ 312 | (#poke duckdb_string, size) ptr size 313 | 314 | {- FOURMOLU_ENABLE -} 315 | 316 | -- typedef struct { 317 | -- union { 318 | -- struct { 319 | -- uint32_t length; 320 | -- char prefix[4]; 321 | -- char *ptr; 322 | -- } pointer; 323 | -- struct { 324 | -- uint32_t length; 325 | -- char inlined[12]; 326 | -- } inlined; 327 | -- } value; 328 | -- } duckdb_string_t; 329 | 330 | data DuckDBBlob = DuckDBBlob 331 | { data_ :: Ptr () 332 | , size :: DuckDBIndexType 333 | } 334 | deriving (Eq, Show) 335 | 336 | {- FOURMOLU_DISABLE -} 337 | 338 | instance Storable DuckDBBlob where 339 | sizeOf _ = (#size duckdb_blob) 340 | alignment _ = alignment (undefined :: CInt) 341 | peek ptr = 342 | DuckDBBlob 343 | <$> (#peek duckdb_blob, data) ptr 344 | <*> (#peek duckdb_blob, size) ptr 345 | poke ptr (DuckDBBlob data_ size) = do 346 | (#poke duckdb_blob, data) ptr data_ 347 | (#poke duckdb_blob, size) ptr size 348 | 349 | {- FOURMOLU_ENABLE -} 350 | 351 | data DuckDBListEntry = DuckDBListEntry 352 | { offset :: Word64 353 | , length :: Word64 354 | } 355 | deriving (Eq, Show) 356 | 357 | {- FOURMOLU_DISABLE -} 358 | 359 | instance Storable DuckDBListEntry where 360 | sizeOf _ = (#size duckdb_list_entry) 361 | alignment _ = alignment (undefined :: CInt) 362 | peek ptr = 363 | DuckDBListEntry 364 | <$> (#peek duckdb_list_entry, offset) ptr 365 | <*> (#peek duckdb_list_entry, length) ptr 366 | poke ptr (DuckDBListEntry offset length_) = do 367 | (#poke duckdb_list_entry, offset) ptr offset 368 | (#poke duckdb_list_entry, length) ptr length_ 369 | 370 | {- FOURMOLU_ENABLE -} 371 | 372 | data DuckDBColumn = DuckDBColumn 373 | { data_ :: Ptr () 374 | , nullmask :: Ptr Bool 375 | , type_ :: DuckDBType 376 | , name :: CString 377 | , internal_data :: Ptr () 378 | } 379 | deriving (Eq, Show) 380 | 381 | {- FOURMOLU_DISABLE -} 382 | 383 | instance Storable DuckDBColumn where 384 | sizeOf _ = (#size duckdb_column) 385 | alignment _ = alignment (undefined :: CInt) 386 | peek ptr = 387 | DuckDBColumn 388 | <$> (#peek duckdb_column, __deprecated_data) ptr 389 | <*> (#peek duckdb_column, __deprecated_nullmask) ptr 390 | <*> (#peek duckdb_column, __deprecated_type) ptr 391 | <*> (#peek duckdb_column, __deprecated_name) ptr 392 | <*> (#peek duckdb_column, internal_data) ptr 393 | poke ptr (DuckDBColumn data_ nullmask type_ name internal_data) = do 394 | (#poke duckdb_column, __deprecated_data) ptr data_ 395 | (#poke duckdb_column, __deprecated_nullmask) ptr nullmask 396 | (#poke duckdb_column, __deprecated_type) ptr type_ 397 | (#poke duckdb_column, __deprecated_name) ptr name 398 | (#poke duckdb_column, internal_data) ptr internal_data 399 | 400 | {- FOURMOLU_ENABLE -} 401 | 402 | data DuckDBResult = DuckDBResult 403 | { column_count :: DuckDBIndexType 404 | , row_count :: DuckDBIndexType 405 | , rows_changed :: DuckDBIndexType 406 | , columns :: Ptr DuckDBColumn 407 | , error_message :: CString 408 | , internal_data :: Ptr () 409 | } 410 | deriving (Eq, Show) 411 | 412 | {- FOURMOLU_DISABLE -} 413 | 414 | instance Storable DuckDBResult where 415 | sizeOf _ = (#size duckdb_result) 416 | alignment _ = alignment (undefined :: CInt) 417 | peek ptr = 418 | DuckDBResult 419 | <$> (#peek duckdb_result, __deprecated_column_count) ptr 420 | <*> (#peek duckdb_result, __deprecated_row_count) ptr 421 | <*> (#peek duckdb_result, __deprecated_rows_changed) ptr 422 | <*> (#peek duckdb_result, __deprecated_columns) ptr 423 | <*> (#peek duckdb_result, __deprecated_error_message) ptr 424 | <*> (#peek duckdb_result, internal_data) ptr 425 | poke ptr (DuckDBResult column_count row_count rows_changed columns error_message internal_data) = do 426 | (#poke duckdb_result, __deprecated_column_count) ptr column_count 427 | (#poke duckdb_result, __deprecated_row_count) ptr row_count 428 | (#poke duckdb_result, __deprecated_rows_changed) ptr rows_changed 429 | (#poke duckdb_result, __deprecated_columns) ptr columns 430 | (#poke duckdb_result, __deprecated_error_message) ptr error_message 431 | (#poke duckdb_result, internal_data) ptr internal_data 432 | 433 | {- FOURMOLU_ENABLE -} 434 | 435 | newtype DuckDBDatabase = DuckDBDatabase (Ptr ()) deriving (Eq, Storable) 436 | 437 | newtype DuckDBConnection = DuckDBConnection (Ptr ()) deriving (Eq, Storable) 438 | 439 | newtype DuckDBPreparedStatement = DuckDBPreparedStatement (Ptr ()) 440 | deriving (Eq, Storable) 441 | 442 | newtype DuckDBExtractedStatements = DuckDBExtractedStatements (Ptr ()) 443 | deriving (Eq, Storable) 444 | 445 | newtype DuckDBPendingResult = DuckDBPendingResult (Ptr ()) 446 | deriving (Eq, Storable) 447 | 448 | newtype DuckDBAppender = DuckDBAppender (Ptr ()) deriving (Eq, Storable) 449 | 450 | newtype DuckDBArrow = DuckDBArrow (Ptr ()) deriving (Eq, Storable) 451 | 452 | newtype DuckDBConfig = DuckDBConfig (Ptr ()) deriving (Eq, Storable) 453 | 454 | newtype DuckDBArrowSchema = DuckDBArrowSchema (Ptr ()) deriving (Eq, Storable) 455 | 456 | newtype DuckDBArrowArray = DuckDBArrowArray (Ptr ()) deriving (Eq, Storable) 457 | 458 | newtype DuckDBLogicalType = DuckDBLogicalType (Ptr ()) deriving (Eq, Storable) 459 | 460 | newtype DuckDBDataChunk = DuckDBDataChunk (Ptr ()) deriving (Eq, Storable) 461 | 462 | newtype DuckDBVector = DuckDBVector (Ptr ()) deriving (Eq, Storable) 463 | 464 | newtype DuckDBValue = DuckDBValue (Ptr ()) deriving (Eq, Storable) 465 | 466 | type DuckDBState = Int32 467 | 468 | pattern DuckDBSuccess :: DuckDBState 469 | pattern DuckDBSuccess = 0 470 | 471 | pattern DuckDBError :: DuckDBState 472 | pattern DuckDBError = 1 473 | 474 | {-# COMPLETE 475 | DuckDBSuccess 476 | , DuckDBError :: 477 | DuckDBState 478 | #-} 479 | 480 | type DuckDBPendingState = Int32 481 | 482 | pattern DUCKDB_PENDING_RESULT_READY :: DuckDBPendingState 483 | pattern DUCKDB_PENDING_RESULT_READY = 0 484 | 485 | pattern DUCKDB_PENDING_RESULT_NOT_READY :: DuckDBPendingState 486 | pattern DUCKDB_PENDING_RESULT_NOT_READY = 1 487 | 488 | pattern DUCKDB_PENDING_ERROR :: DuckDBPendingState 489 | pattern DUCKDB_PENDING_ERROR = 2 490 | 491 | {-# COMPLETE 492 | DUCKDB_PENDING_RESULT_READY 493 | , DUCKDB_PENDING_RESULT_NOT_READY 494 | , DUCKDB_PENDING_ERROR :: 495 | DuckDBPendingState 496 | #-} 497 | 498 | ----------------------------------------------------- 499 | -- Open/Connect 500 | ----------------------------------------------------- 501 | 502 | foreign import ccall "duckdb.h duckdb_open" 503 | duckdb_open 504 | :: CString -> Ptr DuckDBDatabase -> IO DuckDBState 505 | 506 | foreign import ccall "duckdb.h duckdb_open_ext" 507 | duckdb_open_ext 508 | :: CString -> Ptr DuckDBDatabase -> DuckDBConfig -> Ptr CString -> IO DuckDBState 509 | 510 | foreign import ccall "duckdb.h duckdb_close" 511 | duckdb_close 512 | :: Ptr DuckDBDatabase -> IO () 513 | 514 | foreign import ccall "duckdb.h duckdb_connect" 515 | duckdb_connect 516 | :: DuckDBDatabase -> Ptr DuckDBConnection -> IO DuckDBState 517 | 518 | foreign import ccall "duckdb.h duckdb_disconnect" 519 | duckdb_disconnect 520 | :: Ptr DuckDBConnection -> IO () 521 | 522 | foreign import ccall "duckdb.h duckdb_library_version" 523 | duckdb_library_version 524 | :: IO CString 525 | 526 | ----------------------------------------------------- 527 | -- Configuration 528 | ----------------------------------------------------- 529 | 530 | foreign import ccall "duckdb.h duckdb_create_config" 531 | duckdb_create_config 532 | :: Ptr DuckDBConfig -> IO DuckDBState 533 | 534 | foreign import ccall "duckdb.h duckdb_config_count" 535 | duckdb_config_count 536 | :: IO CSize 537 | 538 | foreign import ccall "duckdb.h duckdb_get_config_flag" 539 | duckdb_get_config_flag 540 | :: CSize -> Ptr CString -> Ptr CString -> IO DuckDBState 541 | 542 | foreign import ccall "duckdb.h duckdb_set_config" 543 | duckdb_set_config 544 | :: DuckDBConfig -> CString -> CString -> IO DuckDBState 545 | 546 | foreign import ccall "duckdb.h duckdb_destroy_config" 547 | duckdb_destroy_config 548 | :: Ptr DuckDBConfig -> IO () 549 | 550 | ----------------------------------------------------- 551 | -- Query Execution 552 | ----------------------------------------------------- 553 | 554 | foreign import ccall "duckdb.h duckdb_query" 555 | duckdb_query 556 | :: DuckDBConnection -> CString -> Ptr DuckDBResult -> IO DuckDBState 557 | 558 | foreign import ccall "duckdb.h duckdb_destroy_result" 559 | duckdb_destroy_result 560 | :: Ptr DuckDBResult -> IO () 561 | 562 | foreign import ccall "duckdb.h duckdb_column_name" 563 | duckdb_column_name 564 | :: Ptr DuckDBResult -> DuckDBIndexType -> IO CString 565 | 566 | foreign import ccall "duckdb.h duckdb_column_type" 567 | duckdb_column_type 568 | :: Ptr DuckDBResult -> DuckDBIndexType -> IO DuckDBType 569 | 570 | foreign import ccall "duckdb.h duckdb_column_logical_type" 571 | duckdb_column_logical_type 572 | :: Ptr DuckDBResult -> DuckDBIndexType -> IO DuckDBLogicalType 573 | 574 | foreign import ccall "duckdb.h duckdb_column_count" 575 | duckdb_column_count 576 | :: Ptr DuckDBResult -> IO DuckDBIndexType 577 | 578 | foreign import ccall "duckdb.h duckdb_row_count" 579 | duckdb_row_count 580 | :: Ptr DuckDBResult -> IO DuckDBIndexType 581 | 582 | foreign import ccall "duckdb.h duckdb_rows_changed" 583 | duckdb_rows_changed 584 | :: Ptr DuckDBResult -> IO DuckDBIndexType 585 | 586 | foreign import ccall "duckdb.h duckdb_column_data" 587 | duckdb_column_data 588 | :: Ptr DuckDBResult -> DuckDBIndexType -> IO (Ptr a) 589 | 590 | foreign import ccall "duckdb.h duckdb_nullmask_data" 591 | duckdb_nullmask_data 592 | :: Ptr DuckDBResult -> DuckDBIndexType -> IO (Ptr Bool) 593 | 594 | foreign import ccall "duckdb.h duckdb_result_error" 595 | duckdb_result_error 596 | :: Ptr DuckDBResult -> IO CString 597 | 598 | ----------------------------------------------------- 599 | -- Result Functions 600 | ----------------------------------------------------- 601 | 602 | foreign import ccall "duckdb.h duckdb_result_get_chunk_capi" 603 | duckdb_result_get_chunk 604 | :: Ptr DuckDBResult -> DuckDBIndexType -> IO DuckDBDataChunk 605 | 606 | foreign import ccall "duckdb.h duckdb_result_is_streaming_capi" 607 | duckdb_result_is_streaming 608 | :: Ptr DuckDBResult -> IO Bool 609 | 610 | foreign import ccall "duckdb.h duckdb_result_chunk_count_capi" 611 | duckdb_result_chunk_count 612 | :: Ptr DuckDBResult -> IO DuckDBIndexType 613 | 614 | foreign import ccall "duckdb.h duckdb_value_boolean" 615 | duckdb_value_boolean 616 | :: Ptr DuckDBResult -> DuckDBIndexType -> DuckDBIndexType -> IO Bool 617 | 618 | foreign import ccall "duckdb.h duckdb_value_int8" 619 | duckdb_value_int8 620 | :: Ptr DuckDBResult -> DuckDBIndexType -> DuckDBIndexType -> IO Int8 621 | 622 | foreign import ccall "duckdb.h duckdb_value_int16" 623 | duckdb_value_int16 624 | :: Ptr DuckDBResult -> DuckDBIndexType -> DuckDBIndexType -> IO Int16 625 | 626 | foreign import ccall "duckdb.h duckdb_value_int32" 627 | duckdb_value_int32 628 | :: Ptr DuckDBResult -> DuckDBIndexType -> DuckDBIndexType -> IO Int32 629 | 630 | foreign import ccall "duckdb.h duckdb_value_int64" 631 | duckdb_value_int64 632 | :: Ptr DuckDBResult -> DuckDBIndexType -> DuckDBIndexType -> IO Int64 633 | 634 | -- DUCKDB_API duckdb_hugeint duckdb_value_hugeint(duckdb_result *result, idx_t col, idx_t row); 635 | 636 | -- DUCKDB_API duckdb_decimal duckdb_value_decimal(duckdb_result *result, idx_t col, idx_t row); 637 | 638 | foreign import ccall "duckdb.h duckdb_value_uint8" 639 | duckdb_value_uint8 640 | :: Ptr DuckDBResult -> DuckDBIndexType -> DuckDBIndexType -> IO Word8 641 | 642 | foreign import ccall "duckdb.h duckdb_value_uint16" 643 | duckdb_value_uint16 644 | :: Ptr DuckDBResult -> DuckDBIndexType -> DuckDBIndexType -> IO Word16 645 | 646 | foreign import ccall "duckdb.h duckdb_value_uint32" 647 | duckdb_value_uint32 648 | :: Ptr DuckDBResult -> DuckDBIndexType -> DuckDBIndexType -> IO Word32 649 | 650 | foreign import ccall "duckdb.h duckdb_value_uint64" 651 | duckdb_value_uint64 652 | :: Ptr DuckDBResult -> DuckDBIndexType -> DuckDBIndexType -> IO Word64 653 | 654 | foreign import ccall "duckdb.h duckdb_value_float" 655 | duckdb_value_float 656 | :: Ptr DuckDBResult -> DuckDBIndexType -> DuckDBIndexType -> IO Float 657 | 658 | foreign import ccall "duckdb.h duckdb_value_double" 659 | duckdb_value_double 660 | :: Ptr DuckDBResult -> DuckDBIndexType -> DuckDBIndexType -> IO Double 661 | 662 | foreign import ccall "duckdb.h duckdb_value_date" 663 | duckdb_value_date 664 | :: Ptr DuckDBResult -> DuckDBIndexType -> DuckDBIndexType -> IO DuckDBDate 665 | 666 | foreign import ccall "duckdb.h duckdb_value_time" 667 | duckdb_value_time 668 | :: Ptr DuckDBResult -> DuckDBIndexType -> DuckDBIndexType -> IO DuckDBTime 669 | 670 | foreign import ccall "duckdb.h duckdb_value_timestamp" 671 | duckdb_value_timestamp 672 | :: Ptr DuckDBResult -> DuckDBIndexType -> DuckDBIndexType -> IO DuckDBTimestamp 673 | 674 | -- DUCKDB_API duckdb_interval duckdb_value_interval(duckdb_result *result, idx_t col, idx_t row); 675 | 676 | foreign import ccall "duckdb.h duckdb_value_varchar" 677 | duckdb_value_varchar 678 | :: Ptr DuckDBResult -> DuckDBIndexType -> DuckDBIndexType -> IO CString 679 | 680 | -- DUCKDB_API duckdb_string duckdb_value_string(duckdb_result *result, idx_t col, idx_t row); 681 | 682 | foreign import ccall "duckdb.h duckdb_value_varchar_internal" 683 | duckdb_value_varchar_internal 684 | :: Ptr DuckDBResult -> DuckDBIndexType -> DuckDBIndexType -> IO CString 685 | 686 | -- DUCKDB_API duckdb_string duckdb_value_string_internal(duckdb_result *result, idx_t col, idx_t row); 687 | 688 | -- DUCKDB_API duckdb_blob duckdb_value_blob(duckdb_result *result, idx_t col, idx_t row); 689 | 690 | foreign import ccall "duckdb.h duckdb_value_is_null" 691 | duckdb_value_is_null 692 | :: Ptr DuckDBResult -> DuckDBIndexType -> DuckDBIndexType -> IO Bool 693 | 694 | ----------------------------------------------------- 695 | -- Helpers 696 | ----------------------------------------------------- 697 | 698 | foreign import ccall "duckdb.h duckdb_malloc" 699 | duckdb_malloc 700 | :: CSize -> IO (Ptr a) 701 | 702 | foreign import ccall "duckdb.h duckdb_free" 703 | duckdb_free 704 | :: Ptr a -> IO () 705 | 706 | foreign import ccall "duckdb.h duckdb_vector_size" 707 | duckdb_vector_size 708 | :: IO DuckDBIndexType 709 | 710 | -- DUCKDB_API bool duckdb_string_is_inlined(duckdb_string_t string); 711 | 712 | ----------------------------------------------------- 713 | -- Date/Time/Timestamp Helpers 714 | ----------------------------------------------------- 715 | 716 | -- DUCKDB_API duckdb_date_struct duckdb_from_date(duckdb_date date); 717 | 718 | -- DUCKDB_API duckdb_date duckdb_to_date(duckdb_date_struct date); 719 | 720 | -- DUCKDB_API duckdb_time_struct duckdb_from_time(duckdb_time time); 721 | 722 | -- DUCKDB_API duckdb_time duckdb_to_time(duckdb_time_struct time); 723 | 724 | -- DUCKDB_API duckdb_timestamp_struct duckdb_from_timestamp(duckdb_timestamp ts); 725 | 726 | -- DUCKDB_API duckdb_timestamp duckdb_to_timestamp(duckdb_timestamp_struct ts); 727 | 728 | ----------------------------------------------------- 729 | -- Hugeint Helpers 730 | ----------------------------------------------------- 731 | 732 | -- DUCKDB_API double duckdb_hugeint_to_double(duckdb_hugeint val); 733 | 734 | -- DUCKDB_API duckdb_hugeint duckdb_double_to_hugeint(double val); 735 | 736 | ----------------------------------------------------- 737 | -- Decimal Helpers 738 | ----------------------------------------------------- 739 | 740 | -- DUCKDB_API duckdb_decimal duckdb_double_to_decimal(double val, uint8_t width, uint8_t scale); 741 | 742 | -- DUCKDB_API double duckdb_decimal_to_double(duckdb_decimal val); 743 | 744 | ----------------------------------------------------- 745 | -- Prepared Statements 746 | ----------------------------------------------------- 747 | 748 | foreign import ccall "duckdb.h duckdb_prepare" 749 | duckdb_prepare 750 | :: DuckDBConnection -> CString -> Ptr DuckDBPreparedStatement -> IO DuckDBState 751 | 752 | foreign import ccall "duckdb.h duckdb_destroy_prepare" 753 | duckdb_destroy_prepare 754 | :: Ptr DuckDBPreparedStatement -> IO () 755 | 756 | foreign import ccall "duckdb.h duckdb_prepare_error" 757 | duckdb_prepare_error 758 | :: DuckDBPreparedStatement -> IO CString 759 | 760 | foreign import ccall "duckdb.h duckdb_nparams" 761 | duckdb_nparams 762 | :: DuckDBPreparedStatement -> IO DuckDBIndexType 763 | 764 | foreign import ccall "duckdb.h duckdb_param_type" 765 | duckdb_param_type 766 | :: DuckDBPreparedStatement -> DuckDBIndexType -> IO DuckDBType 767 | 768 | foreign import ccall "duckdb.h duckdb_clear_bindings" 769 | duckdb_clear_bindings 770 | :: DuckDBPreparedStatement -> IO DuckDBState 771 | 772 | foreign import ccall "duckdb.h duckdb_bind_boolean" 773 | duckdb_bind_boolean 774 | :: DuckDBPreparedStatement -> DuckDBIndexType -> Bool -> IO DuckDBState 775 | 776 | foreign import ccall "duckdb.h duckdb_bind_int8" 777 | duckdb_bind_int8 778 | :: DuckDBPreparedStatement -> DuckDBIndexType -> Int8 -> IO DuckDBState 779 | 780 | foreign import ccall "duckdb.h duckdb_bind_int16" 781 | duckdb_bind_int16 782 | :: DuckDBPreparedStatement -> DuckDBIndexType -> Int16 -> IO DuckDBState 783 | 784 | foreign import ccall "duckdb.h duckdb_bind_int32" 785 | duckdb_bind_int32 786 | :: DuckDBPreparedStatement -> DuckDBIndexType -> Int32 -> IO DuckDBState 787 | 788 | foreign import ccall "duckdb.h duckdb_bind_int64" 789 | duckdb_bind_int64 790 | :: DuckDBPreparedStatement -> DuckDBIndexType -> Int64 -> IO DuckDBState 791 | 792 | -- DUCKDB_API duckdb_state duckdb_bind_hugeint(duckdb_prepared_statement prepared_statement, idx_t param_idx, 793 | -- duckdb_hugeint val); 794 | 795 | -- DUCKDB_API duckdb_state duckdb_bind_decimal(duckdb_prepared_statement prepared_statement, idx_t param_idx, 796 | -- duckdb_decimal val); 797 | 798 | foreign import ccall "duckdb.h duckdb_bind_uint8" 799 | duckdb_bind_uint8 800 | :: DuckDBPreparedStatement -> DuckDBIndexType -> Word8 -> IO DuckDBState 801 | 802 | foreign import ccall "duckdb.h duckdb_bind_uint16" 803 | duckdb_bind_uint16 804 | :: DuckDBPreparedStatement -> DuckDBIndexType -> Word16 -> IO DuckDBState 805 | 806 | foreign import ccall "duckdb.h duckdb_bind_uint32" 807 | duckdb_bind_uint32 808 | :: DuckDBPreparedStatement -> DuckDBIndexType -> Word32 -> IO DuckDBState 809 | 810 | foreign import ccall "duckdb.h duckdb_bind_uint64" 811 | duckdb_bind_uint64 812 | :: DuckDBPreparedStatement -> DuckDBIndexType -> Word64 -> IO DuckDBState 813 | 814 | foreign import ccall "duckdb.h duckdb_bind_float" 815 | duckdb_bind_float 816 | :: DuckDBPreparedStatement -> DuckDBIndexType -> Float -> IO DuckDBState 817 | 818 | foreign import ccall "duckdb.h duckdb_bind_double" 819 | duckdb_bind_double 820 | :: DuckDBPreparedStatement -> DuckDBIndexType -> Double -> IO DuckDBState 821 | 822 | foreign import ccall "duckdb.h duckdb_bind_date" 823 | duckdb_bind_date 824 | :: DuckDBPreparedStatement -> DuckDBIndexType -> DuckDBDate -> IO DuckDBState 825 | 826 | foreign import ccall "duckdb.h duckdb_bind_time" 827 | duckdb_bind_time 828 | :: DuckDBPreparedStatement -> DuckDBIndexType -> DuckDBTime -> IO DuckDBState 829 | 830 | foreign import ccall "duckdb.h duckdb_bind_timestamp" 831 | duckdb_bind_timestamp 832 | :: DuckDBPreparedStatement -> DuckDBIndexType -> DuckDBTimestamp -> IO DuckDBState 833 | 834 | -- DUCKDB_API duckdb_state duckdb_bind_interval(duckdb_prepared_statement prepared_statement, idx_t param_idx, 835 | -- duckdb_interval val); 836 | 837 | foreign import ccall "duckdb.h duckdb_bind_varchar" 838 | duckdb_bind_varchar 839 | :: DuckDBPreparedStatement -> DuckDBIndexType -> CString -> IO DuckDBState 840 | 841 | foreign import ccall "duckdb.h duckdb_bind_varchar_length" 842 | duckdb_bind_varchar_length 843 | :: DuckDBPreparedStatement 844 | -> DuckDBIndexType 845 | -> CString 846 | -> DuckDBIndexType 847 | -> IO DuckDBState 848 | 849 | foreign import ccall "duckdb.h duckdb_bind_blob" 850 | duckdb_bind_blob 851 | :: DuckDBPreparedStatement 852 | -> DuckDBIndexType 853 | -> Ptr () 854 | -> DuckDBIndexType 855 | -> IO DuckDBState 856 | 857 | foreign import ccall "duckdb.h duckdb_bind_null" 858 | duckdb_bind_null 859 | :: DuckDBPreparedStatement -> DuckDBIndexType -> IO DuckDBState 860 | 861 | foreign import ccall "duckdb.h duckdb_execute_prepared" 862 | duckdb_execute_prepared 863 | :: DuckDBPreparedStatement -> Ptr DuckDBResult -> IO DuckDBState 864 | 865 | foreign import ccall "duckdb.h duckdb_execute_prepared_arrow" 866 | duckdb_execute_prepared_arrow 867 | :: DuckDBPreparedStatement -> Ptr DuckDBArrow -> IO DuckDBState 868 | 869 | ----------------------------------------------------- 870 | -- Extract Statements 871 | ----------------------------------------------------- 872 | 873 | foreign import ccall "duckdb.h duckdb_extract_statements" 874 | duckdb_extract_statements 875 | :: DuckDBConnection 876 | -> CString 877 | -> Ptr DuckDBExtractedStatements 878 | -> IO DuckDBIndexType 879 | 880 | foreign import ccall "duckdb.h duckdb_prepare_extracted_statement" 881 | duckdb_prepare_extracted_statement 882 | :: DuckDBConnection 883 | -> DuckDBExtractedStatements 884 | -> DuckDBIndexType 885 | -> Ptr DuckDBPreparedStatement 886 | -> IO DuckDBState 887 | 888 | foreign import ccall "duckdb.h duckdb_extract_statements_error" 889 | duckdb_extract_statements_error 890 | :: DuckDBExtractedStatements -> IO CString 891 | 892 | foreign import ccall "duckdb.h duckdb_destroy_extracted" 893 | duckdb_destroy_extracted 894 | :: Ptr DuckDBExtractedStatements -> IO () 895 | 896 | ----------------------------------------------------- 897 | -- Pending Result Interface 898 | ----------------------------------------------------- 899 | 900 | foreign import ccall "duckdb.h duckdb_pending_prepared" 901 | duckdb_pending_prepared 902 | :: DuckDBPreparedStatement -> Ptr DuckDBPendingResult -> IO DuckDBState 903 | 904 | foreign import ccall "duckdb.h duckdb_pending_prepared_streaming" 905 | duckdb_pending_prepared_streaming 906 | :: DuckDBPreparedStatement -> Ptr DuckDBPendingResult -> IO DuckDBState 907 | 908 | foreign import ccall "duckdb.h duckdb_destroy_pending" 909 | duckdb_destroy_pending 910 | :: Ptr DuckDBPendingResult -> IO () 911 | 912 | foreign import ccall "duckdb.h duckdb_pending_error" 913 | duckdb_pending_error 914 | :: DuckDBPendingResult -> IO CString 915 | 916 | foreign import ccall "duckdb.h duckdb_pending_execute_task" 917 | duckdb_pending_execute_task 918 | :: DuckDBPendingResult -> IO DuckDBPendingState 919 | 920 | foreign import ccall "duckdb.h duckdb_execute_pending" 921 | duckdb_execute_pending 922 | :: DuckDBPendingResult -> Ptr DuckDBResult -> IO DuckDBState 923 | 924 | ----------------------------------------------------- 925 | -- Value Interface 926 | ----------------------------------------------------- 927 | 928 | foreign import ccall "duckdb.h duckdb_destroy_value" 929 | duckdb_destroy_value 930 | :: Ptr DuckDBValue -> IO () 931 | 932 | foreign import ccall "duckdb.h duckdb_create_varchar" 933 | duckdb_create_varchar 934 | :: CString -> IO DuckDBValue 935 | 936 | foreign import ccall "duckdb.h duckdb_create_varchar_length" 937 | duckdb_create_varchar_length 938 | :: CString -> DuckDBIndexType -> IO DuckDBValue 939 | 940 | foreign import ccall "duckdb.h duckdb_create_int64" 941 | duckdb_create_int64 942 | :: Int64 -> IO DuckDBValue 943 | 944 | foreign import ccall "duckdb.h duckdb_get_varchar" 945 | duckdb_get_varchar 946 | :: DuckDBValue -> IO CString 947 | 948 | foreign import ccall "duckdb.h duckdb_get_int64" 949 | duckdb_get_int64 950 | :: DuckDBValue -> IO Int64 951 | 952 | ----------------------------------------------------- 953 | -- Logical Type Interface 954 | ----------------------------------------------------- 955 | 956 | foreign import ccall "duckdb.h duckdb_create_logical_type" 957 | duckdb_create_logical_type 958 | :: DuckDBType -> IO DuckDBLogicalType 959 | 960 | foreign import ccall "duckdb.h duckdb_create_list_type" 961 | duckdb_create_list_type 962 | :: DuckDBLogicalType -> IO DuckDBLogicalType 963 | 964 | foreign import ccall "duckdb.h duckdb_create_map_type" 965 | duckdb_create_map_type 966 | :: DuckDBLogicalType -> DuckDBLogicalType -> IO DuckDBLogicalType 967 | 968 | foreign import ccall "duckdb.h duckdb_create_union_type" 969 | duckdb_create_union_type 970 | :: Ptr DuckDBLogicalType -> Ptr CString -> DuckDBIndexType -> IO DuckDBLogicalType 971 | 972 | foreign import ccall "duckdb.h duckdb_create_decimal_type" 973 | duckdb_create_decimal_type 974 | :: Word8 -> Word8 -> IO DuckDBLogicalType 975 | 976 | foreign import ccall "duckdb.h duckdb_get_type_id" 977 | duckdb_get_type_id 978 | :: DuckDBLogicalType -> IO DuckDBType 979 | 980 | foreign import ccall "duckdb.h duckdb_decimal_width" 981 | duckdb_decimal_width 982 | :: DuckDBLogicalType -> IO Word8 983 | 984 | foreign import ccall "duckdb.h duckdb_decimal_scale" 985 | duckdb_decimal_scale 986 | :: DuckDBLogicalType -> IO Word8 987 | 988 | foreign import ccall "duckdb.h duckdb_decimal_internal_type" 989 | duckdb_decimal_internal_type 990 | :: DuckDBLogicalType -> IO DuckDBType 991 | 992 | foreign import ccall "duckdb.h duckdb_enum_internal_type" 993 | duckdb_enum_internal_type 994 | :: DuckDBLogicalType -> IO DuckDBType 995 | 996 | foreign import ccall "duckdb.h duckdb_enum_dictionary_size" 997 | duckdb_enum_dictionary_size 998 | :: DuckDBLogicalType -> IO Word32 999 | 1000 | foreign import ccall "duckdb.h duckdb_enum_dictionary_value" 1001 | duckdb_enum_dictionary_value 1002 | :: DuckDBLogicalType -> DuckDBIndexType -> IO CString 1003 | 1004 | foreign import ccall "duckdb.h duckdb_list_type_child_type" 1005 | duckdb_list_type_child_type 1006 | :: DuckDBLogicalType -> IO DuckDBLogicalType 1007 | 1008 | foreign import ccall "duckdb.h duckdb_map_type_key_type" 1009 | duckdb_map_type_key_type 1010 | :: DuckDBLogicalType -> IO DuckDBLogicalType 1011 | 1012 | foreign import ccall "duckdb.h duckdb_map_type_value_type" 1013 | duckdb_map_type_value_type 1014 | :: DuckDBLogicalType -> IO DuckDBLogicalType 1015 | 1016 | foreign import ccall "duckdb.h duckdb_struct_type_child_count" 1017 | duckdb_struct_type_child_count 1018 | :: DuckDBLogicalType -> IO DuckDBIndexType 1019 | 1020 | foreign import ccall "duckdb.h duckdb_struct_type_child_name" 1021 | duckdb_struct_type_child_name 1022 | :: DuckDBLogicalType -> DuckDBIndexType -> IO CString 1023 | 1024 | foreign import ccall "duckdb.h duckdb_struct_type_child_type" 1025 | duckdb_struct_type_child_type 1026 | :: DuckDBLogicalType -> DuckDBIndexType -> IO DuckDBLogicalType 1027 | 1028 | foreign import ccall "duckdb.h duckdb_union_type_member_count" 1029 | duckdb_union_type_member_count 1030 | :: DuckDBLogicalType -> IO DuckDBIndexType 1031 | 1032 | foreign import ccall "duckdb.h duckdb_union_type_member_name" 1033 | duckdb_union_type_member_name 1034 | :: DuckDBLogicalType -> DuckDBIndexType -> IO CString 1035 | 1036 | foreign import ccall "duckdb.h duckdb_union_type_member_type" 1037 | duckdb_union_type_member_type 1038 | :: DuckDBLogicalType -> DuckDBIndexType -> IO DuckDBLogicalType 1039 | 1040 | foreign import ccall "duckdb.h duckdb_destroy_logical_type" 1041 | duckdb_destroy_logical_type 1042 | :: Ptr DuckDBLogicalType -> IO () 1043 | 1044 | ----------------------------------------------------- 1045 | -- Data Chunk Interface 1046 | ----------------------------------------------------- 1047 | 1048 | foreign import ccall "duckdb.h duckdb_create_data_chunk" 1049 | duckdb_create_data_chunk 1050 | :: Ptr DuckDBLogicalType -> DuckDBIndexType -> IO DuckDBDataChunk 1051 | 1052 | foreign import ccall "duckdb.h duckdb_destroy_data_chunk" 1053 | duckdb_destroy_data_chunk 1054 | :: Ptr DuckDBDataChunk -> IO () 1055 | 1056 | foreign import ccall "duckdb.h duckdb_data_chunk_reset" 1057 | duckdb_data_chunk_reset 1058 | :: DuckDBDataChunk -> IO () 1059 | 1060 | foreign import ccall "duckdb.h duckdb_data_chunk_get_column_count" 1061 | duckdb_data_chunk_get_column_count 1062 | :: DuckDBDataChunk -> IO DuckDBIndexType 1063 | 1064 | foreign import ccall "duckdb.h duckdb_data_chunk_get_vector" 1065 | duckdb_data_chunk_get_vector 1066 | :: DuckDBDataChunk -> DuckDBIndexType -> IO DuckDBVector 1067 | 1068 | foreign import ccall "duckdb.h duckdb_data_chunk_get_size" 1069 | duckdb_data_chunk_get_size 1070 | :: DuckDBDataChunk -> IO DuckDBIndexType 1071 | 1072 | foreign import ccall "duckdb.h duckdb_data_chunk_set_size" 1073 | duckdb_data_chunk_set_size 1074 | :: DuckDBDataChunk -> DuckDBIndexType -> IO () 1075 | 1076 | ----------------------------------------------------- 1077 | -- Vector Interface 1078 | ----------------------------------------------------- 1079 | foreign import ccall "duckdb.h duckdb_vector_get_column_type" 1080 | duckdb_vector_get_column_type 1081 | :: DuckDBVector -> IO DuckDBLogicalType 1082 | 1083 | foreign import ccall "duckdb.h duckdb_vector_get_data" 1084 | duckdb_vector_get_data 1085 | :: DuckDBVector -> IO (Ptr a) 1086 | 1087 | foreign import ccall "duckdb.h duckdb_vector_get_validity" 1088 | duckdb_vector_get_validity 1089 | :: DuckDBVector -> IO (Ptr Word64) 1090 | 1091 | foreign import ccall "duckdb.h duckdb_vector_ensure_validity_writable" 1092 | duckdb_vector_ensure_validity_writable 1093 | :: DuckDBVector -> IO () 1094 | 1095 | foreign import ccall "duckdb.h duckdb_vector_assign_string_element" 1096 | duckdb_vector_assign_string_element 1097 | :: DuckDBVector -> DuckDBIndexType -> CString -> IO () 1098 | 1099 | foreign import ccall "duckdb.h duckdb_vector_assign_string_element_len" 1100 | duckdb_vector_assign_string_element_len 1101 | :: DuckDBVector -> DuckDBIndexType -> CString -> DuckDBIndexType -> IO () 1102 | 1103 | foreign import ccall "duckdb.h duckdb_list_vector_get_child" 1104 | duckdb_list_vector_get_child 1105 | :: DuckDBVector -> IO DuckDBVector 1106 | 1107 | foreign import ccall "duckdb.h duckdb_list_vector_get_size" 1108 | duckdb_list_vector_get_size 1109 | :: DuckDBVector -> IO DuckDBIndexType 1110 | 1111 | foreign import ccall "duckdb.h duckdb_list_vector_set_size" 1112 | duckdb_list_vector_set_size 1113 | :: DuckDBVector -> DuckDBIndexType -> IO DuckDBState 1114 | 1115 | foreign import ccall "duckdb.h duckdb_list_vector_reserve" 1116 | duckdb_list_vector_reserve 1117 | :: DuckDBVector -> DuckDBIndexType -> IO DuckDBState 1118 | 1119 | foreign import ccall "duckdb.h duckdb_struct_vector_get_child" 1120 | duckdb_struct_vector_get_child 1121 | :: DuckDBVector -> DuckDBIndexType -> IO DuckDBVector 1122 | 1123 | ----------------------------------------------------- 1124 | -- Validity Mask Functions 1125 | ----------------------------------------------------- 1126 | foreign import ccall "duckdb.h duckdb_validity_row_is_valid" 1127 | duckdb_validity_row_is_valid 1128 | :: Ptr Word64 -> DuckDBIndexType -> IO Bool 1129 | 1130 | foreign import ccall "duckdb.h duckdb_validity_set_row_validity" 1131 | duckdb_validity_set_row_validity 1132 | :: Ptr Word64 -> DuckDBIndexType -> Bool -> IO () 1133 | 1134 | foreign import ccall "duckdb.h duckdb_validity_set_row_invalid" 1135 | duckdb_validity_set_row_invalid 1136 | :: Ptr Word64 -> DuckDBIndexType -> IO () 1137 | 1138 | foreign import ccall "duckdb.h duckdb_validity_set_row_valid" 1139 | duckdb_validity_set_row_valid 1140 | :: Ptr Word64 -> DuckDBIndexType -> IO () 1141 | 1142 | ----------------------------------------------------- 1143 | -- Table Functions 1144 | ----------------------------------------------------- 1145 | 1146 | newtype DuckDBTableFunction = DuckDBTableFunction (Ptr ()) 1147 | deriving (Eq, Storable) 1148 | 1149 | newtype DuckDBBindInfo = DuckDBBindInfo (Ptr ()) deriving (Eq, Storable) 1150 | 1151 | newtype DuckDBInitInfo = DuckDBInitInfo (Ptr ()) deriving (Eq, Storable) 1152 | 1153 | newtype DuckDBFunctionInfo = DuckDBFunctionInfo (Ptr ()) deriving (Eq, Storable) 1154 | 1155 | type DuckDBTableFunctionBindFunc = FunPtr (DuckDBBindInfo -> IO ()) 1156 | 1157 | type DuckDBTableFunctionInitFunc = FunPtr (DuckDBInitInfo -> IO ()) 1158 | 1159 | type DuckDBTableFunctionFunc = 1160 | FunPtr (DuckDBFunctionInfo -> DuckDBDataChunk -> IO ()) 1161 | 1162 | type DuckDBDeleteCallbackFunc = FunPtr (Ptr () -> IO ()) 1163 | 1164 | foreign import ccall "duckdb.h duckdb_create_table_function" 1165 | duckdb_create_table_function 1166 | :: IO DuckDBTableFunction 1167 | 1168 | foreign import ccall "duckdb.h duckdb_destroy_table_function" 1169 | duckdb_destroy_table_function 1170 | :: DuckDBTableFunction -> IO () 1171 | 1172 | foreign import ccall "duckdb.h duckdb_table_function_set_name" 1173 | duckdb_table_function_set_name 1174 | :: DuckDBTableFunction -> CString -> IO () 1175 | 1176 | foreign import ccall "duckdb.h duckdb_table_function_add_parameter" 1177 | duckdb_table_function_add_parameter 1178 | :: DuckDBTableFunction -> DuckDBLogicalType -> IO () 1179 | 1180 | foreign import ccall "duckdb.h duckdb_table_function_add_named_parameter" 1181 | duckdb_table_function_add_named_parameter 1182 | :: DuckDBTableFunction -> CString -> DuckDBLogicalType -> IO () 1183 | 1184 | foreign import ccall "duckdb.h duckdb_table_function_set_extra_info" 1185 | duckdb_table_function_set_extra_info 1186 | :: DuckDBTableFunction -> Ptr () -> DuckDBDeleteCallbackFunc -> IO () 1187 | 1188 | foreign import ccall "duckdb.h duckdb_table_function_set_bind" 1189 | duckdb_table_function_set_bind 1190 | :: DuckDBTableFunction -> DuckDBTableFunctionBindFunc -> IO () 1191 | 1192 | foreign import ccall "duckdb.h duckdb_table_function_set_init" 1193 | duckdb_table_function_set_init 1194 | :: DuckDBTableFunction -> DuckDBTableFunctionInitFunc -> IO () 1195 | 1196 | foreign import ccall "duckdb.h duckdb_table_function_set_local_init" 1197 | duckdb_table_function_set_local_init 1198 | :: DuckDBTableFunction -> DuckDBTableFunctionInitFunc -> IO () 1199 | 1200 | foreign import ccall "duckdb.h duckdb_table_function_set_function" 1201 | duckdb_table_function_set_function 1202 | :: DuckDBTableFunction -> DuckDBTableFunctionFunc -> IO () 1203 | 1204 | foreign import ccall "duckdb.h duckdb_table_function_supports_projection_pushdown" 1205 | duckdb_table_function_supports_projection_pushdown 1206 | :: DuckDBTableFunction -> Bool -> IO () 1207 | 1208 | foreign import ccall "duckdb.h duckdb_register_table_function" 1209 | duckdb_register_table_function 1210 | :: DuckDBConnection -> DuckDBTableFunction -> IO DuckDBState 1211 | 1212 | ----------------------------------------------------- 1213 | -- Table Function Bind 1214 | ----------------------------------------------------- 1215 | 1216 | foreign import ccall "duckdb.h duckdb_bind_get_extra_info" 1217 | duckdb_bind_get_extra_info 1218 | :: DuckDBBindInfo -> IO (Ptr ()) 1219 | 1220 | foreign import ccall "duckdb.h duckdb_bind_add_result_column" 1221 | duckdb_bind_add_result_column 1222 | :: DuckDBBindInfo -> CString -> DuckDBLogicalType -> IO () 1223 | 1224 | foreign import ccall "duckdb.h duckdb_bind_get_parameter_count" 1225 | duckdb_bind_get_parameter_count 1226 | :: DuckDBBindInfo -> IO DuckDBIndexType 1227 | 1228 | foreign import ccall "duckdb.h duckdb_bind_get_parameter" 1229 | duckdb_bind_get_parameter 1230 | :: DuckDBBindInfo -> DuckDBIndexType -> IO DuckDBValue 1231 | 1232 | foreign import ccall "duckdb.h duckdb_bind_get_named_parameter" 1233 | duckdb_bind_get_named_parameter 1234 | :: DuckDBBindInfo -> CString -> IO DuckDBValue 1235 | 1236 | foreign import ccall "duckdb.h duckdb_bind_set_bind_data" 1237 | duckdb_bind_set_bind_data 1238 | :: DuckDBBindInfo -> Ptr () -> DuckDBDeleteCallbackFunc -> IO () 1239 | 1240 | foreign import ccall "duckdb.h duckdb_bind_set_cardinality" 1241 | duckdb_bind_set_cardinality 1242 | :: DuckDBBindInfo -> DuckDBIndexType -> Bool -> IO () 1243 | 1244 | foreign import ccall "duckdb.h duckdb_bind_set_error" 1245 | duckdb_bind_set_error 1246 | :: DuckDBBindInfo -> CString -> IO () 1247 | 1248 | ----------------------------------------------------- 1249 | -- Table Function Init 1250 | ----------------------------------------------------- 1251 | 1252 | foreign import ccall "duckdb.h duckdb_init_get_extra_info" 1253 | duckdb_init_get_extra_info 1254 | :: DuckDBInitInfo -> IO (Ptr ()) 1255 | 1256 | foreign import ccall "duckdb.h duckdb_init_get_bind_data" 1257 | duckdb_init_get_bind_data 1258 | :: DuckDBInitInfo -> IO (Ptr ()) 1259 | 1260 | foreign import ccall "duckdb.h duckdb_init_set_init_data" 1261 | duckdb_init_set_init_data 1262 | :: DuckDBInitInfo -> Ptr () -> DuckDBDeleteCallbackFunc -> IO () 1263 | 1264 | foreign import ccall "duckdb.h duckdb_init_get_column_count" 1265 | duckdb_init_get_column_count 1266 | :: DuckDBInitInfo -> IO DuckDBIndexType 1267 | 1268 | foreign import ccall "duckdb.h duckdb_init_get_column_index" 1269 | duckdb_init_get_column_index 1270 | :: DuckDBInitInfo -> DuckDBIndexType -> IO DuckDBIndexType 1271 | 1272 | foreign import ccall "duckdb.h duckdb_init_set_max_threads" 1273 | duckdb_init_set_max_threads 1274 | :: DuckDBInitInfo -> DuckDBIndexType -> IO () 1275 | 1276 | foreign import ccall "duckdb.h duckdb_init_set_error" 1277 | duckdb_init_set_error 1278 | :: DuckDBInitInfo -> CString -> IO () 1279 | 1280 | ----------------------------------------------------- 1281 | -- Table Function 1282 | ----------------------------------------------------- 1283 | 1284 | foreign import ccall "duckdb.h duckdb_function_get_extra_info" 1285 | duckdb_function_get_extra_info 1286 | :: DuckDBFunctionInfo -> IO (Ptr ()) 1287 | 1288 | foreign import ccall "duckdb.h duckdb_function_get_bind_data" 1289 | duckdb_function_get_bind_data 1290 | :: DuckDBFunctionInfo -> IO (Ptr ()) 1291 | 1292 | foreign import ccall "duckdb.h duckdb_function_get_init_data" 1293 | duckdb_function_get_init_data 1294 | :: DuckDBFunctionInfo -> IO (Ptr ()) 1295 | 1296 | foreign import ccall "duckdb.h duckdb_function_get_local_init_data" 1297 | duckdb_function_get_local_init_data 1298 | :: DuckDBFunctionInfo -> IO (Ptr ()) 1299 | 1300 | foreign import ccall "duckdb.h duckdb_function_set_error" 1301 | duckdb_function_set_error 1302 | :: DuckDBFunctionInfo -> CString -> IO () 1303 | 1304 | ----------------------------------------------------- 1305 | -- Replacement Scans 1306 | ----------------------------------------------------- 1307 | 1308 | newtype DuckDBReplacementScanInfo = DuckDBReplacementScanInfo (Ptr ()) 1309 | deriving (Eq, Storable) 1310 | 1311 | type DuckDBReplacementCallbackFunc = 1312 | FunPtr (DuckDBReplacementScanInfo -> CString -> Ptr () -> IO ()) 1313 | 1314 | foreign import ccall "duckdb.h duckdb_add_replacement_scan" 1315 | duckdb_add_replacement_scan 1316 | :: DuckDBDatabase 1317 | -> DuckDBReplacementCallbackFunc 1318 | -> Ptr () 1319 | -> DuckDBDeleteCallbackFunc 1320 | -> IO () 1321 | 1322 | foreign import ccall "duckdb.h duckdb_replacement_scan_set_function_name" 1323 | duckdb_replacement_scan_set_function_name 1324 | :: DuckDBReplacementScanInfo -> CString -> IO () 1325 | 1326 | foreign import ccall "duckdb.h duckdb_replacement_scan_add_parameter" 1327 | duckdb_replacement_scan_add_parameter 1328 | :: DuckDBReplacementScanInfo -> DuckDBValue -> IO () 1329 | 1330 | foreign import ccall "duckdb.h duckdb_replacement_scan_set_error" 1331 | duckdb_replacement_scan_set_error 1332 | :: DuckDBReplacementScanInfo -> CString -> IO () 1333 | 1334 | ----------------------------------------------------- 1335 | -- Appender 1336 | ----------------------------------------------------- 1337 | 1338 | foreign import ccall "duckdb.h duckdb_appender_create" 1339 | duckdb_appender_create 1340 | :: DuckDBConnection 1341 | -> CString 1342 | -> CString 1343 | -> Ptr DuckDBAppender 1344 | -> IO DuckDBState 1345 | 1346 | foreign import ccall "duckdb.h duckdb_appender_error" 1347 | duckdb_appender_error 1348 | :: DuckDBAppender -> IO CString 1349 | 1350 | foreign import ccall "duckdb.h duckdb_appender_flush" 1351 | duckdb_appender_flush 1352 | :: DuckDBAppender -> IO DuckDBState 1353 | 1354 | foreign import ccall "duckdb.h duckdb_appender_close" 1355 | duckdb_appender_close 1356 | :: DuckDBAppender -> IO DuckDBState 1357 | 1358 | foreign import ccall "duckdb.h duckdb_appender_destroy" 1359 | duckdb_appender_destroy 1360 | :: Ptr DuckDBAppender -> IO DuckDBState 1361 | 1362 | foreign import ccall "duckdb.h duckdb_appender_begin_row" 1363 | duckdb_appender_begin_row :: DuckDBAppender -> IO DuckDBState 1364 | 1365 | foreign import ccall "duckdb.h duckdb_appender_end_row" 1366 | duckdb_appender_end_row :: DuckDBAppender -> IO DuckDBState 1367 | 1368 | foreign import ccall "duckdb.h duckdb_append_bool" 1369 | duckdb_append_bool :: DuckDBAppender -> Bool -> IO DuckDBState 1370 | 1371 | foreign import ccall "duckdb.h duckdb_append_int8" 1372 | duckdb_append_int8 :: DuckDBAppender -> Int8 -> IO DuckDBState 1373 | 1374 | foreign import ccall "duckdb.h duckdb_append_int16" 1375 | duckdb_append_int16 :: DuckDBAppender -> Int16 -> IO DuckDBState 1376 | 1377 | foreign import ccall "duckdb.h duckdb_append_int32" 1378 | duckdb_append_int32 :: DuckDBAppender -> Int32 -> IO DuckDBState 1379 | 1380 | foreign import ccall "duckdb.h duckdb_append_int64" 1381 | duckdb_append_int64 :: DuckDBAppender -> Int64 -> IO DuckDBState 1382 | 1383 | -- DUCKDB_API duckdb_state duckdb_append_hugeint(duckdb_appender appender, duckdb_hugeint value); 1384 | 1385 | foreign import ccall "duckdb.h duckdb_append_uint8" 1386 | duckdb_append_uint8 :: DuckDBAppender -> Word8 -> IO DuckDBState 1387 | 1388 | foreign import ccall "duckdb.h duckdb_append_uint16" 1389 | duckdb_append_uint16 :: DuckDBAppender -> Word16 -> IO DuckDBState 1390 | 1391 | foreign import ccall "duckdb.h duckdb_append_uint32" 1392 | duckdb_append_uint32 :: DuckDBAppender -> Word32 -> IO DuckDBState 1393 | 1394 | foreign import ccall "duckdb.h duckdb_append_uint64" 1395 | duckdb_append_uint64 :: DuckDBAppender -> Word64 -> IO DuckDBState 1396 | 1397 | foreign import ccall "duckdb.h duckdb_append_float" 1398 | duckdb_append_float :: DuckDBAppender -> Float -> IO DuckDBState 1399 | 1400 | foreign import ccall "duckdb.h duckdb_append_double" 1401 | duckdb_append_double :: DuckDBAppender -> Double -> IO DuckDBState 1402 | 1403 | foreign import ccall "duckdb.h duckdb_append_date" 1404 | duckdb_append_date :: DuckDBAppender -> DuckDBDate -> IO DuckDBState 1405 | 1406 | foreign import ccall "duckdb.h duckdb_append_time" 1407 | duckdb_append_time :: DuckDBAppender -> DuckDBTime -> IO DuckDBState 1408 | 1409 | foreign import ccall "duckdb.h duckdb_append_timestamp" 1410 | duckdb_append_timestamp :: DuckDBAppender -> DuckDBTimestamp -> IO DuckDBState 1411 | 1412 | -- DUCKDB_API duckdb_state duckdb_append_interval(duckdb_appender appender, duckdb_interval value); 1413 | 1414 | foreign import ccall "duckdb.h duckdb_append_varchar" 1415 | duckdb_append_varchar :: DuckDBAppender -> CString -> IO DuckDBState 1416 | 1417 | foreign import ccall "duckdb.h duckdb_append_varchar_length" 1418 | duckdb_append_varchar_length 1419 | :: DuckDBAppender -> CString -> DuckDBIndexType -> IO DuckDBState 1420 | 1421 | foreign import ccall "duckdb.h duckdb_append_blob" 1422 | duckdb_append_blob 1423 | :: DuckDBAppender -> Ptr () -> DuckDBIndexType -> IO DuckDBState 1424 | 1425 | foreign import ccall "duckdb.h duckdb_append_null" 1426 | duckdb_append_null :: DuckDBAppender -> IO DuckDBState 1427 | 1428 | foreign import ccall "duckdb.h duckdb_append_data_chunk" 1429 | duckdb_append_data_chunk :: DuckDBAppender -> DuckDBDataChunk -> IO DuckDBState 1430 | 1431 | ----------------------------------------------------- 1432 | -- Arrow Interface 1433 | ----------------------------------------------------- 1434 | 1435 | foreign import ccall "duckdb.h duckdb_query_arrow" 1436 | duckdb_query_arrow 1437 | :: DuckDBConnection -> CString -> Ptr DuckDBArrow -> IO DuckDBState 1438 | 1439 | foreign import ccall "duckdb.h duckdb_query_arrow_schema" 1440 | duckdb_query_arrow_schema 1441 | :: DuckDBArrow -> Ptr DuckDBArrowSchema -> IO DuckDBState 1442 | 1443 | foreign import ccall "duckdb.h duckdb_query_arrow_array" 1444 | duckdb_query_arrow_array 1445 | :: DuckDBArrow -> Ptr DuckDBArrowArray -> IO DuckDBState 1446 | 1447 | foreign import ccall "duckdb.h duckdb_arrow_column_count" 1448 | duckdb_arrow_column_count :: DuckDBArrow -> IO DuckDBIndexType 1449 | 1450 | foreign import ccall "duckdb.h duckdb_arrow_row_count" 1451 | duckdb_arrow_row_count :: DuckDBArrow -> IO DuckDBIndexType 1452 | 1453 | foreign import ccall "duckdb.h duckdb_arrow_rows_changed" 1454 | duckdb_arrow_rows_changed :: DuckDBArrow -> IO DuckDBIndexType 1455 | 1456 | foreign import ccall "duckdb.h duckdb_query_arrow_error" 1457 | duckdb_query_arrow_error :: DuckDBArrow -> IO CString 1458 | 1459 | foreign import ccall "duckdb.h duckdb_destroy_arrow" 1460 | duckdb_destroy_arrow :: DuckDBArrow -> IO () 1461 | 1462 | ----------------------------------------------------- 1463 | -- Threading Information 1464 | ----------------------------------------------------- 1465 | 1466 | newtype DuckDBTaskState = DuckDBTaskState (Ptr ()) deriving (Eq, Storable) 1467 | 1468 | foreign import ccall "duckdb.h duckdb_execute_tasks" 1469 | duckdb_execute_tasks :: DuckDBDatabase -> DuckDBIndexType -> IO () 1470 | 1471 | foreign import ccall "duckdb.h duckdb_create_task_state" 1472 | duckdb_create_task_state :: DuckDBDatabase -> IO DuckDBTaskState 1473 | 1474 | foreign import ccall "duckdb.h duckdb_execute_tasks_state" 1475 | duckdb_execute_tasks_state :: DuckDBTaskState -> IO () 1476 | 1477 | foreign import ccall "duckdb.h duckdb_execute_n_tasks_state" 1478 | duckdb_execute_n_tasks_state 1479 | :: DuckDBTaskState -> DuckDBIndexType -> IO DuckDBIndexType 1480 | 1481 | foreign import ccall "duckdb.h duckdb_finish_execution" 1482 | duckdb_finish_execution :: DuckDBTaskState -> IO () 1483 | 1484 | foreign import ccall "duckdb.h duckdb_task_state_is_finished" 1485 | duckdb_task_state_is_finished :: DuckDBTaskState -> IO Bool 1486 | 1487 | foreign import ccall "duckdb.h duckdb_destroy_task_state" 1488 | duckdb_destroy_task_state :: DuckDBTaskState -> IO () 1489 | 1490 | foreign import ccall "duckdb.h duckdb_execution_is_finished" 1491 | duckdb_execution_is_finished :: DuckDBConnection -> IO Bool 1492 | 1493 | ----------------------------------------------------- 1494 | -- Streaming Result Interface 1495 | ----------------------------------------------------- 1496 | 1497 | foreign import ccall "duckdb.h duckdb_stream_fetch_chunk_capi" 1498 | duckdb_stream_fetch_chunk :: Ptr DuckDBResult -> IO DuckDBDataChunk 1499 | --------------------------------------------------------------------------------