diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2016 Thierry Bourrillon
+Copyright (c) 2016 FPInsight, Eurl.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,21 @@
+# Welcome to hocilib
+
+hocilib is a FFI binding of [ocilib](http://www.ocilib.net) for haskell.
+
+[![build status](https://travis-ci.org/fpinsight/hocilib.svg?branch=master)](https://travis-ci.org/fpinsight/hocilib)
+
+# Join in!
+
+We are happy to receive bug reports, fixes, documentation enhancements,
+and other improvements.
+
+Please report bugs via the
+[github issue tracker](https://github.com/fpinsight/hocilib/issues).
+
+Master [git repository](https://github.com/fpinsight/hocilib):
+
+* `git clone git@github.com:fpinsight/hocilib.git`
+
+# Authors
+
+This library is written and maintained by Thierry Bourrillon, <thierry.bourrillon@fpinsight.com>.
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,7 @@
+#!/usr/bin/env runhaskell
+
+> module Main where
+> import Distribution.Simple
+
+> main :: IO ()
+> main = defaultMain
diff --git a/hocilib.cabal b/hocilib.cabal
new file mode 100644
--- /dev/null
+++ b/hocilib.cabal
@@ -0,0 +1,86 @@
+name:               hocilib
+version:            0.0.0
+license:            BSD3
+license-file:       LICENSE
+category:           Database, Oracle, Ocilib, FFI
+copyright:          (c) 2016 Thierry Bourrillon
+                    (c) 2016 FPInsight, Eurl.
+author:             Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+maintainer:         Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+stability:          experimental
+synopsis:           FFI binding to OCILIB
+cabal-version:      >= 1.10
+homepage:           https://github.com/fpinsight/hocilib
+bug-reports:        https://github.com/fpinsight/hocilib/issues
+build-type:         Simple
+description:
+            A low-level client library for the Oracle database, implemented as
+            bindings to the C OCILIB API.
+
+extra-source-files: README.md
+                  , stack.yaml
+
+library
+  default-language: Haskell2010
+
+  exposed-modules:  Database.Ocilib
+                  , Database.Ocilib.Bindings
+                  , Database.Ocilib.Collections
+                  , Database.Ocilib.Connection
+                  , Database.Ocilib.Enums
+                  , Database.Ocilib.Errors
+                  , Database.Ocilib.Fetch
+                  , Database.Ocilib.Oci
+                  , Database.Ocilib.Pool
+                  , Database.Ocilib.Statement
+
+
+  other-modules:    Database.Ocilib.BitMask
+                  , Database.Ocilib.Schemas
+                  , Database.Ocilib.Transaction
+                  , Database.Ocilib.DateTime
+                  , Database.Ocilib.Timestamp
+                  , Database.Ocilib.Internal
+
+  build-tools:      c2hs
+  hs-source-dirs:   src
+  ghc-options:      -Wall -fwarn-tabs
+
+  c-sources:        src/Database/Ocilib.c
+                  , src/Database/Ocilib/Bindings.c
+                  , src/Database/Ocilib/Errors.c
+                  , src/Database/Ocilib/Pool.c
+                  , src/Database/Ocilib/Fetch.c
+                  , src/Database/Ocilib/Schemas.c
+                  , src/Database/Ocilib/Statement.c
+                  , src/Database/Ocilib/Connection.c
+                  , src/Database/Ocilib/Transaction.c
+                  , src/Database/Ocilib/DateTime.c
+                  , src/Database/Ocilib/Timestamp.c
+                  , src/Database/Ocilib/Collections.c
+
+
+  cc-options:       -Wall
+  extra-libraries:  ocilib
+
+  build-depends: base             >= 4.8 && < 5
+               , containers       >= 0.5 && < 1
+               , inline-c         >= 0.5 && < 1
+               , template-haskell
+
+
+
+test-suite test
+  type:           exitcode-stdio-1.0
+  hs-source-dirs: tests
+  main-is:        Tests.hs
+  ghc-options:    -Wall -threaded -rtsopts
+  other-modules:
+
+  default-language: Haskell2010
+
+  build-depends: base
+               , bytestring
+               , hocilib
+               , tasty
+               , tasty-hunit
diff --git a/src/Database/Ocilib.c b/src/Database/Ocilib.c
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib.c
@@ -0,0 +1,62 @@
+
+#include <ocilib.h>
+
+int inline_c_Database_Ocilib_0_1028660842d167554069a2bc5adfb396fb946b18(unsigned m_inline_c_0) {
+return ( OCI_Initialize(NULL, NULL, m_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_1_e0668872f2f8d77d8345a7b06dc600538ce44ec2(char * cs_inline_c_0, unsigned m_inline_c_1) {
+return ( OCI_Initialize(NULL, cs_inline_c_0, m_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_2_1028660842d167554069a2bc5adfb396fb946b18(unsigned m_inline_c_0) {
+return ( OCI_Initialize(NULL, NULL, m_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_3_fd1dbc379720de7b6f55219f3e1df58079b5d066(void (* h_inline_c_0)(OCI_Error *), char * cs_inline_c_1, unsigned m_inline_c_2) {
+return ( OCI_Initialize(h_inline_c_0, cs_inline_c_1, m_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_4_e9702999bdcc5439354b94df98f13c7a3d9f4bf7() {
+return ( OCI_Cleanup() );
+}
+
+
+unsigned inline_c_Database_Ocilib_5_4bfa618ffe8776c5d3d4a536b55e532639b08c93() {
+return ( OCI_GetOCICompileVersion() );
+}
+
+
+unsigned inline_c_Database_Ocilib_6_228926acef411dfe4567328aecf9b2e6a17de51f() {
+return ( OCI_GetOCIRuntimeVersion() );
+}
+
+
+unsigned inline_c_Database_Ocilib_7_cdadd8779ce62f3165fb44015c52775a15692207() {
+return ( OCI_GetImportMode() );
+}
+
+
+unsigned inline_c_Database_Ocilib_8_85bf5f1d7fb6b302c40c284e78ab62effc17b935() {
+return ( OCI_GetCharset() );
+}
+
+
+unsigned inline_c_Database_Ocilib_9_0b56b57c4967df461362c5b92cd15223500525fe(unsigned abt_inline_c_0) {
+return ( OCI_GetAllocatedBytes(abt_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_10_bdee6aa4f3a350a6a00a88b827df4102cee919e9(int vAsInt_inline_c_0) {
+return ( OCI_EnableWarnings(vAsInt_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_11_185beec350082b7de12743bf701de6568c451c05(void (* h_inline_c_0)(OCI_Error *)) {
+return ( OCI_SetErrorHandler(h_inline_c_0) );
+}
+
diff --git a/src/Database/Ocilib.hs b/src/Database/Ocilib.hs
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib.hs
@@ -0,0 +1,170 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE QuasiQuotes       #-}
+
+-- |
+-- Module:      Database.Ocilib
+-- Copyright:   (c) 2016 Thierry Bourrillon
+--              (c) 2016 FPInsight, Eurl.
+-- License:     BSD3
+-- Maintainer:  Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+-- FFI wrapper to Ocilib
+
+module Database.Ocilib
+    (
+    -- * Initializing library
+      ociInitialize
+    , ociCleanup
+    , ociGetOCICompileVersion
+    , ociGetOCIRuntimeVersion
+    , ociGetImportMode
+    , ociGetCharset
+    , ociGetAllocatedBytes
+    , ociEnableWarnings
+    , ociSetErrorHandler
+
+    -- * Describing Schema Meta data and Objects
+    , ociTypeInfoGet
+    , ociTypeInfoGetType
+    , ociTypeInfoGetConnection
+    , ociTypeInfoFree
+    , ociTypeInfoGetColumnCount
+    , ociTypeInfoGetColumn
+    , ociTypeInfoGetName
+
+    -- * Types
+    , ImportMode(..)
+    , CharsetMode(..)
+    , ErrorType(..)
+    , ErrorCode(..)
+    , AllocatedBytesType(..)
+    , BindMode(..)
+    , ColumnType(..)
+    , DataTypeCode(..)
+    , StatementType(..)
+    , EnvironmentMode(..)
+    , SessionMode(..)
+    , ChangeNotificationType(..)
+    , EventNotificationType(..)
+    , EventObjectNotificationType(..)
+    , DatabaseStartupMode(..)
+    , DatabaseStartupFlag(..)
+    , DatabaseShutdownMode(..)
+    , DatabaseShutdownFlag(..)
+    , CharsetFormType(..)
+    , StatementFetchMode(..)
+    , StatementFetchDirection(..)
+    , BindAllocationMode(..)
+    , BindDirectionMode(..)
+    , ColumnPropertyFlag(..)
+    , TimestampType(..)
+    , IntervalType(..)
+    , LongType(..)
+    , LobType(..)
+    , LobOpeningMode(..)
+    , FileType(..)
+    , LobBrowsingMode(..)
+    , TypeInfoType(..)
+    , ObjectType(..)
+    , CollectionType(..)
+    , PoolType(..)
+    , AQMessageState(..)
+    , AQSequenceDeviation(..)
+    , OCI_Error
+    ) where
+
+import           Data.Monoid ((<>))
+import           Foreign.C.Types
+import           Foreign.C.String
+import           Foreign.Marshal.Utils
+import           Foreign.Ptr
+import qualified Language.C.Inline as C
+import           Database.Ocilib.BitMask
+-- import           Database.Ocilib.Bindings
+import           Database.Ocilib.Oci
+import           Database.Ocilib.Enums
+-- import           Database.Ocilib.Errors
+-- import           Database.Ocilib.Pool
+-- import           Database.Ocilib.Fetch
+import           Database.Ocilib.Schemas
+-- import           Database.Ocilib.Statement
+-- import           Database.Ocilib.Connection
+-- import           Database.Ocilib.Collections
+-- import           Database.Ocilib.Transaction
+-- import           Database.Ocilib.DateTime
+-- import           Database.Ocilib.Timestamp
+
+C.context (C.baseCtx <> C.funCtx <> ociCtx)
+
+C.include "<ocilib.h>"
+
+type ErrorHandler = Ptr OCI_Error -> IO ()
+
+-- Initializing the library
+
+-- | Initialize the library.
+ociInitialize :: Maybe ErrorHandler -> Maybe FilePath -> [EnvironmentMode] -> IO Bool
+ociInitialize Nothing fp mode = do
+    let m = fromIntegral $ toBitMask mode
+    case fp of
+        Nothing ->
+            fmap toBool[C.exp| int { OCI_Initialize(NULL, NULL, $(unsigned int m)) } |]
+        Just a ->
+            withCString a (\cs ->
+                fmap toBool [C.exp| int { OCI_Initialize(NULL, $(char *cs), $(unsigned int m)) } |]
+            )
+ociInitialize (Just h) fp mode = do
+    let m = fromIntegral $ toBitMask mode
+    case fp of
+        Nothing ->
+            fmap toBool [C.exp| int { OCI_Initialize(NULL, NULL, $(unsigned int m)) } |]
+        Just a ->
+            withCString a (\cs -> do
+                fmap toBool [C.exp| int { OCI_Initialize($fun:(void (*h)(OCI_Error*)), $(char *cs), $(unsigned int m)) } |]
+            )
+
+-- | Clean up all resources allocated by the library.
+ociCleanup :: IO Bool
+ociCleanup = fmap toBool [C.exp| int { OCI_Cleanup() } |]
+
+-- | Return the version of OCI used for compilation.
+ociGetOCICompileVersion :: IO CUInt
+ociGetOCICompileVersion = [C.exp| unsigned int { OCI_GetOCICompileVersion() } |]
+
+-- | Return the version of OCI used at runtime.
+ociGetOCIRuntimeVersion :: IO CUInt
+ociGetOCIRuntimeVersion = [C.exp| unsigned int { OCI_GetOCIRuntimeVersion() } |]
+
+-- | Return the Oracle shared library import mode.
+ociGetImportMode :: IO ImportMode
+ociGetImportMode = fmap (toEnum . fromIntegral) [C.exp| unsigned int { OCI_GetImportMode() } |]
+
+-- | Return the OCILIB charset type.
+ociGetCharset :: IO CharsetMode
+ociGetCharset = fmap (toEnum . fromIntegral) [C.exp| unsigned int { OCI_GetCharset() } |]
+
+-- | Return the current number of bytes allocated internally in the library.
+ociGetAllocatedBytes :: AllocatedBytesType -> IO CUInt
+ociGetAllocatedBytes memType = do
+    let abt = fromIntegral $ fromEnum memType
+    [C.exp| unsigned int { OCI_GetAllocatedBytes($(unsigned int abt)) } |]
+
+-- | Enable or disable Oracle warning notifications.
+ociEnableWarnings :: Bool -> IO Bool
+ociEnableWarnings v = do
+    let vAsInt = fromIntegral $ fromEnum v
+    fmap toBool [C.exp| int { OCI_EnableWarnings($(int vAsInt)) } |]
+
+-- | Set the global error user handler.
+-- boolean OCI_SetErrorHandler (POCI_ERROR handler)
+ociSetErrorHandler :: (Ptr OCI_Error -> IO ()) -> IO Bool
+ociSetErrorHandler h = fmap toBool [C.exp| int { OCI_SetErrorHandler($fun:(void (*h)(OCI_Error *))) } |]
+
+{-
+-- | Set the High availability (HA) user handler.
+-- boolean OCI_SetHAHandler (POCI_HA_HANDLER handler)
+--ociSetHAHandler :: (ptr  -> IO)
+-}
diff --git a/src/Database/Ocilib/Bindings.c b/src/Database/Ocilib/Bindings.c
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Bindings.c
@@ -0,0 +1,316 @@
+
+#include <ocilib.h>
+
+int inline_c_Database_Ocilib_Bindings_0_674c680c8a466d401cebb13f34684d95fd2de187(OCI_Statement * st_inline_c_0, unsigned s_inline_c_1) {
+return ( OCI_BindArraySetSize(st_inline_c_0, s_inline_c_1) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Bindings_1_33167569c5ffa09deb2bc52a4f800e81b06b44a6(OCI_Statement * st_inline_c_0) {
+return ( OCI_BindArrayGetSize(st_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_2_a2abd1011a89e75dfd7d46e1bc915d94f184c387(OCI_Statement * st_inline_c_0, int v_inline_c_1) {
+return ( OCI_AllowRebinding(st_inline_c_0, v_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_3_f97384d960dad957c3ced40a56fa40ecba9ff8ab(OCI_Statement * st_inline_c_0) {
+return ( OCI_IsRebindingAllowed(st_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_4_89fdae3715b67b2fe43dd20429181c8429bbe1a1(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, int * d_inline_c_2) {
+return ( OCI_BindBoolean(st_inline_c_0, n_27_inline_c_1, d_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_5_ec7f1ed63bca63a5a0c400d8a0e46eb4da989521(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, short * d_inline_c_2) {
+return ( OCI_BindShort(st_inline_c_0, n_27_inline_c_1, d_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_6_8cc8dc4509e0e4321be31452944655009fb74303(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, short * d_inline_c_2, unsigned nb_inline_c_3) {
+return ( OCI_BindArrayOfShorts(st_inline_c_0
+                                                      , n_27_inline_c_1
+                                                      , d_inline_c_2
+                                                      , nb_inline_c_3) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_7_9152d7e53c52bd4d0659d4a890519448574e1a91(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, unsigned short * d_inline_c_2) {
+return ( OCI_BindUnsignedShort(st_inline_c_0
+                                                      , n_27_inline_c_1
+                                                      , d_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_8_0c17e19f5834a8612fa569649e0fec2997f530a8(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, unsigned short * d_inline_c_2, unsigned nb_inline_c_3) {
+return ( OCI_BindArrayOfUnsignedShorts(st_inline_c_0
+                                                              , n_27_inline_c_1
+                                                              , d_inline_c_2
+                                                              , nb_inline_c_3) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_9_8d8b93750e962c2ca881a68e24067c6fac853ed4(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, int * d_inline_c_2) {
+return ( OCI_BindInt(st_inline_c_0
+                                            , n_27_inline_c_1
+                                            , d_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_10_610ff3963e3db5a6fa81c5d015c932f3c101efc6(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, int * d_inline_c_2, unsigned nb_inline_c_3) {
+return ( OCI_BindArrayOfInts(st_inline_c_0
+                                                    , n_27_inline_c_1
+                                                    , d_inline_c_2
+                                                    , nb_inline_c_3) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_11_91f3c23e6c3506a0249576c6c71bb120876ae946(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, unsigned * d_inline_c_2) {
+return ( OCI_BindUnsignedInt(st_inline_c_0
+                                                    , n_27_inline_c_1
+                                                    , d_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_12_ae2b3e30ddcbad843ccc2feec3f50e0fc254b7df(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, unsigned * d_inline_c_2, unsigned nb_inline_c_3) {
+return ( OCI_BindArrayOfUnsignedInts(st_inline_c_0
+                                                            , n_27_inline_c_1
+                                                            , d_inline_c_2
+                                                            , nb_inline_c_3) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_13_b8b121da0b1ed3f1c4e63a0d2527f528b039675b(OCI_Statement * st_inline_c_0, char * n_inline_c_1, char * d_inline_c_2, unsigned l_inline_c_3) {
+return ( OCI_BindString(st_inline_c_0
+                                               , n_inline_c_1
+                                               , d_inline_c_2
+                                               , l_inline_c_3));
+}
+
+
+int inline_c_Database_Ocilib_Bindings_14_15b40c0fc5082bf1ec77a95132f12c8f32d57d5c(OCI_Statement * st_inline_c_0, char * n_inline_c_1, char * d_inline_c_2, unsigned len_inline_c_3, unsigned nbElem_inline_c_4) {
+return ( OCI_BindArrayOfStrings(st_inline_c_0
+                                                       , n_inline_c_1
+                                                       , d_inline_c_2
+                                                       , len_inline_c_3
+                                                       , nbElem_inline_c_4) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_15_231253bcc6d4371835282d2b49887491a967415d(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, double * d_inline_c_2) {
+return ( OCI_BindDouble(st_inline_c_0
+                                               , n_27_inline_c_1
+                                               , d_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_16_d63863c74d5b71c5ec6843c38ffb03efeda51ea0(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, double * d_inline_c_2, unsigned nb_inline_c_3) {
+return ( OCI_BindArrayOfDoubles(st_inline_c_0
+                                                       , n_27_inline_c_1
+                                                       , d_inline_c_2
+                                                       , nb_inline_c_3) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_17_5cbbcee16e5c521596b3ae446a4ee232169aa66c(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, float * d_inline_c_2) {
+return ( OCI_BindFloat(st_inline_c_0
+                                              , n_27_inline_c_1
+                                              , d_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_18_c61f0ae8e668be897a677d6bc2678f6cce7118f1(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, float * d_inline_c_2, unsigned nb_inline_c_3) {
+return ( OCI_BindArrayOfFloats(st_inline_c_0
+                                                      , n_27_inline_c_1
+                                                      , d_inline_c_2
+                                                      , nb_inline_c_3) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_19_bc111cd143166c877bbe5655e982827a8965597b(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, OCI_Date * d_inline_c_2) {
+return ( OCI_BindDate(st_inline_c_0
+                                             , n_27_inline_c_1
+                                             , d_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_20_9f8f94134d2b617f03c271e0824773b379a0044e(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, OCI_Timestamp * d_inline_c_2) {
+return ( OCI_BindTimestamp(st_inline_c_0
+                                                  , n_27_inline_c_1
+                                                  , d_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_21_14ecdd4ecb31a8e7616b0ba79b43fa69dc4fe1f9(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, OCI_Interval * d_inline_c_2) {
+return ( OCI_BindInterval(st_inline_c_0
+                                                 , n_27_inline_c_1
+                                                 , d_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_22_8a73c102fa0b869b693439c0da65aaa72719c1ac(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, OCI_Lob * d_inline_c_2) {
+return ( OCI_BindLob(st_inline_c_0
+                                            , n_27_inline_c_1
+                                            , d_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_23_896c9ddfc5751399318c0ce8a97ee11f1d8db0c1(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, OCI_File * d_inline_c_2) {
+return ( OCI_BindFile(st_inline_c_0
+                                             , n_27_inline_c_1
+                                             , d_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_24_76faa522ed485e20c17b2a0c843b96a66378629e(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, OCI_Object * d_inline_c_2) {
+return ( OCI_BindObject(st_inline_c_0, n_27_inline_c_1, d_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_25_491bd90c18b4cd3878659775a11578ed9de05c19(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, OCI_Coll * d_inline_c_2) {
+return ( OCI_BindColl(st_inline_c_0
+                                             , n_27_inline_c_1
+                                             , d_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_26_b09a17af807ad77f145d0608e783cd69f3264bfb(OCI_Statement * st_inline_c_0, const char * n_27_inline_c_1, OCI_Ref * d_inline_c_2) {
+return ( OCI_BindRef(st_inline_c_0
+                                            , n_27_inline_c_1
+                                            , d_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_27_b6db82f9fea2ed7fe7ae4b2742fe0afe53b8aa56(OCI_Statement * st_inline_c_0, const char * name_27_inline_c_1, OCI_Statement * d_inline_c_2) {
+return ( OCI_BindStatement(st_inline_c_0, name_27_inline_c_1, d_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_28_0ba1888f2a7107ecdbafa31be448e31e5ba304c8(OCI_Statement * st_inline_c_0, const char * name_27_inline_c_1, OCI_Long * d_inline_c_2, unsigned s_inline_c_3) {
+return ( OCI_BindLong(st_inline_c_0, name_27_inline_c_1, d_inline_c_2, s_inline_c_3) );
+}
+
+
+OCI_Error * inline_c_Database_Ocilib_Bindings_29_b73c7c9f65f22e34d766dd2c1e502ac6b19440a9(OCI_Statement * st_inline_c_0) {
+return ( OCI_GetBatchError(st_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Bindings_30_f5d93ee011572382d8da48a4770f38580048dae7(OCI_Statement * st_inline_c_0) {
+return ( OCI_GetBatchErrorCount(st_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Bindings_31_5e5f4b2fd94cc9138b3496296ae06eefed4b3557(OCI_Statement * st_inline_c_0) {
+return ( OCI_GetBindCount(st_inline_c_0) );
+}
+
+
+OCI_Bind * inline_c_Database_Ocilib_Bindings_32_c8a72c553941ff8cfaa0e76f8b23f66e6d49191a(OCI_Statement * st_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_GetBind(st_inline_c_0, i_inline_c_1) );
+}
+
+
+OCI_Bind * inline_c_Database_Ocilib_Bindings_33_dfe73eb2c3e30bd8a75e59a9feab0d5992acbe09(OCI_Statement * st_inline_c_0, char * name_27_inline_c_1) {
+return ( OCI_GetBind2(st_inline_c_0, name_27_inline_c_1) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Bindings_34_3a6123865d83d5cfadb02d7b922f6ae6530b3e6d(OCI_Statement * st_inline_c_0, char * name_27_inline_c_1) {
+return ( OCI_GetBindIndex(st_inline_c_0, name_27_inline_c_1) );
+}
+
+
+const char * inline_c_Database_Ocilib_Bindings_35_fc678d0bb1739fec235f69b76f5d49491afa0dd3(OCI_Bind * b_inline_c_0) {
+return ( OCI_BindGetName(b_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_36_21dba495142899b00a5d672bd4a41b34e1ab743b(OCI_Bind * b_inline_c_0, unsigned d_27_inline_c_1) {
+return ( OCI_BindSetDirection(b_inline_c_0, d_27_inline_c_1) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Bindings_37_251033e1fdb3fad2774dd892d257c2ee32986048(OCI_Bind * b_inline_c_0) {
+return ( OCI_BindGetDirection(b_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Bindings_38_539a31f9229ce2cd9602b57e678d6454a52c8f5f(OCI_Bind * b_inline_c_0) {
+return ( OCI_BindGetType(b_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Bindings_39_8f08ada4904931166b2e521961d3ce76cb626515(OCI_Bind * b_inline_c_0) {
+return ( OCI_BindGetDataCount(b_inline_c_0) );
+}
+
+
+void * inline_c_Database_Ocilib_Bindings_40_4a9102e6a09555898286bc6a172d273ba0528a6c(OCI_Bind * b_inline_c_0) {
+return ( OCI_BindGetData(b_inline_c_0) );
+}
+
+
+OCI_Statement * inline_c_Database_Ocilib_Bindings_41_fa64ca1b1c026954ee2943b05f7a947ae9939998(OCI_Bind * b_inline_c_0) {
+return ( OCI_BindGetStatement(b_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_42_29de124d0b0da75c1ac601bab48ee1d72c446f35(OCI_Bind * b_inline_c_0, unsigned s_inline_c_1) {
+return ( OCI_BindSetDataSize(b_inline_c_0, s_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_43_e70d2e65b9b2dc3b28f4090f3312b5df20b2802e(OCI_Bind * b_inline_c_0, unsigned p_inline_c_1, unsigned s_inline_c_2) {
+return ( OCI_BindSetDataSizeAtPos(b_inline_c_0, p_inline_c_1, s_inline_c_2) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Bindings_44_3178d8ae040630ca1001b9f0d31d4ce9a8be8eae(OCI_Bind * b_inline_c_0) {
+return ( OCI_BindGetDataSize(b_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Bindings_45_9b4b7a9565a84dd59836134b89c42f340750602a(OCI_Bind * b_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_BindGetDataSizeAtPos(b_inline_c_0, i_inline_c_1));
+}
+
+
+int inline_c_Database_Ocilib_Bindings_46_58f557e4e7748f325cc231d0be3ce19617d47890(OCI_Bind * b_inline_c_0) {
+return ( OCI_BindSetNull(b_inline_c_0));
+}
+
+
+int inline_c_Database_Ocilib_Bindings_47_45985d0805248d668f62389f4a61ea7739565b82(OCI_Bind * b_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_BindSetNullAtPos(b_inline_c_0, i_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_48_4a57a10fb202679af3615d68c37d09fc2bfe0a32(OCI_Bind * b_inline_c_0) {
+return ( OCI_BindSetNotNull(b_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_49_1c32c2a4be700b0ecd555ca08ab198a48ff0031e(OCI_Bind * b_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_BindSetNotNullAtPos(b_inline_c_0, i_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_50_121c6f54a732fa542706c304396bbe124460e0a8(OCI_Bind * b_inline_c_0) {
+return ( OCI_BindIsNull(b_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_51_06149f6bb2c4fdae5543e6b566e887e6a9d7d9fe(OCI_Bind * b_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_BindIsNullAtPos(b_inline_c_0, i_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_Bindings_52_9c8765f1ca341661075cb24885c7c3828bb543ce(OCI_Bind * b_inline_c_0, unsigned c_27_inline_c_1) {
+return ( OCI_BindSetCharsetForm(b_inline_c_0, c_27_inline_c_1) );
+}
+
diff --git a/src/Database/Ocilib/Bindings.hs b/src/Database/Ocilib/Bindings.hs
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Bindings.hs
@@ -0,0 +1,498 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE QuasiQuotes       #-}
+
+-- |
+-- Module:      Database.Ocilib.Bindings
+-- Copyright:   (c) 2016 Thierry Bourrillon
+--              (c) 2016 FPInsight, Eurl.
+-- License:     BSD3
+-- Maintainer:  Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+--
+
+module Database.Ocilib.Bindings
+    ( ociBindArraySetSize
+    , ociBindArrayGetSize
+    , ociAllowRebinding
+    , ociIsRebindingAllowed
+    , ociBindBoolean
+    , ociBindShort
+    , ociBindArrayOfShorts
+    , ociBindUnsignedShort
+    , ociBindArrayOfUnsignedShorts
+    , ociBindInt
+    , ociBindArrayOfInts
+    , ociBindUnsignedInt
+    , ociBindArrayOfUnsignedInts
+    --, ociBindBigInt
+    --, ociBindArrayOfBigInts
+    --, ociBindUnsignedBigInts
+    --, ociBindArrayOfUnsignedBigInts
+    , ociBindString
+    , ociBindArrayOfStrings
+    --, ociBindRaw
+    --, ociBindArrayOfRaws
+    , ociBindDouble
+    , ociBindArrayOfDoubles
+    , ociBindFloat
+    , ociBindArrayOfFloats
+    , ociBindDate
+    --, ociBindArrayOfDates
+    , ociBindTimestamp
+    --, ociBindArrayOfTimestamps
+    , ociBindInterval
+    --, ociBindArrayOfIntervals
+    , ociBindLob
+    --, ociBindArrayOfLobs
+    , ociBindFile
+    --, ociBindArrayOfFiles
+    , ociBindObject
+    --, ociBindArrayOfObjects
+    , ociBindColl
+    --, ociBindArrayOfColls
+    , ociBindRef
+    --, ociBindArrayOfRefs
+    , ociBindStatement
+    , ociBindLong
+    , ociGetBatchError
+    , ociGetBatchErrorCount
+    , ociGetBindCount
+    , ociGetBind
+    , ociGetBind2
+    , ociGetBindIndex
+    , ociBindGetName
+    , ociBindSetDirection
+    , ociBindGetDirection
+    , ociBindGetType
+    --, ociBindGetSubtype
+    , ociBindGetDataCount
+    , ociBindGetData
+    , ociBindGetStatement
+    , ociBindSetDataSize
+    , ociBindGetDataSize
+    , ociBindSetDataSizeAtPos
+    , ociBindGetDataSizeAtPos
+    , ociBindSetNull
+    , ociBindSetNullAtPos
+    , ociBindSetNotNull
+    , ociBindSetNotNullAtPos
+    , ociBindIsNull
+    , ociBindIsNullAtPos
+    , ociBindSetCharsetForm
+    ) where
+
+import           Data.Monoid ((<>))
+import           Foreign.C.Types
+import           Foreign.C.String
+import           Foreign.Marshal.Utils
+import           Foreign.Ptr
+import qualified Language.C.Inline as C
+import           Database.Ocilib.Oci
+import           Database.Ocilib.Enums
+import           Database.Ocilib.Internal
+
+C.context (C.baseCtx <> C.funCtx <> ociCtx)
+
+C.include "<ocilib.h>"
+
+-- Binding variables and arrays
+
+-- | Set the input array size for bulk operations.
+ociBindArraySetSize :: Ptr OCI_Statement -> CUInt -> IO Bool
+ociBindArraySetSize st s =
+    fmap toBool [C.exp| int { OCI_BindArraySetSize($(OCI_Statement *st), $(unsigned int s)) } |]
+
+-- | Return the current input array size for bulk operations.
+ociBindArrayGetSize :: Ptr OCI_Statement -> IO CUInt
+ociBindArrayGetSize st = [C.exp| unsigned int { OCI_BindArrayGetSize($(OCI_Statement *st)) } |]
+
+-- | Allow different host variables to be binded using the same bind name or position between executions of a prepared statement.
+ociAllowRebinding :: Ptr OCI_Statement -> Bool -> IO Bool
+ociAllowRebinding st value = do
+    let v = fromIntegral $ fromEnum value
+    fmap toBool [C.exp| int { OCI_AllowRebinding($(OCI_Statement *st), $(int v)) }|]
+
+-- | Indicate if rebinding is allowed on the given statement.
+ociIsRebindingAllowed :: Ptr OCI_Statement -> IO Bool
+ociIsRebindingAllowed st =
+    fmap toBool [C.exp| int { OCI_IsRebindingAllowed($(OCI_Statement *st)) } |]
+
+-- | Bind a boolean variable (PL/SQL ONLY)
+ociBindBoolean :: Ptr OCI_Statement -> String -> Ptr CInt -> IO Bool
+ociBindBoolean st n d = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindBoolean($(OCI_Statement *st), $(const char *n'), $(int *d)) } |]
+    )
+
+-- | Bind an short variable.
+ociBindShort :: Ptr OCI_Statement -> String -> Ptr CShort -> IO Bool
+ociBindShort st n d = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindShort($(OCI_Statement *st), $(const char *n'), $(short *d)) } |]
+    )
+
+-- | Bind an array of shorts.
+ociBindArrayOfShorts :: Ptr OCI_Statement -> String -> Ptr CShort -> CUInt -> IO Bool
+ociBindArrayOfShorts st n d nb = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindArrayOfShorts($(OCI_Statement *st)
+                                                      , $(const char *n')
+                                                      , $(short *d)
+                                                      , $(unsigned int nb)) } |]
+    )
+
+-- | Bind an unsigned short variable.
+ociBindUnsignedShort :: Ptr OCI_Statement -> String -> Ptr CUShort -> IO Bool
+ociBindUnsignedShort st n d = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindUnsignedShort($(OCI_Statement *st)
+                                                      , $(const char *n')
+                                                      , $(unsigned short *d)) } |]
+    )
+
+-- | Bind an array of unsigned shorts.
+ociBindArrayOfUnsignedShorts :: Ptr OCI_Statement -> String -> Ptr CUShort -> CUInt -> IO Bool
+ociBindArrayOfUnsignedShorts st n d nb = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindArrayOfUnsignedShorts($(OCI_Statement * st)
+                                                              , $(const char *n')
+                                                              , $(unsigned short *d)
+                                                              , $(unsigned int nb)) } |]
+    )
+
+-- | Bind an integer variable.
+ociBindInt :: Ptr OCI_Statement -> String -> Ptr CInt -> IO Bool
+ociBindInt st n d = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindInt($(OCI_Statement *st)
+                                            , $(const char *n')
+                                            , $(int *d)) } |]
+    )
+
+-- | Bind an array of integers.
+ociBindArrayOfInts :: Ptr OCI_Statement -> String -> Ptr CInt -> CUInt -> IO Bool
+ociBindArrayOfInts st n d nb = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindArrayOfInts($(OCI_Statement *st)
+                                                    , $(const char *n')
+                                                    , $(int *d)
+                                                    , $(unsigned int nb)) } |]
+    )
+
+-- | Bind an unsigned integer variable.
+ociBindUnsignedInt :: Ptr OCI_Statement -> String -> Ptr CUInt -> IO Bool
+ociBindUnsignedInt st n d = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindUnsignedInt($(OCI_Statement *st)
+                                                    , $(const char* n')
+                                                    , $(unsigned int *d)) } |]
+    )
+
+-- | Bind an array of unsigned integers.
+ociBindArrayOfUnsignedInts :: Ptr OCI_Statement -> String -> Ptr CUInt -> CUInt -> IO Bool
+ociBindArrayOfUnsignedInts st n d nb = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindArrayOfUnsignedInts($(OCI_Statement *st)
+                                                            , $(const char *n')
+                                                            , $(unsigned int *d)
+                                                            , $(unsigned int nb)) } |]
+    )
+{-
+-- | Bind a big integer variable.
+-- boolean OCI_BindBigInt (OCI_Statement *stmt, const otext *name, big_int *data)
+ociBindBigInt :: Ptr OCI_Statement -> String -> Ptr Big_Int -> IO Bool
+ociBindBigInt st n d = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindBigInt($(OCI_Statement *st)
+                                               , $(const char *n')
+                                               , $(Big_Int  *d)) } |]
+    )
+
+-- | Bind an array of big integers.
+-- boolean OCI_BindArrayOfBigInts (OCI_Statement *stmt, const otext *name, big_int *data, unsigned int nbelem)
+
+-- | Bind an unsigned big integer variable.
+-- boolean OCI_BindUnsignedBigInt (OCI_Statement *stmt, const otext *name, big_uint *data)
+
+-- | Bind an array of unsigned big integers.
+-- boolean OCI_BindArrayOfUnsignedBigInts (OCI_Statement *stmt, const otext *name, big_uint *data, unsigned int nbelem)
+-}
+
+-- | Bind a string variable.
+ociBindString :: Ptr OCI_Statement -> String -> CString -> CUInt -> IO Bool
+ociBindString st name d l =
+    withCString name (\n ->
+        fmap toBool [C.exp| int { OCI_BindString($(OCI_Statement *st)
+                                               , $(char *n)
+                                               , $(char *d)
+                                               , $(unsigned int l))} |]
+    )
+
+-- | Bind an array of strings.
+ociBindArrayOfStrings :: Ptr OCI_Statement -> String -> CString -> CUInt -> CUInt -> IO Bool
+ociBindArrayOfStrings st name d len nbElem =
+    withCString name (\n ->
+        fmap toBool [C.exp| int { OCI_BindArrayOfStrings($(OCI_Statement *st)
+                                                       , $(char *n)
+                                                       , $(char *d)
+                                                       , $(unsigned int len)
+                                                       , $(unsigned int nbElem)) } |]
+    )
+
+-- | Bind a raw buffer.
+-- boolean OCI_BindRaw (OCI_Statement *stmt, const otext *name, void *data, unsigned int len)
+-- ociBindRaw :: Ptr OCI_Statement -> String ->
+
+-- | Bind an array of raw buffers.
+-- boolean OCI_BindArrayOfRaws (OCI_Statement *stmt, const otext *name, void *data, unsigned int len, unsigned int nbelem)
+
+-- | Bind a double variable.
+ociBindDouble :: Ptr OCI_Statement -> String -> Ptr CDouble -> IO Bool
+ociBindDouble st n d = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindDouble($(OCI_Statement *st)
+                                               , $(const char *n')
+                                               , $(double *d)) } |]
+    )
+
+-- | Bind an array of doubles.
+ociBindArrayOfDoubles :: Ptr OCI_Statement -> String -> Ptr CDouble -> CUInt -> IO Bool
+ociBindArrayOfDoubles st n d nb = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindArrayOfDoubles($(OCI_Statement *st)
+                                                       , $(const char *n')
+                                                       , $(double *d)
+                                                       , $(unsigned int nb)) } |]
+    )
+
+-- | Bind a float variable.
+ociBindFloat :: Ptr OCI_Statement -> String -> Ptr CFloat -> IO Bool
+ociBindFloat st n d = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindFloat($(OCI_Statement *st)
+                                              , $(const char *n')
+                                              , $(float *d)) } |]
+    )
+-- | Bind an array of floats.
+ociBindArrayOfFloats :: Ptr OCI_Statement -> String -> Ptr CFloat -> CUInt -> IO Bool
+ociBindArrayOfFloats st n d nb = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindArrayOfFloats($(OCI_Statement *st)
+                                                      , $(const char *n')
+                                                      , $(float *d)
+                                                      , $(unsigned int nb)) } |]
+    )
+-- | Bind a date variable.
+ociBindDate :: Ptr OCI_Statement -> String -> Ptr OCI_Date -> IO Bool
+ociBindDate st n d = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindDate($(OCI_Statement *st)
+                                             , $(const char* n')
+                                             , $(OCI_Date *d)) } |]
+    )
+
+-- | Bind an array of dates.
+-- boolean OCI_BindArrayOfDates (OCI_Statement *stmt, const otext *name, OCI_Date **data, unsigned int nbelem)
+{-
+ociBindArrayOfDates :: Ptr OCI_Statement -> String -> Ptr OCI_Date -> CUInt -> IO Bool
+ociBindArrayOfDates st n d nb = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindArrayOfDates($(OCI_Statement *st)
+                                                     , $(const char *n')
+                                                     , $(OCI_Date *d)
+                                                     , $(unsigned int nb)) } |]
+    )
+-}
+
+-- | Bind a timestamp variable.
+ociBindTimestamp :: Ptr OCI_Statement -> String -> Ptr OCI_Timestamp -> IO Bool
+ociBindTimestamp st n d = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindTimestamp($(OCI_Statement *st)
+                                                  , $(const char *n')
+                                                  , $(OCI_Timestamp *d)) } |]
+    )
+
+-- | Bind an array of timestamp handles.
+-- boolean OCI_BindArrayOfTimestamps (OCI_Statement *stmt, const otext *name, OCI_Timestamp **data, unsigned int type, unsigned int nbelem)
+
+-- | Bind an interval variable.
+ociBindInterval :: Ptr OCI_Statement -> String -> Ptr OCI_Interval -> IO Bool
+ociBindInterval st n d = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindInterval($(OCI_Statement *st)
+                                                 , $(const char *n')
+                                                 , $(OCI_Interval *d)) } |]
+    )
+-- | Bind an array of interval handles.
+-- boolean OCI_BindArrayOfIntervals (OCI_Statement *stmt, const otext *name, OCI_Interval **data, unsigned int type, unsigned int nbelem)
+
+-- | Bind a Lob variable.
+ociBindLob :: Ptr OCI_Statement -> String -> Ptr OCI_Lob -> IO Bool
+ociBindLob st n d = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindLob($(OCI_Statement *st)
+                                            , $(const char *n')
+                                            , $(OCI_Lob *d)) } |]
+    )
+
+-- | Bind an array of Lob handles.
+-- boolean OCI_BindArrayOfLobs (OCI_Statement *stmt, const otext *name, OCI_Lob **data, unsigned int type, unsigned int nbelem)
+
+-- | Bind a File variable.
+ociBindFile :: Ptr OCI_Statement -> String -> Ptr OCI_File -> IO Bool
+ociBindFile st n d = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindFile($(OCI_Statement *st)
+                                             , $(const char *n')
+                                             , $(OCI_File *d)) } |]
+    )
+
+-- | Bind an array of File handles.
+-- boolean OCI_BindArrayOfFiles (OCI_Statement *stmt, const otext *name, OCI_File **data, unsigned int type, unsigned int nbelem)
+
+-- | Bind an object (named type) variable.
+ociBindObject :: Ptr OCI_Statement -> String -> Ptr OCI_Object -> IO Bool
+ociBindObject st n d = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindObject($(OCI_Statement *st), $(const char * n'), $(OCI_Object *d)) } |]
+    )
+
+-- | Bind an array of object handles.
+-- boolean OCI_BindArrayOfObjects (OCI_Statement *stmt, const otext *name, OCI_Object **data, OCI_TypeInfo *typinf, unsigned int nbelem)
+
+-- | Bind a Collection variable.
+ociBindColl :: Ptr OCI_Statement -> String -> Ptr OCI_Coll -> IO Bool
+ociBindColl st n d = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindColl($(OCI_Statement *st)
+                                             , $(const char *n')
+                                             , $(OCI_Coll *d)) } |]
+    )
+
+-- | Bind an array of Collection handles.
+-- boolean OCI_BindArrayOfColls (OCI_Statement *stmt, const otext *name, OCI_Coll **data, OCI_TypeInfo *typinf, unsigned int nbelem)
+
+-- | Bind a Ref variable.
+ociBindRef :: Ptr OCI_Statement -> String -> Ptr OCI_Ref -> IO Bool
+ociBindRef st n d = withCString n (\n' ->
+        fmap toBool [C.exp| int { OCI_BindRef($(OCI_Statement *st)
+                                            , $(const char *n')
+                                            , $(OCI_Ref *d)) } |]
+    )
+
+-- | Bind an array of Ref handles.
+-- boolean OCI_BindArrayOfRefs (OCI_Statement *stmt, const otext *name, OCI_Ref **data, OCI_TypeInfo *typinf, unsigned int nbelem)
+
+-- | Bind a Statement variable (PL/SQL Ref Cursor)
+ociBindStatement :: Ptr OCI_Statement -> String -> Ptr OCI_Statement -> IO Bool
+ociBindStatement st name d = withCString name (\name' ->
+        fmap toBool [C.exp| int { OCI_BindStatement($(OCI_Statement *st), $(const char *name'), $(OCI_Statement *d)) } |]
+    )
+
+-- | Bind a Long variable.
+ociBindLong :: Ptr OCI_Statement -> String -> Ptr OCI_Long -> CUInt -> IO Bool
+ociBindLong st name d s = withCString name (\name' ->
+        fmap toBool [C.exp| int { OCI_BindLong($(OCI_Statement *st), $(const char *name'), $(OCI_Long *d), $(unsigned int s)) } |]
+    )
+
+-- | Returns the first or next error that occurred within a DML array statement execution.
+ociGetBatchError :: Ptr OCI_Statement -> IO (Maybe (Ptr OCI_Error))
+ociGetBatchError st = fmap toMaybePtr [C.exp| OCI_Error* { OCI_GetBatchError($(OCI_Statement *st)) } |]
+
+-- | Returns the number of errors that occurred within the last DML array statement.
+ociGetBatchErrorCount :: Ptr OCI_Statement -> IO CUInt
+ociGetBatchErrorCount st = [C.exp| unsigned int { OCI_GetBatchErrorCount($(OCI_Statement *st)) } |]
+
+-- | Return the number of binds currently associated to a statement.
+ociGetBindCount :: Ptr OCI_Statement -> IO CUInt
+ociGetBindCount st = [C.exp| unsigned int { OCI_GetBindCount($(OCI_Statement *st)) } |]
+
+-- | Return the bind handle at the given index in the internal array of bind handle.
+ociGetBind :: Ptr OCI_Statement -> CUInt -> IO (Maybe (Ptr OCI_Bind))
+ociGetBind st i = fmap toMaybePtr [C.exp| OCI_Bind* { OCI_GetBind($(OCI_Statement *st), $(unsigned int i)) } |]
+
+-- | Return a bind handle from its name.
+ociGetBind2 :: Ptr OCI_Statement -> String -> IO (Maybe (Ptr OCI_Bind))
+ociGetBind2 st name = withCString name (\name' ->
+        fmap toMaybePtr [C.exp| OCI_Bind* { OCI_GetBind2($(OCI_Statement *st), $(char *name')) } |]
+    )
+
+-- | Return the index of the bind from its name belonging to the given statement.
+ociGetBindIndex :: Ptr OCI_Statement -> String -> IO CUInt
+ociGetBindIndex st name = withCString name (\name' ->
+        [C.exp| unsigned int { OCI_GetBindIndex($(OCI_Statement *st), $(char* name')) } |]
+    )
+
+-- | Return the name of the given bind.
+ociBindGetName :: Ptr OCI_Bind -> IO String
+ociBindGetName b = do
+    name <- [C.exp| const char* { OCI_BindGetName($(OCI_Bind *b)) } |]
+    peekCString name
+
+-- | Set the direction mode of a bind handle.
+ociBindSetDirection :: Ptr OCI_Bind -> BindDirectionMode -> IO Bool
+ociBindSetDirection b d = do
+    let d' = fromIntegral $ fromEnum d
+    fmap toBool [C.exp| int { OCI_BindSetDirection($(OCI_Bind *b), $(unsigned int d')) } |]
+
+-- | Get the direction mode of a bind handle.
+ociBindGetDirection :: Ptr OCI_Bind -> IO BindDirectionMode
+ociBindGetDirection b = fmap
+    (toEnum . fromIntegral)
+    [C.exp| unsigned int { OCI_BindGetDirection($(OCI_Bind *b)) } |]
+
+-- | Return the OCILIB type of the given bind.
+-- unsigned int OCI_BindGetType (OCI_Bind *bnd)
+ociBindGetType :: Ptr OCI_Bind -> IO ColumnType
+ociBindGetType b = fmap
+    (toEnum . fromIntegral)
+    [C.exp| unsigned int { OCI_BindGetType($(OCI_Bind *b)) } |]
+
+-- | Return the OCILIB object subtype of the given bind.
+-- unsigned int OCI_BindGetSubtype (OCI_Bind *bnd)
+-- ociBindGetSubtype :: Ptr OCI_Bind -> IO
+
+-- | Return the number of elements of the bind handle.
+ociBindGetDataCount :: Ptr OCI_Bind -> IO CUInt
+ociBindGetDataCount b = [C.exp| unsigned int { OCI_BindGetDataCount($(OCI_Bind *b)) } |]
+
+-- | Return the user defined data associated with a bind handle.
+ociBindGetData :: Ptr OCI_Bind -> IO (Ptr ())
+ociBindGetData b = [C.exp| void* { OCI_BindGetData($(OCI_Bind *b)) } |]
+
+-- | Return the statement handle associated with a bind handle.
+ociBindGetStatement :: Ptr OCI_Bind -> IO (Ptr OCI_Statement)
+ociBindGetStatement b = [C.exp| OCI_Statement* { OCI_BindGetStatement($(OCI_Bind *b)) } |]
+
+-- | Set the actual size of the element held by the given bind handle.
+ociBindSetDataSize :: Ptr OCI_Bind -> CUInt -> IO Bool
+ociBindSetDataSize b s = fmap
+    toBool
+    [C.exp| int { OCI_BindSetDataSize($(OCI_Bind *b), $(unsigned int s)) } |]
+
+-- | Set the size of the element at the given position in the bind input array.
+ociBindSetDataSizeAtPos :: Ptr OCI_Bind -> CUInt -> CUInt -> IO Bool
+ociBindSetDataSizeAtPos b p s = fmap
+    toBool
+    [C.exp| int { OCI_BindSetDataSizeAtPos($(OCI_Bind *b), $(unsigned int p), $(unsigned int s)) } |]
+
+-- | Return the actual size of the element held by the given bind handle.
+ociBindGetDataSize :: Ptr OCI_Bind -> IO CUInt
+ociBindGetDataSize b = [C.exp| unsigned int { OCI_BindGetDataSize($(OCI_Bind *b)) } |]
+
+-- | Return the actual size of the element at the given position in the bind input array.
+ociBindGetDataSizeAtPos :: Ptr OCI_Bind -> CUInt -> IO CUInt
+ociBindGetDataSizeAtPos b i = [C.exp| unsigned int { OCI_BindGetDataSizeAtPos($(OCI_Bind *b), $(unsigned int i))} |]
+
+-- | Set the bind variable to null.
+ociBindSetNull :: Ptr OCI_Bind -> IO Bool
+ociBindSetNull b = fmap toBool [C.exp| int { OCI_BindSetNull($(OCI_Bind *b))} |]
+
+-- | Set to null the entry in the bind variable input array.
+ociBindSetNullAtPos :: Ptr OCI_Bind -> CUInt -> IO Bool
+ociBindSetNullAtPos b i = fmap toBool [C.exp| int { OCI_BindSetNullAtPos($(OCI_Bind *b), $(unsigned int i)) } |]
+
+-- | Set the bind variable to NOT null.
+ociBindSetNotNull :: Ptr OCI_Bind -> IO Bool
+ociBindSetNotNull b = fmap toBool [C.exp| int { OCI_BindSetNotNull($(OCI_Bind *b)) } |]
+
+-- | Set to NOT null the entry in the bind variable input array.
+ociBindSetNotNullAtPos :: Ptr OCI_Bind -> CUInt -> IO Bool
+ociBindSetNotNullAtPos b i = fmap toBool [C.exp| int { OCI_BindSetNotNullAtPos($(OCI_Bind *b), $(unsigned int i)) } |]
+
+-- | Check if the current value of the binded variable is marked as NULL.
+ociBindIsNull :: Ptr OCI_Bind -> IO Bool
+ociBindIsNull b = fmap toBool [C.exp| int { OCI_BindIsNull($(OCI_Bind *b)) } |]
+
+-- | Check if the current entry value at the given index of the binded array is marked as NULL.
+ociBindIsNullAtPos :: Ptr OCI_Bind -> CUInt -> IO Bool
+ociBindIsNullAtPos b i = fmap toBool [C.exp| int { OCI_BindIsNullAtPos($(OCI_Bind *b), $(unsigned int i)) } |]
+
+-- | Set the charset form of the given character based bind variable.
+-- boolean OCI_BindSetCharsetForm (OCI_Bind *bnd, unsigned int csfrm)
+ociBindSetCharsetForm :: Ptr OCI_Bind -> CharsetFormType -> IO Bool
+ociBindSetCharsetForm b c = do
+    let c' = fromIntegral $ fromEnum c
+    fmap toBool [C.exp| int { OCI_BindSetCharsetForm($(OCI_Bind *b), $(unsigned int c')) } |]
diff --git a/src/Database/Ocilib/BitMask.hs b/src/Database/Ocilib/BitMask.hs
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/BitMask.hs
@@ -0,0 +1,43 @@
+{-# LANGUAGE DefaultSignatures #-}
+
+-- |
+-- Module:      Database.Ocilib.BitMask
+-- Copyright:   (c) 2016 Thierry Bourrillon
+--              (c) 2016 FPInsight, Eurl.
+-- License:     BSD3
+-- Maintainer:  Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+--
+
+module Database.Ocilib.BitMask
+    ( ToBitMask
+    , fromBitMask
+    , isInBitMask
+    , toBitMask
+    ) where
+
+import Data.Bits
+import Control.Monad
+
+class ToBitMask a where
+  toBitMask :: a -> Int
+  -- | Using a DefaultSignatures extension to declare a default signature with
+  -- an `Enum` constraint without affecting the constraints of the class itself.
+  default toBitMask :: Enum a => a -> Int
+  toBitMask = shiftL 1 . fromEnum
+
+instance ( ToBitMask a ) => ToBitMask [a] where
+  toBitMask = foldr (.|.) 0 . map toBitMask
+
+-- | Not making this a typeclass, since it already generalizes over all
+-- imaginable instances with help of `MonadPlus`.
+fromBitMask ::
+  ( MonadPlus m, Enum a, Bounded a, ToBitMask a ) =>
+    Int -> m a
+fromBitMask bm = msum $ map asInBM $ enumFrom minBound where
+  asInBM a = if isInBitMask bm a then return a else mzero
+
+isInBitMask :: ( ToBitMask a ) => Int -> a -> Bool
+isInBitMask bm a = let aBM = toBitMask a in aBM == aBM .&. bm
diff --git a/src/Database/Ocilib/Collections.c b/src/Database/Ocilib/Collections.c
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Collections.c
@@ -0,0 +1,137 @@
+
+#include <ocilib.h>
+
+OCI_Coll * inline_c_Database_Ocilib_Collections_0_195d861fb7cebfc2f52e6f3fdb5ab55d143be2a0(OCI_TypeInfo * ti_inline_c_0) {
+return ( OCI_CollCreate(ti_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Collections_1_e65221f64bccb0e682ec7d209af08084c0381c88(OCI_Coll * coll_inline_c_0) {
+return ( OCI_CollFree(coll_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Collections_2_a5417b4966dfb9811e8c72bd47f7abc4889af37f(OCI_Coll * dst_inline_c_0, OCI_Coll * src_inline_c_1) {
+return ( OCI_CollAssign(dst_inline_c_0, src_inline_c_1) );
+}
+
+
+OCI_TypeInfo * inline_c_Database_Ocilib_Collections_3_14c1646f9bfd146673ae331d72c893eeaa437149(OCI_Coll * c_inline_c_0) {
+return ( OCI_CollGetTypeInfo(c_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Collections_4_38d1d095f4a8862c1bd5a32bea8a46d542aa8057(OCI_Coll * c_inline_c_0) {
+return ( OCI_CollGetType(c_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Collections_5_5e5b813b7b9919dd7619c81538b72b550fc3e097(OCI_Coll * c_inline_c_0) {
+return ( OCI_CollGetMax(c_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Collections_6_3eeb2cabfe66acd2ba4244dab744a6a73a0bb1ea(OCI_Coll * c_inline_c_0) {
+return ( OCI_CollGetSize(c_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Collections_7_51d3c4a9ee939748d1407261c9f0baeb5f43ce32(OCI_Coll * c_inline_c_0) {
+return ( OCI_CollGetCount(c_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Collections_8_59b9cc8a575d146a41a8798ba5f5ab2301a91834(OCI_Coll * c_inline_c_0, unsigned n_inline_c_1) {
+return ( OCI_CollTrim(c_inline_c_0, n_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_Collections_9_a1c31f5c4268054dd7aa04bc1eed60c8a9f5574d(OCI_Coll * c_inline_c_0) {
+return ( OCI_CollClear(c_inline_c_0) );
+}
+
+
+OCI_Elem * inline_c_Database_Ocilib_Collections_10_ffe2b8e3470fff5959f9289a3a2d52128a41bf9f(OCI_Coll * c_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_CollGetElem(c_inline_c_0, i_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_Collections_11_e21bda570846150155f2343cbf3c946cafbf0239(OCI_Coll * c_inline_c_0, unsigned i_inline_c_1, OCI_Elem * e_inline_c_2) {
+return ( OCI_CollSetElem(c_inline_c_0, i_inline_c_1, e_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Collections_12_94990112fc2670d212c2c87ac9bfc3c6eabdc436(OCI_Coll * c_inline_c_0, OCI_Elem * e_inline_c_1) {
+return ( OCI_CollAppend(c_inline_c_0, e_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_Collections_13_2722aecc838c501f310b8c3d7171389215007545(OCI_Coll * c_inline_c_0, unsigned * sizePtr_inline_c_1, char * csptr_inline_c_2) {
+return ( OCI_CollToText(c_inline_c_0, sizePtr_inline_c_1, csptr_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Collections_14_46b6014df980da18ca197bda3ac12f4282b71d6a(OCI_Coll * c_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_CollDeleteElem(c_inline_c_0, i_inline_c_1) );
+}
+
+
+OCI_Iter * inline_c_Database_Ocilib_Collections_15_151f5e756397161f82e71e7ddbdb681c516efcc6(OCI_Coll * c_inline_c_0) {
+return ( OCI_IterCreate(c_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Collections_16_1525dc042f16086c416d12ed77db6452323e5c30(OCI_Iter * i_inline_c_0) {
+return ( OCI_IterFree(i_inline_c_0) );
+}
+
+
+OCI_Elem * inline_c_Database_Ocilib_Collections_17_cbee7fa80f0f68b251291227610bf1faeaa8e680(OCI_Iter * i_inline_c_0) {
+return ( OCI_IterGetNext(i_inline_c_0) );
+}
+
+
+OCI_Elem * inline_c_Database_Ocilib_Collections_18_2830848932ad5f9e77246adef17138802dedb965(OCI_Iter * i_inline_c_0) {
+return (OCI_IterGetPrev(i_inline_c_0) );
+}
+
+
+OCI_Elem * inline_c_Database_Ocilib_Collections_19_4ea35db2554ee76d18eaec7c692c33847f4985e7(OCI_Iter * i_inline_c_0) {
+return ( OCI_IterGetCurrent(i_inline_c_0) );
+}
+
+
+OCI_Elem * inline_c_Database_Ocilib_Collections_20_d2761415e70a6da70cec4de0a7c61800b77f8cc5(OCI_TypeInfo * ti_inline_c_0) {
+return ( OCI_ElemCreate(ti_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Collections_21_ff70dfeb07bc82dbbc392ca215676b6cde85dff5(OCI_Elem * e_inline_c_0) {
+return ( OCI_ElemFree(e_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Collections_22_a35f1d1edafb6e457e97665353674919ad3ddb07(OCI_Elem * e_inline_c_0) {
+return ( OCI_ElemGetBoolean(e_inline_c_0) );
+}
+
+
+const char * inline_c_Database_Ocilib_Collections_23_bec4b2e39b7f4fa73bf6a40840bbfbc7956b42c6(OCI_Elem * elem_inline_c_0) {
+return ( OCI_ElemGetString(elem_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Collections_24_e1ffdb9e2555de8d7a6e3f36f51760bd83e0b9c4(OCI_Elem * elem_inline_c_0, char * value_27_inline_c_1) {
+return ( OCI_ElemSetString(elem_inline_c_0, value_27_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_Collections_25_38ef00d25c0dbb1d2475e2e26e35a4194f94ea65(OCI_Elem * e_inline_c_0) {
+return ( OCI_ElemIsNull(e_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Collections_26_4a2eca8d652c8fd3ad33223ad22ac8d8f4b95dfd(OCI_Elem * e_inline_c_0) {
+return ( OCI_ElemSetNull(e_inline_c_0) );
+}
+
diff --git a/src/Database/Ocilib/Collections.hs b/src/Database/Ocilib/Collections.hs
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Collections.hs
@@ -0,0 +1,338 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE QuasiQuotes       #-}
+
+-- |
+-- Module:      Database.Ocilib.Collections
+-- Copyright:   (c) 2016 Thierry Bourrillon
+--              (c) 2016 FPInsight, Eurl.
+-- License:     BSD3
+-- Maintainer:  Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+--
+
+module Database.Ocilib.Collections
+    ( ociCollCreate
+    , ociCollFree
+    , ociCollAssign
+    , ociCollGetTypeInfo
+    , ociCollGetType
+    , ociCollGetMax
+    , ociCollGetSize
+    , ociCollGetCount
+    , ociCollTrim
+    , ociCollClear
+    , ociCollGetElem
+    --, ociCollGetElem2
+    , ociCollSetElem
+    , ociCollAppend
+    , ociCollToText
+    , ociCollDeleteElem
+    , ociIterCreate
+    , ociIterFree
+    , ociIterGetNext
+    , ociIterGetPrev
+    , ociIterGetCurrent
+    , ociElemCreate
+    , ociElemFree
+    , ociElemGetBoolean
+    --, ociElemGetShort
+    --, ociElemGetUnsignedShort
+    --, ociElemGetInt
+    --, ociElemGetUnsignedInt
+    --, ociElemGetBigInt
+    --, ociElemGetUnsignedBigInt
+    --, ociElemGetDouble
+    --, ociElemGetFloat
+    , ociElemGetString
+    --, ociElemGetRaw
+    --, ociElemGetRawSize
+    --, ociElemGetDate
+    --, ociElemGetTimestamp
+    --, ociElemGetInterval
+    --, ociElemGetLob
+    --, ociElemGetFile
+    --, ociElemGetObject
+    --, ociElemGetColl
+    --, ociElemGetRef
+    --, ociElemSetShort
+    --, ociElemSetUnsignedShort
+    --, ociElemSetInt
+    --, ociElemSetUnsignedInt
+    --, ociElemSetBigInt
+    --, ociElemSetUnsignedBigInt
+    --, ociElemSetDouble
+    --, ociElemSetFloat
+    , ociElemSetString
+    --, ociElemSetRaw
+    --, ociElemSetDate
+    --, ociElemSetTimestamp
+    --, ociElemSetInterval
+    --, ociElemSetColl
+    --, ociElemSetObject
+    --, ociElemSetLob
+    --, ociElemSetFile
+    --, ociElemSetRef
+    , ociElemIsNull
+    , ociElemSetNull
+    ) where
+
+import           Data.Monoid ((<>))
+import           Foreign.C.Types
+import           Foreign.C.String
+import           Foreign.Ptr
+import           Foreign.Marshal.Utils
+import qualified Language.C.Inline as C
+import           Database.Ocilib.Oci
+import           Database.Ocilib.Enums
+import           Database.Ocilib.Internal
+
+C.context (C.baseCtx <> C.funCtx <> ociCtx)
+
+C.include "<ocilib.h>"
+
+-- Oracle Collections (VARRAYS and Nested Tables)
+
+-- | Create a local collection instance.
+ociCollCreate :: Ptr OCI_TypeInfo -> IO (Maybe (Ptr OCI_Coll))
+ociCollCreate ti = fmap toMaybePtr [C.exp| OCI_Coll* { OCI_CollCreate($(OCI_TypeInfo *ti)) } |]
+
+-- | Free a local collection.
+ociCollFree :: Ptr OCI_Coll -> IO Bool
+ociCollFree coll =
+    fmap toBool [C.exp| int { OCI_CollFree($(OCI_Coll* coll)) } |]
+
+{-
+-- | Create an array of Collection object.
+-- OCI_Coll **OCI_CollArrayCreate (OCI_Connection *con, OCI_TypeInfo *typinf, unsigned int nbelem)
+
+-- | Free an array of Collection objects.
+-- boolean OCI_CollArrayFree (OCI_Coll **colls)
+-}
+
+-- | Assign a collection to another one.
+ociCollAssign :: Ptr OCI_Coll -> Ptr OCI_Coll -> IO Bool
+ociCollAssign dst src =
+    fmap toBool [C.exp| int { OCI_CollAssign($(OCI_Coll *dst), $(OCI_Coll *src)) } |]
+
+-- | Return the type info object associated to the collection.
+ociCollGetTypeInfo :: Ptr OCI_Coll -> IO (Ptr OCI_TypeInfo)
+ociCollGetTypeInfo c = [C.exp| OCI_TypeInfo* { OCI_CollGetTypeInfo($(OCI_Coll *c)) }|]
+
+-- | Return the collection type.
+ociCollGetType :: Ptr OCI_Coll -> IO CollectionType
+ociCollGetType c = fmap (toEnum . fromIntegral) [C.exp| unsigned int { OCI_CollGetType($(OCI_Coll *c)) } |]
+
+-- | Returns the maximum number of elements of the given collection.
+ociCollGetMax :: Ptr OCI_Coll -> IO CUInt
+ociCollGetMax c = [C.exp| unsigned int { OCI_CollGetMax($(OCI_Coll *c)) } |]
+
+-- | Returns the total number of elements of the given collection.
+ociCollGetSize :: Ptr OCI_Coll -> IO CUInt
+ociCollGetSize c = [C.exp| unsigned int { OCI_CollGetSize($(OCI_Coll *c)) } |]
+
+-- | Returns the current number of elements of the given collection.
+ociCollGetCount :: Ptr OCI_Coll -> IO CUInt
+ociCollGetCount c = [C.exp| unsigned int { OCI_CollGetCount($(OCI_Coll *c)) } |]
+
+-- | Trims the given number of elements from the end of the collection.
+ociCollTrim :: Ptr OCI_Coll -> CUInt -> IO Bool
+ociCollTrim c n = fmap toBool [C.exp| int { OCI_CollTrim($(OCI_Coll *c), $(unsigned int n)) } |]
+
+-- | clear all items of the given collection.
+ociCollClear :: Ptr OCI_Coll -> IO Bool
+ociCollClear c = fmap toBool [C.exp| int { OCI_CollClear($(OCI_Coll *c)) } |]
+
+-- | Return the element at the given position in the collection.
+ociCollGetElem :: Ptr OCI_Coll -> CUInt -> IO (Maybe (Ptr OCI_Elem))
+ociCollGetElem c i = fmap toMaybePtr [C.exp| OCI_Elem* { OCI_CollGetElem($(OCI_Coll *c), $(unsigned int i)) } |]
+
+{-
+-- | Return the element at the given position in the collection.
+-- boolean OCI_CollGetElem2 (OCI_Coll *coll, unsigned int index, OCI_Elem *elem)
+-}
+
+-- | Assign the given element value to the element at the given position in the collection.
+ociCollSetElem :: Ptr OCI_Coll -> CUInt -> Ptr OCI_Elem -> IO Bool
+ociCollSetElem c i e = fmap toBool [C.exp| int { OCI_CollSetElem($(OCI_Coll *c), $(unsigned int i), $(OCI_Elem *e)) } |]
+
+-- | Append the given element at the end of the collection.
+ociCollAppend :: Ptr OCI_Coll -> Ptr OCI_Elem -> IO Bool
+ociCollAppend c e = fmap toBool [C.exp| int { OCI_CollAppend($(OCI_Coll *c), $(OCI_Elem *e)) } |]
+
+-- | Convert a collection handle value to a string.
+ociCollToText :: Ptr OCI_Coll -> Ptr CUInt -> CString -> IO Bool
+ociCollToText c sizePtr csptr = fmap toBool [C.exp| int { OCI_CollToText($(OCI_Coll *c), $(unsigned int *sizePtr), $(char *csptr)) } |]
+
+-- | Delete the element at the given position in the Nested Table Collection.
+ociCollDeleteElem :: Ptr OCI_Coll -> CUInt -> IO Bool
+ociCollDeleteElem c i = fmap toBool [C.exp| int { OCI_CollDeleteElem($(OCI_Coll *c), $(unsigned int i)) }|]
+
+-- | Create an iterator handle to iterate through a collection.
+ociIterCreate :: Ptr OCI_Coll -> IO (Maybe (Ptr OCI_Iter))
+ociIterCreate c = fmap toMaybePtr [C.exp| OCI_Iter* { OCI_IterCreate($(OCI_Coll *c)) } |]
+
+-- | Free an iterator handle.
+ociIterFree :: Ptr OCI_Iter -> IO Bool
+ociIterFree i = fmap toBool [C.exp| int { OCI_IterFree($(OCI_Iter *i)) } |]
+
+-- | Get the next element in the collection.
+ociIterGetNext :: Ptr OCI_Iter -> IO (Maybe (Ptr OCI_Elem))
+ociIterGetNext i = fmap toMaybePtr [C.exp| OCI_Elem* { OCI_IterGetNext($(OCI_Iter *i)) } |]
+
+-- | Get the previous element in the collection.
+ociIterGetPrev :: Ptr OCI_Iter -> IO (Maybe (Ptr OCI_Elem))
+ociIterGetPrev i = fmap toMaybePtr [C.exp| OCI_Elem* {OCI_IterGetPrev($(OCI_Iter *i)) } |]
+
+-- | Get the current element in the collection.
+ociIterGetCurrent :: Ptr OCI_Iter -> IO (Maybe (Ptr OCI_Elem))
+ociIterGetCurrent i = fmap toMaybePtr [C.exp| OCI_Elem* { OCI_IterGetCurrent($(OCI_Iter *i)) } |]
+
+-- | Create a local collection element instance based on a collection type descriptor.
+ociElemCreate :: Ptr OCI_TypeInfo -> IO (Maybe (Ptr OCI_Elem))
+ociElemCreate ti = fmap toMaybePtr [C.exp| OCI_Elem* { OCI_ElemCreate($(OCI_TypeInfo *ti)) } |]
+
+-- | Free a local collection element.
+ociElemFree :: Ptr OCI_Elem -> IO Bool
+ociElemFree e = fmap toBool [C.exp| int { OCI_ElemFree($(OCI_Elem *e)) } |]
+
+-- | Return the boolean value of the given collection element.
+ociElemGetBoolean :: Ptr OCI_Elem -> IO Bool
+ociElemGetBoolean e = fmap toBool [C.exp| int { OCI_ElemGetBoolean($(OCI_Elem *e)) } |]
+
+{-
+-- | Return the short value of the given collection element.
+-- short OCI_ElemGetShort (OCI_Elem *elem)
+
+-- | Return the unsigned short value of the given collection element.
+-- unsigned short OCI_ElemGetUnsignedShort (OCI_Elem *elem)
+
+-- | Return the int value of the given collection element.
+-- int OCI_ElemGetInt (OCI_Elem *elem)
+
+-- | Return the unsigned int value of the given collection element.
+-- unsigned int OCI_ElemGetUnsignedInt (OCI_Elem *elem)
+
+-- | Return the big int value of the given collection element.
+-- big_int OCI_ElemGetBigInt (OCI_Elem *elem)
+
+-- | Return the unsigned big int value of the given collection element.
+-- big_uint OCI_ElemGetUnsignedBigInt (OCI_Elem *elem)
+
+-- | Return the Double value of the given collection element.
+-- double OCI_ElemGetDouble (OCI_Elem *elem)
+
+-- | Return the float value of the given collection element.
+-- float OCI_ElemGetFloat (OCI_Elem *elem)
+
+-}
+
+-- | Return the String value of the given collection element.
+ociElemGetString :: Ptr OCI_Elem -> IO String
+ociElemGetString elem = do
+    s <- [C.exp| const char* { OCI_ElemGetString($(OCI_Elem *elem)) } |]
+    peekCString s
+
+{-
+-- | Read the RAW value of the collection element into the given buffer.
+-- unsigned int OCI_ElemGetRaw (OCI_Elem *elem, void *value, unsigned int len)
+
+-- | Return the raw attribute value size of the given element handle.
+-- unsigned int OCI_ElemGetRawSize (OCI_Elem *elem)
+
+-- | Return the Date value of the given collection element.
+-- OCI_Date *OCI_ElemGetDate (OCI_Elem *elem)
+
+-- | Return the Timestamp value of the given collection element.
+-- OCI_Timestamp *OCI_ElemGetTimestamp (OCI_Elem *elem)
+
+-- | Return the Interval value of the given collection element.
+-- OCI_Interval *OCI_ElemGetInterval (OCI_Elem *elem)
+
+-- | Return the Lob value of the given collection element.
+-- OCI_Lob *OCI_ElemGetLob (OCI_Elem *elem)
+
+-- | Return the File value of the given collection element.
+-- OCI_File *OCI_ElemGetFile (OCI_Elem *elem)
+
+-- | Return the object value of the given collection element.
+-- OCI_Object *OCI_ElemGetObject (OCI_Elem *elem)
+
+-- | Return the collection value of the given collection element.
+-- OCI_Coll *OCI_ElemGetColl (OCI_Elem *elem)
+
+-- | Return the Ref value of the given collection element.
+-- OCI_Ref *OCI_ElemGetRef (OCI_Elem *elem)
+
+-- | Set a boolean value to a collection element.
+-- boolean OCI_ElemSetBoolean (OCI_Elem *elem, boolean value)
+
+-- | Set a short value to a collection element.
+-- boolean OCI_ElemSetShort (OCI_Elem *elem, short value)
+
+-- | Set a unsigned short value to a collection element.
+-- boolean OCI_ElemSetUnsignedShort (OCI_Elem *elem, unsigned short value)
+
+-- | Set a int value to a collection element.
+-- boolean OCI_ElemSetInt (OCI_Elem *elem, int value)
+
+-- | Set a unsigned int value to a collection element.
+-- boolean OCI_ElemSetUnsignedInt (OCI_Elem *elem, unsigned int value)
+
+-- | Set a big int value to a collection element.
+-- boolean OCI_ElemSetBigInt (OCI_Elem *elem, big_int value)
+
+-- | Set a unsigned big_int value to a collection element.
+-- boolean OCI_ElemSetUnsignedBigInt (OCI_Elem *elem, big_uint value)
+
+-- | Set a double value to a collection element.
+-- boolean OCI_ElemSetDouble (OCI_Elem *elem, double value)
+
+-- | Set a float value to a collection element.
+-- boolean OCI_ElemSetFloat (OCI_Elem *elem, float value)
+-}
+
+-- | Set a string value to a collection element.
+ociElemSetString :: Ptr OCI_Elem -> String -> IO Bool
+ociElemSetString elem value =
+    withCString value (\value' ->
+        fmap toBool [C.exp| int { OCI_ElemSetString($(OCI_Elem *elem), $(char *value')) } |]
+    )
+{-
+-- | Set a RAW value to a collection element.
+-- boolean OCI_ElemSetRaw (OCI_Elem *elem, void *value, unsigned int len)
+
+-- | Assign a Date handle to a collection element.
+-- boolean OCI_ElemSetDate (OCI_Elem *elem, OCI_Date *value)
+
+-- | Assign a Timestamp handle to a collection element.
+-- boolean OCI_ElemSetTimestamp (OCI_Elem *elem, OCI_Timestamp *value)
+
+-- | Assign an Interval handle to a collection element.
+-- boolean OCI_ElemSetInterval (OCI_Elem *elem, OCI_Interval *value)
+
+-- | Assign a Collection handle to a collection element.
+-- boolean OCI_ElemSetColl (OCI_Elem *elem, OCI_Coll *value)
+
+-- | Assign an Object handle to a collection element.
+-- boolean OCI_ElemSetObject (OCI_Elem *elem, OCI_Object *value)
+
+-- | Assign a Lob handle to a collection element.
+-- boolean OCI_ElemSetLob (OCI_Elem *elem, OCI_Lob *value)
+
+-- | Assign a File handle to a collection element.
+-- boolean OCI_ElemSetFile (OCI_Elem *elem, OCI_File *value)
+
+-- | Assign a Ref handle to a collection element.
+-- boolean OCI_ElemSetRef (OCI_Elem *elem, OCI_Ref *value)
+-}
+
+-- | Check if the collection element value is null.
+ociElemIsNull :: Ptr OCI_Elem -> IO Bool
+ociElemIsNull e = fmap toBool [C.exp| int { OCI_ElemIsNull($(OCI_Elem *e)) }|]
+
+-- | Set a collection element value to null.
+ociElemSetNull :: Ptr OCI_Elem -> IO Bool
+ociElemSetNull e = fmap toBool [C.exp| int { OCI_ElemSetNull($(OCI_Elem *e)) } |]
diff --git a/src/Database/Ocilib/Connection.c b/src/Database/Ocilib/Connection.c
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Connection.c
@@ -0,0 +1,27 @@
+
+#include <ocilib.h>
+
+OCI_Connection * inline_c_Database_Ocilib_Connection_0_cb27b4dad4bd70fd6af21b42c7b947e0834bbcc6(char * d_inline_c_0, char * u_inline_c_1, char * p_inline_c_2, unsigned m_inline_c_3) {
+return ( OCI_ConnectionCreate(d_inline_c_0, u_inline_c_1, p_inline_c_2, m_inline_c_3) );
+}
+
+
+int inline_c_Database_Ocilib_Connection_1_f2c89c7670fdb5ec369d67b76354a55b869ab370(OCI_Connection * c_inline_c_0) {
+return ( OCI_ConnectionFree(c_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Connection_2_5bbc3fc6b8f4fb9f03b845dbc3a52c08582c2fa3(OCI_Connection * c_inline_c_0) {
+return ( OCI_IsConnected(c_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Connection_3_ef6d0fcfe7a9782f52d5fd8de99e6342e79a0f8c(OCI_Connection * c_inline_c_0) {
+return ( OCI_Ping(c_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Connection_4_a0b66ad2930b7d692ad29550de7ef247b7a0f990(OCI_Connection * c_inline_c_0) {
+return ( OCI_Break(c_inline_c_0) );
+}
+
diff --git a/src/Database/Ocilib/Connection.hs b/src/Database/Ocilib/Connection.hs
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Connection.hs
@@ -0,0 +1,176 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE QuasiQuotes       #-}
+
+-- |
+-- Module:      Database.Ocilib.Connection
+-- Copyright:   (c) 2016 Thierry Bourrillon
+--              (c) 2016 FPInsight, Eurl.
+-- License:     BSD3
+-- Maintainer:  Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+--
+
+module Database.Ocilib.Connection
+    (
+    -- * Connecting to Database
+      ociConnectionCreate
+    , ociConnectionFree
+    , ociIsConnected
+    , ociPing
+    , ociBreak
+    ) where
+
+import           Data.Monoid ((<>))
+-- import           Foreign.C.Types
+import           Foreign.C.String
+import           Foreign.Marshal.Utils
+import           Foreign.Ptr
+import qualified Language.C.Inline as C
+import           Database.Ocilib.Oci
+import           Database.Ocilib.Enums
+import           Database.Ocilib.Internal
+
+C.context (C.baseCtx <> C.funCtx <> ociCtx)
+
+C.include "<ocilib.h>"
+
+-- Connecting to database
+
+type Connection = Ptr OCI_Connection
+
+-- | Create a physical connection to an Oracle database server.
+ociConnectionCreate :: String -> String -> String -> SessionMode -> IO (Maybe Connection)
+ociConnectionCreate db user pass mode = do
+    let m = fromIntegral $ fromEnum mode
+    withCString db ( \d ->
+        withCString user ( \u ->
+            withCString pass ( \p ->
+                fmap toMaybePtr [C.exp| OCI_Connection* { OCI_ConnectionCreate($(char* d), $(char* u), $(char* p), $(unsigned int m)) } |]
+            )
+        )
+        )
+
+-- | Close a physical connection to an Oracle database server.
+ociConnectionFree :: Ptr OCI_Connection -> IO Bool
+ociConnectionFree c =
+    fmap toBool [C.exp| int { OCI_ConnectionFree($(OCI_Connection *c)) } |]
+
+-- | Returns TRUE is the given connection is still connected otherwise FALSE.
+ociIsConnected :: Ptr OCI_Connection -> IO Bool
+ociIsConnected c =
+    fmap toBool [C.exp| int { OCI_IsConnected($(OCI_Connection *c)) } |]
+
+{-
+-- | Return the pointer to user data previously associated with the connection.
+-- void *OCI_GetUserData (OCI_Connection *con)
+
+-- | Associate a pointer to user data to the given connection.
+-- boolean OCI_SetUserData (OCI_Connection *con, void *data)
+
+-- | Associate a tag to the given connection/session.
+-- boolean OCI_SetSessionTag (OCI_Connection *con, const otext *tag)
+
+-- | Return the tag associated the given connection.
+-- const otext *OCI_GetSessionTag (OCI_Connection *con)
+
+-- | Return the name of the connected database/service name.
+-- const otext *OCI_GetDatabase (OCI_Connection *con)
+
+-- | Return the current logged user name.
+-- const otext *OCI_GetUserName (OCI_Connection *con)
+
+-- | Return the current logged user password.
+-- const otext *OCI_GetPassword (OCI_Connection *con)
+
+-- | Change the password of the logged user.
+-- boolean OCI_SetPassword(OCI_Connection *con, const otext *password)
+
+-- | Change the password of the given user on the given database.
+-- boolean OCI_SetUserPassword (const otext *db, const otext *user, const otext *pwd, const otext *new_pwd)
+
+-- | Return the current session mode.
+-- unsigned int OCI_GetSessionMode (OCI_Connection *con)
+
+-- | Return the connected database server version.
+-- const otext *OCI_GetVersionServer (OCI_Connection *con)
+
+-- | Return the major version number of the connected database server.
+-- unsigned int OCI_GetServerMajorVersion (OCI_Connection *con)
+
+-- | Return the minor version number of the connected database server.
+-- unsigned int OCI_GetServerMinorVersion (OCI_Connection *con)
+
+-- | Return the revision version number of the connected database server.
+-- unsigned int OCI_GetServerRevisionVersion (OCI_Connection *con)
+
+-- | Set the format string for implicit string conversions of the given type.
+-- boolean OCI_SetFormat (OCI_Connection *con, unsigned int type, const otext *format)
+
+-- | Return the format string for implicit string conversions of the given type.
+-- const otext *OCI_GetFormat (OCI_Connection *con, unsigned int type)
+
+-- | Return the current transaction of the connection.
+-- OCI_Transaction *OCI_GetTransaction (OCI_Connection *con)
+
+-- | Return the highest Oracle version is supported by the connection.
+-- unsigned int OCI_GetVersionConnection (OCI_Connection *con)
+
+-- | Set tracing information to the session of the given connection.
+-- boolean OCI_SetTrace (OCI_Connection *con, unsigned int trace, const otext *value)
+
+-- | Get the current trace for the trace type from the given connection.
+-- const otext *OCI_GetTrace (OCI_Connection *con, unsigned int trace)
+
+-}
+
+-- | Makes a round trip call to the server to confirm that the connection and the server are active.
+ociPing :: Ptr OCI_Connection -> IO Bool
+ociPing c = fmap toBool [C.exp| int { OCI_Ping($(OCI_Connection *c)) } |]
+
+{-
+-- | Return the Oracle server database name of the connected database/service name.
+-- const otext *OCI_GetDBName (OCI_Connection *con)
+
+-- | Return the Oracle server Instance name of the connected database/service name.
+-- const otext *OCI_GetInstanceName (OCI_Connection *con)
+
+-- | Return the Oracle server service name of the connected database/service name.
+-- const otext *OCI_GetServiceName (OCI_Connection *con)
+
+-- | Return the Oracle server machine name of the connected database/service name.
+-- const otext *OCI_GetServerName (OCI_Connection *con)
+
+-- | Return the Oracle server domain name of the connected database/service name.
+-- const otext *OCI_GetDomainName (OCI_Connection *con)
+
+-- | Return the date and time (Timestamp) server instance start of the connected database/service name.
+-- OCI_Timestamp *OCI_GetInstanceStartTime (OCI_Connection *con)
+
+-- | Verify if the given connection support TAF events.
+-- boolean OCI_IsTAFCapable (OCI_Connection *con)
+
+-- | Set the Transparent Application Failover (TAF) user handler.
+-- boolean OCI_SetTAFHandler (OCI_Connection *con, POCI_TAF_HANDLER handler)
+
+-- | Return the maximum number of statements to keep in the statement cache.
+-- unsigned int OCI_GetStatementCacheSize (OCI_Connection *con)
+
+-- | Set the maximum number of statements to keep in the statement cache.
+-- boolean OCI_SetStatementCacheSize (OCI_Connection *con, unsigned int value)
+
+-- | Return the default LOB prefetch buffer size for the connection.
+-- unsigned int OCI_GetDefaultLobPrefetchSize (OCI_Connection *con)
+
+-- | Enable or disable prefetching for all LOBs fetched in the connection.
+-- boolean OCI_SetDefaultLobPrefetchSize (OCI_Connection *con, unsigned int value)
+
+-- | Return the maximum number of SQL statements that can be opened in one session.
+-- unsigned int OCI_GetMaxCursors (OCI_Connection *con)
+-}
+
+-- | Perform an immediate abort of any currently Oracle OCI call.
+ociBreak :: Ptr OCI_Connection -> IO Bool
+ociBreak c = fmap toBool [C.exp| int { OCI_Break($(OCI_Connection *c)) } |]
diff --git a/src/Database/Ocilib/DateTime.c b/src/Database/Ocilib/DateTime.c
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/DateTime.c
@@ -0,0 +1,12 @@
+
+#include <ocilib.h>
+
+OCI_Date * inline_c_Database_Ocilib_DateTime_0_5473f9adb146f44d53fb5c38cfdde4d6ff37b705(OCI_Connection * c_inline_c_0) {
+return ( OCI_DateCreate(c_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_DateTime_1_789c0ae5ec780f1e0435d1e238b69c16d0b33e08(OCI_Date * d_inline_c_0) {
+return ( OCI_DateFree(d_inline_c_0) );
+}
+
diff --git a/src/Database/Ocilib/DateTime.hs b/src/Database/Ocilib/DateTime.hs
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/DateTime.hs
@@ -0,0 +1,105 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE QuasiQuotes       #-}
+
+-- |
+-- Module:      Database.Ocilib.DateTime
+-- Copyright:   (c) 2016 Thierry Bourrillon
+--              (c) 2016 FPInsight, Eurl.
+-- License:     BSD3
+-- Maintainer:  Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+--
+
+module Database.Ocilib.DateTime where
+
+import           Data.Monoid ((<>))
+-- import           Foreign.C.Types
+-- import           Foreign.C.String
+import           Foreign.Marshal.Utils
+import           Foreign.Ptr
+import qualified Language.C.Inline as C
+import           Database.Ocilib.Oci
+-- import           Database.Ocilib.Enums
+
+C.context (C.baseCtx <> C.funCtx <> ociCtx)
+
+C.include "<ocilib.h>"
+
+-- | Create a local date object.
+ociDateCreate :: Ptr OCI_Connection -> IO (Ptr OCI_Date)
+ociDateCreate c = [C.exp| OCI_Date* { OCI_DateCreate($(OCI_Connection *c)) } |]
+
+-- | Free a date object.
+ociDateFree :: Ptr OCI_Date -> IO Bool
+ociDateFree d = fmap toBool [C.exp| int { OCI_DateFree($(OCI_Date *d)) } |]
+
+{-
+-- | Create an array of date object.
+-- OCI_Date **OCI_DateArrayCreate (OCI_Connection *con, unsigned int nbelem)
+
+-- | Free an array of date objects.
+-- boolean OCI_DateArrayFree (OCI_Date **dates)
+
+-- | Add or subtract days to a date handle.
+-- boolean OCI_DateAddDays (OCI_Date *date, int nb)
+
+-- | Add or subtract months to a date handle.
+-- boolean OCI_DateAddMonths (OCI_Date *date, int nb)
+
+-- | Assign the value of a date handle to another one.
+-- int OCI_DateAssign (OCI_Date *date, OCI_Date *date_src)
+
+-- | Check if the given date is valid.
+-- int OCI_DateCheck (OCI_Date *date)
+
+-- | Compares two date handles.
+-- int OCI_DateCompare (OCI_Date *date, OCI_Date *date2)
+
+-- | Return the number of days betWeen two dates.
+-- int OCI_DateDaysBetween (OCI_Date *date, OCI_Date *date2)
+
+-- | Convert a string to a date and store it in the given date handle.
+-- boolean OCI_DateFromText (OCI_Date *date, const otext *str, const otext *fmt)
+
+-- | Convert a Date value from the given date handle to a string.
+-- boolean OCI_DateToText (OCI_Date *date, const otext *fmt, int size, otext *str)
+
+-- | Extract the date part from a date handle.
+-- boolean OCI_DateGetDate (OCI_Date *date, int *year, int *month, int *day)
+
+-- | Extract the time part from a date handle.
+-- boolean OCI_DateGetTime (OCI_Date *date, int *hour, int *min, int *sec)
+
+-- | Extract the date and time parts from a date handle.
+-- boolean OCI_DateGetDateTime (OCI_Date *date, int *year, int *month, int *day, int *hour, int *min, int *sec)
+
+-- | Set the date portion if the given date handle.
+-- boolean OCI_DateSetDate (OCI_Date *date, int year, int month, int day)
+
+-- | Set the time portion if the given date handle.
+-- boolean OCI_DateSetTime (OCI_Date *date, int hour, int min, int sec)
+
+-- | Set the date and time portions if the given date handle.
+-- boolean OCI_DateSetDateTime (OCI_Date *date, int year, int month, int day, int hour, int min, int sec)
+
+-- | Place the last day of month (from the given date) into the given date.
+-- boolean OCI_DateLastDay (OCI_Date *date)
+
+-- | Gets the date of next day of the week, after a given date.
+-- boolean OCI_DateNextDay (OCI_Date *date, const otext *day)
+
+-- | Return the current system date/time into the date handle.
+-- boolean OCI_DateSysDate (OCI_Date *date)
+
+-- | Convert a date from one zone to another zone. More...
+-- boolean OCI_DateZoneToZone (OCI_Date *date, const otext *zone1, const otext *zone2)
+
+-- | Affect an OCI_Date handle value to ISO C time data types.
+-- boolean OCI_DateToCTime (OCI_Date *date, struct tm *ptm, time_t *pt)
+
+-- | Affect ISO C time data types values to an OCI_Date handle.
+-- boolean OCI_DateFromCTime (OCI_Date *date, struct tm *ptm, time_t t)
+-}
diff --git a/src/Database/Ocilib/Enums.chs b/src/Database/Ocilib/Enums.chs
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Enums.chs
@@ -0,0 +1,613 @@
+{-# LANGUAGE EmptyDataDecls           #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+-- |
+-- Module:      Database.Ocilib.Enums
+-- Copyright:   (c) 2016 Thierry Bourrillon
+--              (c) 2016 FPInsight, Eurl.
+-- License:     BSD3
+-- Maintainer:  Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+--
+
+module Database.Ocilib.Enums where
+
+import Database.Ocilib.BitMask
+
+
+#include <ocilib.h>
+
+{#enum define ImportMode { OCI_IMPORT_MODE_LINKAGE as OCI_IMPORT_MODE_LINKAGE
+                         , OCI_IMPORT_MODE_RUNTIME as OCI_IMPORT_MODE_RUNTIME
+                         } deriving (Eq, Ord, Show) #}
+
+{#enum define CharsetMode { OCI_CHAR_ANSI as OCI_CHAR_ANSI
+                          , OCI_CHAR_WIDE as OCI_CHAR_WIDE
+                          } deriving (Eq, Ord, Show) #}
+
+-- OCILIB Error types
+
+{#enum define ErrorType { OCI_ERR_ORACLE  as OCI_ERR_ORACLE
+                        , OCI_ERR_OCILIB  as OCI_ERR_OCILIB
+                        , OCI_ERR_WARNING as OCI_ERR_WARNING
+                        } deriving (Eq, Ord, Show) #}
+
+-- OCILIB Error codes
+
+{#enum define ErrorCode { OCI_ERR_NONE                   as OCI_ERR_NONE
+                        , OCI_ERR_NOT_INITIALIZED        as OCI_ERR_NOT_INITIALIZED
+                        , OCI_ERR_LOADING_SHARED_LIB     as OCI_ERR_LOADING_SHARED_LIB
+                        , OCI_ERR_LOADING_SYMBOLS        as OCI_ERR_LOADING_SYMBOLS
+                        , OCI_ERR_MULTITHREADED          as OCI_ERR_MULTITHREADED
+                        , OCI_ERR_MEMORY                 as OCI_ERR_MEMORY
+                        , OCI_ERR_NOT_AVAILABLE          as OCI_ERR_NOT_AVAILABLE
+                        , OCI_ERR_NULL_POINTER           as OCI_ERR_NULL_POINTER
+                        , OCI_ERR_DATATYPE_NOT_SUPPORTED as OCI_ERR_DATATYPE_NOT_SUPPORTED
+                        , OCI_ERR_PARSE_TOKEN            as OCI_ERR_PARSE_TOKEN
+                        , OCI_ERR_MAP_ARGUMENT           as OCI_ERR_MAP_ARGUMENT
+                        , OCI_ERR_OUT_OF_BOUNDS          as OCI_ERR_OUT_OF_BOUNDS
+                        , OCI_ERR_UNFREED_DATA           as OCI_ERR_UNFREED_DATA
+                        , OCI_ERR_MAX_BIND               as OCI_ERR_MAX_BIND
+                        , OCI_ERR_ATTR_NOT_FOUND         as OCI_ERR_ATTR_NOT_FOUND
+                        , OCI_ERR_MIN_VALUE              as OCI_ERR_MIN_VALUE
+                        , OCI_ERR_NOT_COMPATIBLE         as OCI_ERR_NOT_COMPATIBLE
+                        , OCI_ERR_STMT_STATE             as OCI_ERR_STMT_STATE
+                        , OCI_ERR_STMT_NOT_SCROLLABLE    as OCI_ERR_STMT_NOT_SCROLLABLE
+                        , OCI_ERR_BIND_ALREADY_USED      as OCI_ERR_BIND_ALREADY_USED
+                        , OCI_ERR_BIND_ARRAY_SIZE        as OCI_ERR_BIND_ARRAY_SIZE
+                        , OCI_ERR_COLUMN_NOT_FOUND       as OCI_ERR_COLUMN_NOT_FOUND
+                        , OCI_ERR_DIRPATH_STATE          as OCI_ERR_DIRPATH_STATE
+                        , OCI_ERR_CREATE_OCI_ENVIRONMENT as OCI_ERR_CREATE_OCI_ENVIRONMENT
+                        , OCI_ERR_REBIND_BAD_DATATYPE    as OCI_ERR_REBIND_BAD_DATATYPE
+                        , OCI_ERR_TYPEINFO_DATATYPE      as OCI_ERR_TYPEINFO_DATATYPE
+                        , OCI_ERR_ITEM_NOT_FOUND         as OCI_ERR_ITEM_NOT_FOUND
+                        , OCI_ERR_ARG_INVALID_VALUE      as OCI_ERR_ARG_INVALID_VALUE
+                        } deriving (Eq, Ord, Show) #}
+
+-- allocated bytes types --
+
+{#enum define AllocatedBytesType { OCI_MEM_ORACLE as OCI_MEM_ORACLE
+                                 , OCI_MEM_OCILIB as OCI_MEM_OCILIB
+                                 , OCI_MEM_ALL    as OCI_MEM_ALL
+                                 } deriving (Eq, Ord, Show) #}
+
+-- binding --
+
+{#enum define BindMode { OCI_BIND_BY_POS as OCI_BIND_BY_POS
+                       , OCI_BIND_BY_NAME as OCI_BIND_BY_NAME
+                       } deriving (Eq, Ord, Show) #}
+
+
+-- fetching --
+{#enum define LongMode { OCI_LONG_EXPLICIT as OCI_LONG_EXPLICIT
+                       , OCI_LONG_IMPLICIT as OCI_LONG_IMPLICIT
+                       } deriving (Eq, Ord, Show) #}
+
+{-
+-- unknown value --
+
+OCI_UNKNOWN                         0
+-}
+
+-- C Data Type mapping --
+{#enum define ColumnType { OCI_CDT_NUMERIC    as OCI_CDT_NUMERIC
+                         , OCI_CDT_DATETIME   as OCI_CDT_DATETIME
+                         , OCI_CDT_TEXT       as OCI_CDT_TEXT
+                         , OCI_CDT_LONG       as OCI_CDT_LONG
+                         , OCI_CDT_CURSOR     as OCI_CDT_CURSOR
+                         , OCI_CDT_LOB        as OCI_CDT_LOB
+                         , OCI_CDT_FILE       as OCI_CDT_FILE
+                         , OCI_CDT_TIMESTAMP  as OCI_CDT_TIMESTAMP
+                         , OCI_CDT_INTERVAL   as OCI_CDT_INTERVAL
+                         , OCI_CDT_RAW        as OCI_CDT_RAW
+                         , OCI_CDT_OBJECT     as OCI_CDT_OBJECT
+                         , OCI_CDT_COLLECTION as OCI_CDT_COLLECTION
+                         , OCI_CDT_REF        as OCI_CDT_REF
+                         , OCI_CDT_BOOLEAN    as OCI_CDT_BOOLEAN
+                         } deriving (Eq, Ord, Show) #}
+
+-- Data Type codes for OCI_ImmediateXXX() calls --
+{#enum define DataTypeCode { OCI_ARG_SHORT      as OCI_ARG_SHORT
+                           , OCI_ARG_USHORT     as OCI_ARG_USHORT
+                           , OCI_ARG_INT        as OCI_ARG_INT
+                           , OCI_ARG_UINT       as OCI_ARG_UINT
+                           , OCI_ARG_BIGINT     as OCI_ARG_BIGINT
+                           , OCI_ARG_BIGUINT    as OCI_ARG_BIGUINT
+                           , OCI_ARG_DOUBLE     as OCI_ARG_DOUBLE
+                           , OCI_ARG_DATETIME   as OCI_ARG_DATETIME
+                           , OCI_ARG_TEXT       as OCI_ARG_TEXT
+                           , OCI_ARG_LOB        as OCI_ARG_LOB
+                           , OCI_ARG_FILE       as OCI_ARG_FILE
+                           , OCI_ARG_TIMESTAMP  as OCI_ARG_TIMESTAMP
+                           , OCI_ARG_INTERVAL   as OCI_ARG_INTERVAL
+                           , OCI_ARG_RAW        as OCI_ARG_RAW
+                           , OCI_ARG_OBJECT     as OCI_ARG_OBJECT
+                           , OCI_ARG_COLLECTION as OCI_ARG_COLLECTION
+                           , OCI_ARG_REF        as OCI_ARG_REF
+                           , OCI_ARG_FLOAT      as OCI_ARG_FLOAT
+                           } deriving (Eq, Ord, Show) #}
+
+
+-- statement types --
+
+{#enum define StatementType { OCI_CST_SELECT as OCI_CST_SELECT
+                            , OCI_CST_UPDATE as OCI_CST_UPDATE
+                            , OCI_CST_DELETE as OCI_CST_DELETE
+                            , OCI_CST_INSERT as OCI_CST_INSERT
+                            , OCI_CST_CREATE as OCI_CST_CREATE
+                            , OCI_CST_DROP as OCI_CST_DROP
+                            , OCI_CST_ALTER as OCI_CST_ALTER
+                            , OCI_CST_BEGIN as OCI_CST_BEGIN
+                            , OCI_CST_DECLARE as OCI_CST_DECLARE
+                            , OCI_CST_CALL as OCI_CST_CALL
+                            } deriving (Eq, Ord, Show) #}
+
+-- environment modes --
+
+{#enum define EnvironmentMode { OCI_ENV_DEFAULT as OCI_ENV_DEFAULT
+                              , OCI_ENV_THREADED as OCI_ENV_THREADED
+                              , OCI_ENV_CONTEXT as OCI_ENV_CONTEXT
+                              , OCI_ENV_EVENTS as OCI_ENV_EVENTS
+                              } deriving (Eq, Ord, Show) #}
+
+instance ToBitMask EnvironmentMode
+
+-- sessions modes --
+
+{#enum define SessionMode { OCI_SESSION_DEFAULT as OCI_SESSION_DEFAULT
+                          , OCI_SESSION_XA as OCI_SESSION_XA
+                          , OCI_SESSION_SYSDBA as OCI_SESSION_SYSDBA
+                          , OCI_SESSION_SYSOPER as OCI_SESSION_SYSOPER
+                          , OCI_SESSION_PRELIM_AUTH as OCI_SESSION_PRELIM_AUTH
+                          } deriving (Eq, Ord, Show) #}
+
+
+-- change notification types --
+
+{#enum define ChangeNotificationType { OCI_CNT_OBJECTS   as OCI_CNT_OBJECTS
+                                     , OCI_CNT_ROWS      as OCI_CNT_ROWS
+                                     , OCI_CNT_DATABASES as OCI_CNT_DATABASES
+                                     , OCI_CNT_ALL       as OCI_CNT_ALL
+                                     } deriving (Eq, Ord, Show) #}
+
+-- event notification types --
+
+{#enum define EventNotificationType { OCI_ENT_STARTUP        as OCI_ENT_STARTUP
+                                    , OCI_ENT_SHUTDOWN       as OCI_ENT_SHUTDOWN
+                                    , OCI_ENT_SHUTDOWN_ANY   as OCI_ENT_SHUTDOWN_ANY
+                                    , OCI_ENT_DROP_DATABASE  as OCI_ENT_DROP_DATABASE
+                                    , OCI_ENT_DEREGISTER     as OCI_ENT_DEREGISTER
+                                    , OCI_ENT_OBJECT_CHANGED as OCI_ENT_OBJECT_CHANGED
+                                    } deriving (Eq, Ord, Show) #}
+
+-- event object notification types --
+
+{#enum define EventObjectNotificationType { OCI_ONT_INSERT  as OCI_ONT_INSERT
+                                          , OCI_ONT_UPDATE  as OCI_ONT_UPDATE
+                                          , OCI_ONT_DELETE  as OCI_ONT_DELETE
+                                          , OCI_ONT_ALTER   as OCI_ONT_ALTER
+                                          , OCI_ONT_DROP    as OCI_ONT_DROP
+                                          , OCI_ONT_GENERIC as OCI_ONT_GENERIC
+                                          } deriving (Eq, Ord, Show) #}
+
+-- database startup modes --
+
+{#enum define DatabaseStartupMode { OCI_DB_SPM_START as OCI_DB_SPM_START
+                                  , OCI_DB_SPM_MOUNT as OCI_DB_SPM_MOUNT
+                                  , OCI_DB_SPM_OPEN  as OCI_DB_SPM_OPEN
+                                  , OCI_DB_SPM_FULL  as OCI_DB_SPM_FULL
+                                  } deriving (Eq, Ord, Show) #}
+
+-- database startup flags --
+
+{#enum define DatabaseStartupFlag { OCI_DB_SPF_DEFAULT  as OCI_DB_SPF_DEFAULT
+                                  , OCI_DB_SPF_FORCE    as OCI_DB_SPF_FORCE
+                                  , OCI_DB_SPF_RESTRICT as OCI_DB_SPF_RESTRICT
+                                  } deriving (Eq, Ord, Show) #}
+
+
+-- database shutdown modes --
+
+{#enum define DatabaseShutdownMode { OCI_DB_SDM_SHUTDOWN as OCI_DB_SDM_SHUTDOWN
+                                   , OCI_DB_SDM_CLOSE    as OCI_DB_SDM_CLOSE
+                                   , OCI_DB_SDM_DISMOUNT as OCI_DB_SDM_DISMOUNT
+                                   , OCI_DB_SDM_FULL     as OCI_DB_SDM_FULL
+                                   } deriving (Eq, Ord, Show) #}
+
+-- database shutdown flags --
+
+{#enum define DatabaseShutdownFlag { OCI_DB_SDF_DEFAULT     as OCI_DB_SDF_DEFAULT
+                                   , OCI_DB_SDF_TRANS       as OCI_DB_SDF_TRANS
+                                   , OCI_DB_SDF_TRANS_LOCAL as OCI_DB_SDF_TRANS_LOCAL
+                                   , OCI_DB_SDF_IMMEDIATE   as OCI_DB_SDF_IMMEDIATE
+                                   , OCI_DB_SDF_ABORT       as OCI_DB_SDF_ABORT
+                                   } deriving (Eq, Ord, Show) #}
+
+-- charset form types --
+{#enum define CharsetFormType { OCI_CSF_NONE     as OCI_CSF_NONE
+                              , OCI_CSF_DEFAULT  as OCI_CSF_DEFAULT
+                              , OCI_CSF_NATIONAL as OCI_CSF_NATIONAL
+                              } deriving (Eq, Ord, Show) #}
+
+-- statement fetch mode --
+
+{#enum define StatementFetchMode { OCI_SFM_DEFAULT    as OCI_SFM_DEFAULT
+                                 , OCI_SFM_SCROLLABLE as OCI_SFM_SCROLLABLE
+                                 } deriving (Eq, Ord, Show) #}
+
+-- statement fetch direction --
+
+{#enum define StatementFetchDirection { OCI_SFD_ABSOLUTE as OCI_SFD_ABSOLUTE
+                                      , OCI_SFD_RELATIVE as OCI_SFD_RELATIVE
+                                      } deriving (Eq, Ord, Show) #}
+
+-- bind allocation mode --
+
+{#enum define BindAllocationMode { OCI_BAM_EXTERNAL as OCI_BAM_EXTERNAL
+                                 , OCI_BAM_INTERNAL as OCI_BAM_INTERNAL
+                                 } deriving (Eq, Ord, Show) #}
+
+-- bind direction mode --
+
+{#enum define BindDirectionMode { OCI_BDM_IN     as OCI_BDM_IN
+                                , OCI_BDM_OUT    as OCI_BDM_OUT
+                                , OCI_BDM_IN_OUT as OCI_BDM_IN_OUT
+                                } deriving (Eq, Ord, Show) #}
+
+-- Column property flags --
+
+{#enum define ColumnPropertyFlag { OCI_CPF_NONE                      as OCI_CPF_NONE
+                                 , OCI_CPF_IS_IDENTITY               as OCI_CPF_IS_IDENTITY
+                                 , OCI_CPF_IS_GEN_ALWAYS             as OCI_CPF_IS_GEN_ALWAYS
+                                 , OCI_CPF_IS_GEN_BY_DEFAULT_ON_NULL as OCI_CPF_IS_GEN_BY_DEFAULT_ON_NULL
+                                 } deriving (Eq, Ord, Show) #}
+
+{- See OCI_SUBTYPE
+-- Integer sign flag --
+
+OCI_NUM_UNSIGNED                    2
+
+-- External Integer types --
+
+OCI_NUM_SHORT                       4
+OCI_NUM_INT                         8
+OCI_NUM_BIGINT                      16
+OCI_NUM_FLOAT                       32
+OCI_NUM_DOUBLE                      64
+
+OCI_NUM_USHORT                      (OCI_NUM_SHORT  | OCI_NUM_UNSIGNED)
+OCI_NUM_UINT                        (OCI_NUM_INT    | OCI_NUM_UNSIGNED)
+OCI_NUM_BIGUINT                     (OCI_NUM_BIGINT | OCI_NUM_UNSIGNED)
+
+-}
+
+-- timestamp types --
+
+{#enum define TimestampType { OCI_TIMESTAMP     as OCI_TIMESTAMP
+                            , OCI_TIMESTAMP_TZ  as OCI_TIMESTAMP_TZ
+                            , OCI_TIMESTAMP_LTZ as OCI_TIMESTAMP_LTZ
+                            } deriving (Eq, Ord, Show) #}
+
+-- interval types --
+{#enum define IntervalType { OCI_INTERVAL_YM as OCI_INTERVAL_YM
+                           , OCI_INTERVAL_DS as OCI_INTERVAL_DS
+                           } deriving (Eq, Ord, Show) #}
+
+-- long types --
+
+{#enum define LongType { OCI_BLONG as OCI_BLONG
+                       , OCI_CLONG as OCI_CLONG
+                       } deriving (Eq, Ord, Show) #}
+
+-- lob types --
+
+{#enum define LobType { OCI_BLOB as OCI_BLOB
+                      , OCI_CLOB as OCI_CLOB
+                      , OCI_NCLOB as OCI_NCLOB
+                      } deriving (Eq, Ord, Show) #}
+
+-- lob opening mode --
+
+{#enum define LobOpeningMode { OCI_LOB_READONLY as OCI_LOB_READONLY
+                             , OCI_LOB_READWRITE as OCI_LOB_READWRITE
+                             } deriving (Eq, Ord, Show) #}
+
+-- file types --
+
+{#enum define FileType { OCI_BFILE as OCI_BFILE
+                       , OCI_CFILE as OCI_CFILE
+                       } deriving (Eq, Ord, Show) #}
+
+-- lob browsing mode --
+
+{#enum define LobBrowsingMode { OCI_SEEK_SET as OCI_SEEK_SET
+                              , OCI_SEEK_END as OCI_SEEK_END
+                              , OCI_SEEK_CUR as OCI_SEEK_CUR
+                              } deriving (Eq, Ord, Show) #}
+
+-- type info types --
+
+{#enum define TypeInfoType { OCI_UNKNOWN as OCI_UNKNOWN
+                           , OCI_TIF_TABLE as OCI_TIF_TABLE
+                           , OCI_TIF_VIEW  as OCI_TIF_VIEW
+                           , OCI_TIF_TYPE  as OCI_TIF_TYPE
+                           } deriving (Eq, Ord, Show) #}
+
+-- object type --
+
+{#enum define ObjectType { OCI_OBJ_PERSISTENT as OCI_OBJ_PERSISTENT
+                         , OCI_OBJ_TRANSIENT  as OCI_OBJ_TRANSIENT
+                         , OCI_OBJ_VALUE      as OCI_OBJ_VALUE
+                         } deriving (Eq, Ord, Show) #}
+
+-- collection types --
+{#enum define CollectionType { OCI_COLL_VARRAY        as OCI_COLL_VARRAY
+                             , OCI_COLL_NESTED_TABLE  as OCI_COLL_NESTED_TABLE
+                             , OCI_COLL_INDEXED_TABLE as OCI_COLL_INDEXED_TABLE
+                             } deriving (Eq, Ord, Show) #}
+
+-- pool types --
+{#enum define PoolType { OCI_POOL_CONNECTION as OCI_POOL_CONNECTION
+                       , OCI_POOL_SESSION as OCI_POOL_SESSION
+                       } deriving (Eq, Ord, Show) #}
+
+-- AQ message state --
+{#enum define AQMessageState { OCI_AMS_READY as OCI_AMS_READY
+                             , OCI_AMS_WAITING as OCI_AMS_WAITING
+                             , OCI_AMS_PROCESSED as OCI_AMS_PROCESSED
+                             , OCI_AMS_EXPIRED as OCI_AMS_EXPIRED
+                             } deriving (Eq, Ord, Show) #}
+
+-- AQ sequence deviation --
+{#enum define AQSequenceDeviation { OCI_ASD_BEFORE as OCI_ASD_BEFORE
+                                  , OCI_ASD_TOP as OCI_ASD_TOP
+                                  } deriving (Eq, Ord, Show) #}
+
+{-
+-- AQ message visibility --
+
+OCI_AMV_IMMEDIATE as OCI_AMV_IMMEDIATE
+OCI_AMV_ON_COMMIT as OCI_AMV_ON_COMMIT
+
+-- AQ dequeue mode --
+
+OCI_ADM_BROWSE        as OCI_ADM_BROWSE
+OCI_ADM_LOCKED        as OCI_ADM_LOCKED
+OCI_ADM_REMOVE        as OCI_ADM_REMOVE
+OCI_ADM_REMOVE_NODATA as OCI_ADM_REMOVE_NODATA
+
+-- AQ dequeue navigation --
+
+OCI_ADN_FIRST_MSG        as OCI_ADN_FIRST_MSG
+OCI_ADN_NEXT_TRANSACTION as OCI_ADN_NEXT_TRANSACTION
+OCI_ADN_NEXT_MSG         as OCI_ADN_NEXT_MSG
+
+-- AQ queue table purge mode --
+
+OCI_APM_BUFFERED   as OCI_APM_BUFFERED
+OCI_APM_PERSISTENT as OCI_APM_PERSISTENT
+OCI_APM_ALL        as OCI_APM_ALL
+
+-- AQ queue table grouping mode --
+
+OCI_AGM_NONE           as OCI_AGM_NONE
+OCI_AGM_TRANSACTIONNAL as OCI_AGM_TRANSACTIONNAL
+
+-- AQ queue table type --
+
+OCI_AQT_NORMAL         as OCI_AQT_NORMAL
+OCI_AQT_EXCEPTION      as OCI_AQT_EXCEPTION
+OCI_AQT_NON_PERSISTENT as OCI_AQT_NON_PERSISTENT
+
+
+-- direct path processing return status --
+
+OCI_DPR_COMPLETE as OCI_DPR_COMPLETE
+OCI_DPR_ERROR    as OCI_DPR_ERROR
+OCI_DPR_FULL     as OCI_DPR_FULL
+OCI_DPR_PARTIAL  as OCI_DPR_PARTIAL
+OCI_DPR_EMPTY    as OCI_DPR_EMPTY
+
+-- direct path conversion modes --
+
+OCI_DCM_DEFAULT as OCI_DCM_DEFAULT
+OCI_DCM_FORCE   as OCI_DCM_FORCE
+
+-- trace size constants --
+
+OCI_SIZE_TRACE_ID     as OCI_SIZE_TRACE_ID
+OCI_SIZE_TRACE_MODULE as OCI_SIZE_TRACE_MODULE
+OCI_SIZE_TRACE_ACTION as OCI_SIZE_TRACE_ACTION
+OCI_SIZE_TRACE_INFO   as OCI_SIZE_TRACE_INFO
+
+-- trace types --
+
+OCI_TRC_IDENTITY as OCI_TRC_IDENTITY
+OCI_TRC_MODULE   as OCI_TRC_MODULE
+OCI_TRC_ACTION   as OCI_TRC_ACTION
+OCI_TRC_DETAIL   as OCI_TRC_DETAIL
+
+-- HA event type --
+
+OCI_HET_DOWN as OCI_HET_DOWN
+OCI_HET_UP   as OCI_HET_UP
+
+-- HA event source --
+OCI_HES_INSTANCE       as OCI_HES_INSTANCE
+OCI_HES_DATABASE       as OCI_HES_DATABASE
+OCI_HES_NODE           as OCI_HES_NODE
+OCI_HES_SERVICE        as OCI_HES_SERVICE
+OCI_HES_SERVICE_MEMBER as OCI_HES_SERVICE_MEMBER
+OCI_HES_ASM_INSTANCE   as OCI_HES_ASM_INSTANCE
+OCI_HES_PRECONNECT     as OCI_HES_PRECONNECT
+
+-- Fail over types --
+
+OCI_FOT_NONE    as OCI_FOT_NONE
+OCI_FOT_SESSION as OCI_FOT_SESSION
+OCI_FOT_SELECT  as OCI_FOT_SELECT
+
+-- fail over notifications --
+
+OCI_FOE_END    as OCI_FOE_END
+OCI_FOE_ABORT  as OCI_FOE_ABORT
+OCI_FOE_REAUTH as OCI_FOE_REAUTH
+OCI_FOE_BEGIN  as OCI_FOE_BEGIN
+OCI_FOE_ERROR  as OCI_FOE_ERROR
+
+-- fail over callback return code --
+
+OCI_FOC_OK    as OCI_FOC_OK
+OCI_FOC_RETRY as OCI_FOC_RETRY
+
+-- hash tables support --
+
+OCI_HASH_STRING  as OCI_HASH_STRING
+OCI_HASH_INTEGER as OCI_HASH_INTEGER
+OCI_HASH_POINTER as OCI_HASH_POINTER
+
+-- transaction types --
+
+OCI_TRS_NEW          as OCI_TRS_NEW
+OCI_TRS_READONLY     as OCI_TRS_READONLY
+OCI_TRS_READWRITE    as OCI_TRS_READWRITE
+OCI_TRS_SERIALIZABLE as OCI_TRS_SERIALIZABLE
+OCI_TRS_LOOSE        as OCI_TRS_LOOSE
+OCI_TRS_TIGHT        as OCI_TRS_TIGHT
+
+-- format types --
+OCI_FMT_DATE          as OCI_FMT_DATE
+OCI_FMT_TIMESTAMP     as OCI_FMT_TIMESTAMP
+OCI_FMT_NUMERIC       as OCI_FMT_NUMERIC
+OCI_FMT_BINARY_DOUBLE as OCI_FMT_BINARY_DOUBLE
+OCI_FMT_BINARY_FLOAT  as OCI_FMT_BINARY_FLOAT
+
+-- sql function codes --
+OCI_SFC_CREATE_TABLE             as OCI_SFC_CREATE_TABLE
+OCI_SFC_SET_ROLE                 as OCI_SFC_SET_ROLE
+OCI_SFC_INSERT                   as OCI_SFC_INSERT
+OCI_SFC_SELECT                   as OCI_SFC_SELECT
+OCI_SFC_UPDATE                   as OCI_SFC_UPDATE
+OCI_SFC_DROP_ROLE                as OCI_SFC_DROP_ROLE
+OCI_SFC_DROP_VIEW                as OCI_SFC_DROP_VIEW
+OCI_SFC_DROP_TABLE               as OCI_SFC_DROP_TABLE
+OCI_SFC_DELETE                   as OCI_SFC_DELETE
+OCI_SFC_CREATE_VIEW              as OCI_SFC_CREATE_VIEW
+OCI_SFC_DROP_USER                as OCI_SFC_DROP_USER
+OCI_SFC_CREATE_ROLE              as OCI_SFC_CREATE_ROLE
+OCI_SFC_CREATE_SEQUENCE          as OCI_SFC_CREATE_SEQUENCE
+OCI_SFC_ALTER_SEQUENCE           as OCI_SFC_ALTER_SEQUENCE
+OCI_SFC_DROP_SEQUENCE            as OCI_SFC_DROP_SEQUENCE
+OCI_SFC_CREATE_SCHEMA            as OCI_SFC_CREATE_SCHEMA
+OCI_SFC_CREATE_CLUSTER           as OCI_SFC_CREATE_CLUSTER
+OCI_SFC_CREATE_USER              as OCI_SFC_CREATE_USER
+OCI_SFC_CREATE_INDEX             as OCI_SFC_CREATE_INDEX
+OCI_SFC_DROP_INDEX               as OCI_SFC_DROP_INDEX
+OCI_SFC_DROP_CLUSTER             as OCI_SFC_DROP_CLUSTER
+OCI_SFC_VALIDATE_INDEX           as OCI_SFC_VALIDATE_INDEX
+OCI_SFC_CREATE_PROCEDURE         as OCI_SFC_CREATE_PROCEDURE
+OCI_SFC_ALTER_PROCEDURE          as OCI_SFC_ALTER_PROCEDURE
+OCI_SFC_ALTER_TABLE              as OCI_SFC_ALTER_TABLE
+OCI_SFC_EXPLAIN                  as OCI_SFC_EXPLAIN
+OCI_SFC_GRANT                    as OCI_SFC_GRANT
+OCI_SFC_REVOKE                   as OCI_SFC_REVOKE
+OCI_SFC_CREATE_SYNONYM           as OCI_SFC_CREATE_SYNONYM
+OCI_SFC_DROP_SYNONYM             as OCI_SFC_DROP_SYNONYM
+OCI_SFC_ALTER_SYSTEM_SWITCHLOG   as OCI_SFC_ALTER_SYSTEM_SWITCHLOG
+OCI_SFC_SET_TRANSACTION          as OCI_SFC_SET_TRANSACTION
+OCI_SFC_PLSQL_EXECUTE            as OCI_SFC_PLSQL_EXECUTE
+OCI_SFC_LOCK                     as OCI_SFC_LOCK
+OCI_SFC_NOOP                     as OCI_SFC_NOOP
+OCI_SFC_RENAME                   as OCI_SFC_RENAME
+OCI_SFC_COMMENT                  as OCI_SFC_COMMENT
+OCI_SFC_AUDIT                    as OCI_SFC_AUDIT
+OCI_SFC_NO_AUDIT                 as OCI_SFC_NO_AUDIT
+OCI_SFC_ALTER_INDEX              as OCI_SFC_ALTER_INDEX
+OCI_SFC_CREATE_EXTERNAL_DATABASE as OCI_SFC_CREATE_EXTERNAL_DATABASE
+OCI_SFC_DROP_EXTERNALDATABASE    as OCI_SFC_DROP_EXTERNALDATABASE
+OCI_SFC_CREATE_DATABASE          as OCI_SFC_CREATE_DATABASE
+OCI_SFC_ALTER_DATABASE           as OCI_SFC_ALTER_DATABASE
+OCI_SFC_CREATE_ROLLBACK_SEGMENT  as OCI_SFC_CREATE_ROLLBACK_SEGMENT
+OCI_SFC_ALTER_ROLLBACK_SEGMENT   as OCI_SFC_ALTER_ROLLBACK_SEGMENT
+OCI_SFC_DROP_ROLLBACK_SEGMENT    as OCI_SFC_DROP_ROLLBACK_SEGMENT
+OCI_SFC_CREATE_TABLESPACE        as OCI_SFC_CREATE_TABLESPACE
+OCI_SFC_ALTER_TABLESPACE         as OCI_SFC_ALTER_TABLESPACE
+OCI_SFC_DROP_TABLESPACE          as OCI_SFC_DROP_TABLESPACE
+OCI_SFC_ALTER_SESSION            as OCI_SFC_ALTER_SESSION
+OCI_SFC_ALTER_USER               as OCI_SFC_ALTER_USER
+OCI_SFC_COMMIT_WORK              as OCI_SFC_COMMIT_WORK
+OCI_SFC_ROLLBACK                 as OCI_SFC_ROLLBACK
+OCI_SFC_SAVEPOINT                as OCI_SFC_SAVEPOINT
+OCI_SFC_CREATE_CONTROL_FILE      as OCI_SFC_CREATE_CONTROL_FILE
+OCI_SFC_ALTER_TRACING            as OCI_SFC_ALTER_TRACING
+OCI_SFC_CREATE_TRIGGER           as OCI_SFC_CREATE_TRIGGER
+OCI_SFC_ALTER_TRIGGER            as OCI_SFC_ALTER_TRIGGER
+OCI_SFC_DROP_TRIGGER             as OCI_SFC_DROP_TRIGGER
+OCI_SFC_ANALYZE_TABLE            as OCI_SFC_ANALYZE_TABLE
+OCI_SFC_ANALYZE_INDEX            as OCI_SFC_ANALYZE_INDEX
+OCI_SFC_ANALYZE_CLUSTER          as OCI_SFC_ANALYZE_CLUSTER
+OCI_SFC_CREATE_PROFILE           as OCI_SFC_CREATE_PROFILE
+OCI_SFC_DROP_PROFILE             as OCI_SFC_DROP_PROFILE
+OCI_SFC_ALTER_PROFILE            as OCI_SFC_ALTER_PROFILE
+OCI_SFC_DROP_PROCEDURE           as OCI_SFC_DROP_PROCEDURE
+OCI_SFC_ALTER_RESOURCE_COST      as OCI_SFC_ALTER_RESOURCE_COST
+OCI_SFC_CREATE_SNAPSHOT_LOG      as OCI_SFC_CREATE_SNAPSHOT_LOG
+OCI_SFC_ALTER_SNAPSHOT_LOG       as OCI_SFC_ALTER_SNAPSHOT_LOG
+OCI_SFC_DROP_SNAPSHOT_LOG        as OCI_SFC_DROP_SNAPSHOT_LOG
+OCI_SFC_DROP_SUMMARY             as OCI_SFC_DROP_SUMMARY
+OCI_SFC_CREATE_SNAPSHOT          as OCI_SFC_CREATE_SNAPSHOT
+OCI_SFC_ALTER_SNAPSHOT           as OCI_SFC_ALTER_SNAPSHOT
+OCI_SFC_DROP_SNAPSHOT            as OCI_SFC_DROP_SNAPSHOT
+OCI_SFC_CREATE_TYPE              as OCI_SFC_CREATE_TYPE
+OCI_SFC_DROP_TYPE                as OCI_SFC_DROP_TYPE
+OCI_SFC_ALTER_ROLE               as OCI_SFC_ALTER_ROLE
+OCI_SFC_ALTER_TYPE               as OCI_SFC_ALTER_TYPE
+OCI_SFC_CREATE_TYPE_BODY         as OCI_SFC_CREATE_TYPE_BODY
+OCI_SFC_ALTER_TYPE_BODY          as OCI_SFC_ALTER_TYPE_BODY
+OCI_SFC_DROP_TYPE_BODY           as OCI_SFC_DROP_TYPE_BODY
+OCI_SFC_DROP_LIBRARY             as OCI_SFC_DROP_LIBRARY
+OCI_SFC_TRUNCATE_TABLE           as OCI_SFC_TRUNCATE_TABLE
+OCI_SFC_TRUNCATE_CLUSTER         as OCI_SFC_TRUNCATE_CLUSTER
+OCI_SFC_CREATE_BITMAPFILE        as OCI_SFC_CREATE_BITMAPFILE
+OCI_SFC_ALTER_VIEW               as OCI_SFC_ALTER_VIEW
+OCI_SFC_DROP_BITMAPFILE          as OCI_SFC_DROP_BITMAPFILE
+OCI_SFC_SET_CONSTRAINTS          as OCI_SFC_SET_CONSTRAINTS
+OCI_SFC_CREATE_FUNCTION          as OCI_SFC_CREATE_FUNCTION
+OCI_SFC_ALTER_FUNCTION           as OCI_SFC_ALTER_FUNCTION
+OCI_SFC_DROP_FUNCTION            as OCI_SFC_DROP_FUNCTION
+OCI_SFC_CREATE_PACKAGE           as OCI_SFC_CREATE_PACKAGE
+OCI_SFC_ALTER_PACKAGE            as OCI_SFC_ALTER_PACKAGE
+OCI_SFC_DROP_PACKAGE             as OCI_SFC_DROP_PACKAGE
+OCI_SFC_CREATE_PACKAGE_BODY      as OCI_SFC_CREATE_PACKAGE_BODY
+OCI_SFC_ALTER_PACKAGE_BODY       as OCI_SFC_ALTER_PACKAGE_BODY
+OCI_SFC_DROP_PACKAGE_BODY        as OCI_SFC_DROP_PACKAGE_BODY
+OCI_SFC_CREATE_DIRECTORY         as OCI_SFC_CREATE_DIRECTORY
+OCI_SFC_DROP_DIRECTORY           as OCI_SFC_DROP_DIRECTORY
+OCI_SFC_CREATE_LIBRARY           as OCI_SFC_CREATE_LIBRARY
+OCI_SFC_CREATE_JAVA              as OCI_SFC_CREATE_JAVA
+OCI_SFC_ALTER_JAVA               as OCI_SFC_ALTER_JAVA
+OCI_SFC_DROP_JAVA                as OCI_SFC_DROP_JAVA
+OCI_SFC_CREATE_OPERATOR          as OCI_SFC_CREATE_OPERATOR
+OCI_SFC_CREATE_INDEXTYPE         as OCI_SFC_CREATE_INDEXTYPE
+OCI_SFC_DROP_INDEXTYPE           as OCI_SFC_DROP_INDEXTYPE
+OCI_SFC_ALTER_INDEXTYPE          as OCI_SFC_ALTER_INDEXTYPE
+OCI_SFC_DROP_OPERATOR            as OCI_SFC_DROP_OPERATOR
+OCI_SFC_ASSOCIATE_STATISTICS     as OCI_SFC_ASSOCIATE_STATISTICS
+OCI_SFC_DISASSOCIATE_STATISTICS  as OCI_SFC_DISASSOCIATE_STATISTICS
+OCI_SFC_CALL_METHOD              as OCI_SFC_CALL_METHOD
+OCI_SFC_CREATE_SUMMARY           as OCI_SFC_CREATE_SUMMARY
+OCI_SFC_ALTER_SUMMARY            as OCI_SFC_ALTER_SUMMARY
+OCI_SFC_CREATE_DIMENSION         as OCI_SFC_CREATE_DIMENSION
+OCI_SFC_ALTER_DIMENSION          as OCI_SFC_ALTER_DIMENSION
+OCI_SFC_DROP_DIMENSION           as OCI_SFC_DROP_DIMENSION
+OCI_SFC_CREATE_CONTEXT           as OCI_SFC_CREATE_CONTEXT
+OCI_SFC_DROP_CONTEXT             as OCI_SFC_DROP_CONTEXT
+OCI_SFC_ALTER_OUTLINE            as OCI_SFC_ALTER_OUTLINE
+OCI_SFC_CREATE_OUTLINE           as OCI_SFC_CREATE_OUTLINE
+OCI_SFC_DROP_OUTLINE             as OCI_SFC_DROP_OUTLINE
+OCI_SFC_UPDATE_INDEXES           as OCI_SFC_UPDATE_INDEXES
+OCI_SFC_ALTER_OPERATOR           as OCI_SFC_ALTER_OPERATOR
+
+-}
diff --git a/src/Database/Ocilib/Errors.c b/src/Database/Ocilib/Errors.c
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Errors.c
@@ -0,0 +1,42 @@
+
+#include <ocilib.h>
+
+OCI_Error * inline_c_Database_Ocilib_Errors_0_7beeef1c4dc9691ebb78d5a26a8ae0572202a70b() {
+return ( OCI_GetLastError() );
+}
+
+
+const char * inline_c_Database_Ocilib_Errors_1_e032dc5de014e09a03b1b14f113099a477171ca8(OCI_Error * err_inline_c_0) {
+return ( OCI_ErrorGetString(err_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Errors_2_3cfa347a8c7a8f28f3d9463302d9073dc1b0e4b5(OCI_Error * err_inline_c_0) {
+return ( OCI_ErrorGetType(err_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Errors_3_a907d525edc71dffd40e5b3277fcc2d4f33998d0(OCI_Error * err_inline_c_0) {
+return ( OCI_ErrorGetOCICode(err_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Errors_4_5ab9c18596de4737ccd9134dbbe03498517174c3(OCI_Error * err_inline_c_0) {
+return ( OCI_ErrorGetInternalCode(err_inline_c_0) );
+}
+
+
+OCI_Connection * inline_c_Database_Ocilib_Errors_5_32fd746f64f5aa2eac1b3fc11fd4db291b64aac1(OCI_Error * err_inline_c_0) {
+return ( OCI_ErrorGetConnection(err_inline_c_0) );
+}
+
+
+OCI_Statement * inline_c_Database_Ocilib_Errors_6_5b747c234b547b1a00684b46ec0d1c27ee79d780(OCI_Error * err_inline_c_0) {
+return ( OCI_ErrorGetStatement(err_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Errors_7_a3876c79c751e5901a5b0c363e1f38929481d430(OCI_Error * err_inline_c_0) {
+return (OCI_ErrorGetRow(err_inline_c_0) );
+}
+
diff --git a/src/Database/Ocilib/Errors.hs b/src/Database/Ocilib/Errors.hs
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Errors.hs
@@ -0,0 +1,74 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE QuasiQuotes       #-}
+
+-- |
+-- Module:      Database.Ocilib.Errors
+-- Copyright:   (c) 2016 Thierry Bourrillon
+--              (c) 2016 FPInsight, Eurl.
+-- License:     BSD3
+-- Maintainer:  Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+--
+
+module Database.Ocilib.Errors
+    ( ociGetLastError
+    , ociErrorGetString
+    , ociErrorGetType
+    , ociErrorGetOCICode
+    , ociErrorGetInternalCode
+    , ociErrorGetConnection
+    , ociErrorGetStatement
+    , ociErrorGetRow
+    ) where
+
+import           Data.Monoid ((<>))
+import           Foreign.C.Types
+import           Foreign.C.String
+import           Foreign.Ptr
+import qualified Language.C.Inline as C
+import           Database.Ocilib.Oci
+import           Database.Ocilib.Enums
+import           Database.Ocilib.Internal
+
+C.context (C.baseCtx <> C.funCtx <> ociCtx)
+
+C.include "<ocilib.h>"
+
+-- error handling
+
+-- | Retrieve the last error or warning occurred within the last OCILIB call.
+ociGetLastError :: IO (Maybe (Ptr OCI_Error))
+ociGetLastError = fmap toMaybePtr [C.exp| OCI_Error* { OCI_GetLastError() } |]
+
+-- | Retrieve error message from error handle.
+ociErrorGetString :: Ptr OCI_Error -> IO String
+ociErrorGetString err = do
+    s <- [C.exp| const char* { OCI_ErrorGetString($(OCI_Error *err)) } |]
+    peekCString s
+
+-- | Retrieve the type of error from error handle.
+ociErrorGetType :: Ptr OCI_Error -> IO ErrorType
+ociErrorGetType err = fmap (toEnum . fromIntegral) [C.exp| unsigned int { OCI_ErrorGetType($(OCI_Error *err)) } |]
+
+-- | Retrieve Oracle Error code from error handle.
+ociErrorGetOCICode :: Ptr OCI_Error -> IO ErrorCode
+ociErrorGetOCICode err = fmap (toEnum . fromIntegral) [C.exp| int { OCI_ErrorGetOCICode($(OCI_Error *err)) } |]
+
+-- | Retrieve Internal Error code from error handle.
+ociErrorGetInternalCode :: Ptr OCI_Error -> IO CInt
+ociErrorGetInternalCode err = [C.exp| int { OCI_ErrorGetInternalCode($(OCI_Error *err)) } |]
+
+-- | Retrieve connection handle within the error occurred.
+ociErrorGetConnection :: Ptr OCI_Error -> IO (Ptr OCI_Connection)
+ociErrorGetConnection err = [C.exp| OCI_Connection* { OCI_ErrorGetConnection($(OCI_Error *err)) }|]
+
+-- | Retrieve statement handle within the error occurred.
+ociErrorGetStatement :: Ptr OCI_Error -> IO (Maybe (Ptr OCI_Statement))
+ociErrorGetStatement err = fmap toMaybePtr [C.exp| OCI_Statement* { OCI_ErrorGetStatement($(OCI_Error *err)) }|]
+
+-- | Return the row index which caused an error during statement execution.
+ociErrorGetRow :: Ptr OCI_Error -> IO CUInt
+ociErrorGetRow err = [C.exp| unsigned int {OCI_ErrorGetRow($(OCI_Error *err)) }|] -- FIXME should be Maybe CUInt
diff --git a/src/Database/Ocilib/Fetch.c b/src/Database/Ocilib/Fetch.c
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Fetch.c
@@ -0,0 +1,274 @@
+
+#include <ocilib.h>
+
+OCI_Resultset * inline_c_Database_Ocilib_Fetch_0_3dcb896f92046574ef290d3e00bb1b2b046a2c2e(OCI_Statement * s_inline_c_0) {
+return ( OCI_GetResultset(s_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Fetch_1_be39ae8d98d65d4fc1081774d58bc5895a191f73(OCI_Statement * s_inline_c_0) {
+return ( OCI_ReleaseResultsets(s_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Fetch_2_6b808fd5e78aa14bcd56d51e1a5d9bb5dd63133a(OCI_Resultset * rs_inline_c_0) {
+return ( OCI_FetchNext(rs_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Fetch_3_66ec023638443d77cd68c587867be0bd905b9de4(OCI_Resultset * rs_inline_c_0) {
+return ( OCI_FetchPrev(rs_inline_c_0));
+}
+
+
+int inline_c_Database_Ocilib_Fetch_4_b74161a35303f9615f076add53c10287db39e8a9(OCI_Resultset * rs_inline_c_0) {
+return ( OCI_FetchFirst(rs_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Fetch_5_1e6b3dd31b09ef9a5e9eb9d1e1b8558e0479f2fc(OCI_Resultset * rs_inline_c_0) {
+return (OCI_FetchLast(rs_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Fetch_6_eb5dc9739c79a93e9e1754fb0fa0d92cd9c06c22(OCI_Resultset * rs_inline_c_0, unsigned mode_27_inline_c_1, unsigned offset_inline_c_2) {
+return ( OCI_FetchSeek(rs_inline_c_0
+                                          , mode_27_inline_c_1
+                                          , offset_inline_c_2) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Fetch_7_536033f09b27b48d9ba766c07df61f76d5a7aeaa(OCI_Resultset * rs_inline_c_0) {
+return ( OCI_GetRowCount(rs_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Fetch_8_07d87fccc6c9cbfbcb91fe5686fef059c4b10ad6(OCI_Resultset * rs_inline_c_0) {
+return ( OCI_GetCurrentRow(rs_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Fetch_9_a4119ce143b79a6d15397d3a97e4e4c1747d3348(OCI_Resultset * rs_inline_c_0) {
+return ( OCI_GetColumnCount(rs_inline_c_0) );
+}
+
+
+OCI_Column * inline_c_Database_Ocilib_Fetch_10_52906257e2bfd6d91b634a27cb35d9d63bcf65a3(OCI_Resultset * rs_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_GetColumn(rs_inline_c_0, i_inline_c_1) );
+}
+
+
+OCI_Column * inline_c_Database_Ocilib_Fetch_11_5069632e7f306c4a9e8c60453fdfb1b20f07f8dc(OCI_Resultset * rs_inline_c_0, char * n_inline_c_1) {
+return ( OCI_GetColumn2(rs_inline_c_0, n_inline_c_1) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Fetch_12_043df3a3111ff1a41c535000db8600e35c732e02(OCI_Resultset * rs_inline_c_0, char * n_inline_c_1) {
+return ( OCI_GetColumnIndex(rs_inline_c_0, n_inline_c_1) );
+}
+
+
+const char * inline_c_Database_Ocilib_Fetch_13_e359c4e4c192b493bc8626909bff44865e890635(OCI_Column * c_inline_c_0) {
+return ( OCI_ColumnGetName(c_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Fetch_14_9a03941975910d59f935536e0097cc2aef1a85c4(OCI_Column * c_inline_c_0) {
+return ( OCI_ColumnGetType(c_inline_c_0) );
+}
+
+
+const char * inline_c_Database_Ocilib_Fetch_15_1a5769154fb80d642c0599809237f7c7c20fecad(OCI_Column * c_inline_c_0) {
+return ( OCI_ColumnGetSQLType(c_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Fetch_16_42cece029cf63ba1e61d83a6d28c7def14c9c989(OCI_Column * c_inline_c_0) {
+return ( OCI_ColumnGetSize(c_inline_c_0));
+}
+
+
+int inline_c_Database_Ocilib_Fetch_17_8a17740e4091cf5b40f6cafb58d936858bd86e9c(OCI_Column * c_inline_c_0) {
+return ( OCI_ColumnGetScale(c_inline_c_0));
+}
+
+
+int inline_c_Database_Ocilib_Fetch_18_0c5998c414d11d7037402797196790887a7add70(OCI_Column * c_inline_c_0) {
+return ( OCI_ColumnGetPrecision(c_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Fetch_19_98753ec98ab2336cdd462923c576c712a3a0a710(OCI_Column * c_inline_c_0) {
+return ( OCI_ColumnGetFractionalPrecision(c_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Fetch_20_d83164fa6c9f0d3bd5facae5ff73c88894698066(OCI_Column * c_inline_c_0) {
+return ( OCI_ColumnGetLeadingPrecision(c_inline_c_0));
+}
+
+
+int inline_c_Database_Ocilib_Fetch_21_3fc3628544023f53f334f1f0913711a240ece1f0(OCI_Column * c_inline_c_0) {
+return ( OCI_ColumnGetNullable(c_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Fetch_22_dfa1087910ed173d22ba5b9fc9796f659a22b50b(OCI_Column * c_inline_c_0) {
+return ( OCI_ColumnGetCharUsed(c_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Fetch_23_36f945b21c741713d7d2160043747335956c6fd8(OCI_Column * c_inline_c_0) {
+return ( OCI_ColumnGetPropertyFlags(c_inline_c_0) );
+}
+
+
+OCI_TypeInfo * inline_c_Database_Ocilib_Fetch_24_2ddade88b863862aa67f2e39c91af9fc7489e84b(OCI_Column * c_inline_c_0) {
+return ( OCI_ColumnGetTypeInfo(c_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Fetch_25_a59f254c9c01cff23d8a8b063a829d5b607046cc(OCI_Column * c_inline_c_0) {
+return ( OCI_ColumnGetSubType(c_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Fetch_26_88cc8ef435e5cd21e44fa29e4bb0c9b77d8cd0f0(OCI_Resultset * rs_inline_c_0, unsigned i_inline_c_1, unsigned t_inline_c_2) {
+return ( OCI_SetStructNumericType(rs_inline_c_0, i_inline_c_1, t_inline_c_2) );
+}
+
+
+int inline_c_Database_Ocilib_Fetch_27_469fd064fdc5d0848c98aa3135a2dc806d1580ff(OCI_Resultset * rs_inline_c_0, char * n_inline_c_1, unsigned t_inline_c_2) {
+return ( OCI_SetStructNumericType2(rs_inline_c_0, n_inline_c_1, t_inline_c_2));
+}
+
+
+short inline_c_Database_Ocilib_Fetch_28_0e0f54e6886f95eb897191f06813c8e5fe84e287(OCI_Resultset * rs_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_GetShort(rs_inline_c_0, i_inline_c_1) );
+}
+
+
+short inline_c_Database_Ocilib_Fetch_29_9fb237b4f79eba20213e0a5323003e8cc93ed0f4(OCI_Resultset * rs_inline_c_0, char * n_inline_c_1) {
+return ( OCI_GetShort2(rs_inline_c_0, n_inline_c_1) );
+}
+
+
+unsigned short inline_c_Database_Ocilib_Fetch_30_b6b7a3faed09e0f021be018b3dd15645dfaf0f56(OCI_Resultset * rs_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_GetUnsignedShort(rs_inline_c_0, i_inline_c_1) );
+}
+
+
+unsigned short inline_c_Database_Ocilib_Fetch_31_231cecff745b04fcf3451bf8943e8e8dd38d63af(OCI_Resultset * rs_inline_c_0, char * n_inline_c_1) {
+return ( OCI_GetUnsignedShort2(rs_inline_c_0, n_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_Fetch_32_8692f30fc7fa27925fcc8e955319c1b181668f3a(OCI_Resultset * rs_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_GetInt(rs_inline_c_0, i_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_Fetch_33_e2aec50570ee7012eb7ac4bac06cdc5add7e4c81(OCI_Resultset * rs_inline_c_0, char * n_inline_c_1) {
+return ( OCI_GetInt2(rs_inline_c_0, n_inline_c_1) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Fetch_34_cad91b115c47c33b7be28b224af6ef9ad1c5a277(OCI_Resultset * rs_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_GetUnsignedInt(rs_inline_c_0, i_inline_c_1) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Fetch_35_4b2d557d5f921470a3d031dee5807d7c56570702(OCI_Resultset * rs_inline_c_0, char * n_inline_c_1) {
+return ( OCI_GetUnsignedInt2(rs_inline_c_0, n_inline_c_1));
+}
+
+
+const char * inline_c_Database_Ocilib_Fetch_36_e20d6f203a70cd4919c755b496524dbf7f0fdbcb(OCI_Resultset * rs_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_GetString(rs_inline_c_0, i_inline_c_1) );
+}
+
+
+const char * inline_c_Database_Ocilib_Fetch_37_e1bfb4e3bf276389de710439dda65f3c6bf3323b(OCI_Resultset * rs_inline_c_0, char * n_inline_c_1) {
+return ( OCI_GetString2(rs_inline_c_0, n_inline_c_1) );
+}
+
+
+double inline_c_Database_Ocilib_Fetch_38_9212251d93e89b712508b4d3529f8de732233acd(OCI_Resultset * rs_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_GetDouble(rs_inline_c_0, i_inline_c_1));
+}
+
+
+double inline_c_Database_Ocilib_Fetch_39_42bb73b1973c3cd25024c139557ab034375f3eb7(OCI_Resultset * rs_inline_c_0, char * n_inline_c_1) {
+return ( OCI_GetDouble2(rs_inline_c_0, n_inline_c_1));
+}
+
+
+float inline_c_Database_Ocilib_Fetch_40_bc5fa03c1b614befbda6f698182e932aac3d0da3(OCI_Resultset * rs_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_GetFloat(rs_inline_c_0, i_inline_c_1) );
+}
+
+
+float inline_c_Database_Ocilib_Fetch_41_6e0ef42a05b85fbb227d54bdedeb3ac70cdbef88(OCI_Resultset * rs_inline_c_0, char * n_inline_c_1) {
+return ( OCI_GetFloat2(rs_inline_c_0, n_inline_c_1));
+}
+
+
+OCI_Date * inline_c_Database_Ocilib_Fetch_42_57e669652ce73668ae2e666a7ab7838b41e00b19(OCI_Resultset * rs_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_GetDate(rs_inline_c_0, i_inline_c_1));
+}
+
+
+OCI_Date * inline_c_Database_Ocilib_Fetch_43_e47d0d4b579133691a1a6cee1966d8a98e905469(OCI_Resultset * rs_inline_c_0, char * n_inline_c_1) {
+return ( OCI_GetDate2(rs_inline_c_0, n_inline_c_1));
+}
+
+
+OCI_Timestamp * inline_c_Database_Ocilib_Fetch_44_c808756940ea1969cd34f56f94c2da36daa8d91b(OCI_Resultset * rs_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_GetTimestamp(rs_inline_c_0, i_inline_c_1) );
+}
+
+
+OCI_Timestamp * inline_c_Database_Ocilib_Fetch_45_2d778e40891306fc301ec8ac0f06e6d81539aa3c(OCI_Resultset * rs_inline_c_0, char * n_inline_c_1) {
+return ( OCI_GetTimestamp2(rs_inline_c_0, n_inline_c_1) );
+}
+
+
+OCI_Interval * inline_c_Database_Ocilib_Fetch_46_9d266e89c16a09900f11b9cdacf8ba5975544ed7(OCI_Resultset * rs_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_GetInterval(rs_inline_c_0, i_inline_c_1)  );
+}
+
+
+OCI_Interval * inline_c_Database_Ocilib_Fetch_47_4a32cb01c3a3bdc94976686c28f60bd9cc4fabb1(OCI_Resultset * rs_inline_c_0, char * n_inline_c_1) {
+return ( OCI_GetInterval2(rs_inline_c_0, n_inline_c_1) );
+}
+
+
+OCI_Statement * inline_c_Database_Ocilib_Fetch_48_aba383d6d9e7793a73b60683f1da4fd0505566d6(OCI_Resultset * rs_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_GetStatement(rs_inline_c_0, i_inline_c_1) );
+}
+
+
+OCI_Statement * inline_c_Database_Ocilib_Fetch_49_5a386b14506031470a1235d38b8d7df9c1ac623b(OCI_Resultset * rs_inline_c_0, char * n_inline_c_1) {
+return ( OCI_GetStatement2(rs_inline_c_0, n_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_Fetch_50_2b56fd120c110500275eca5335032e1048faeeb0(OCI_Resultset * rs_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_IsNull(rs_inline_c_0, i_inline_c_1));
+}
+
+
+int inline_c_Database_Ocilib_Fetch_51_31b9816b950d880ac764a7d895eba88e69d05563(OCI_Resultset * rs_inline_c_0, char * n_inline_c_1) {
+return ( OCI_IsNull2(rs_inline_c_0, n_inline_c_1) );
+}
+
+
+OCI_Statement * inline_c_Database_Ocilib_Fetch_52_85f8936a8026236a4ce02471545e60582279c5ec(OCI_Resultset * rs_inline_c_0) {
+return ( OCI_ResultsetGetStatement(rs_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Fetch_53_96c20a82e36b7841166d81a6198176278a40eab5(OCI_Resultset * rs_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_GetDataLength(rs_inline_c_0, i_inline_c_1) );
+}
+
diff --git a/src/Database/Ocilib/Fetch.hs b/src/Database/Ocilib/Fetch.hs
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Fetch.hs
@@ -0,0 +1,458 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE QuasiQuotes       #-}
+
+-- |
+-- Module:      Database.Ocilib.Fetch
+-- Copyright:   (c) 2016 Thierry Bourrillon
+--              (c) 2016 FPInsight, Eurl.
+-- License:     BSD3
+-- Maintainer:  Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+--
+
+module Database.Ocilib.Fetch
+    ( ociGetResultset
+    , ociReleaseResultsets
+    , ociFetchNext
+    , ociFetchPrev
+    , ociFetchFirst
+    , ociFetchLast
+    , ociFetchSeek
+    , ociGetRowCount
+    , ociGetCurrentRow
+    , ociGetColumnCount
+    , ociGetColumn
+    , ociGetColumn2
+    , ociGetColumnIndex
+    , ociColumnGetName
+    , ociColumnGetType
+    , ociColumnGetSQLType
+    , ociColumnGetSize
+    , ociColumnGetScale
+    , ociColumnGetPrecision
+    , ociColumnGetFractionalPrecision
+    , ociColumnGetLeadingPrecision
+    , ociColumnGetNullable
+    , ociColumnGetCharUsed
+    , ociColumnGetPropertyFlags
+    , ociColumnGetTypeInfo
+    , ociColumnGetSubType
+    , ociSetStructNumericType
+    , ociSetStructNumericType2
+    --, ociGetStruct
+    , ociGetShort
+    , ociGetShort2
+    , ociGetUnsignedShort
+    , ociGetUnsignedShort2
+    , ociGetInt
+    , ociGetInt2
+    , ociGetUnsignedInt
+    , ociGetUnsignedInt2
+    --, ociGetBigInt
+    --, ociGetBigInt2
+    --, ociGetUnsignedBigInt
+    --, ociGetUnsignedBigInt2
+    , ociGetString
+    , ociGetString2
+    --, ociGetRaw
+    --, ociGetRaw2
+    , ociGetDouble
+    , ociGetDouble2
+    , ociGetFloat
+    , ociGetFloat2
+    , ociGetDate
+    , ociGetDate2
+    , ociGetTimestamp
+    , ociGetTimestamp2
+    , ociGetInterval
+    , ociGetInterval2
+    , ociGetStatement
+    , ociGetStatement2
+    -- , ociGetLob
+    -- , ociGetLob2
+    -- , ociGetFile
+    -- , ociGetFile2
+    -- , ociGetObject
+    -- , ociGetObject2
+    -- , ociGetColl
+    -- , ociGetColl2
+    -- , ociGetRef
+    -- , ociGetRef2
+    -- , ociGetLong
+    -- , ociGetLong2
+    , ociIsNull
+    , ociIsNull2
+    , ociResultsetGetStatement
+    , ociGetDataLength
+    ) where
+
+import           Data.Monoid ((<>))
+import           Foreign.C.Types
+import           Foreign.C.String
+import           Foreign.Marshal.Utils
+import           Foreign.Ptr
+import qualified Language.C.Inline as C
+import           Database.Ocilib.Oci
+import           Database.Ocilib.Enums
+import           Database.Ocilib.Internal
+
+C.context (C.baseCtx <> C.funCtx <> ociCtx)
+
+C.include "<ocilib.h>"
+
+-- | Retrieve the resultset handle from an executed statement.
+ociGetResultset :: Ptr OCI_Statement -> IO (Maybe (Ptr OCI_Resultset))
+ociGetResultset s = fmap toMaybePtr [C.exp| OCI_Resultset* { OCI_GetResultset($(OCI_Statement *s)) } |]
+
+-- | Free the statement resultsets.
+ociReleaseResultsets :: Ptr OCI_Statement -> IO Bool
+ociReleaseResultsets s = fmap toBool [C.exp| int { OCI_ReleaseResultsets($(OCI_Statement *s)) } |]
+
+-- | Fetch the next row of the resultset.
+ociFetchNext :: Ptr OCI_Resultset -> IO Bool
+ociFetchNext rs = fmap toBool [C.exp| int { OCI_FetchNext($(OCI_Resultset *rs)) } |]
+
+-- | Fetch the previous row of the resultset.
+ociFetchPrev :: Ptr OCI_Resultset -> IO Bool
+ociFetchPrev rs = fmap toBool [C.exp| int { OCI_FetchPrev($(OCI_Resultset *rs))}|]
+
+-- | Fetch the first row of the resultset.
+ociFetchFirst :: Ptr OCI_Resultset -> IO Bool
+ociFetchFirst rs = fmap toBool [C.exp| int { OCI_FetchFirst($(OCI_Resultset *rs)) } |]
+
+-- | Fetch the last row of the resultset.
+ociFetchLast :: Ptr OCI_Resultset -> IO Bool
+ociFetchLast rs = fmap toBool [C.exp| int {OCI_FetchLast($(OCI_Resultset *rs)) }|]
+
+-- | Custom Fetch of the resultset.
+ociFetchSeek :: Ptr OCI_Resultset -> StatementFetchDirection -> CUInt -> IO Bool
+ociFetchSeek rs mode offset = do
+    let mode' = fromIntegral $ fromEnum mode
+    fmap toBool [C.exp| int { OCI_FetchSeek($(OCI_Resultset *rs)
+                                          , $(unsigned int mode')
+                                          , $(unsigned int offset)) } |]
+
+-- | Retrieve the number of rows fetched so far.
+ociGetRowCount :: Ptr OCI_Resultset -> IO CUInt
+ociGetRowCount rs = [C.exp| unsigned int { OCI_GetRowCount($(OCI_Resultset *rs)) } |]
+
+-- | Retrieve the current row number.
+ociGetCurrentRow :: Ptr OCI_Resultset -> IO CUInt
+ociGetCurrentRow rs = [C.exp| unsigned int { OCI_GetCurrentRow($(OCI_Resultset *rs)) }|]
+
+-- | Return the number of columns in the resultset.
+ociGetColumnCount :: Ptr OCI_Resultset -> IO CUInt
+ociGetColumnCount rs = [C.exp| unsigned int { OCI_GetColumnCount($(OCI_Resultset *rs)) } |]
+
+-- | Return the column object handle at the given index in the resultset.
+ociGetColumn :: Ptr OCI_Resultset -> CUInt -> IO (Ptr OCI_Column)
+ociGetColumn rs i = [C.exp| OCI_Column* { OCI_GetColumn($(OCI_Resultset *rs), $(unsigned int i)) } |]
+
+-- | Return the column object handle from its name in the resultset.
+ociGetColumn2 :: Ptr OCI_Resultset -> String -> IO (Ptr OCI_Column)
+ociGetColumn2 rs name =
+    withCString name (\n ->
+        [C.exp| OCI_Column* { OCI_GetColumn2($(OCI_Resultset *rs), $(char *n)) } |]
+    )
+
+-- | Return the index of the column in the result from its name.
+ociGetColumnIndex :: Ptr OCI_Resultset -> String -> IO CUInt
+ociGetColumnIndex rs name =
+    withCString name (\n ->
+        [C.exp| unsigned int { OCI_GetColumnIndex($(OCI_Resultset *rs), $(char *n)) } |]
+    )
+
+-- | Return the name of the given column.
+ociColumnGetName :: Ptr OCI_Column -> IO String
+ociColumnGetName c = do
+    s <- [C.exp| const char* { OCI_ColumnGetName($(OCI_Column *c)) } |]
+    peekCString s
+
+-- | Return the type of the given column.
+ociColumnGetType :: Ptr OCI_Column -> IO ColumnType
+ociColumnGetType c = do
+    ct <- [C.exp| int { OCI_ColumnGetType($(OCI_Column *c)) } |]
+    return $ toEnum $ fromIntegral ct
+
+{-
+-- | Return the charset form of the given column.
+-- unsigned int OCI_ColumnGetCharsetForm (OCI_Column *col)
+-}
+
+-- | Return the Oracle SQL type name of the column data type.
+ociColumnGetSQLType :: Ptr OCI_Column -> IO String
+ociColumnGetSQLType c = do
+    s <- [C.exp| const char* { OCI_ColumnGetSQLType($(OCI_Column *c)) } |]
+    peekCString s
+
+{-
+-- | Return the Oracle SQL Full name including precision and size of the column data type.
+-- unsigned int OCI_ColumnGetFullSQLType (OCI_Column *col, otext *buffer, unsigned int len)
+-}
+
+-- | Return the size of the column.
+ociColumnGetSize :: Ptr OCI_Column -> IO CUInt
+ociColumnGetSize c = [C.exp| unsigned int { OCI_ColumnGetSize($(OCI_Column *c))} |]
+
+-- | Return the scale of the column for numeric columns.
+ociColumnGetScale :: Ptr OCI_Column -> IO CInt
+ociColumnGetScale c = [C.exp| int { OCI_ColumnGetScale($(OCI_Column *c))} |]
+
+-- | Return the precision of the column for numeric columns.
+ociColumnGetPrecision :: Ptr OCI_Column -> IO CInt
+ociColumnGetPrecision c = [C.exp| int { OCI_ColumnGetPrecision($(OCI_Column *c)) } |]
+
+-- | Return the fractional precision of the column for timestamp and interval columns.
+ociColumnGetFractionalPrecision :: Ptr OCI_Column -> IO CInt
+ociColumnGetFractionalPrecision c = [C.exp| int { OCI_ColumnGetFractionalPrecision($(OCI_Column *c)) } |]
+
+-- | Return the leading precision of the column for interval columns.
+ociColumnGetLeadingPrecision :: Ptr OCI_Column -> IO CInt
+ociColumnGetLeadingPrecision c = [C.exp| int { OCI_ColumnGetLeadingPrecision($(OCI_Column *c))} |]
+
+-- | Return the nullable attribute of the column.
+ociColumnGetNullable :: Ptr OCI_Column -> IO Bool
+ociColumnGetNullable c = fmap toBool [C.exp| int { OCI_ColumnGetNullable($(OCI_Column *c)) } |]
+
+-- | Return TRUE if the length of the column is character-length or FALSE if it is byte-length.
+ociColumnGetCharUsed :: Ptr OCI_Column -> IO Bool
+ociColumnGetCharUsed c = fmap toBool [C.exp| int { OCI_ColumnGetCharUsed($(OCI_Column *c)) } |]
+
+-- | Return the column property flags.
+ociColumnGetPropertyFlags :: Ptr OCI_Column -> IO CUInt
+ociColumnGetPropertyFlags c = [C.exp| unsigned int { OCI_ColumnGetPropertyFlags($(OCI_Column *c)) }|]
+
+-- | Return the type information object associated to the column.
+ociColumnGetTypeInfo :: Ptr OCI_Column -> IO (Ptr OCI_TypeInfo)
+ociColumnGetTypeInfo c = [C.exp| OCI_TypeInfo* { OCI_ColumnGetTypeInfo($(OCI_Column *c)) } |]
+
+-- | Return the OCILIB object subtype of a column.
+ociColumnGetSubType :: Ptr OCI_Column -> IO CUInt
+ociColumnGetSubType c = [C.exp| unsigned int { OCI_ColumnGetSubType($(OCI_Column *c)) } |]
+
+-- | set the numeric data type of the given structure member (identified from position in the resultset) to retrieve when calling OCI_GetStruct()
+ociSetStructNumericType :: Ptr OCI_Resultset -> CUInt -> CUInt -> IO Bool -- FIXME use enum for the type
+ociSetStructNumericType rs i t = fmap toBool [C.exp| int { OCI_SetStructNumericType($(OCI_Resultset *rs), $(unsigned int i), $(unsigned int t)) } |]
+
+-- | set the numeric data type of the given structure member (identified from column name in the resultset) to retrieve when calling OCI_GetStruct()
+ociSetStructNumericType2 :: Ptr OCI_Resultset -> String -> CUInt -> IO Bool -- FIXME use enum for the type
+ociSetStructNumericType2 rs name t =
+    withCString name (\n ->
+        fmap toBool [C.exp| int { OCI_SetStructNumericType2($(OCI_Resultset *rs), $(char *n), $(unsigned int t))} |]
+    )
+
+{-
+-- | Return the row columns values into a single structure.
+-- boolean OCI_GetStruct (OCI_Resultset *rs, void *row_struct, void *row_struct_ind)
+-}
+
+-- | Return the current short value of the column at the given index in the resultset.
+ociGetShort :: Ptr OCI_Resultset -> CUInt -> IO CShort
+ociGetShort rs i = [C.exp| short { OCI_GetShort($(OCI_Resultset *rs), $(unsigned int i)) } |]
+
+-- | Return the current short value of the column from its name in the resultset.
+ociGetShort2 :: Ptr OCI_Resultset -> String -> IO CShort
+ociGetShort2 rs name =
+    withCString name (\n ->
+        [C.exp| short { OCI_GetShort2($(OCI_Resultset *rs), $(char *n)) } |]
+    )
+
+-- | Return the current unsigned short value of the column at the given index in the resultset.
+ociGetUnsignedShort :: Ptr OCI_Resultset -> CUInt -> IO CUShort
+ociGetUnsignedShort rs i = [C.exp| unsigned short { OCI_GetUnsignedShort($(OCI_Resultset *rs), $(unsigned int i)) } |]
+
+-- | Return the current unsigned short value of the column from its name in the resultset.
+ociGetUnsignedShort2 :: Ptr OCI_Resultset -> String -> IO CUShort
+ociGetUnsignedShort2 rs name =
+    withCString name (\n ->
+        [C.exp| unsigned short { OCI_GetUnsignedShort2($(OCI_Resultset *rs), $(char *n)) } |]
+    )
+
+-- Return the current integer value of the column at the given index in the resultset.
+ociGetInt :: Ptr OCI_Resultset -> CUInt -> IO CInt
+ociGetInt rs i = [C.exp| int { OCI_GetInt($(OCI_Resultset *rs), $(unsigned int i)) } |]
+
+-- | Return the current integer value of the column from its name in the resultset.
+ociGetInt2 :: Ptr OCI_Resultset -> String -> IO CInt
+ociGetInt2 rs name =
+    withCString name (\n ->
+        [C.exp| int { OCI_GetInt2($(OCI_Resultset *rs), $(char *n)) } |]
+    )
+
+-- | Return the current unsigned integer value of the column at the given index in the resultset.
+ociGetUnsignedInt :: Ptr OCI_Resultset -> CUInt -> IO CUInt
+ociGetUnsignedInt rs i = [C.exp| unsigned int { OCI_GetUnsignedInt($(OCI_Resultset *rs), $(unsigned int i)) } |]
+
+-- | Return the current unsigned integer value of the column from its name in the resultset.
+ociGetUnsignedInt2 :: Ptr OCI_Resultset -> String -> IO CUInt
+ociGetUnsignedInt2 rs name =
+    withCString name (\n ->
+        [C.exp| unsigned int { OCI_GetUnsignedInt2($(OCI_Resultset *rs), $(char *n))} |]
+    )
+
+{-
+-- | Return the current big integer value of the column at the given index in the resultset.
+-- big_int OCI_GetBigInt (OCI_Resultset *rs, unsigned int index)
+-- ociGetBigInt :: Ptr OCI_resultset -> CUInt -> IO
+
+-- | Return the current big integer value of the column from its name in the resultset.
+-- big_int OCI_GetBigInt2 (OCI_Resultset *rs, const otext *name)
+
+-- | Return the current unsigned big integer value of the column at the given index in the resultset.
+-- big_uint OCI_GetUnsignedBigInt (OCI_Resultset *rs, unsigned int index)
+
+-- | Return the current unsigned big integer value of the column from its name in the resultset.
+-- big_uint OCI_GetUnsignedBigInt2 (OCI_Resultset *rs, const otext *name)
+-}
+
+-- | Return the current string value of the column at the given index in the resultset.
+ociGetString :: Ptr OCI_Resultset -> CUInt -> IO String
+ociGetString rs i = do
+    s <- [C.exp| const char* { OCI_GetString($(OCI_Resultset *rs), $(unsigned int i)) }|]
+    peekCString s -- FIXME release CString ?
+
+-- | Return the current string value of the column from its name in the resultset.
+ociGetString2 :: Ptr OCI_Resultset -> String -> IO String
+ociGetString2 rs name =
+    withCString name (\n -> do
+        s <- [C.exp| const char* { OCI_GetString2($(OCI_Resultset *rs), $(char *n)) } |]
+        peekCString s
+    )
+
+{-
+-- | Copy the current raw value of the column at the given index into the specified buffer.
+-- unsigned int OCI_GetRaw (OCI_Resultset *rs, unsigned int index, void *buffer, unsigned int len)
+
+-- | Copy the current raw value of the column from its name into the specified buffer.
+-- unsigned int OCI_GetRaw2 (OCI_Resultset *rs, const otext *name, void *buffer, unsigned int len)
+-}
+
+-- | Return the current double value of the column at the given index in the resultset.
+ociGetDouble :: Ptr OCI_Resultset -> CUInt -> IO CDouble
+ociGetDouble rs i = [C.exp| double { OCI_GetDouble($(OCI_Resultset *rs), $(unsigned int i))} |]
+
+-- | Return the current double value of the column from its name in the resultset.
+ociGetDouble2 :: Ptr OCI_Resultset -> String -> IO CDouble
+ociGetDouble2 rs name =
+    withCString name (\n ->
+        [C.exp| double { OCI_GetDouble2($(OCI_Resultset *rs), $(char *n))} |]
+    )
+
+-- | Return the current float value of the column at the given index in the resultset.
+ociGetFloat :: Ptr OCI_Resultset -> CUInt -> IO CFloat
+ociGetFloat rs i = [C.exp| float { OCI_GetFloat($(OCI_Resultset *rs), $(unsigned int i)) } |]
+
+-- | Return the current float value of the column from its name in the resultset.
+ociGetFloat2 :: Ptr OCI_Resultset -> String -> IO CFloat
+ociGetFloat2 rs name =
+    withCString name (\n ->
+        [C.exp| float { OCI_GetFloat2($(OCI_Resultset *rs), $(char *n))} |]
+    )
+
+-- | Return the current date value of the column at the given index in the resultset.
+ociGetDate :: Ptr OCI_Resultset -> CUInt -> IO (Ptr OCI_Date)
+ociGetDate rs i = [C.exp| OCI_Date* { OCI_GetDate($(OCI_Resultset *rs), $(unsigned int i))} |]
+
+-- | Return the current date value of the column from its name in the resultset.
+ociGetDate2 :: Ptr OCI_Resultset -> String -> IO (Ptr OCI_Date)
+ociGetDate2 rs name =
+    withCString name (\n ->
+        [C.exp| OCI_Date* { OCI_GetDate2($(OCI_Resultset *rs), $(char *n))} |]
+    )
+
+-- | Return the current timestamp value of the column at the given index in the resultset.
+ociGetTimestamp :: Ptr OCI_Resultset -> CUInt -> IO (Ptr OCI_Timestamp)
+ociGetTimestamp rs i = [C.exp| OCI_Timestamp* { OCI_GetTimestamp($(OCI_Resultset *rs), $(unsigned int i)) } |]
+
+-- | Return the current timestamp value of the column from its name in the resultset.
+ociGetTimestamp2 :: Ptr OCI_Resultset -> String -> IO (Ptr OCI_Timestamp)
+ociGetTimestamp2 rs name =
+    withCString name (\n ->
+        [C.exp| OCI_Timestamp* { OCI_GetTimestamp2($(OCI_Resultset *rs), $(char *n)) } |]
+    )
+
+-- | Return the current interval value of the column at the given index in the resultset.
+ociGetInterval :: Ptr OCI_Resultset -> CUInt -> IO (Ptr OCI_Interval)
+ociGetInterval rs i = [C.exp| OCI_Interval* { OCI_GetInterval($(OCI_Resultset *rs), $(unsigned int i))  } |]
+
+-- | Return the current interval value of the column from its name in the resultset.
+ociGetInterval2 :: Ptr OCI_Resultset -> String -> IO (Ptr OCI_Interval)
+ociGetInterval2 rs name =
+    withCString name (\n ->
+        [C.exp| OCI_Interval* { OCI_GetInterval2($(OCI_Resultset *rs), $(char *n)) } |]
+    )
+
+-- | Return the current cursor value (Nested table) of the column at the given index in the resultset.
+ociGetStatement :: Ptr OCI_Resultset -> CUInt -> IO (Ptr OCI_Statement)
+ociGetStatement rs i = [C.exp| OCI_Statement* { OCI_GetStatement($(OCI_Resultset *rs), $(unsigned int i)) }|]
+
+-- | Return the current cursor value of the column from its name in the resultset.
+ociGetStatement2 :: Ptr OCI_Resultset -> String -> IO (Ptr OCI_Statement)
+ociGetStatement2 rs name =
+    withCString name (\n ->
+        [C.exp| OCI_Statement* { OCI_GetStatement2($(OCI_Resultset *rs), $(char *n)) } |]
+    )
+
+{-
+-- | Return the current lob value of the column at the given index in the resultset.
+-- OCI_Lob *OCI_GetLob (OCI_Resultset *rs, unsigned int index)
+
+-- | Return the current lob value of the column from its name in the resultset.
+-- OCI_Lob *OCI_GetLob2 (OCI_Resultset *rs, const otext *name)
+
+-- | Return the current File value of the column at the given index in the resultset.
+-- OCI_File *OCI_GetFile (OCI_Resultset *rs, unsigned int index)
+
+-- | Return the current File value of the column from its name in the resultset.
+-- OCI_File *OCI_GetFile2 (OCI_Resultset *rs, const otext *name)
+
+-- | Return the current Object value of the column at the given index in the resultset.
+-- OCI_Object *OCI_GetObject (OCI_Resultset *rs, unsigned int index)
+
+-- | Return the current Object value of the column from its name in the resultset.
+-- OCI_Object *OCI_GetObject2 (OCI_Resultset *rs, const otext *name)
+
+-- | Return the current Collection value of the column at the given index in the resultset.
+-- OCI_Coll *OCI_GetColl (OCI_Resultset *rs, unsigned int index)
+
+-- | Return the current Collection value of the column from its name in the resultset.
+-- OCI_Coll *OCI_GetColl2 (OCI_Resultset *rs, const otext *name)
+
+-- | Return the current Ref value of the column at the given index in the resultset.
+-- OCI_Ref *OCI_GetRef (OCI_Resultset *rs, unsigned int index)
+
+-- | Return the current Ref value of the column from its name in the resultset.
+-- OCI_Ref *OCI_GetRef2 (OCI_Resultset *rs, const otext *name)
+
+-- | Return the current Long value of the column at the given index in the resultset.
+-- OCI_Long *OCI_GetLong (OCI_Resultset *rs, unsigned int index)
+
+-- | Return the current Long value of the column from its name in the resultset.
+-- OCI_Long *OCI_GetLong2 (OCI_Resultset *rs, const otext *name)
+-}
+
+-- | Check if the current row value is null for the column at the given index in the resultset.
+-- boolean OCI_IsNull (OCI_Resultset *rs, unsigned int index)
+ociIsNull :: Ptr OCI_Resultset -> CUInt -> IO Bool
+ociIsNull rs i = fmap toBool [C.exp| int { OCI_IsNull($(OCI_Resultset *rs), $(unsigned int i))}|]
+
+-- | Check if the current row value is null for the column of the given name in the resultset.
+-- boolean OCI_IsNull2 (OCI_Resultset *rs, const otext *name)
+ociIsNull2 :: Ptr OCI_Resultset -> String -> IO Bool
+ociIsNull2 rs name =
+    withCString name (\n ->
+        fmap toBool [C.exp| int { OCI_IsNull2($(OCI_Resultset *rs), $(char *n)) } |]
+    )
+
+-- | Return the statement handle associated with a resultset handle.
+-- OCI_Statement *OCI_ResultsetGetStatement (OCI_Resultset *rs)
+ociResultsetGetStatement :: Ptr OCI_Resultset -> IO (Ptr OCI_Statement)
+ociResultsetGetStatement rs = [C.exp| OCI_Statement* { OCI_ResultsetGetStatement($(OCI_Resultset* rs)) } |]
+
+-- | Return the current row data length of the column at the given index in the resultset.
+-- unsigned int OCI_GetDataLength (OCI_Resultset *rs, unsigned int index)
+ociGetDataLength :: Ptr OCI_Resultset -> CUInt -> IO CUInt
+ociGetDataLength rs i = [C.exp| unsigned int { OCI_GetDataLength($(OCI_Resultset *rs), $(unsigned int i)) } |]
diff --git a/src/Database/Ocilib/Internal.hs b/src/Database/Ocilib/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Internal.hs
@@ -0,0 +1,19 @@
+-- |
+-- Module:      Database.Ocilib.Internal
+-- Copyright:   (c) 2016 Thierry Bourrillon
+--              (c) 2016 FPInsight, Eurl.
+-- License:     BSD3
+-- Maintainer:  Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+--
+
+module Database.Ocilib.Internal where
+
+import Foreign.Ptr
+
+toMaybePtr :: Ptr a -> Maybe (Ptr a)
+toMaybePtr a
+    | a == nullPtr = Nothing
+    | otherwise    = Just a
diff --git a/src/Database/Ocilib/Oci.hs b/src/Database/Ocilib/Oci.hs
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Oci.hs
@@ -0,0 +1,191 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE QuasiQuotes     #-}
+
+-- |
+-- Module:      Database.Ocilib.Oci
+-- Copyright:   (c) 2016 Thierry Bourrillon
+--              (c) 2016 FPInsight, Eurl.
+-- License:     BSD3
+-- Maintainer:  Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+--
+
+module Database.Ocilib.Oci
+    ( ociCtx
+    , OCI_Pool
+    , OCI_Connection
+    , OCI_Statement
+    , OCI_Bind
+    , OCI_Resultset
+    , OCI_Column
+    , OCI_Lob
+    , OCI_File
+    , OCI_Transaction
+    , OCI_Long
+    , OCI_Date
+    , OCI_Timestamp
+    , OCI_Interval
+    , OCI_Object
+    , OCI_Coll
+    , OCI_Elem
+    , OCI_Iter
+    , OCI_Ref
+    , OCI_TypeInfo
+    , OCI_HashTable
+    , OCI_Error
+    , OCI_Mutex
+    , OCI_Thread
+    , OCI_DirPath
+    , OCI_Subscription
+    , OCI_Event
+    , OCI_Msg
+    , OCI_Agent
+    , OCI_Dequeue
+    , OCI_Enqueue
+    ) where
+
+import qualified Data.Map as Map
+import qualified Language.C.Inline as C
+import           Language.C.Inline.Context
+import qualified Language.C.Types as C
+import qualified Language.Haskell.TH as TH
+
+ociCtx :: C.Context
+ociCtx = mempty { ctxTypesTable = ociTypesTable }
+
+-- | Pool object (session or connection)
+-- A pool is a set of pooled objects
+data OCI_Pool
+
+-- | Oracle physical connection.
+-- It holds all information about a connection such as error handling, associated statements, ... Error handling and transactions are embedded within a connection object.
+data OCI_Connection
+
+-- | Oracle SQL or PL/SQL statement.
+-- A Statement object allows users to prepare, execute SQL orders or PL/SQL blocks
+data OCI_Statement
+
+-- | Internal bind representation.
+-- A bind object is an object that holds all information about an Oracle statement binding operation
+data OCI_Bind
+
+-- | Collection of output columns from a select statement.
+-- A resultset object is the result of 'select' SQL Statement.
+-- It's a set of data (ordered in columns) that can be fetched row by row to get data returned by the SQL statement
+data OCI_Resultset
+
+-- | Oracle SQL Column and Type member representation.
+-- A column object represents an output column from a select statement
+data OCI_Column
+
+-- | Oracle Internal Large objects
+data OCI_Lob
+
+-- | Oracle External Large objects
+-- FILEs were introduced by OCI8 in order to store references to files located outside the database.
+data OCI_File
+
+-- | Oracle Transaction
+data OCI_Transaction
+
+-- | Oracle Long data type
+-- Those types were used in older versions of Oracle (before Oracle8i) to store large chunks of data in the database.
+-- It's now depreciated by Oracle that recommends using LOBs
+data OCI_Long
+
+-- | Oracle internal date representation
+data OCI_Date
+
+-- | Oracle internal timestamp representation.
+data OCI_Timestamp
+
+-- | Oracle internal interval representation.
+data OCI_Interval
+
+-- | Oracle Named types representation.
+data OCI_Object
+
+-- | Oracle Collections (VARRAYs and Nested Tables) representation.
+data OCI_Coll
+
+-- | Oracle Collection item representation.
+data OCI_Elem
+
+-- | Oracle Collection iterator representation.
+data OCI_Iter
+
+-- | Oracle REF type representation.
+data OCI_Ref
+
+-- | Type info metadata handle.
+data OCI_TypeInfo
+
+-- | OCILIB implementation of hash tables.
+data OCI_HashTable
+
+-- | Encapsulates an Oracle or OCILIB exception.
+data OCI_Error
+
+-- | OCILIB encapsulation of OCI mutexes.
+data OCI_Mutex
+
+-- | OCILIB encapsulation of OCI Threads.
+data OCI_Thread
+
+-- | OCILIB encapsulation of OCI Direct Path handle.
+data OCI_DirPath
+
+-- | OCILIB encapsulation of Oracle DCN notification.
+data OCI_Subscription
+
+-- | OCILIB encapsulation of Oracle DCN event.
+data OCI_Event
+
+-- | OCILIB encapsulation of A/Q message.
+data OCI_Msg
+
+-- | OCILIB encapsulation of A/Q Agent.
+data OCI_Agent
+
+-- | OCILIB encapsulation of A/Q dequeuing operations.
+data OCI_Dequeue
+
+-- | OCILIB encapsulation of A/Q enqueuing operations.
+data OCI_Enqueue
+
+ociTypesTable :: Map.Map C.TypeSpecifier TH.TypeQ
+ociTypesTable = Map.fromList
+    [ (C.TypeName "OCI_Pool"        , [t| OCI_Pool         |])
+    , (C.TypeName "OCI_Connection"  , [t| OCI_Connection   |])
+    , (C.TypeName "OCI_Statement"   , [t| OCI_Statement    |])
+    , (C.TypeName "OCI_Bind"        , [t| OCI_Bind         |])
+    , (C.TypeName "OCI_Resultset"   , [t| OCI_Resultset    |])
+    , (C.TypeName "OCI_Column"      , [t| OCI_Column       |])
+    , (C.TypeName "OCI_Lob"         , [t| OCI_Lob          |])
+    , (C.TypeName "OCI_File"        , [t| OCI_File         |])
+    , (C.TypeName "OCI_Transaction" , [t| OCI_Transaction  |])
+    , (C.TypeName "OCI_Long"        , [t| OCI_Long         |])
+    , (C.TypeName "OCI_Date"        , [t| OCI_Date         |])
+    , (C.TypeName "OCI_Timestamp"   , [t| OCI_Timestamp    |])
+    , (C.TypeName "OCI_Interval"    , [t| OCI_Interval     |])
+    , (C.TypeName "OCI_Object"      , [t| OCI_Object       |])
+    , (C.TypeName "OCI_Coll"        , [t| OCI_Coll         |])
+    , (C.TypeName "OCI_Elem"        , [t| OCI_Elem         |])
+    , (C.TypeName "OCI_Iter"        , [t| OCI_Iter         |])
+    , (C.TypeName "OCI_Ref"         , [t| OCI_Ref          |])
+    , (C.TypeName "OCI_TypeInfo"    , [t| OCI_TypeInfo     |])
+    , (C.TypeName "OCI_HashTable"   , [t| OCI_HashTable    |])
+    , (C.TypeName "OCI_Error"       , [t| OCI_Error        |])
+    , (C.TypeName "OCI_Mutex"       , [t| OCI_Mutex        |])
+    , (C.TypeName "OCI_Thread"      , [t| OCI_Thread       |])
+    , (C.TypeName "OCI_DirPath"     , [t| OCI_DirPath      |])
+    , (C.TypeName "OCI_Subscription", [t| OCI_Subscription |])
+    , (C.TypeName "OCI_Event"       , [t| OCI_Event        |])
+    , (C.TypeName "OCI_Msg"         , [t| OCI_Msg          |])
+    , (C.TypeName "OCI_Agent"       , [t| OCI_Agent        |])
+    , (C.TypeName "OCI_Dequeue"     , [t| OCI_Dequeue      |])
+    , (C.TypeName "OCI_Enqueue"     , [t| OCI_Enqueue      |])
+    ]
diff --git a/src/Database/Ocilib/Pool.c b/src/Database/Ocilib/Pool.c
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Pool.c
@@ -0,0 +1,79 @@
+
+#include <ocilib.h>
+
+OCI_Pool * inline_c_Database_Ocilib_Pool_0_82aec755a8a9e047db340f5345218afd32ce3a4d(char * d_inline_c_0, char * u_inline_c_1, char * p_inline_c_2, unsigned pt_inline_c_3, unsigned m_inline_c_4, unsigned minCon_inline_c_5, unsigned maxCon_inline_c_6, unsigned incrCon_inline_c_7) {
+return ( OCI_PoolCreate( d_inline_c_0
+                                                                  , u_inline_c_1
+                                                                  , p_inline_c_2
+                                                                  , pt_inline_c_3
+                                                                  , m_inline_c_4
+                                                                  , minCon_inline_c_5
+                                                                  , maxCon_inline_c_6
+                                                                  , incrCon_inline_c_7) );
+}
+
+
+int inline_c_Database_Ocilib_Pool_1_2790699693458e1964ab6e937b9419024eb4e5d8(OCI_Pool * p_inline_c_0) {
+return ( OCI_PoolFree(p_inline_c_0));
+}
+
+
+OCI_Connection * inline_c_Database_Ocilib_Pool_2_39138970fd6d534061a69617ecad141e849b07ab(OCI_Pool * p_inline_c_0, char * t_inline_c_1) {
+return ( OCI_PoolGetConnection(p_inline_c_0, t_inline_c_1) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Pool_3_49602f6c3a43a22fcecaf84e65ea7198c17960b3(OCI_Pool * p_inline_c_0) {
+return ( OCI_PoolGetTimeout(p_inline_c_0));
+}
+
+
+int inline_c_Database_Ocilib_Pool_4_aaa5d32d0d4bc733b8dccb7f519d1178bc07152f(OCI_Pool * p_inline_c_0, unsigned t_inline_c_1) {
+return ( OCI_PoolSetTimeout(p_inline_c_0, t_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_Pool_5_ee352659b8a463bf9645ce0c6a004779cf3f76ce(OCI_Pool * p_inline_c_0) {
+return ( OCI_PoolGetNoWait(p_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Pool_6_e2fb3226b91b9f540459ba77c8d7a15aaa66f768(OCI_Pool * p_inline_c_0, int v_inline_c_1) {
+return ( OCI_PoolSetNoWait(p_inline_c_0, v_inline_c_1) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Pool_7_8d518908083d3c33713b56a7d74171a4defb3804(OCI_Pool * p_inline_c_0) {
+return ( OCI_PoolGetBusyCount(p_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Pool_8_d638354baa925f5889c95c89695f30437b1d1a7f(OCI_Pool * p_inline_c_0) {
+return ( OCI_PoolGetOpenedCount(p_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Pool_9_2a83833c3b976686733be09b5ddfdb394b9e7d08(OCI_Pool * p_inline_c_0) {
+return ( OCI_PoolGetMin(p_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Pool_10_59e6b7e4612a58e617e6c1a192af9d615d0e9c53(OCI_Pool * p_inline_c_0) {
+return ( OCI_PoolGetMax(p_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Pool_11_fcc01256a4059887226257cac0c06c147cb01d33(OCI_Pool * p_inline_c_0) {
+return ( OCI_PoolGetIncrement(p_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Pool_12_0f7e050f975ff5b4bf2110e7d0d93b364a55e0ae(OCI_Pool * p_inline_c_0) {
+return ( OCI_PoolGetStatementCacheSize(p_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Pool_13_e112369f99e121c3b8d715818e194c6e2f70a7f3(OCI_Pool * p_inline_c_0, unsigned value_inline_c_1) {
+return ( OCI_PoolSetStatementCacheSize(p_inline_c_0, value_inline_c_1) );
+}
+
diff --git a/src/Database/Ocilib/Pool.hs b/src/Database/Ocilib/Pool.hs
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Pool.hs
@@ -0,0 +1,129 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE QuasiQuotes       #-}
+
+-- |
+-- Module:      Database.Ocilib.Pool
+-- Copyright:   (c) 2016 Thierry Bourrillon
+--              (c) 2016 FPInsight, Eurl.
+-- License:     BSD3
+-- Maintainer:  Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+--
+
+module Database.Ocilib.Pool
+    (
+    -- * Oracle Pools
+      Pool
+    , ociPoolCreate
+    , ociPoolFree
+    , ociPoolGetConnection
+    , ociPoolGetTimeout
+    , ociPoolSetTimeout
+    , ociPoolGetNoWait
+    , ociPoolSetNoWait
+    , ociPoolGetBusyCount
+    , ociPoolGetOpenedCount
+    , ociPoolGetMin
+    , ociPoolGetMax
+    , ociPoolGetIncrement
+    , ociPoolGetStatementCacheSize
+    , ociPoolSetStatementCacheSize
+    ) where
+
+import           Data.Monoid ((<>))
+import           Foreign.C.Types
+import           Foreign.C.String
+import           Foreign.Marshal.Utils
+import           Foreign.Ptr
+import qualified Language.C.Inline as C
+import           Database.Ocilib.Oci
+import           Database.Ocilib.Enums
+import           Database.Ocilib.Internal
+
+C.context (C.baseCtx <> C.funCtx <> ociCtx)
+
+C.include "<ocilib.h>"
+
+-- Oracle Pools
+
+type Pool = Ptr OCI_Pool
+
+-- | Create an Oracle pool of connections or sessions.
+ociPoolCreate :: String -> String -> String -> PoolType -> SessionMode -> CUInt -> CUInt -> CUInt -> IO (Maybe Pool)
+ociPoolCreate db user pwd pType mode minCon maxCon incrCon = do
+    let pt = fromIntegral $ fromEnum pType
+        m  = fromIntegral $ fromEnum mode
+    withCString db (\d ->
+        withCString user (\u ->
+            withCString pwd (\p ->
+                fmap toMaybePtr [C.exp| OCI_Pool* { OCI_PoolCreate( $(char *d)
+                                                                  , $(char *u)
+                                                                  , $(char *p)
+                                                                  , $(unsigned int pt)
+                                                                  , $(unsigned int m)
+                                                                  , $(unsigned int minCon)
+                                                                  , $(unsigned int maxCon)
+                                                                  , $(unsigned int incrCon)) }|]
+                )
+            )
+        )
+
+-- | Destroy a pool object.
+ociPoolFree :: Ptr OCI_Pool -> IO Bool
+ociPoolFree p = fmap toBool [C.exp| int { OCI_PoolFree($(OCI_Pool *p))} |]
+
+-- | Get a connection from the pool.
+ociPoolGetConnection :: Ptr OCI_Pool -> String -> IO (Maybe (Ptr OCI_Connection))
+ociPoolGetConnection p tag =
+    withCString tag (\t ->
+        fmap toMaybePtr [C.exp| OCI_Connection* { OCI_PoolGetConnection($(OCI_Pool *p), $(char *t)) } |]
+    )
+
+-- | Get the idle timeout for connections/sessions in the pool.
+ociPoolGetTimeout :: Ptr OCI_Pool -> IO CUInt
+ociPoolGetTimeout p = [C.exp| unsigned int { OCI_PoolGetTimeout($(OCI_Pool *p))} |]
+
+-- | Set the connections/sessions idle timeout.
+ociPoolSetTimeout :: Ptr OCI_Pool -> CUInt -> IO Bool
+ociPoolSetTimeout p t = fmap toBool [C.exp| int { OCI_PoolSetTimeout($(OCI_Pool *p), $(unsigned int t)) } |]
+
+-- | Get the waiting mode used when no more connections/sessions are available from the pool.
+ociPoolGetNoWait :: Ptr OCI_Pool -> IO Bool
+ociPoolGetNoWait p = fmap toBool [C.exp| int { OCI_PoolGetNoWait($(OCI_Pool *p)) } |]
+
+-- | Set the waiting mode used when no more connections/sessions are available from the pool.
+ociPoolSetNoWait :: Ptr OCI_Pool -> Bool -> IO Bool
+ociPoolSetNoWait p value = do
+    let v = fromIntegral $ fromEnum value
+    fmap toBool [C.exp| int { OCI_PoolSetNoWait($(OCI_Pool *p), $(int v)) }|]
+
+-- | Return the current number of busy connections/sessions.
+ociPoolGetBusyCount :: Ptr OCI_Pool -> IO CUInt
+ociPoolGetBusyCount p = [C.exp| unsigned int { OCI_PoolGetBusyCount($(OCI_Pool *p)) } |]
+
+-- | Return the current number of opened connections/sessions.
+ociPoolGetOpenedCount :: Ptr OCI_Pool -> IO CUInt
+ociPoolGetOpenedCount p = [C.exp| unsigned int { OCI_PoolGetOpenedCount($(OCI_Pool *p)) } |]
+
+-- | Return the minimum number of connections/sessions that can be opened to the database.
+ociPoolGetMin :: Ptr OCI_Pool -> IO CUInt
+ociPoolGetMin p = [C.exp| unsigned int { OCI_PoolGetMin($(OCI_Pool *p)) } |]
+
+-- | Return the maximum number of connections/sessions that can be opened to the database.
+ociPoolGetMax :: Ptr OCI_Pool -> IO CUInt
+ociPoolGetMax p = [C.exp| unsigned int { OCI_PoolGetMax($(OCI_Pool *p)) } |]
+
+-- | Return the increment for connections/sessions to be opened to the database when the pool is not full.
+ociPoolGetIncrement :: Ptr OCI_Pool -> IO CUInt
+ociPoolGetIncrement p = [C.exp| unsigned int { OCI_PoolGetIncrement($(OCI_Pool *p)) }|]
+
+-- | Return the maximum number of statements to keep in the pool statement cache.
+ociPoolGetStatementCacheSize :: Ptr OCI_Pool -> IO CUInt
+ociPoolGetStatementCacheSize p = [C.exp| unsigned int { OCI_PoolGetStatementCacheSize($(OCI_Pool *p)) } |]
+
+-- | Set the maximum number of statements to keep in the pool statement cache.
+ociPoolSetStatementCacheSize :: Ptr OCI_Pool -> CUInt -> IO Bool
+ociPoolSetStatementCacheSize p value = fmap toBool [C.exp| int { OCI_PoolSetStatementCacheSize($(OCI_Pool *p), $(unsigned int value)) } |]
diff --git a/src/Database/Ocilib/Schemas.c b/src/Database/Ocilib/Schemas.c
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Schemas.c
@@ -0,0 +1,37 @@
+
+#include <ocilib.h>
+
+OCI_TypeInfo * inline_c_Database_Ocilib_Schemas_0_755f5b80fa9779e51708ddf04a01d763a459002a(OCI_Connection * c_inline_c_0, char * name_27_inline_c_1, unsigned typ_27_inline_c_2) {
+return ( OCI_TypeInfoGet(c_inline_c_0, name_27_inline_c_1, typ_27_inline_c_2) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Schemas_1_ce9fd978e78766e62c3eb36751d58f035de371b2(OCI_TypeInfo * t_inline_c_0) {
+return ( OCI_TypeInfoGetType(t_inline_c_0) );
+}
+
+
+OCI_Connection * inline_c_Database_Ocilib_Schemas_2_c1a83b748f60963945a676070c47018bb4146f7a(OCI_TypeInfo * t_inline_c_0) {
+return ( OCI_TypeInfoGetConnection(t_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Schemas_3_e34af20cef6a0958893a49e6f4ef88a10ee20b2c(OCI_TypeInfo * t_inline_c_0) {
+return ( OCI_TypeInfoFree(t_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Schemas_4_9edcaaeb6bb88f375c7786774fdbb7e57fb13f22(OCI_TypeInfo * t_inline_c_0) {
+return ( OCI_TypeInfoGetColumnCount(t_inline_c_0) );
+}
+
+
+OCI_Column * inline_c_Database_Ocilib_Schemas_5_23c26c89b99d961f218f01e2db26236fe466db8a(OCI_TypeInfo * t_inline_c_0, unsigned i_inline_c_1) {
+return ( OCI_TypeInfoGetColumn(t_inline_c_0, i_inline_c_1));
+}
+
+
+const char * inline_c_Database_Ocilib_Schemas_6_60277e1a68a6c51fd8b4ec0690ddfae9e8097398(OCI_TypeInfo * t_inline_c_0) {
+return ( OCI_TypeInfoGetName(t_inline_c_0) );
+}
+
diff --git a/src/Database/Ocilib/Schemas.hs b/src/Database/Ocilib/Schemas.hs
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Schemas.hs
@@ -0,0 +1,66 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE QuasiQuotes       #-}
+
+-- |
+-- Module:      Database.Ocilib.Schemas
+-- Copyright:   (c) 2016 Thierry Bourrillon
+--              (c) 2016 FPInsight, Eurl.
+-- License:     BSD3
+-- Maintainer:  Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+--
+
+module Database.Ocilib.Schemas where
+
+import           Data.Monoid ((<>))
+import           Foreign.C.Types
+import           Foreign.C.String
+import           Foreign.Marshal.Utils
+import           Foreign.Ptr
+import qualified Language.C.Inline as C
+import           Database.Ocilib.Oci
+import           Database.Ocilib.Enums
+import           Database.Ocilib.Internal
+
+C.context (C.baseCtx <> C.funCtx <> ociCtx)
+
+C.include "<ocilib.h>"
+
+-- Describing Schema Meta data and Objects
+
+-- | Retrieve the available type info information.
+ociTypeInfoGet :: Ptr OCI_Connection -> String -> TypeInfoType -> IO (Maybe (Ptr OCI_TypeInfo))
+ociTypeInfoGet c name typ = do
+    let typ' = fromIntegral $ fromEnum typ
+    withCString name (\name' ->
+            fmap toMaybePtr [C.exp| OCI_TypeInfo* { OCI_TypeInfoGet($(OCI_Connection *c), $(char *name'), $(unsigned int typ')) } |]
+        )
+
+-- | Return the type of the type info object.
+ociTypeInfoGetType :: Ptr OCI_TypeInfo -> IO CUInt
+ociTypeInfoGetType t = [C.exp| unsigned int { OCI_TypeInfoGetType($(OCI_TypeInfo *t)) } |]
+
+-- | Retrieve connection handle from the type info handle.
+ociTypeInfoGetConnection :: Ptr OCI_TypeInfo -> IO (Ptr OCI_Connection)
+ociTypeInfoGetConnection t = [C.exp| OCI_Connection* { OCI_TypeInfoGetConnection($(OCI_TypeInfo *t)) } |]
+
+-- | Free a type info object.
+ociTypeInfoFree :: Ptr OCI_TypeInfo -> IO Bool
+ociTypeInfoFree t = fmap toBool [C.exp| int { OCI_TypeInfoFree($(OCI_TypeInfo *t)) } |]
+
+-- | Return the number of columns of a table/view/object.
+ociTypeInfoGetColumnCount :: Ptr OCI_TypeInfo -> IO CUInt
+ociTypeInfoGetColumnCount t = [C.exp| unsigned int { OCI_TypeInfoGetColumnCount($(OCI_TypeInfo *t)) } |]
+
+-- | Return the column object handle at the given index in the table.
+ociTypeInfoGetColumn :: Ptr OCI_TypeInfo -> CUInt -> IO (Ptr OCI_Column)
+ociTypeInfoGetColumn t i = [C.exp| OCI_Column* { OCI_TypeInfoGetColumn($(OCI_TypeInfo *t), $(unsigned int i))} |]
+
+-- | Return the name described by the type info object.
+ociTypeInfoGetName :: Ptr OCI_TypeInfo -> IO String
+ociTypeInfoGetName t = do
+    s <- [C.exp| const char* { OCI_TypeInfoGetName($(OCI_TypeInfo *t)) } |]
+    peekCString s
diff --git a/src/Database/Ocilib/Statement.c b/src/Database/Ocilib/Statement.c
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Statement.c
@@ -0,0 +1,152 @@
+
+#include <ocilib.h>
+
+OCI_Statement * inline_c_Database_Ocilib_Statement_0_437be4210d1a7b4010dede1d54486d53e32915e0(OCI_Connection * c_inline_c_0) {
+return ( OCI_StatementCreate(c_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Statement_1_fbbd67e595c510af9e5773bdb3d0759f50dee678(OCI_Statement * s_inline_c_0) {
+return ( OCI_StatementFree(s_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Statement_2_c58779ee6294620d975a9e6b8502938abcbaaa84(OCI_Statement * s_inline_c_0, char * q_inline_c_1) {
+return ( OCI_Prepare(s_inline_c_0, q_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_Statement_3_2ad0953861746bbbd3b16b66e15925ae15871280(OCI_Statement * s_inline_c_0) {
+return ( OCI_Execute(s_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Statement_4_abadaa71701db4bcedf6964af8240c1f70a06afd(OCI_Statement * s_inline_c_0, char * q_inline_c_1) {
+return ( OCI_ExecuteStmt(s_inline_c_0, q_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_Statement_5_029274b5d7bd0f545cabab68f3ce0f2c6330502e(OCI_Statement * st_inline_c_0, char * s_inline_c_1) {
+return ( OCI_Parse(st_inline_c_0, s_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_Statement_6_9a0ac755d0e0f3a1d265486aee4697aa859c74f2(OCI_Statement * st_inline_c_0, char * s_inline_c_1) {
+return (OCI_Describe(st_inline_c_0, s_inline_c_1) );
+}
+
+
+const char * inline_c_Database_Ocilib_Statement_7_edde4271bef41d20dd467fd1a9b120f2bafeeb52(OCI_Statement * st_inline_c_0) {
+return ( OCI_GetSql(st_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Statement_8_fa2cb61dd79a34d3743710a301e5be859dbe035e(OCI_Statement * st_inline_c_0) {
+return ( OCI_GetSqlErrorPos(st_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Statement_9_1d25780b80989c1e7c405492a312ded422cb5b32(OCI_Statement * st_inline_c_0) {
+return ( OCI_GetAffectedRows(st_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Statement_10_71bc41ca8d843a075c6bb8935dcafaad2e26f9bd(OCI_Statement * st_inline_c_0) {
+return ( OCI_GetSQLCommand(st_inline_c_0) );
+}
+
+
+const char * inline_c_Database_Ocilib_Statement_11_1e8e1b86c1a6a28c9c7afe577cc754e812ad0250(OCI_Statement * st_inline_c_0) {
+return ( OCI_GetSQLVerb(st_inline_c_0) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Statement_12_db878660e7be4efc9d2b501d75cba17d3b5efcc8(OCI_Statement * st_inline_c_0) {
+return ( OCI_GetStatementType(st_inline_c_0));
+}
+
+
+int inline_c_Database_Ocilib_Statement_13_b8fdfd82c34e695d85d65b1da785ce5805d82f00(OCI_Statement * st_inline_c_0, unsigned mode_27_inline_c_1) {
+return ( OCI_SetFetchMode(st_inline_c_0, mode_27_inline_c_1) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Statement_14_2dc382511e88304dd7a6f68132b1c439ccc26c0d(OCI_Statement * st_inline_c_0) {
+return ( OCI_GetFetchMode(st_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Statement_15_063cf386b02cf94743537cef943a5d2d143e6d5c(OCI_Statement * st_inline_c_0, unsigned mode_27_inline_c_1) {
+return ( OCI_SetBindMode(st_inline_c_0, mode_27_inline_c_1) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Statement_16_74b7fbdcf8434988809675370e566c6cb7e1feff(OCI_Statement * st_inline_c_0) {
+return ( OCI_GetBindMode(st_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Statement_17_a2751679e9c65d09edcaaff3a6b63f6ba463e1d2(OCI_Statement * st_inline_c_0, unsigned mode_27_inline_c_1) {
+return ( OCI_SetBindAllocation(st_inline_c_0, mode_27_inline_c_1) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Statement_18_ebd9b1d17b73fecabed2eddc767fffdfaf2ba9bc(OCI_Statement * st_inline_c_0) {
+return ( OCI_GetBindAllocation(st_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Statement_19_3f16e5e176f38647e36f4d445ea55c04046bb9a3(OCI_Statement * st_inline_c_0, unsigned sz_inline_c_1) {
+return (OCI_SetFetchSize(st_inline_c_0, sz_inline_c_1) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Statement_20_760d38b6745151bf01dfb2b766304979d93cffac(OCI_Statement * st_inline_c_0) {
+return ( OCI_GetFetchSize(st_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Statement_21_53cd8741d11899bb3f5a9b8ce8300b0b3ddec4d0(OCI_Statement * st_inline_c_0, unsigned n_inline_c_1) {
+return ( OCI_SetPrefetchSize(st_inline_c_0, n_inline_c_1) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Statement_22_03dd0956e1662399840b699d360a6c522a6f0cfb(OCI_Statement * st_inline_c_0) {
+return ( OCI_GetPrefetchSize(st_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Statement_23_66fbdbd29e181452c52d3dc95e3d9a2315b363d0(OCI_Statement * st_inline_c_0, unsigned s_inline_c_1) {
+return (OCI_SetPrefetchMemory(st_inline_c_0, s_inline_c_1) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Statement_24_9d0192b0fd7dc077b854e4ae5a7fd352e73b4149(OCI_Statement * st_inline_c_0) {
+return ( OCI_GetPrefetchMemory(st_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Statement_25_aecb97d252206b7d30fc810d4895164485cda656(OCI_Statement * st_inline_c_0, unsigned s_inline_c_1) {
+return ( OCI_SetLongMaxSize(st_inline_c_0, s_inline_c_1) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Statement_26_2e778318e7fd00c9faaaada8f257c611779cfdc4(OCI_Statement * st_inline_c_0) {
+return ( OCI_GetLongMaxSize(st_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Statement_27_b325f7aa5b598d655d5298b9dcd37d74604e706c(OCI_Statement * st_inline_c_0, unsigned mode_27_inline_c_1) {
+return ( OCI_SetLongMode(st_inline_c_0, mode_27_inline_c_1) );
+}
+
+
+unsigned inline_c_Database_Ocilib_Statement_28_483f469de9853673a6c58f2acf525f2f6f1ea0e1(OCI_Statement * st_inline_c_0) {
+return ( OCI_GetLongMode(st_inline_c_0) );
+}
+
+
+OCI_Connection * inline_c_Database_Ocilib_Statement_29_9d1330e2292ab6521736a4002f37e85c1087fa1b(OCI_Statement * st_inline_c_0) {
+return ( OCI_StatementGetConnection(st_inline_c_0) );
+}
+
diff --git a/src/Database/Ocilib/Statement.hs b/src/Database/Ocilib/Statement.hs
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Statement.hs
@@ -0,0 +1,214 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE QuasiQuotes       #-}
+
+-- |
+-- Module:      Database.Ocilib.Statement
+-- Copyright:   (c) 2016 Thierry Bourrillon
+--              (c) 2016 FPInsight, Eurl.
+-- License:     BSD3
+-- Maintainer:  Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+--
+
+module Database.Ocilib.Statement
+    ( ociStatementCreate
+    , ociStatementFree
+    , ociPrepare
+    , ociExecute
+    , ociExecuteStmt
+    , ociParse
+    , ociDescribe
+    , ociGetSql
+    , ociGetSqlErrorPos
+    , ociGetAffectedRows
+    , ociGetSQLCommand
+    , ociGetSQLVerb
+    , ociGetStatementType
+    , ociSetFetchMode
+    , ociGetFetchMode
+    , ociSetBindMode
+    , ociGetBindMode
+    , ociSetBindAllocation
+    , ociGetBindAllocation
+    , ociSetFetchSize
+    , ociGetFetchSize
+    , ociSetPrefetchSize
+    , ociGetPrefetchSize
+    , ociSetPrefetchMemory
+    , ociGetPrefetchMemory
+    , ociSetLongMaxSize
+    , ociGetLongMaxSize
+    , ociSetLongMode
+    , ociGetLongMode
+    , ociStatementGetConnection
+    ) where
+
+import           Data.Monoid ((<>))
+import           Foreign.C.Types
+import           Foreign.C.String
+import           Foreign.Marshal.Utils
+import           Foreign.Ptr
+import qualified Language.C.Inline as C
+import           Database.Ocilib.Oci
+import           Database.Ocilib.Enums
+
+C.context (C.baseCtx <> C.funCtx <> ociCtx)
+
+C.include "<ocilib.h>"
+
+-- Executing Statements
+
+-- | Create a statement object and return its handle.
+ociStatementCreate :: Ptr OCI_Connection -> IO (Ptr OCI_Statement)
+ociStatementCreate c = [C.exp| OCI_Statement* { OCI_StatementCreate($(OCI_Connection *c)) } |]
+
+-- | Free a statement and all resources associated to it (resultsets ...)
+ociStatementFree :: Ptr OCI_Statement -> IO Bool
+ociStatementFree s = fmap toBool [C.exp| int { OCI_StatementFree($(OCI_Statement *s)) } |]
+
+-- | Prepare a SQL statement or PL/SQL block.
+ociPrepare :: Ptr OCI_Statement -> String -> IO Bool
+ociPrepare s sql =
+    withCString sql (\q ->
+        fmap toBool [C.exp| int { OCI_Prepare($(OCI_Statement *s), $(char *q)) } |]
+    )
+
+-- | Execute a prepared SQL statement or PL/SQL block.
+ociExecute :: Ptr OCI_Statement -> IO Bool
+ociExecute s = fmap toBool [C.exp| int { OCI_Execute($(OCI_Statement *s)) } |]
+
+-- | Prepare and Execute a SQL statement or PL/SQL block.
+ociExecuteStmt :: Ptr OCI_Statement -> String -> IO Bool
+ociExecuteStmt s sql =
+    withCString sql (\q ->
+        fmap toBool [C.exp| int { OCI_ExecuteStmt($(OCI_Statement *s), $(char *q)) } |]
+    )
+
+-- | Parse a SQL statement or PL/SQL block.
+ociParse :: Ptr OCI_Statement -> String -> IO Bool
+ociParse st sql =
+    withCString sql (\s ->
+        fmap toBool [C.exp| int { OCI_Parse($(OCI_Statement *st), $(char *s)) } |]
+    )
+
+-- | Describe the select list of a SQL select statement.
+ociDescribe :: Ptr OCI_Statement -> String -> IO Bool
+ociDescribe st sql =
+    withCString sql (\s ->
+        fmap toBool [C.exp| int {OCI_Describe($(OCI_Statement *st), $(char *s)) } |]
+    )
+
+-- | Return the last SQL or PL/SQL statement prepared or executed by the statement.
+ociGetSql :: Ptr OCI_Statement -> IO String
+ociGetSql st = do
+    r <- [C.exp| const char* { OCI_GetSql($(OCI_Statement *st)) } |] -- FIXME should release the CString
+    peekCString r
+
+-- | Return the error position (in terms of characters) in the SQL statement where the error occurred in case of SQL parsing error.
+ociGetSqlErrorPos :: Ptr OCI_Statement -> IO CUInt
+ociGetSqlErrorPos st = [C.exp| unsigned int { OCI_GetSqlErrorPos($(OCI_Statement *st)) } |]
+
+-- | Return the number of rows affected by the SQL statement.
+ociGetAffectedRows :: Ptr OCI_Statement -> IO CUInt
+ociGetAffectedRows st = [C.exp| unsigned int { OCI_GetAffectedRows($(OCI_Statement *st)) } |]
+
+-- | Return the Oracle SQL code the command held by the statement handle.
+ociGetSQLCommand :: Ptr OCI_Statement -> IO CUInt
+ociGetSQLCommand st = [C.exp| unsigned int { OCI_GetSQLCommand($(OCI_Statement *st)) } |]
+
+-- | Return the verb of the SQL command held by the statement handle.
+ociGetSQLVerb :: Ptr OCI_Statement -> IO String
+ociGetSQLVerb st = do
+    v <- [C.exp| const char* { OCI_GetSQLVerb($(OCI_Statement *st)) } |]
+    peekCString v
+
+-- Statement Control
+
+-- | Return the type of a SQL statement.
+ociGetStatementType :: Ptr OCI_Statement -> IO StatementType
+ociGetStatementType st = fmap (toEnum . fromIntegral) [C.exp| unsigned int { OCI_GetStatementType($(OCI_Statement *st))} |]
+
+-- | Set the fetch mode of a SQL statement.
+ociSetFetchMode :: Ptr OCI_Statement -> StatementFetchMode -> IO Bool
+ociSetFetchMode st mode = do
+    let mode' = fromIntegral $ fromEnum mode
+    fmap toBool [C.exp| int { OCI_SetFetchMode($(OCI_Statement *st), $(unsigned int mode')) } |]
+
+-- | Return the fetch mode of a SQL statement.
+ociGetFetchMode :: Ptr OCI_Statement -> IO StatementFetchMode
+ociGetFetchMode st = fmap (toEnum . fromIntegral) [C.exp| unsigned int { OCI_GetFetchMode($(OCI_Statement *st)) } |]
+
+-- | Set the binding mode of a SQL statement.
+ociSetBindMode :: Ptr OCI_Statement -> BindMode -> IO Bool
+ociSetBindMode st mode = do
+    let mode' = fromIntegral $ fromEnum mode
+    fmap toBool [C.exp| int { OCI_SetBindMode($(OCI_Statement *st), $(unsigned int mode')) } |]
+
+-- | Return the binding mode of a SQL statement.
+ociGetBindMode :: Ptr OCI_Statement -> IO BindMode
+ociGetBindMode st = fmap (toEnum . fromIntegral) [C.exp| unsigned int { OCI_GetBindMode($(OCI_Statement *st)) }|]
+
+-- | Set the bind allocation mode of a SQL statement.
+ociSetBindAllocation :: Ptr OCI_Statement -> BindAllocationMode -> IO Bool
+ociSetBindAllocation st mode = do
+    let mode' = fromIntegral $ fromEnum mode
+    fmap toBool [C.exp| int { OCI_SetBindAllocation($(OCI_Statement *st), $(unsigned int mode')) } |]
+
+-- | Return the bind allocation mode of a SQL statement.
+ociGetBindAllocation :: Ptr OCI_Statement -> IO BindAllocationMode
+ociGetBindAllocation st = fmap (toEnum . fromIntegral)
+    [C.exp| unsigned int { OCI_GetBindAllocation($(OCI_Statement *st)) } |]
+
+-- | Set the number of rows fetched per internal server fetch call.
+ociSetFetchSize :: Ptr OCI_Statement -> CUInt -> IO Bool
+ociSetFetchSize st sz =
+    fmap toBool [C.exp| int {OCI_SetFetchSize($(OCI_Statement *st), $(unsigned int sz)) } |]
+
+-- | Return the number of rows fetched per internal server fetch call.
+ociGetFetchSize :: Ptr OCI_Statement -> IO CUInt
+ociGetFetchSize st = [C.exp| unsigned int { OCI_GetFetchSize($(OCI_Statement *st)) } |]
+
+-- | Set the number of rows pre-fetched by OCI Client.
+ociSetPrefetchSize :: Ptr OCI_Statement -> CUInt -> IO Bool
+ociSetPrefetchSize st n =
+    fmap toBool [C.exp| int { OCI_SetPrefetchSize($(OCI_Statement *st), $(unsigned int n)) } |]
+
+-- | Return the number of rows pre-fetched by OCI Client.
+ociGetPrefetchSize :: Ptr OCI_Statement -> IO CUInt
+ociGetPrefetchSize st = [C.exp| unsigned int { OCI_GetPrefetchSize($(OCI_Statement *st)) } |]
+
+-- | Set the amount of memory pre-fetched by OCI Client.
+ociSetPrefetchMemory :: Ptr OCI_Statement -> CUInt -> IO Bool
+ociSetPrefetchMemory st s =
+    fmap toBool [C.exp| int {OCI_SetPrefetchMemory($(OCI_Statement *st), $(unsigned int s)) } |]
+
+-- | Return the amount of memory used to retrieve rows pre-fetched by OCI Client.
+ociGetPrefetchMemory :: Ptr OCI_Statement -> IO CUInt
+ociGetPrefetchMemory st =
+    [C.exp| unsigned int { OCI_GetPrefetchMemory($(OCI_Statement *st)) } |]
+
+-- | Set the LONG data type piece buffer size.
+ociSetLongMaxSize :: Ptr OCI_Statement -> CUInt -> IO Bool
+ociSetLongMaxSize st s =
+    fmap toBool [C.exp| int { OCI_SetLongMaxSize($(OCI_Statement *st), $(unsigned int s)) } |]
+
+-- | Return the LONG data type piece buffer size.
+ociGetLongMaxSize :: Ptr OCI_Statement -> IO CUInt
+ociGetLongMaxSize st = [C.exp| unsigned int { OCI_GetLongMaxSize($(OCI_Statement *st)) } |]
+
+-- | Set the long data type handling mode of a SQL statement.
+ociSetLongMode :: Ptr OCI_Statement -> LongMode -> IO Bool
+ociSetLongMode st mode = do
+    let mode' = fromIntegral $ fromEnum mode
+    fmap toBool [C.exp| int { OCI_SetLongMode($(OCI_Statement *st), $(unsigned int mode')) } |]
+
+-- | Return the long data type handling mode of a SQL statement.
+ociGetLongMode :: Ptr OCI_Statement -> IO LongMode
+ociGetLongMode st = fmap (toEnum . fromIntegral) [C.exp| unsigned int { OCI_GetLongMode($(OCI_Statement *st)) } |]
+
+-- | Return the connection handle associated with a statement handle.
+ociStatementGetConnection :: Ptr OCI_Statement -> IO (Ptr OCI_Connection)
+ociStatementGetConnection st = [C.exp| OCI_Connection* { OCI_StatementGetConnection($(OCI_Statement *st)) } |]
diff --git a/src/Database/Ocilib/Timestamp.c b/src/Database/Ocilib/Timestamp.c
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Timestamp.c
@@ -0,0 +1,12 @@
+
+#include <ocilib.h>
+
+OCI_Timestamp * inline_c_Database_Ocilib_Timestamp_0_d207c7e0a83cdd4b3e56aa6f7830ab9281b863a7(OCI_Connection * c_inline_c_0, unsigned t_inline_c_1) {
+return ( OCI_TimestampCreate(c_inline_c_0, t_inline_c_1) );
+}
+
+
+int inline_c_Database_Ocilib_Timestamp_1_25db7b5cf8a20a1ea9afd9112cf63309e5a0cb0c(OCI_Timestamp * t_inline_c_0) {
+return ( OCI_TimestampFree(t_inline_c_0) );
+}
+
diff --git a/src/Database/Ocilib/Timestamp.hs b/src/Database/Ocilib/Timestamp.hs
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Timestamp.hs
@@ -0,0 +1,154 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE QuasiQuotes       #-}
+
+-- |
+-- Module:      Database.Ocilib.Timestamp
+-- Copyright:   (c) 2016 Thierry Bourrillon
+--              (c) 2016 FPInsight, Eurl.
+-- License:     BSD3
+-- Maintainer:  Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+--
+
+module Database.Ocilib.Timestamp where
+
+import           Data.Monoid ((<>))
+import           Foreign.C.Types
+-- import           Foreign.C.String
+import           Foreign.Marshal.Utils
+import           Foreign.Ptr
+import qualified Language.C.Inline as C
+import           Database.Ocilib.Oci
+-- import           Database.Ocilib.Enums
+
+C.context (C.baseCtx <> C.funCtx <> ociCtx)
+
+C.include "<ocilib.h>"
+
+-- | Create a local Timestamp instance.
+ociTimestampCreate :: Ptr OCI_Connection -> CUInt -> IO (Ptr OCI_Timestamp)
+ociTimestampCreate c t = [C.exp| OCI_Timestamp* { OCI_TimestampCreate($(OCI_Connection *c), $(unsigned int t)) } |] -- FIXME use enum for type
+
+-- | Free an OCI_Timestamp handle.
+ociTimestampFree :: Ptr OCI_Timestamp -> IO Bool
+ociTimestampFree t = fmap toBool [C.exp| int { OCI_TimestampFree($(OCI_Timestamp *t)) } |]
+
+{-
+-- | Create an array of timestamp object.
+OCI_Timestamp **OCI_TimestampArrayCreate (OCI_Connection *con, unsigned int type, unsigned int nbelem)
+
+-- | Free an array of timestamp objects.
+boolean OCI_TimestampArrayFree (OCI_Timestamp **tmsps)
+
+-- | Return the type of the given Timestamp object.
+unsigned int OCI_TimestampGetType (OCI_Timestamp *tmsp)
+
+-- | Assign the value of a timestamp handle to another one.
+boolean OCI_TimestampAssign (OCI_Timestamp *tmsp, OCI_Timestamp *tmsp_src)
+
+-- | Check if the given timestamp is valid.
+int OCI_TimestampCheck (OCI_Timestamp *tmsp)
+
+-- | Compares two timestamp handles. More...
+int OCI_TimestampCompare (OCI_Timestamp *tmsp, OCI_Timestamp *tmsp2)
+
+-- | Set a timestamp handle value.
+boolean OCI_TimestampConstruct (OCI_Timestamp *tmsp, int year, int month, int day, int hour, int min, int sec, int fsec, const otext *time_zone)
+
+-- | Convert one timestamp value from one type to another.
+boolean OCI_TimestampConvert (OCI_Timestamp *tmsp, OCI_Timestamp *tmsp_src)
+
+-- | Convert a string to a timestamp and store it in the given timestamp handle.
+boolean OCI_TimestampFromText (OCI_Timestamp *tmsp, const otext *str, const otext *fmt)
+
+-- |Convert a timestamp value from the given timestamp handle to a string.
+boolean OCI_TimestampToText (OCI_Timestamp *tmsp, const otext *fmt, int size, otext *str, int precision)
+
+-- | Extract the date part from a timestamp handle.
+boolean OCI_TimestampGetDate (OCI_Timestamp *tmsp, int *year, int *month, int *day)
+
+-- | Extract the time portion from a timestamp handle.
+boolean OCI_TimestampGetTime (OCI_Timestamp *tmsp, int *hour, int *min, int *sec, int *fsec)
+
+-- | Extract the date and time parts from a date handle.
+boolean OCI_TimestampGetDateTime (OCI_Timestamp *tmsp, int *year, int *month, int *day, int *hour, int *min, int *sec, int *fsec)
+
+-- | Return the time zone name of a timestamp handle.
+boolean OCI_TimestampGetTimeZoneName (OCI_Timestamp *tmsp, int size, otext *str)
+
+-- | Return the time zone (hour, minute) portion of a timestamp handle.
+boolean OCI_TimestampGetTimeZoneOffset (OCI_Timestamp *tmsp, int *hour, int *min)
+
+-- | Add an interval value to a timestamp value of a timestamp handle.
+boolean OCI_TimestampIntervalAdd (OCI_Timestamp *tmsp, OCI_Interval *itv)
+
+-- | Subtract an interval value from a timestamp value of a timestamp handle.
+boolean OCI_TimestampIntervalSub (OCI_Timestamp *tmsp, OCI_Interval *itv)
+
+-- | Store the difference of two timestamp handles into an interval handle.
+boolean OCI_TimestampSubtract (OCI_Timestamp *tmsp, OCI_Timestamp *tmsp2, OCI_Interval *itv)
+
+-- | Stores the system current date and time as a timestamp value with time zone into the timestamp handle.
+boolean OCI_TimestampSysTimestamp (OCI_Timestamp *tmsp)
+
+-- | Affect an OCI_Timestamp handle value to ISO C time data types.
+boolean OCI_TimestampToCTime (OCI_Timestamp *tmsp, struct tm *ptm, time_t *pt)
+
+-- | Affect ISO C time data types values to an OCI_Timestamp handle.
+boolean OCI_TimestampFromCTime (OCI_Timestamp *tmsp, struct tm *ptm, time_t t)
+
+-- | Create a local interval object.
+OCI_Interval *OCI_IntervalCreate (OCI_Connection *con, unsigned int type)
+
+-- Free an OCI_Interval handle.
+boolean OCI_IntervalFree (OCI_Interval *itv)
+
+-- | Create an array of Interval object.
+OCI_Interval **OCI_IntervalArrayCreate (OCI_Connection *con, unsigned int type, unsigned int nbelem)
+
+-- | Free an array of Interval objects.
+boolean OCI_IntervalArrayFree (OCI_Interval **itvs)
+
+-- | Return the type of the given Interval object.
+unsigned int OCI_IntervalGetType (OCI_Interval *itv)
+
+-- | Assign the value of a interval handle to another one.
+boolean OCI_IntervalAssign (OCI_Interval *itv, OCI_Interval *itv_src)
+
+-- | Check if the given interval is valid.
+int OCI_IntervalCheck (OCI_Interval *itv)
+
+-- | Compares two interval handles.
+int OCI_IntervalCompare (OCI_Interval *itv, OCI_Interval *itv2)
+
+-- | Convert a string to an interval and store it in the given interval handle.
+boolean OCI_IntervalFromText (OCI_Interval *itv, const otext *str)
+
+-- | Convert an interval value from the given interval handle to a string.
+boolean OCI_IntervalToText (OCI_Interval *itv, int leading_prec, int fraction_prec, int size, otext *str)
+
+-- | Correct an interval handle value with the given time zone.
+boolean OCI_IntervalFromTimeZone (OCI_Interval *itv, const otext *str)
+
+-- | Return the day / time portion of an interval handle.
+boolean OCI_IntervalGetDaySecond (OCI_Interval *itv, int *day, int *hour, int *min, int *sec, int *fsec)
+
+-- | Return the year / month portion of an interval handle.
+boolean OCI_IntervalGetYearMonth (OCI_Interval *itv, int *year, int *month)
+
+-- | Set the day / time portion if the given interval handle.
+boolean OCI_IntervalSetDaySecond (OCI_Interval *itv, int day, int hour, int min, int sec, int fsec)
+
+-- | Set the year / month portion if the given Interval handle.
+boolean OCI_IntervalSetYearMonth (OCI_Interval *itv, int year, int month)
+
+-- | Adds an interval handle value to another.
+boolean OCI_IntervalAdd (OCI_Interval *itv, OCI_Interval *itv2)
+
+-- | Subtract an interval handle value from another.
+boolean OCI_IntervalSubtract (OCI_Interval *itv, OCI_Interval *itv2)
+
+-}
diff --git a/src/Database/Ocilib/Transaction.c b/src/Database/Ocilib/Transaction.c
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Transaction.c
@@ -0,0 +1,22 @@
+
+#include <ocilib.h>
+
+int inline_c_Database_Ocilib_Transaction_0_f5421b76946e52bf0e69956395597c4ff8820ac3(OCI_Connection * c_inline_c_0) {
+return ( OCI_Commit(c_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Transaction_1_caca70d123cff07f7290f9e777e8893c5e17987d(OCI_Connection * c_inline_c_0) {
+return ( OCI_Rollback(c_inline_c_0) );
+}
+
+
+int inline_c_Database_Ocilib_Transaction_2_53cd6012d62ea021551b42ab4087ef0e5d019c81(OCI_Connection * c_inline_c_0, int b_27_inline_c_1) {
+return ( OCI_SetAutoCommit(c_inline_c_0, b_27_inline_c_1));
+}
+
+
+int inline_c_Database_Ocilib_Transaction_3_87c21aa56ac0c5228441e9c18823f3ecac44dd68(OCI_Connection * c_inline_c_0) {
+return ( OCI_GetAutoCommit(c_inline_c_0) );
+}
+
diff --git a/src/Database/Ocilib/Transaction.hs b/src/Database/Ocilib/Transaction.hs
new file mode 100644
--- /dev/null
+++ b/src/Database/Ocilib/Transaction.hs
@@ -0,0 +1,77 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE QuasiQuotes       #-}
+
+-- |
+-- Module:      Database.Ocilib.Transaction
+-- Copyright:   (c) 2016 Thierry Bourrillon
+--              (c) 2016 FPInsight, Eurl.
+-- License:     BSD3
+-- Maintainer:  Thierry Bourrillon <thierry.bourrillon@fpinsight.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+--
+
+module Database.Ocilib.Transaction where
+
+import           Data.Monoid ((<>))
+-- import           Foreign.C.Types
+-- import           Foreign.C.String
+import           Foreign.Marshal.Utils
+import           Foreign.Ptr
+import qualified Language.C.Inline as C
+import           Database.Ocilib.Oci
+-- import           Database.Ocilib.Enums
+
+C.context (C.baseCtx <> C.funCtx <> ociCtx)
+
+C.include "<ocilib.h>"
+
+-- | Commit current pending changes.
+ociCommit :: Ptr OCI_Connection -> IO Bool
+ociCommit c = fmap toBool [C.exp| int { OCI_Commit($(OCI_Connection *c)) }|]
+
+-- | Cancel current pending changes.
+ociRollback :: Ptr OCI_Connection -> IO Bool
+ociRollback c = fmap toBool [C.exp| int { OCI_Rollback($(OCI_Connection *c)) } |]
+
+-- | Enable / disable auto commit mode.
+ociSetAutoCommit :: Ptr OCI_Connection -> Bool -> IO Bool
+ociSetAutoCommit c b = do
+    let b' = fromBool b
+    fmap toBool [C.exp| int { OCI_SetAutoCommit($(OCI_Connection *c), $(int b'))} |]
+
+-- | Get current auto commit mode status.
+ociGetAutoCommit :: Ptr OCI_Connection -> IO Bool
+ociGetAutoCommit c = fmap toBool [C.exp| int { OCI_GetAutoCommit($(OCI_Connection *c)) } |]
+
+{-
+-- | Create a new global transaction or a serializable/read-only local transaction.
+-- OCI_Transaction *OCI_TransactionCreate (OCI_Connection *con, unsigned int timeout, unsigned int mode, OCI_XID *pxid)
+
+-- | Free current transaction.
+-- boolean OCI_TransactionFree (OCI_Transaction *trans)
+
+-- | Start global transaction.
+-- boolean OCI_TransactionStart (OCI_Transaction *trans)
+
+-- | Stop current global transaction.
+-- boolean OCI_TransactionStop (OCI_Transaction *trans)
+
+-- | Resume a stopped global transaction.
+-- boolean OCI_TransactionResume (OCI_Transaction *trans)
+
+-- | Prepare a global transaction validation. More...
+-- boolean OCI_TransactionPrepare (OCI_Transaction *trans)
+
+-- | Cancel the prepared global transaction validation.
+-- boolean OCI_TransactionForget (OCI_Transaction *trans)
+
+-- | Return global transaction mode.
+-- unsigned int OCI_TransactionGetMode (OCI_Transaction *trans)
+
+-- | Return global transaction Timeout.
+-- unsigned int OCI_TransactionGetTimeout (OCI_Transaction *trans)
+
+-}
diff --git a/stack.yaml b/stack.yaml
new file mode 100644
--- /dev/null
+++ b/stack.yaml
@@ -0,0 +1,8 @@
+resolver: lts-6.12
+packages:
+- '.'
+extra-deps: []
+flags: {}
+extra-package-dbs: []
+extra-include-dirs: []
+extra-lib-dirs: []
diff --git a/tests/Tests.hs b/tests/Tests.hs
new file mode 100644
--- /dev/null
+++ b/tests/Tests.hs
@@ -0,0 +1,192 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+import Data.Maybe
+import Database.Ocilib
+import Database.Ocilib.Bindings
+import Database.Ocilib.Connection
+import Database.Ocilib.Collections
+import Database.Ocilib.Errors
+import Database.Ocilib.Fetch
+import Database.Ocilib.Pool
+import Database.Ocilib.Statement
+
+import Foreign.Ptr
+import Test.Tasty
+import Test.Tasty.HUnit
+
+main :: IO ()
+main = defaultMain tests
+
+tests :: TestTree
+tests = testGroup "Tests"
+    [ testCase "fetchTest" fetchTest
+--    , testCase "poolTest" poolTest
+--    , testCase "testErrors" testErrors
+    , testCase "testStringBinding" testStringBinding
+    , testCase "testVarray" testVarray
+    ]
+
+fetchTest :: Assertion
+fetchTest = do
+    e <- ociInitialize Nothing Nothing [OCI_ENV_DEFAULT, OCI_ENV_CONTEXT]
+    assertBool "ociInitialize" e
+
+    maybeC <- ociConnectionCreate "localhost:1521/xe" "system" "oracle" OCI_SESSION_DEFAULT
+    case maybeC of
+        Nothing -> assertFailure "failed to create connection"
+        Just c -> do
+            st <- ociStatementCreate c
+            b <- ociExecuteStmt st "select * from test_fetch"
+            assertBool "ociExecuteStatement" b
+
+            maybeRs <- ociGetResultset st
+            case maybeRs of
+                Nothing -> assertFailure "fail to get resultset"
+                Just rs -> do
+                    ml <- ociFetchNext rs
+                    assertBool "ociFetchNext" ml
+
+                    code    <- ociGetInt2    rs "code"
+                    article <- ociGetString2 rs "article"
+                    price   <- ociGetDouble2 rs "price"
+                    date    <- ociGetString2 rs "creation"
+
+                    assertEqual "code"    1 code
+                    assertEqual "article" "shoes" article
+                    assertEqual "price" 3.14 price
+                    assertEqual "Date" "1978-12-23" date
+
+                    _ <- ociStatementFree st
+                    _ <- ociConnectionFree c
+
+                    q <- ociCleanup
+                    assertBool "ociCleanup" q
+
+--------------------------------------------------------------------------------
+poolTest :: Assertion
+poolTest = do
+    e <- ociInitialize Nothing Nothing [OCI_ENV_DEFAULT, OCI_ENV_THREADED, OCI_ENV_CONTEXT]
+    assertBool "ociInitialize" e
+
+    maybeP <- ociPoolCreate "localhost:1521/xe" "system" "oracle" OCI_POOL_CONNECTION OCI_SESSION_DEFAULT 1 2 1
+    case maybeP of
+        Nothing -> assertFailure "failed to create pool"
+        Just p -> do
+            maybeC <- ociPoolGetConnection p ""
+            case maybeC of
+                Nothing -> assertFailure "failed to get Connection"
+                Just c ->  do
+                    bc <- ociPoolGetBusyCount p
+                    assertEqual "ociPoolGetBusyCount" 1 bc
+                    _ <- ociConnectionFree c
+                    return ()
+            f <- ociPoolFree p
+            assertBool "ociPoolFree" f
+    _ <- ociCleanup
+    return ()
+
+--------------------------------------------------------------------------------
+testErrors :: Assertion
+testErrors = do
+    e <- ociInitialize (Just errHandler) Nothing [OCI_ENV_DEFAULT, OCI_ENV_THREADED, OCI_ENV_CONTEXT]
+    assertBool "ociInitialize" e
+
+    p <- ociPoolCreate "localhost:1521/xe" "system" "bad" OCI_POOL_CONNECTION OCI_SESSION_DEFAULT 5 10 1
+    assertBool "ociPoolCreate" $ isNothing p
+
+    e <- ociGetLastError
+    assertBool "got error" $ isJust e
+
+    where
+        errHandler :: Ptr OCI_Error -> IO ()
+        errHandler e = do
+            message <- ociErrorGetString e
+            print message
+
+
+--------------------------------------------------------------------------------
+testStringBinding :: Assertion
+testStringBinding = do
+    _ <- ociInitialize Nothing Nothing [OCI_ENV_DEFAULT, OCI_ENV_CONTEXT]
+
+    maybeC <- ociConnectionCreate "localhost:1521/xe" "system" "oracle" OCI_SESSION_DEFAULT
+    case maybeC of
+        Nothing -> assertFailure "unable to connect"
+        Just c -> do
+            st <- ociStatementCreate c
+            ociSetBindAllocation st OCI_BAM_INTERNAL
+            b <- ociPrepare st "select * from test_fetch where article=(:article)"
+            assertBool "prepared" b
+            b <- ociBindString st "article" nullPtr 30
+            assertBool "bound" b
+            mBind <- ociGetBind2 st "article"
+            case mBind of
+                Nothing -> assertFailure "failed to get Bind"
+                Just bind -> return ()
+
+            b <- ociExecute st
+            assertBool "Execute" b
+
+            maybeRs <- ociGetResultset st
+            assertBool "ociGetResultSet" (isJust maybeRs)
+
+            {-
+            b <- ociFetchNext rs
+            assertBool "ociFetchNext" b
+
+            code    <- ociGetInt2    rs "code"
+            article <- ociGetString2 rs "article"
+            price   <- ociGetDouble2 rs "price"
+            date    <- ociGetString2 rs "creation"
+
+            assertEqual "code"    2 code
+            assertEqual "article" "shirt" article
+            assertEqual "price" 5.99 price
+            assertEqual "Date" "1999-09-12" date
+            -}
+            {-
+            e <- ociGetLastError
+            m <- ociErrorGetString e
+            print m
+            -}
+
+            _ <- ociStatementFree st
+
+            _ <- ociConnectionFree c
+
+            _ <- ociCleanup
+            return ()
+
+--------------------------------------------------------------------------------
+testVarray :: Assertion
+testVarray = do
+    i <- ociInitialize Nothing Nothing [OCI_ENV_DEFAULT, OCI_ENV_CONTEXT]
+    assertBool "initialization" i
+
+    maybeCn <- ociConnectionCreate "localhost:1521/xe" "system" "oracle" OCI_SESSION_DEFAULT
+    let cn = fromJust maybeCn
+    mt <- ociTypeInfoGet cn "t_tab1_emp" OCI_TIF_TYPE
+    case mt of
+        Nothing -> assertFailure "get t_tab1 type"
+        Just t_tab1_emp -> do
+            mcoll <- ociCollCreate t_tab1_emp
+            case mcoll of
+                Nothing -> assertFailure "create t_tab_emp coll"
+                Just coll -> do
+                    me <- ociElemCreate t_tab1_emp
+                    case me of
+                        Nothing -> assertFailure "create elem"
+                        Just elem  -> do
+                            b <- ociCollAppend coll elem
+                            assertBool "append elem" b
+                            s <- ociCollGetSize coll
+                            assertEqual "collection size" 1 s
+
+printErrorIfAny :: IO ()
+printErrorIfAny = do
+    me <- ociGetLastError
+    case me of
+        Nothing -> return ()
+        Just e -> do
+            s <- ociErrorGetString e
+            print s
