1- {-# LANGUAGE PolyKinds #-}
21{-# LANGUAGE DeriveAnyClass #-}
2+ {-# LANGUAGE DeriveDataTypeable #-}
33{-# LANGUAGE GeneralisedNewtypeDeriving #-}
4+ {-# LANGUAGE PolyKinds #-}
45{-# OPTIONS_GHC -Wno-orphans #-}
56module Cardano.Analysis.API.Ground
67 ( module Cardano.Analysis.API.Ground
@@ -10,28 +11,28 @@ module Cardano.Analysis.API.Ground
1011 )
1112where
1213
13- import Prelude as P (show )
14- import Cardano.Prelude hiding (head , toText )
15- import Unsafe.Coerce qualified as Unsafe
14+ import Cardano.Prelude hiding (head , toText )
15+ import Cardano.Slotting.Slot (EpochNo (.. ), SlotNo (.. ))
16+ import Cardano.Util
17+ import Ouroboros.Network.Block (BlockNo (.. ))
1618
17- import Data.Aeson
18- import Data.Aeson.Types (toJSONKeyText )
19- import Data.ByteString.Lazy.Char8 qualified as LBS
20- import Data.Map.Strict qualified as Map
21- import Data.Text qualified as T
22- import Data.Text.Short qualified as SText
23- import Data.Text.Short (ShortText , fromText , toText )
24- import Data.Time.Clock (UTCTime , NominalDiffTime )
25- import Options.Applicative
26- import Options.Applicative qualified as Opt
27- import System.FilePath qualified as F
19+ import Prelude as P (show )
2820
29- import Cardano.Slotting.Slot (EpochNo (.. ), SlotNo (.. ))
30- import Ouroboros.Network.Block (BlockNo (.. ))
21+ import Data.Aeson
22+ import Data.Aeson.Types (toJSONKeyText )
23+ import qualified Data.ByteString.Lazy.Char8 as LBS
24+ import Data.CDF
25+ import Data.Data (Data )
26+ import Data.DataDomain
27+ import qualified Data.Map.Strict as Map
28+ import qualified Data.Text as T
29+ import Data.Text.Short (ShortText , fromText , toText )
30+ import qualified Data.Text.Short as SText
31+ import Data.Time.Clock (NominalDiffTime , UTCTime )
32+ import Options.Applicative as Opt
33+ import qualified System.FilePath as F
3134
32- import Data.CDF
33- import Data.DataDomain
34- import Cardano.Util
35+ import qualified Unsafe.Coerce as Unsafe
3536
3637
3738newtype FieldName = FieldName { unFieldName :: Text }
@@ -51,7 +52,7 @@ instance Show TId where
5152 show = (" TId " ++ ) . P. show . unTId
5253
5354newtype Hash = Hash { unHash :: ShortText }
54- deriving (Eq , Generic , Ord )
55+ deriving (Eq , Generic , Ord , Data )
5556 deriving newtype (FromJSON , ToJSON )
5657 deriving anyclass NFData
5758
@@ -154,17 +155,50 @@ newtype CsvOutputFile
154155 = CsvOutputFile { unCsvOutputFile :: FilePath }
155156 deriving (Show , Eq )
156157
158+ newtype SqliteOutputFile
159+ = SqliteOutputFile { unSqliteOutputFile :: FilePath }
160+ deriving (Show , Eq )
161+
157162newtype OutputFile
158163 = OutputFile { unOutputFile :: FilePath }
159164 deriving (Show , Eq )
160165
166+ data LogObjectSource =
167+ LogObjectSourceJSON JsonLogfile
168+ | LogObjectSourceSQLite FilePath
169+ | LogObjectSourceOther FilePath
170+ deriving (Show , Eq , Generic , NFData )
171+
172+ logObjectSourceFile :: LogObjectSource -> FilePath
173+ logObjectSourceFile = \ case
174+ LogObjectSourceJSON j -> unJsonLogfile j
175+ LogObjectSourceSQLite f -> f
176+ LogObjectSourceOther f -> f
177+
178+ toLogObjectSource :: FilePath -> LogObjectSource
179+ toLogObjectSource fp
180+ | ext == " .sqlite" || ext == " .sqlite3" = LogObjectSourceSQLite fp
181+ | ext == " .json" = LogObjectSourceJSON (JsonLogfile fp)
182+ | otherwise = LogObjectSourceOther fp
183+ where
184+ ext = map toLower $ F. takeExtension fp
185+
186+ instance FromJSON LogObjectSource where
187+ parseJSON = withText " LogObjectSource" (pure . toLogObjectSource . T. unpack)
188+
189+ instance ToJSON LogObjectSource where
190+ toJSON = toJSON . logObjectSourceFile
191+
161192---
162193--- Orphans
163194---
164195deriving newtype instance Real BlockNo
165196deriving newtype instance Divisible BlockNo
197+ deriving instance Data BlockNo
198+
166199deriving newtype instance Real SlotNo
167200deriving newtype instance Divisible SlotNo
201+ deriving instance Data SlotNo
168202
169203---
170204--- Readers
@@ -202,6 +236,14 @@ optJsonLogfile optname desc =
202236 <> metavar " JSONLOGFILE"
203237 <> help desc
204238
239+ optLogObjectSource :: String -> String -> Parser LogObjectSource
240+ optLogObjectSource optname desc =
241+ fmap toLogObjectSource $
242+ Opt. option Opt. str
243+ $ long optname
244+ <> metavar " JSONLOGFILE|SQLITE3LOGFILE"
245+ <> help desc
246+
205247argJsonLogfile :: Parser JsonLogfile
206248argJsonLogfile =
207249 JsonLogfile <$>
@@ -255,6 +297,14 @@ optCsvOutputFile optname desc =
255297 <> metavar " CSV-OUTFILE"
256298 <> help desc
257299
300+ optSqliteOutputFile :: String -> String -> Parser SqliteOutputFile
301+ optSqliteOutputFile optname desc =
302+ fmap SqliteOutputFile $
303+ Opt. option Opt. str
304+ $ long optname
305+ <> metavar " SQLITE-OUTFILE"
306+ <> help desc
307+
258308optOutputFile :: String -> String -> Parser OutputFile
259309optOutputFile optname desc =
260310 fmap OutputFile $
@@ -279,6 +329,12 @@ optWord optname desc def =
279329 <> metavar " INT"
280330 <> help desc
281331 <> value def
332+
333+ optString :: String -> String -> Parser String
334+ optString optname desc =
335+ Opt. option Opt. str $
336+ long optname <> metavar " STRING" <> Opt. help desc
337+
282338-- /path/to/logs-HOSTNAME.some.ext -> HOSTNAME
283339hostFromLogfilename :: JsonLogfile -> Host
284340hostFromLogfilename (JsonLogfile f) =
@@ -302,26 +358,26 @@ dumpObjects ident xs (JsonOutputFile f) = liftIO $ do
302358 withFile f WriteMode $ \ hnd -> do
303359 forM_ xs $ LBS. hPutStrLn hnd . encode
304360
305- dumpAssociatedObjects :: ToJSON a => String -> [(JsonLogfile , a )] -> ExceptT Text IO ()
361+ dumpAssociatedObjects :: ToJSON a => String -> [(LogObjectSource , a )] -> ExceptT Text IO ()
306362dumpAssociatedObjects ident xs = liftIO $
307363 flip mapConcurrently_ xs $
308- \ (JsonLogfile f, x) ->
364+ \ (logObjectSourceFile -> f, x) ->
309365 withFile (replaceExtension f $ ident <> " .json" ) WriteMode $ \ hnd ->
310366 LBS. hPutStrLn hnd $ encode x
311367
312368readAssociatedObjects :: forall a .
313- FromJSON a => String -> [JsonLogfile ] -> ExceptT Text IO [(JsonLogfile , a )]
369+ FromJSON a => String -> [JsonLogfile ] -> ExceptT Text IO [(LogObjectSource , a )]
314370readAssociatedObjects ident fs = firstExceptT T. pack . newExceptT . fmap (mapM sequence ) $
315371 flip mapConcurrently fs $
316372 \ jf@ (JsonLogfile f) -> do
317373 x <- eitherDecode @ a <$> LBS. readFile (replaceExtension f $ ident <> " .json" )
318374 progress ident (Q f)
319- pure (jf, x)
375+ pure (LogObjectSourceJSON jf, x)
320376
321- dumpAssociatedObjectStreams :: ToJSON a => String -> [(JsonLogfile , [a ])] -> ExceptT Text IO ()
377+ dumpAssociatedObjectStreams :: ToJSON a => String -> [(LogObjectSource , [a ])] -> ExceptT Text IO ()
322378dumpAssociatedObjectStreams ident xss = liftIO $
323379 flip mapConcurrently_ xss $
324- \ (JsonLogfile f, xs) -> do
380+ \ (logObjectSourceFile -> f, xs) -> do
325381 withFile (replaceExtension f $ ident <> " .json" ) WriteMode $ \ hnd -> do
326382 forM_ xs $ LBS. hPutStrLn hnd . encode
327383
@@ -331,9 +387,9 @@ dumpText ident xs (TextOutputFile f) = liftIO $ do
331387 withFile f WriteMode $ \ hnd -> do
332388 forM_ xs $ hPutStrLn hnd
333389
334- dumpAssociatedTextStreams :: String -> [(JsonLogfile , [Text ])] -> ExceptT Text IO ()
390+ dumpAssociatedTextStreams :: String -> [(LogObjectSource , [Text ])] -> ExceptT Text IO ()
335391dumpAssociatedTextStreams ident xss = liftIO $
336392 flip mapConcurrently_ xss $
337- \ (JsonLogfile f, xs) -> do
393+ \ (logObjectSourceFile -> f, xs) -> do
338394 withFile (replaceExtension f $ ident <> " .txt" ) WriteMode $ \ hnd -> do
339395 forM_ xs $ hPutStrLn hnd
0 commit comments