packages feed

lazy-csv 0.4 → 0.5

raw patch · 5 files changed

+65/−17 lines, 5 files

Files

Text/CSV/Lazy/ByteString.hs view
@@ -50,7 +50,7 @@ --  , ppCSVTableAsTuples  import Data.List     (groupBy, partition, elemIndex, intercalate, takeWhile-                     ,(\\), nub)+                     ,deleteFirstsBy, nub) import Data.Function (on) import Data.Maybe    (fromJust) import qualified Data.ByteString.Lazy.Char8 as BS@@ -91,6 +91,7 @@                                  , csvField         :: CSVField }                 | FieldError     { csvField         :: CSVField }                 | DuplicateHeader{ csvColsExpected  :: !Int+                                 , csvHeaderSerial  :: !Int                                  , csvDuplicate     :: !String }                 | NoData                                                     deriving (Eq,Show)@@ -126,10 +127,11 @@           beCareful (Left [])                    = []            deduplicate (Left (errs@(DuplicateHeader{}:_)):Right heads:rows) = -                 Right (reverse $ foldl replace [] heads)+--               Right (reverse $ foldl replace [] heads)+                 Right (replaceInOrder errs (zip heads [0..]))                  : rows           deduplicate rows = rows-+{-           replace output header               | headerName `elem` map csvFieldContent output                           = header{ csvFieldContent = headerName@@ -137,6 +139,14 @@                                   : output               | otherwise = header: output               where headerName = csvFieldContent header+-}+          replaceInOrder []       headers        = map fst headers+          replaceInOrder _        []             = []+          replaceInOrder (d:dups) ((h,n):headers)+              | csvHeaderSerial d == n = h{ csvFieldContent = BS.pack+                                                (csvDuplicate d++"_"++show n) }+                                          : replaceInOrder dups     headers+              | otherwise              = h: replaceInOrder (d:dups) headers  -- | The header row of the CSV table, assuming it is non-empty. csvTableHeader :: CSVResult -> [String]@@ -200,11 +210,17 @@  checkDuplicateHeaders :: CSVRow -> CSVResult -> CSVResult checkDuplicateHeaders row result =-    let headers = [ csvFieldContent f | f@(CSVField{}) <- row ]-        dups    = headers \\ nub headers+    let headers = [ f | f@(CSVField{}) <- row ]+        dups    = deleteFirstsBy ((==)`on`csvFieldContent)+                                 headers (nub headers)         n       = length headers     in if null dups then result-       else Left (map (DuplicateHeader n . BS.unpack) dups) : result+       else Left (map (\d-> DuplicateHeader+                              { csvColsExpected = n+                              , csvHeaderSerial = csvColNum d+                              , csvDuplicate = BS.unpack (csvFieldContent d)})+                      dups)+            : result   @@ -358,7 +374,8 @@ ppCSVError (err@FieldError{}) = ppCSVField (csvField err) ppCSVError (err@DuplicateHeader{}) =         "\nThere are two (or more) identical column headers: "++-        show (csvDuplicate err)++"."+        show (csvDuplicate err)++"."+++        "\n    Column number "++show (csvHeaderSerial err) ppCSVError (NoData{})         =         "\nNo usable data (after accounting for any other errors)." 
Text/CSV/Lazy/String.hs view
@@ -48,7 +48,7 @@   ) where  import Data.List (groupBy, partition, elemIndex, intercalate, takeWhile-                 ,(\\), nub)+                 ,deleteFirstsBy, nub) import Data.Function (on) import Data.Maybe (fromJust) @@ -87,6 +87,7 @@                                  , csvField         :: CSVField }                 | FieldError     { csvField         :: CSVField }                 | DuplicateHeader{ csvColsExpected  :: !Int+                                 , csvHeaderSerial  :: !Int                                  , csvDuplicate     :: !String }                 | NoData                                                     deriving (Eq,Show)@@ -103,6 +104,7 @@ csvErrors   :: CSVResult -> [CSVError] csvErrors r  = concat [ v | Left  v <- r ] -- | Extract the full table, including invalid rows, repaired with padding.+--   and de-duplicated headers. csvTableFull:: CSVResult -> CSVTable csvTableFull = map beCareful . deduplicate     where beCareful (Right row) = row@@ -121,16 +123,25 @@           beCareful (Left [])               = []            deduplicate (Left (errs@(DuplicateHeader{}:_)):Right heads:rows) =-                 Right (reverse $ foldl replace [] heads)+--               Right (reverse $ foldl replace [] heads)+                 Right (replaceInOrder errs (zip heads [0..]))                  : rows           deduplicate rows = rows-+{-           replace output header               | headerName `elem` map csvFieldContent output                           = header{ csvFieldContent=headerName++"_duplicate" }                                   : output               | otherwise = header: output               where headerName = csvFieldContent header+-}+          replaceInOrder []       headers        = map fst headers+          replaceInOrder _        []             = []+          replaceInOrder (d:dups) ((h,n):headers)+              | csvHeaderSerial d == n = h{ csvFieldContent =+                                                (csvDuplicate d++"_"++show n) }+                                          : replaceInOrder dups     headers+              | otherwise              = h: replaceInOrder (d:dups) headers  -- | The header row of the CSV table, assuming it is non-empty. csvTableHeader :: CSVResult -> [String]@@ -194,11 +205,17 @@  checkDuplicateHeaders :: CSVRow -> CSVResult -> CSVResult checkDuplicateHeaders row result =-    let headers = [ csvFieldContent f | f@(CSVField{}) <- row ]-        dups    = headers \\ nub headers+    let headers = [ f | f@(CSVField{}) <- row ]+        dups    = deleteFirstsBy ((==)`on`csvFieldContent)+                                 headers (nub headers)         n       = length headers     in if null dups then result-       else Left (map (DuplicateHeader n) dups): result+       else Left (map (\d-> DuplicateHeader+                              { csvColsExpected = n+                              , csvHeaderSerial = csvColNum d+                              , csvDuplicate    = csvFieldContent d })+                      dups)+            : result   -- Reading CSV data is essentially lexical, and can be implemented with a@@ -248,6 +265,10 @@                                     simple s' (textRow s',1) [] cs                                     where s' = incTableRow . incTextRow $!                                                s {tableCol=1, textCol=1}+  simple s begin acc  ('\r' :cs)  = mkField s begin acc False :+                                    simple s' (textRow s',1) [] cs+                                    where s' = incTableRow . incTextRow $!+                                               s {tableCol=1, textCol=1}   simple s begin []   ('"'  :cs)  = string (incTextCol $! s) begin [] cs   simple s begin acc  ('"'  :cs)  = mkError s begin                                             "Start-quote not next to comma":@@ -341,7 +362,8 @@ ppCSVError (err@FieldError{}) = ppCSVField (csvField err) ppCSVError (err@DuplicateHeader{}) =         "\nThere are two (or more) identical column headers: "++-        show (csvDuplicate err)++"."+        show (csvDuplicate err)++"."+++        "\n    Column number "++show (csvHeaderSerial err) ppCSVError (err@NoData{})     =         "\nNo usable data (after accounting for any other errors)." 
changelog.html view
@@ -13,6 +13,12 @@ </center> <hr> +<h3>Release 0.5</h3>+<ul>+<li> Bugfix when encountering CR-only line-endings.+<li> Bugfix when encountering multi-duplicate headers.+</ul>+ <h3>Release 0.4</h3> <ul> <li> First public release.
index.html view
@@ -198,8 +198,8 @@  <p> <b>Current released version:</b><br>-lazy-csv-0.4, release date 2013.02.25 --<a href="http://hackage.haskell.org/packages/lazy-csv">on Hackage</a>+lazy-csv-0.5, release date 2013.05.24 -+<a href="http://hackage.haskell.org/package/lazy-csv">on Hackage</a> <br>  <ul>@@ -208,6 +208,7 @@  <p> <b>Older versions:</b><br>+lazy-csv-0.5, release date 2013.05.24 - Fifth release, public.<br> lazy-csv-0.4, release date 2013.02.25 - Fourth release, first public.<br> lazy-csv-0.3, release date 2011.12.12 - Third (non-public) release.<br> lazy-csv-0.2, release date 2011.10.11 - Second (non-public) release.<br>@@ -216,6 +217,8 @@  <hr> <center><h3><a name="news">Recent news</a></h3></center>+<p>+Version 0.5 fixes a bug when handling (rare) CR-only line-endings. <p> Version 0.4 is the first public release. <p>
lazy-csv.cabal view
@@ -1,5 +1,5 @@ Name:         lazy-csv-Version:      0.4+Version:      0.5 License:      BSD3 License-file: LICENCE-BSD3 Copyright:    Malcolm Wallace, Ian Lynagh, and Well Typed LLP