Browse Source

Add better error messages, small workflow changes

tags/v0.1.1.0
Peter J. Jones 5 years ago
parent
commit
ba7f69c731

+ 5
- 0
CHANGELOG View File

@@ -1,3 +1,8 @@
2014-11-11 Peter Jones <pjones@devalot.com>

* System/IO/Streams/Csv/Decode.hs added more descriptive error messages.
* cassava-streams bumped version number (0.1.1.0).

2014-04-30 Peter Jones <pjones@devalot.com>

* cassava-streams initial release (version 0.1.0.0).

+ 2
- 12
GNUmakefile View File

@@ -8,10 +8,6 @@ CSV_HEADER = test/header.csv
CSV_MEGA = test/massive.csv
TUTORIAL = dist/build/tutorial/tutorial todo
PROF_OPTS = +RTS -sstderr -hc -pa -xc
PROF_ROW_SIZE = 512
PROF_ROW_COUNT = 10000 # Actual rows will be this number * 100
RAND_ROW = openssl rand -base64 $(PROF_ROW_SIZE) | paste -sd/


################################################################################
clean::
@@ -20,18 +16,12 @@ clean::

################################################################################
profile:: $(CSV_MEGA)
$(TUTORIAL) $(PROF_OPTS) < $(CSV_MEGA) > /dev/null
$(TUTORIAL) $(PROF_OPTS) < $(CSV_MEGA) > profile.stdout
hp2ps -M -b -c tutorial.hp
ps2pdf tutorial.ps

################################################################################
# Generate a very large CSV file for profiling.
$(CSV_MEGA): $(CSV_HEADER)
cp $(CSV_HEADER) $@
for i in `seq $(PROF_ROW_COUNT)`; do \
row=`printf "TODO,"; $(RAND_ROW)`; \
for j in `seq 100`; do echo "$$row" >> $@; done; \
printf .; \
done
@ echo # print a newline
sh test/make-huge-csv.sh $@ $(CSV_HEADER)
du -h $@

+ 2
- 2
cassava-streams.cabal View File

@@ -1,6 +1,6 @@
--------------------------------------------------------------------------------
name: cassava-streams
version: 0.1.0.0
version: 0.1.1.0
synopsis: io-streams interface for the cassava CSV library.
license: BSD3
license-file: LICENSE
@@ -10,7 +10,7 @@ copyright: Copyright (c) 2014 Peter Jones
category: Data, Text, CSV, IO-Streams
build-type: Simple
cabal-version: >=1.10
tested-with: GHC==7.8.2
tested-with: GHC==7.8.2, GHC==7.8.3
homepage: https://github.com/pjones/cassava-streams
bug-reports: https://github.com/pjones/cassava-streams/issues
description:

+ 14
- 9
src/System/IO/Streams/Csv/Decode.hs View File

@@ -1,4 +1,5 @@
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE ScopedTypeVariables #-}

{-

@@ -116,12 +117,12 @@ onlyValidRecords input = makeInputStream $ do

case upstream of
Nothing -> return Nothing
Just (Left err) -> bomb err
Just (Left err) -> bomb ("invalid CSV row: " ++ err)
Just (Right x) -> return (Just x)

--------------------------------------------------------------------------------
-- | Internal function which feeds data to the CSV parser.
dispatch :: IORef [Either String a]
dispatch :: forall a. IORef [Either String a]
-- ^ List of queued CSV records.
-> IORef (Maybe (Parser a))
-- ^ Current CSV parser state.
@@ -137,9 +138,10 @@ dispatch queueRef parserRef input = do
parser <- readIORef parserRef
case parser of
Nothing -> return Nothing
Just (Fail _ e) -> bomb e
Just (Many xs f) -> more f >> feed xs
Just (Done xs ) -> writeIORef parserRef Nothing >> feed xs
Just (Fail _ e) -> bomb ("input data malformed: " ++ e)
Just (Many [] f) -> more f
Just (Many xs f) -> writeIORef parserRef (Just $ Many [] f) >> feed xs
Just (Done xs ) -> writeIORef parserRef Nothing >> feed xs

(x:xs) -> do
writeIORef queueRef xs
@@ -148,12 +150,15 @@ dispatch queueRef parserRef input = do
where
-- Send more data to the CSV parser. If there is no more data
-- from upstream then send an empty @ByteString@.
more f = Streams.read input >>=
writeIORef parserRef . Just . maybe (f BS.empty) f
more :: (ByteString -> Parser a) -> IO (Maybe (Either String a))
more f = do bs <- Streams.read input
writeIORef parserRef (Just $ maybe (f BS.empty) f bs)
dispatch queueRef parserRef input

-- Feed records downstream.
feed xs = writeIORef queueRef xs >>
dispatch queueRef parserRef input
feed :: [Either String a] -> IO (Maybe (Either String a))
feed xs = do writeIORef queueRef xs
dispatch queueRef parserRef input

--------------------------------------------------------------------------------
-- | Throw an exception.

+ 8
- 5
src/System/IO/Streams/Csv/Tutorial.hs View File

@@ -41,18 +41,21 @@ import System.IO.Streams.Csv
--------------------------------------------------------------------------------
-- | A to-do item.
data Item = Item
{ title :: String
, state :: TState
{ title :: String -- ^ Title.
, state :: TState -- ^ State.
, time :: Maybe Double -- ^ Seconds taken to complete.
} deriving (Show, Eq)

instance FromNamedRecord Item where
parseNamedRecord m = Item <$> m .: "Title"
<*> m .: "State"
<*> m .: "Time"

instance ToNamedRecord Item where
toNamedRecord (Item t s) =
toNamedRecord (Item t s tm) =
namedRecord [ "Title" .= t
, "State" .= s
, "Time" .= tm
]

--------------------------------------------------------------------------------
@@ -105,7 +108,7 @@ onlyTodo inH outH = do

-- A stream to write items into. They will be converted to CSV.
output <- Streams.handleToOutputStream outH >>=
encodeStreamByName (V.fromList ["State", "Title"])
encodeStreamByName (V.fromList ["State", "Time", "Title"])

-- Connect the input and output streams.
Streams.connect input output
@@ -132,7 +135,7 @@ markDone titleOfItem inH outH = do

-- A stream to write items into. They will be converted to CSV.
output <- Streams.handleToOutputStream outH >>=
encodeStreamByName (V.fromList ["State", "Title"])
encodeStreamByName (V.fromList ["State", "Time", "Title"])

-- Connect the input and output streams.
Streams.connect input output

+ 1
- 1
test/header.csv View File

@@ -1 +1 @@
State,Title
State,Time,Title

+ 30
- 0
test/make-huge-csv.sh View File

@@ -0,0 +1,30 @@
#!/bin/sh

################################################################################
PROF_ROW_SIZE=512
PROF_ROW_COUNT=10000 # Actual rows will be this number * 100

################################################################################
OUT_FILE=$1
CSV_HEADER=$2

################################################################################
cp $CSV_HEADER $OUT_FILE

################################################################################
for i in `seq $PROF_ROW_COUNT`; do
title=`openssl rand -base64 $PROF_ROW_SIZE | paste -sd/`
time=`echo|awk 'srand() {print rand()}'`

if [ `expr $i % 2` -eq 0 ]; then
row="TODO,,$title"
else
row="TODO,$time,$title"
fi

for j in `seq 100`; do echo "$row" >> $OUT_FILE; done
printf .
done

################################################################################
echo # Print blank line to terminate all those dots.

Loading…
Cancel
Save