packages feed

txt-sushi 0.5.1 → 0.6.0

raw patch · 20 files changed

+209/−87 lines, 20 filessetup-changednew-component:exe:csvzip

Files

Database/TxtSushi/CommandLineArgument.hs view
@@ -27,7 +27,6 @@     argumentCountIsFixed) where  import Data.List-import Data.Map (Map) import qualified Data.Map as Map  data CommandLineDescription = CommandLineDescription {
Database/TxtSushi/EvaluatedExpression.hs view
@@ -27,7 +27,6 @@     coerceBool) where  import Data.Char-import Data.List import Data.Ord  import Database.TxtSushi.ParseUtil
Database/TxtSushi/ExternalSort.hs view
@@ -17,7 +17,6 @@     defaultByteQuota,     defaultMaxOpenFiles) where -import Control.Monad import Data.Binary import Data.Binary.Get import Data.Int
Database/TxtSushi/FlatFile.hs view
@@ -11,10 +11,6 @@ -- ----------------------------------------------------------------------------- -{- |-The 'FlatFile' module is for reading misc. 'FlatFile' formats like CSV or-tab delimited--} module Database.TxtSushi.FlatFile (     formatTableWithWidths,     maxTableColumnWidths,@@ -25,7 +21,6 @@     tabDelimitedFormat,     doubleQuote) where -import Data.Function import Data.List import Data.Ord 
Database/TxtSushi/IOUtil.hs view
@@ -13,15 +13,15 @@ module Database.TxtSushi.IOUtil (     bufferStdioToTempFile,     getContentsFromFileOrStdin,-    printSingleFileUsage) where+    printSingleFileUsage,+    versionStr) where -import Data.List-import Data.Version (Version(..)) import System.Directory import System.Environment import System.IO -import Paths_txt_sushi+versionStr :: String+versionStr = "0.6.0"  -- | buffers standard input to a temp file and returns a path to that file bufferStdioToTempFile :: IO FilePath@@ -48,6 +48,4 @@     progName <- getProgName     putStrLn $ progName ++ " (" ++ versionStr ++ ")"     putStrLn $ "Usage: " ++ progName ++ " file_name_or_dash"-    -    where-        versionStr = intercalate "." (map show . versionBranch $ version)+
Database/TxtSushi/ParseUtil.hs view
@@ -40,7 +40,7 @@         anyParseTxt = signedParseTxt <|> unsignedParseTxt <?> "integer"         unsignedParseTxt = many1 digit         signedParseTxt = do-            char '-'+            _ <- char '-'             unsignedDigitTxt <- unsignedParseTxt             return $ '-' : unsignedDigitTxt @@ -75,11 +75,11 @@         txtWithoutExponent = signedTxt <|> unsignedTxt <?> "real"         unsignedTxt = do             intTxt <- many1 digit-            char '.'+            _ <- char '.'             fracTxt <- many1 digit             return $ intTxt ++ "." ++ fracTxt         signedTxt = do-            char '-'+            _ <- char '-'             unsignedDigitTxt <- unsignedTxt             return ('-':unsignedDigitTxt) @@ -101,10 +101,10 @@     let quote = char quoteChar         manyFunc = if allowEmpty then many else many1     -    quote+    _ <- quote     textValue <- manyFunc $ (anyChar `genExcept` quote) <|>                             try (escapedQuote quoteChar)-    quote+    _ <- quote     spaces          return textValue@@ -178,7 +178,7 @@         -- for lists greater than 1 we do need to care about the separator         parseEach (headParser:parserTail) = do             resultHead <- headParser-            sepParser+            _ <- sepParser             resultTail <- parseEach parserTail                          return $ resultHead:resultTail
Database/TxtSushi/Relational.hs view
@@ -11,9 +11,6 @@ -- ----------------------------------------------------------------------------- -{- |-Simple table transformations--} module Database.TxtSushi.Relational (     joinTables,     crossJoinTables,@@ -34,21 +31,23 @@         sortedTable1 = sortBy (compare `on` joinOrdFunc1) table1         sortedTable2 = sortBy (compare `on` joinOrdFunc2) table2     in-        joinPresortedTables joinOrdFunc1 sortedTable1 joinOrdFunc2 sortedTable2+        joinPresortedTables joinOrdFunc1 sortedTable1 Nothing joinOrdFunc2 sortedTable2 Nothing  -- | join together two tables that are presorted on the given column index pairs joinPresortedTables :: (Ord o) =>     (a -> o)     -> [a]+    -> Maybe a     -> (b -> o)     -> [b]+    -> Maybe b     -> [(a, b)]-joinPresortedTables joinOrdFunc1 sortedTable1 joinOrdFunc2 sortedTable2 =+joinPresortedTables joinOrdFunc1 sortedTable1 maybeNull1 joinOrdFunc2 sortedTable2 maybeNull2 =     let         tableGroups1 = groupBy rowEq1 sortedTable1         tableGroups2 = groupBy rowEq2 sortedTable2     in-        joinGroupedTables joinOrdFunc1 tableGroups1 joinOrdFunc2 tableGroups2+        joinGroupedTables joinOrdFunc1 tableGroups1 maybeNull1 joinOrdFunc2 tableGroups2 maybeNull2     where         rowEq1 x y = (compare `on` joinOrdFunc1) x y == EQ         rowEq2 x y = (compare `on` joinOrdFunc2) x y == EQ@@ -62,28 +61,54 @@ joinGroupedTables :: (Ord o) =>     (a -> o)     -> [[a]]+    -> Maybe a     -> (b -> o)     -> [[b]]+    -> Maybe b     -> [(a, b)]-joinGroupedTables _ [] _ _  = []-joinGroupedTables _ _  _ [] = []+joinGroupedTables _ [] Nothing      _ _  _       = []+joinGroupedTables _ _  _            _ [] Nothing = []++joinGroupedTables _ [] (Just null1) _ tableGroups2 _ = zip (repeat null1) (concat tableGroups2)+joinGroupedTables _ tableGroups1 _ _ [] (Just null2) = zip (concat tableGroups1) (repeat null2)+ joinGroupedTables     joinOrdFunc1     tableGroups1@(headTableGroup1:tableGroupsTail1)+    maybeNull1+         joinOrdFunc2-    tableGroups2@(headTableGroup2:tableGroupsTail2) =+    tableGroups2@(headTableGroup2:tableGroupsTail2)+    maybeNull2 =     let         headRow1 = head headTableGroup1         headRow2 = head headTableGroup2     in         case joinOrdFunc1 headRow1 `compare` joinOrdFunc2 headRow2 of             -- drop the 1st group if its smaller-            LT -> joinGroupedTables joinOrdFunc1 tableGroupsTail1 joinOrdFunc2 tableGroups2+            LT ->+                let joinRemainder =+                        joinGroupedTables+                            joinOrdFunc1 tableGroupsTail1 maybeNull1+                            joinOrdFunc2 tableGroups2 maybeNull2 in+                case maybeNull2 of+                    Nothing    -> joinRemainder+                    Just null2 -> zip headTableGroup1 (repeat null2) ++ joinRemainder                          -- drop the 2nd group if its smaller-            GT -> joinGroupedTables joinOrdFunc1 tableGroups1 joinOrdFunc2 tableGroupsTail2+            GT ->+                let joinRemainder =+                        joinGroupedTables+                            joinOrdFunc1 tableGroups1 maybeNull1+                            joinOrdFunc2 tableGroupsTail2 maybeNull2 in+                case maybeNull1 of+                    Nothing    -> joinRemainder+                    Just null1 -> zip (repeat null1) headTableGroup2 ++ joinRemainder                          -- the two groups are equal so permute             _  ->-                (crossJoinTables headTableGroup1 headTableGroup2) ++-                (joinGroupedTables joinOrdFunc1 tableGroupsTail1 joinOrdFunc2 tableGroupsTail2)+                let joinRemainder =+                        joinGroupedTables+                            joinOrdFunc1 tableGroupsTail1 maybeNull1+                            joinOrdFunc2 tableGroupsTail2 maybeNull2 in+                crossJoinTables headTableGroup1 headTableGroup2 ++ joinRemainder
Database/TxtSushi/SQLExecution.hs view
@@ -20,13 +20,11 @@  import Control.Applicative import Data.Binary-import Data.Char import Data.Function import Data.List import qualified Data.Map as M  import Database.TxtSushi.SQLExpression-import Database.TxtSushi.SQLFunctionDefinitions import Database.TxtSushi.EvaluatedExpression import Database.TxtSushi.ExternalSort import Database.TxtSushi.Relational@@ -50,7 +48,8 @@         qualifiedColumnsWithContext = M.empty,         evaluationContext = evalCtxt,         tableData = tblRows,-        isInScope = idInHeader}+        isInScope = idInHeader,+        nullRow = replicate (length headerNames) ""}     where         makeColExpr colName = ColumnExpression (ColumnIdentifier Nothing colName) colName         @@ -86,7 +85,8 @@         qualifiedColumnsWithContext = M.empty,         evaluationContext = eval,         tableData = [shouldNeverOccurError] :: [String],-        isInScope = const False}+        isInScope = const False,+        nullRow = []}     where         eval (ColumnExpression _ colStr)    = columnNotInScopeError colStr         eval expr                           = evalWithContext eval expr@@ -157,16 +157,24 @@             let table = M.findWithDefault (tableNotInScopeError tblName) tblName tableMap             in  maybeRename maybeTblAlias table         -        -- TODO inner join should allow joining on expressions too!!         InnerJoin leftJoinTblExpr rightJoinTblExpr onConditionExpr maybeTblAlias ->             let                 leftJoinTbl = evalTableExpression sortCfg leftJoinTblExpr tableMap                 rightJoinTbl = evalTableExpression sortCfg rightJoinTblExpr tableMap                 joinExprs = extractJoinExprs leftJoinTbl rightJoinTbl onConditionExpr-                joinedTbl = innerJoinDbTables sortCfg joinExprs leftJoinTbl rightJoinTbl+                joinedTbl = sortAndJoinDbTables False sortCfg joinExprs leftJoinTbl rightJoinTbl             in                 maybeRename maybeTblAlias joinedTbl         +        OuterJoin leftJoinTblExpr rightJoinTblExpr onConditionExpr maybeTblAlias ->+            let+                leftJoinTbl = evalTableExpression sortCfg leftJoinTblExpr tableMap+                rightJoinTbl = evalTableExpression sortCfg rightJoinTblExpr tableMap+                joinExprs = extractJoinExprs leftJoinTbl rightJoinTbl onConditionExpr+                joinedTbl = sortAndJoinDbTables True sortCfg joinExprs leftJoinTbl rightJoinTbl+            in+                maybeRename maybeTblAlias joinedTbl+                 SelectExpression selectStmt maybeTblAlias ->             maybeRename maybeTblAlias (select sortCfg selectStmt tableMap)         @@ -330,7 +338,10 @@     tableData :: [a],          -- | is the given identifier in scope for this table-    isInScope :: ColumnIdentifier -> Bool}+    isInScope :: ColumnIdentifier -> Bool,+    +    -- | we can only do an outer join if the concept of a NULL row exists+    nullRow :: a}  allIdentifiers :: Expression -> [ColumnIdentifier] allIdentifiers (FunctionExpression _ args _) = concatMap allIdentifiers args@@ -433,7 +444,8 @@         columnsWithContext = mapSnd toGroupContext (columnsWithContext tbl),         qualifiedColumnsWithContext = M.map (mapSnd toGroupContext) (qualifiedColumnsWithContext tbl),         evaluationContext = toGroupContext $ evaluationContext tbl,-        tableData = groupedData}+        tableData = groupedData,+        nullRow = [nullRow tbl]}     where         eval = evaluationContext tbl         rowOrd row = [eval expr row | expr <- grpExprs]@@ -448,7 +460,8 @@         columnsWithContext = mapSnd toGroupContext (columnsWithContext tbl),         qualifiedColumnsWithContext = M.map (mapSnd toGroupContext) (qualifiedColumnsWithContext tbl),         evaluationContext = toGroupContext $ evaluationContext tbl,-        tableData = [tableData tbl]}+        tableData = [tableData tbl],+        nullRow = [nullRow tbl]}  compareWithDirection :: (Ord a) => [Bool] -> [a] -> [a] -> Ordering compareWithDirection (asc:ascTail) (x:xt) (y:yt) = case x `compare` y of@@ -458,13 +471,14 @@ compareWithDirection [] [] [] = EQ compareWithDirection _ _ _ = error "Internal Error: List sizes should match" -innerJoinDbTables ::-    SortConfiguration+sortAndJoinDbTables ::+    Bool+    -> SortConfiguration     -> [(Expression, Expression)]     -> BoxedTable     -> BoxedTable     -> BoxedTable-innerJoinDbTables sortCfg joinExprs (BoxedTable fstTable) (BoxedTable sndTable) =+sortAndJoinDbTables outerJoin sortCfg joinExprs (BoxedTable fstTable) (BoxedTable sndTable) =     BoxedTable $ zipDbTables joinedData fstTable sndTable     where         fstEval = evaluationContext fstTable@@ -476,7 +490,10 @@         sortedFstData = sortByCfg sortCfg (compare `on` fstRowOrd) (tableData fstTable)         sortedSndData = sortByCfg sortCfg (compare `on` sndRowOrd) (tableData sndTable)         -        joinedData = joinPresortedTables fstRowOrd sortedFstData sndRowOrd sortedSndData+        fstNull = if outerJoin then Just (nullRow fstTable) else Nothing+        sndNull = if outerJoin then Just (nullRow sndTable) else Nothing+        +        joinedData = joinPresortedTables fstRowOrd sortedFstData fstNull sndRowOrd sortedSndData sndNull  crossJoinDbTables ::     BoxedTable@@ -493,7 +510,8 @@     qualifiedColumnsWithContext = M.unionWithKey ambiguousTableError fstQualCols sndQualCols,     evaluationContext = evalCtxt,     tableData = zippedData,-    isInScope = isInFstOrSndScope}+    isInScope = isInFstOrSndScope,+    nullRow = (nullRow fstTable, nullRow sndTable)}          where         isInFstScope = isInScope fstTable
Database/TxtSushi/SQLExpression.hs view
@@ -26,9 +26,6 @@     expressionToString,     columnToString) where -import Data.Char-import Data.List- import Database.TxtSushi.EvaluatedExpression  --------------------------------------------------------------------------------@@ -53,6 +50,11 @@         rightJoinTable :: TableExpression,         onCondition :: Expression,         maybeTableAlias :: Maybe String} |+    OuterJoin {+        leftJoinTable :: TableExpression,+        rightJoinTable :: TableExpression,+        onCondition :: Expression,+        maybeTableAlias :: Maybe String} |     CrossJoin {         leftJoinTable :: TableExpression,         rightJoinTable :: TableExpression,@@ -70,6 +72,8 @@ allTableNames :: TableExpression -> [String] allTableNames (TableIdentifier tblName _) = [tblName] allTableNames (InnerJoin lftTbl rtTbl _ _) =+    (allTableNames lftTbl) ++ (allTableNames rtTbl)+allTableNames (OuterJoin lftTbl rtTbl _ _) =     (allTableNames lftTbl) ++ (allTableNames rtTbl) allTableNames (CrossJoin lftTbl rtTbl _) =     (allTableNames lftTbl) ++ (allTableNames rtTbl)
Database/TxtSushi/SQLFunctionDefinitions.hs view
@@ -36,7 +36,7 @@ -- Functions with "normal" syntax -- normalSyntaxFunctions :: [SQLFunction] normalSyntaxFunctions =-    [absFunction, upperFunction, lowerFunction, trimFunction, ifThenElseFunction,+    [absFunction, upperFunction, lowerFunction, trimFunction, lengthFunction, ifThenElseFunction,      asIntFunction, asRealFunction, isNumericFunction,      -- all aggregates except count which accepts a (*)      avgFunction, firstFunction, lastFunction, maxFunction,@@ -110,6 +110,15 @@     applyFunction       = applyUnaryString trimFunction trimSpace,     functionGrammar     = normalGrammar trimFunction,     functionDescription = "trims whitespace from the beginning and end of the given text"}++lengthFunction :: SQLFunction+lengthFunction = SQLFunction {+    functionName        = "LEN",+    minArgCount         = 1,+    argCountIsFixed     = True,+    applyFunction       = IntExpression . length . coerceString . head . checkArgCount lengthFunction,+    functionGrammar     = normalGrammar lengthFunction,+    functionDescription = "the number of characters in the given text"}  ifThenElseFunction :: SQLFunction ifThenElseFunction = SQLFunction {
Database/TxtSushi/SQLParser.hs view
@@ -129,11 +129,11 @@ parseRangeColumns = parseRangeInner     where         parseRangeInner = do-            parseToken "FOR"+            _ <- parseToken "FOR"             bindingId <- parseColumnId-            parseToken "IN"+            _ <- parseToken "IN"             colRange <- parseColRange-            parseToken "YIELD"+            _ <- parseToken "YIELD"             expr <- parseExpression                          return $ ExpressionColumnRange bindingId colRange expr@@ -141,7 +141,7 @@             where                 parseColRange = brace $ do                     maybeStartCol <- maybeParse parseColumnId-                    parseToken ".."+                    _ <- parseToken ".."                     maybeEndCol <- maybeParse parseColumnId                                          return $ ColumnRange maybeStartCol maybeEndCol@@ -152,7 +152,7 @@ parseAllColsFromTbl :: GenParser Char st ColumnSelection parseAllColsFromTbl = do     tableVal <- parseIdentifier-    string "." >> spaces >> parseToken "*"+    _ <- string "." >> spaces >> parseToken "*"          return $ AllColumnsFrom tableVal @@ -197,6 +197,14 @@     nextTblId <- parseTableIdentifier          let+        ifJoinParse = ifParseThenElse+            -- if+            outerJoinSep -- TODO commit to join+            -- then+            (parseOuterJoinRemainder nextTblId)+            --else+            ifCrossOrInnerJoinParse+                 ifCrossOrInnerJoinParse = ifParseThenElse             -- if             crossJoinSep -- TODO commit to join@@ -213,9 +221,10 @@             -- else             (return nextTblId)         -    ifCrossOrInnerJoinParse+    ifJoinParse          where+        outerJoinSep = parseToken "OUTER" >> parseToken "JOIN"         crossJoinSep = (commaSeparator >> return "") <|> (parseToken "CROSS" >> parseToken "JOIN")         innerJoinSep = ((maybeParse $ parseToken "INNER") >> parseToken "JOIN") @@ -223,7 +232,7 @@ parseInnerJoinRemainder leftTblExpr = do     rightTblExpr <- parseTableExpression     -    parseToken "ON"+    _ <- parseToken "ON"     onPart <- parseExpression          maybeAlias <- maybeParseAlias@@ -234,6 +243,21 @@             onCondition=onPart,             maybeTableAlias=maybeAlias} +parseOuterJoinRemainder :: TableExpression -> GenParser Char a TableExpression+parseOuterJoinRemainder leftTblExpr = do+    rightTblExpr <- parseTableExpression+    +    _ <- parseToken "ON"+    onPart <- parseExpression+    +    maybeAlias <- maybeParseAlias+    +    return OuterJoin {+            leftJoinTable=leftTblExpr,+            rightJoinTable=rightTblExpr,+            onCondition=onPart,+            maybeTableAlias=maybeAlias}+ parseCrossJoinRemainder :: TableExpression -> GenParser Char a TableExpression parseCrossJoinRemainder leftTblExpr = do     rightTblExpr <- parseTableExpression@@ -335,12 +359,12 @@ parseSubstringFunction :: GenParser Char st Expression parseSubstringFunction = do     funcStr <- parseToken $ functionName substringFromFunction-    eatSpacesAfter $ char '('+    _ <- eatSpacesAfter $ char '('     strExpr <- parseExpression     fromStr <- parseToken "FROM"     startExpr <- parseExpression     maybeForStrAndLength <- preservingIfParseThen (parseToken "FOR") parseExpression-    eatSpacesAfter $ char ')'+    _ <- eatSpacesAfter $ char ')'          let funcStrStart =             funcStr ++ "(" ++ expressionToString strExpr ++ " " ++@@ -373,7 +397,7 @@ parseCountStar :: GenParser Char st Expression parseCountStar = do     funcStr <- try (parseToken $ functionName countFunction)-    parenthesize (parseToken "*")+    _ <- parenthesize (parseToken "*")          return $ FunctionExpression countFunction [IntConstantExpression 0 "*"] (funcStr ++ "(*)") @@ -417,17 +441,17 @@ -- | Wraps braces parsers around the given inner parser brace :: GenParser Char st a -> GenParser Char st a brace innerParser = do-    eatSpacesAfter $ char '['+    _ <- eatSpacesAfter $ char '['     innerParseResults <- innerParser-    eatSpacesAfter $ char ']'+    _ <- eatSpacesAfter $ char ']'     return innerParseResults  -- | Wraps parentheses parsers around the given inner parser parenthesize :: GenParser Char st a -> GenParser Char st a parenthesize innerParser = do-    eatSpacesAfter $ char '('+    _ <- eatSpacesAfter $ char '('     innerParseResults <- innerParser-    eatSpacesAfter $ char ')'+    _ <- eatSpacesAfter $ char ')'     return innerParseResults  parseReservedWord :: GenParser Char st String@@ -441,8 +465,8 @@     map functionName normalSyntaxFunctions ++     map functionName (concat infixFunctions) ++     map functionName specialFunctions ++-    ["BY","CROSS", "FROM", "FOR", "GROUP", "HAVING", "IN", "INNER", "JOIN", "ON",-     "ORDER", "SELECT", "WHERE", "TRUE", "FALSE", "YIELD"]+    ["BY", "CROSS", "FROM", "FOR", "GROUP", "HAVING", "IN", "INNER", "JOIN", "ON",+     "ORDER", "OUTER", "SELECT", "WHERE", "TRUE", "FALSE", "YIELD"]  -- | tries parsing both the upper and lower case versions of the given string upperOrLower :: String -> GenParser Char st String
Setup.hs view
@@ -1,2 +1,7 @@+module Main (main) where+ import Distribution.Simple++main :: IO () main = defaultMain+
csvtotab.hs view
@@ -11,7 +11,6 @@ -- ----------------------------------------------------------------------------- import System.Environment-import System.IO  import Database.TxtSushi.FlatFile import Database.TxtSushi.IOUtil
+ csvzip.hs view
@@ -0,0 +1,54 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  csvzip+-- Copyright   :  (c) Keith Sheppard 2009-2010+-- License     :  BSD3+-- Maintainer  :  keithshep@gmail.com+-- Stability   :  experimental+-- Portability :  portable+--+-- Joins CSV files by pasting the columns together. Analogous to cbind for+-- those familliar with the R programming language. This utility streams+-- data so it can work on very large files. If the table row lengths don't+-- match then the shorter tables will be padded with empty cells.+--+-----------------------------------------------------------------------------+import System.Environment (getArgs, getProgName)++import Database.TxtSushi.FlatFile (csvFormat, formatTable, parseTable)+import Database.TxtSushi.IOUtil (getContentsFromFileOrStdin, versionStr)++main :: IO ()+main = do+    fileNames <- getArgs+    +    case fileNames of+        -- parse all CSV files giving us a list of tables, then zip and print them+        (_ : _ : _) -> do+            tables <- mapM getAndParseTable fileNames+            putStr $ formatTable csvFormat (zipAllColumns tables)+        +        _ -> printUsage++-- | read the contents of the given files name and parse it as a CSV file+getAndParseTable :: String -> IO [[String]]+getAndParseTable = fmap (parseTable csvFormat) . getContentsFromFileOrStdin++-- | zips together the columns of a non-empty list of tables+zipAllColumns :: [[[String]]] -> [[String]]+zipAllColumns = foldl1 (zipCols [] [])+    where+        -- if row counts don't match we pad the table that fell short with empty cells+        zipCols _     _     (x:xt) (y:yt) = (x ++ y) : zipCols x y xt yt+        zipCols _     _     []     []     = []+        zipCols _     prevY xs     []     = zipWith (++) xs (padCols prevY)+        zipCols prevX _     []     ys     = zipWith (++) (padCols prevX) ys+        +        padCols lastRow = repeat (replicate (length lastRow) "")++printUsage :: IO ()+printUsage = do+    progName <- getProgName+    putStrLn $ progName ++ " (" ++ versionStr ++ ")"+    putStrLn $ "Usage: " ++ progName ++ " csvfile_or_dash csvfile_or_dash ..."+
namecolumns.hs view
@@ -11,7 +11,6 @@ -- ----------------------------------------------------------------------------- import System.Environment-import System.IO  import Database.TxtSushi.FlatFile import Database.TxtSushi.IOUtil
tabtocsv.hs view
@@ -11,7 +11,6 @@ -- ----------------------------------------------------------------------------- import System.Environment-import System.IO  import Database.TxtSushi.FlatFile import Database.TxtSushi.IOUtil
transposecsv.hs view
@@ -12,7 +12,6 @@ ----------------------------------------------------------------------------- import Data.List import System.Environment-import System.IO  import Database.TxtSushi.FlatFile import Database.TxtSushi.IOUtil
transposetab.hs view
@@ -12,7 +12,6 @@ ----------------------------------------------------------------------------- import Data.List import System.Environment-import System.IO  import Database.TxtSushi.FlatFile import Database.TxtSushi.IOUtil
tssql.hs view
@@ -11,11 +11,9 @@ ----------------------------------------------------------------------------- import Data.Char import Data.List-import Data.Version (Version(..)) import qualified Data.Map as M import System.Environment import System.Exit-import System.IO  import Text.ParserCombinators.Parsec @@ -27,8 +25,6 @@ import Database.TxtSushi.SQLFunctionDefinitions import Database.TxtSushi.SQLParser -import Paths_txt_sushi- helpOption :: OptionDescription helpOption = OptionDescription {     isRequired              = False,@@ -93,8 +89,6 @@ printUsage progName = do     putStrLn $ progName ++ " (" ++ versionStr ++ ")"     putStrLn $ "Usage: " ++ progName ++ " " ++ formatCommandLine sqlCmdLine-    where-        versionStr = intercalate "." (map show $ versionBranch version)  argsToSortConfig :: M.Map OptionDescription a -> SortConfiguration argsToSortConfig argMap =
txt-sushi.cabal view
@@ -1,8 +1,8 @@ Name:                txt-sushi-Version:             0.5.1+Version:             0.6.0 Synopsis:            The SQL link in your *NIX chain Description:-    TxtSushi is a collection of command line utilities for processing+    txt-sushi is a collection of command line utilities for processing     comma-separated and tab-delimited files (AKA flat files, spreadsheets).     The most important utility (tssql) lets you perform SQL selects on CSV files.     By focusing exclusively on processing text files with a tabular structure,@@ -14,19 +14,19 @@ Author:              Keith Sheppard Maintainer:          keithshep@gmail.com Homepage:            http://keithsheppard.name/txt-sushi-Bug-Reports:         http://code.google.com/p/txt-sushi/issues/list+Bug-Reports:         https://github.com/keithshep/txt-sushi/issues Build-Type:          Simple Category:            Database, Console Cabal-Version:       >= 1.6  Source-Repository head-  type:     darcs-  location: http://patch-tag.com/r/keithshep/txt-sushi/pullrepo+  type:     git+  location: git://github.com/keithshep/txt-sushi.git  Source-Repository this-  type:     darcs-  location: http://patch-tag.com/r/keithshep/txt-sushi/pullrepo-  tag:      0.5.1+  type:     git+  location: git://github.com/keithshep/txt-sushi.git+  tag:      0.6.0  Executable tssql   Main-Is:          tssql.hs@@ -61,6 +61,10 @@  Executable transposetab   Main-Is:          transposetab.hs+  GHC-Options:      -O2 -Wall++Executable csvzip+  Main-Is:          csvzip.hs   GHC-Options:      -O2 -Wall  Library