packages feed

csv-conduit 0.1 → 0.2

raw patch · 3 files changed

+131/−41 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Data.CSV.Conduit: class CSVeable s r
- Data.CSV.Conduit: instance (CSVeable s (Row s'), Ord s', IsString s) => CSVeable s (MapRow s')
- Data.CSV.Conduit: instance CSVeable ByteString (Row ByteString)
- Data.CSV.Conduit: instance CSVeable ByteString (Row Text)
- Data.CSV.Conduit: instance CSVeable Text (Row Text)
+ Data.CSV.Conduit: class CSV s r
+ Data.CSV.Conduit: instance (CSV s (Row s'), Ord s', IsString s) => CSV s (MapRow s')
+ Data.CSV.Conduit: instance CSV ByteString (Row ByteString)
+ Data.CSV.Conduit: instance CSV ByteString (Row Text)
+ Data.CSV.Conduit: instance CSV Text (Row Text)
+ Data.CSV.Conduit: runResourceT :: MonadBaseControl IO m => ResourceT m a -> m a
+ Data.CSV.Conduit: transformCSV :: (MonadResource m, CSV s a, CSV s' b) => CSVSettings -> Source m s -> Conduit a m b -> Sink s' m () -> m ()
- Data.CSV.Conduit: fromCSV :: (CSVeable s r, MonadResource m) => CSVSettings -> Conduit r m s
+ Data.CSV.Conduit: fromCSV :: (CSV s r, MonadResource m) => CSVSettings -> Conduit r m s
- Data.CSV.Conduit: intoCSV :: (CSVeable s r, MonadResource m) => CSVSettings -> Conduit s m r
+ Data.CSV.Conduit: intoCSV :: (CSV s r, MonadResource m) => CSVSettings -> Conduit s m r
- Data.CSV.Conduit: mapCSVFile :: (MonadIO m, MonadUnsafeIO m, MonadThrow m, MonadBaseControl IO m, CSVeable ByteString a, CSVeable ByteString b) => CSVSettings -> (a -> b) -> FilePath -> FilePath -> m ()
+ Data.CSV.Conduit: mapCSVFile :: (MonadResource m, CSV ByteString a, CSV ByteString b) => CSVSettings -> (a -> [b]) -> FilePath -> FilePath -> m ()
- Data.CSV.Conduit: readCSVFile :: (MonadUnsafeIO m, MonadThrow m, MonadBaseControl IO m, MonadIO m, CSVeable ByteString a) => CSVSettings -> FilePath -> m [a]
+ Data.CSV.Conduit: readCSVFile :: (MonadResource m, CSV ByteString a) => CSVSettings -> FilePath -> m [a]
- Data.CSV.Conduit: rowToStr :: CSVeable s r => CSVSettings -> r -> s
+ Data.CSV.Conduit: rowToStr :: CSV s r => CSVSettings -> r -> s

Files

README.markdown view
@@ -47,29 +47,47 @@  ### Usage Examples -#### Example 1: Basic Operation  +#### Example #1: Basics Using Convenience API+     {-# LANGUAGE OverloadedStrings #-} -    import Data.Conduit.Text+    import Data.Conduit     import Data.Conduit.Binary+    import Data.Conduit.List as CL+    import Data.CSV.Conduit+    +    -- Just reverse te columns+    myProcessor :: Conduit (Row Text) m (Row Text)+    myProcessor = CL.map reverse+    +    test :: IO ()+    test = runResourceT $ +      transformCSV defCSVSettings +                   (sourceFile "input.csv") +                   myProcessor+                   (sinkFile "output.csv")+++#### Example #2: Basics Using Conduit API++    {-# LANGUAGE OverloadedStrings #-}+     import Data.Conduit+    import Data.Conduit.Binary     import Data.CSV.Conduit     +    myProcessor :: Conduit (Row Text) m (Row Text)+    myProcessor = undefined+         -- Let's simply stream from a file, parse the CSV, reserialize it     -- and push back into another file.     test :: IO ()     test = runResourceT $        sourceFile "test/BigFile.csv" $= -      decode utf8 $=-      (intoCSV defCSVSettings -        :: forall m. MonadResource m => Conduit Text m (MapRow Text)) $= -      fromCSV defCSVSettings $=-      encode utf8 $$+      intoCSV defCSVSettings $=+      myProcessor $=+      fromCSV defCSVSettings $$       sinkFile "test/BigFileOut.csv"---and we are done. -  
csv-conduit.cabal view
@@ -1,12 +1,12 @@ Name:                csv-conduit-Version:             0.1+Version:             0.2 Synopsis:            A flexible, fast, conduit-based CSV parser library for Haskell.   Homepage:            http://github.com/ozataman/csv-conduit License:             BSD3 License-file:        LICENSE Author:              Ozgun Ataman  Maintainer:          Ozgun Ataman <ozataman@gmail.com>-Category:            Data+Category:            Data, Conduit Build-type:          Simple Cabal-version:       >=1.6 Description:
src/Data/CSV/Conduit.hs view
@@ -6,14 +6,21 @@ {-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}  module Data.CSV.Conduit-    ( CSVeable (..)+    ( +    +    -- * Fundamental Types+      CSV (..)     , CSVSettings (..)     , defCSVSettings     , MapRow     , Row     -- * Convenience Functions     , readCSVFile+    , transformCSV     , mapCSVFile+    +    -- * Re-exported For Convenience+    , runResourceT     ) where  -------------------------------------------------------------------------------@@ -50,40 +57,67 @@   ---------------------------------------------------------------------------------- | Represents types 'r' that can be converted from an underlying--- stream of type 's'.+-- | Represents types 'r' that are CSV-like and can be converted+-- to/from an underlying stream of type 's'. ----- Example processing using MapRow Text isntance:+-- +-- Example #1: Basics Using Convenience API+-- +-- @+-- import Data.Conduit+-- import Data.Conduit.Binary+-- import Data.Conduit.List as CL+-- import Data.CSV.Conduit --+-- myProcessor :: Conduit (Row Text) m (Row Text)+-- myProcessor = CL.map reverse+-- +-- test = runResourceT $ +--   transformCSV defCSVSettings +--                (sourceFile "input.csv") +--                myProcessor+--                (sinkFile "output.csv") -- @--- test :: IO ()+--+--+-- Example #2: Basics Using Conduit API+-- +-- @+-- import Data.Conduit+-- import Data.Conduit.Binary+-- import Data.CSV.Conduit+--+-- myProcessor :: Conduit (Row Text) m (Row Text)+-- myProcessor = undefined+-- -- test = runResourceT $  --   sourceFile "test/BigFile.csv" $= ---   decode utf8 $= --   intoCSV defCSVSettings $=---   myMapRowProcessingConduit $=---   fromCSV defCSVSettings $=---   encode utf8 $$+--   myProcessor $=+--   fromCSV defCSVSettings $$ --   sinkFile "test/BigFileOut.csv" -- @-class CSVeable s r where+class CSV s r where    -----------------------------------------------------------------------------   -- | Convert a CSV row into strict ByteString equivalent.   rowToStr :: CSVSettings -> r -> s    ------------------------------------------------------------------------------  -- | Turn a stream of 's' into a stream of CSV row type+  -- | Turn a stream of 's' into a stream of CSV row type. An example+  -- would be parsing a ByteString stream as rows of 'MapRow' 'Text'.   intoCSV :: MonadResource m => CSVSettings -> Conduit s m r    ------------------------------------------------------------------------------  -- | Turn a stream of CSV row type back into a stream of 's'+  -- | Turn a stream of CSV row type back into a stream of 's'. An+  -- example would be rendering a stream of 'Row' 'ByteString' rows as+  -- 'Text'.   fromCSV :: MonadResource m => CSVSettings -> Conduit r m s   ------------------------------------------------------------------------------ -- | 'Row' instance using 'ByteString'-instance CSVeable ByteString (Row ByteString) where+instance CSV ByteString (Row ByteString) where   rowToStr s !r =      let        sep = B.pack [c2w (csvOutputColSep s)] @@ -99,7 +133,7 @@  ------------------------------------------------------------------------------ -- | 'Row' instance using 'Text'-instance CSVeable Text (Row Text) where+instance CSV Text (Row Text) where   rowToStr s !r =      let        sep = T.pack [(csvOutputColSep s)] @@ -115,7 +149,7 @@  ------------------------------------------------------------------------------- -- | 'Row' instance using 'Text' based on 'ByteString' stream-instance CSVeable ByteString (Row Text) where+instance CSV ByteString (Row Text) where     rowToStr s r = T.encodeUtf8 $ rowToStr s r     intoCSV set = intoCSV set =$= C.map (map T.decodeUtf8)     fromCSV set = fromCSV set =$= C.map T.encodeUtf8@@ -151,7 +185,7 @@ ------------------------------------------------------------------------------- -- | Generic 'MapRow' instance; any stream type with a 'Row' instance -- automatically gets a 'MapRow' instance.-instance (CSVeable s (Row s'), Ord s', IsString s) => CSVeable s (MapRow s') where+instance (CSV s (Row s'), Ord s', IsString s) => CSV s (MapRow s') where   rowToStr s r = rowToStr s . M.elems $ r   intoCSV set = intoCSVMap set   fromCSV set = fromCSVMap set@@ -188,32 +222,70 @@   ---------------------------------------------------------------------------------- | Read the entire contents of a CSV file into memory-readCSVFile set fp = runResourceT $ sourceFile fp $= intoCSV set $$ C.consume+-- | Read the entire contents of a CSV file into memory.+--+-- An easy way to run this function would be 'runResourceT' after+-- feeding it all the arguments.+readCSVFile +    :: (MonadResource m, CSV ByteString a) +    => CSVSettings +    -> FilePath +    -- ^ Input file+    -> m [a]+readCSVFile set fp = sourceFile fp $= intoCSV set $$ C.consume   ---------------------------------------------------------------------------------- | Map over the rows of a CSV file. Don't be scared by the type--- signature, this can just run in IO.+-- | Map over the rows of a CSV file. Provided for convenience for+-- historical reasons.+--+-- An easy way to run this function would be 'runResourceT' after+-- feeding it all the arguments. mapCSVFile -    :: (MonadIO m, MonadUnsafeIO m, MonadThrow m, -        MonadBaseControl IO m, CSVeable ByteString a, CSVeable ByteString b) +    :: (MonadResource m, CSV ByteString a, CSV ByteString b)      => CSVSettings      -- ^ Settings to use both for input and output-    -> (a -> b) +    -> (a -> [b])      -- ^ A mapping function     -> FilePath      -- ^ Input file     -> FilePath      -- ^ Output file     -> m ()-mapCSVFile set f fi fo = runResourceT $-    sourceFile fi $=+mapCSVFile set f fi fo = +  transformCSV set (sourceFile fi) (C.concatMap f) (sinkFile fo)+++-------------------------------------------------------------------------------+-- | General purpose CSV transformer. Apply a list-like processing+-- function from 'Data.Conduit.List' to the rows of a CSV stream. You+-- need to provide a stream data source, a transformer and a stream+-- data sink.+--+-- An easy way to run this function would be 'runResourceT' after+-- feeding it all the arguments.+--+-- Example - map a function over the rows of a CSV file:+-- +-- > transformCSV set (sourceFile inFile) (C.map f) (sinkFile outFile)+transformCSV +    :: (MonadResource m, CSV s a, CSV s' b) +    => CSVSettings +    -- ^ Settings to be used for input and output+    -> Source m s+    -- ^ A raw stream data source. Ex: 'sourceFile inFile'+    -> Conduit a m b+    -- ^ A transforming conduit+    -> Sink s' m ()+    -- ^ A raw stream data sink. Ex: 'sinkFile outFile'+    -> m ()+transformCSV set source c sink = +    source $=     intoCSV set $=-    C.map f $=+    c $=     fromCSV set $$-    sinkFile fo-+    sink+                                     -----------------                                -- Simple Test --