@@ -14,6 +14,7 @@
1414-- limitations under the License.
1515--
1616
17+{-# LANGUAGE CPP #-}
1718{-# LANGUAGE GeneralizedNewtypeDeriving #-}
1819{-# LANGUAGE TypeFamilies #-}
1920module Network.Minio.Data where
@@ -25,6 +26,7 @@ import Control.Monad.IO.Unlift (MonadUnliftIO, UnliftIO (..),
2526import Control.Monad.Trans.Resource
2627import qualified Data.ByteString as B
2728import Data.CaseInsensitive (mk)
29+import qualified Data.HashMap.Strict as H
2830import qualified Data.Ini as Ini
2931import qualified Data.Map as Map
3032import Data.String (IsString (..))
@@ -511,6 +513,237 @@ data Notification = Notification
511513defaultNotification :: Notification
512514defaultNotification = Notification [] [] []
513515
516+
517+--------------------------------------------------------------------------
518+-- Select API Related Types
519+--------------------------------------------------------------------------
520+
521+-- | SelectRequest represents the Select API call. Use the
522+-- `selectRequest` function to create a value of this type.
523+data SelectRequest = SelectRequest
524+ { srExpression :: Text
525+ , srExpressionType :: ExpressionType
526+ , srInputSerialization :: InputSerialization
527+ , srOutputSerialization :: OutputSerialization
528+ , srRequestProgressEnabled :: Maybe Bool
529+ } deriving (Eq, Show)
530+
531+data ExpressionType = SQL
532+ deriving (Eq, Show)
533+
534+-- | InputSerialization represents format information of the input
535+-- object being queried. Use one of the smart constructors such as
536+-- `defaultCsvInput` as a starting value, and add compression info
537+-- using `setInputCompressionType`
538+data InputSerialization = InputSerialization
539+ { isCompressionType :: Maybe CompressionType
540+ , isFormatInfo :: InputFormatInfo
541+ } deriving (Eq, Show)
542+
543+data CompressionType = CompressionTypeNone
544+ | CompressionTypeGzip
545+ | CompressionTypeBzip2
546+ deriving (Eq, Show)
547+
548+data InputFormatInfo = InputFormatCSV CSVInputProp
549+ | InputFormatJSON JSONInputProp
550+ | InputFormatParquet
551+ deriving (Eq, Show)
552+
553+-- | defaultCsvInput returns InputSerialization with default CSV
554+-- format, and without any compression setting.
555+defaultCsvInput :: InputSerialization
556+defaultCsvInput = InputSerialization Nothing (InputFormatCSV defaultCSVProp)
557+
558+-- | linesJsonInput returns InputSerialization with JSON line based
559+-- format with no compression setting.
560+linesJsonInput :: InputSerialization
561+linesJsonInput = InputSerialization Nothing
562+ (InputFormatJSON $ JSONInputProp JSONTypeLines)
563+
564+-- | documentJsonInput returns InputSerialization with JSON document
565+-- based format with no compression setting.
566+documentJsonInput :: InputSerialization
567+documentJsonInput = InputSerialization Nothing
568+ (InputFormatJSON $ JSONInputProp JSONTypeDocument)
569+
570+-- | defaultParquetInput returns InputSerialization with Parquet
571+-- format, and no compression setting.
572+defaultParquetInput :: InputSerialization
573+defaultParquetInput = InputSerialization Nothing InputFormatParquet
574+
575+-- | setInputCompressionType sets the compression type for the input
576+-- of the SelectRequest
577+setInputCompressionType :: CompressionType -> SelectRequest
578+ -> SelectRequest
579+setInputCompressionType c i =
580+ let is = srInputSerialization i
581+ is' = is { isCompressionType = Just c }
582+ in i { srInputSerialization = is' }
583+
584+-- | defaultCsvOutput returns OutputSerialization with default CSV
585+-- format.
586+defaultCsvOutput :: OutputSerialization
587+defaultCsvOutput = OutputSerializationCSV defaultCSVProp
588+
589+-- | defaultJsonInput returns OutputSerialization with default JSON
590+-- format.
591+defaultJsonOutput :: OutputSerialization
592+defaultJsonOutput = OutputSerializationJSON (JSONOutputProp Nothing)
593+
594+-- | selectRequest is used to build a `SelectRequest`
595+-- value. @selectRequest query inputSer outputSer@ represents a
596+-- SelectRequest with the SQL query text given by @query@, the input
597+-- serialization settings (compression format and format information)
598+-- @inputSer@ and the output serialization settings @outputSer@.
599+selectRequest :: Text -> InputSerialization -> OutputSerialization
600+ -> SelectRequest
601+selectRequest sqlQuery inputSer outputSer =
602+ SelectRequest { srExpression = sqlQuery
603+ , srExpressionType = SQL
604+ , srInputSerialization = inputSer
605+ , srOutputSerialization = outputSer
606+ , srRequestProgressEnabled = Nothing
607+ }
608+
609+-- | setRequestProgressEnabled sets the flag for turning on progress
610+-- messages when the Select response is being streamed back to the
611+-- client.
612+setRequestProgressEnabled :: Bool -> SelectRequest -> SelectRequest
613+setRequestProgressEnabled enabled sr =
614+ sr { srRequestProgressEnabled = Just enabled }
615+
616+type CSVInputProp = CSVProp
617+
618+-- | CSVProp represents CSV format properties. It is built up using
619+-- the Monoid instance.
620+data CSVProp = CSVProp (H.HashMap Text Text)
621+ deriving (Eq, Show)
622+
623+#if (__GLASGOW_HASKELL__ >= 804)
624+instance Semigroup CSVProp where
625+ (CSVProp a) <> (CSVProp b) = CSVProp (b <> a)
626+#endif
627+
628+instance Monoid CSVProp where
629+ mempty = CSVProp mempty
630+#if (__GLASGOW_HASKELL__ < 804)
631+ mappend (CSVProp a) (CSVProp b) = CSVProp (b <> a)
632+#endif
633+
634+defaultCSVProp :: CSVProp
635+defaultCSVProp = mempty
636+
637+recordDelimiter :: Text -> CSVProp
638+recordDelimiter = CSVProp . H.singleton "RecordDelimiter"
639+
640+fieldDelimiter :: Text -> CSVProp
641+fieldDelimiter = CSVProp . H.singleton "FieldDelimiter"
642+
643+quoteCharacter :: Text -> CSVProp
644+quoteCharacter = CSVProp . H.singleton "QuoteCharacter"
645+
646+quoteEscapeCharacter :: Text -> CSVProp
647+quoteEscapeCharacter = CSVProp . H.singleton "QuoteEscapeCharacter"
648+
649+-- | FileHeaderInfo specifies information about column headers for CSV
650+-- format.
651+data FileHeaderInfo
652+ = FileHeaderNone -- ^ No column headers are present
653+ | FileHeaderUse -- ^ Headers are present and they should be used
654+ | FileHeaderIgnore -- ^ Header are present, but should be ignored
655+ deriving (Eq, Show)
656+
657+fileHeaderInfo :: FileHeaderInfo -> CSVProp
658+fileHeaderInfo = CSVProp . H.singleton "FileHeaderInfo" . toString
659+ where
660+ toString FileHeaderNone = "NONE"
661+ toString FileHeaderUse = "USE"
662+ toString FileHeaderIgnore = "IGNORE"
663+
664+commentCharacter :: Text -> CSVProp
665+commentCharacter = CSVProp . H.singleton "Comments"
666+
667+allowQuotedRecordDelimiter :: CSVProp
668+allowQuotedRecordDelimiter = CSVProp $ H.singleton "AllowQuotedRecordDelimiter" "TRUE"
669+
670+-- | Set the CSV format properties in the InputSerialization.
671+setInputCSVProps :: CSVProp -> InputSerialization -> InputSerialization
672+setInputCSVProps p is = is { isFormatInfo = InputFormatCSV p }
673+
674+-- | Set the CSV format properties in the OutputSerialization.
675+outputCSVFromProps :: CSVProp -> OutputSerialization
676+outputCSVFromProps p = OutputSerializationCSV p
677+
678+data JSONInputProp = JSONInputProp { jsonipType :: JSONType }
679+ deriving (Eq, Show)
680+
681+data JSONType = JSONTypeDocument | JSONTypeLines
682+ deriving (Eq, Show)
683+
684+
685+-- | OutputSerialization represents output serialization settings for
686+-- the SelectRequest. Use `defaultCsvOutput` or `defaultJsonOutput` as
687+-- a starting point.
688+data OutputSerialization = OutputSerializationJSON JSONOutputProp
689+ | OutputSerializationCSV CSVOutputProp
690+ deriving (Eq, Show)
691+
692+type CSVOutputProp = CSVProp
693+
694+-- | quoteFields is an output serialization parameter
695+quoteFields :: QuoteFields -> CSVProp
696+quoteFields q = CSVProp $ H.singleton "QuoteFields" $
697+ case q of
698+ QuoteFieldsAsNeeded -> "ASNEEDED"
699+ QuoteFieldsAlways -> "ALWAYS"
700+
701+data QuoteFields = QuoteFieldsAsNeeded | QuoteFieldsAlways
702+ deriving (Eq, Show)
703+
704+data JSONOutputProp = JSONOutputProp { jsonopRecordDelimiter :: Maybe Text }
705+ deriving (Eq, Show)
706+
707+-- | Set the output record delimiter for JSON format
708+outputJSONFromRecordDelimiter :: Text -> OutputSerialization
709+outputJSONFromRecordDelimiter t =
710+ OutputSerializationJSON (JSONOutputProp $ Just t)
711+
712+-- Response related types
713+
714+-- | An EventMessage represents each kind of message received from the server.
715+data EventMessage = ProgressEventMessage { emProgress :: Progress }
716+ | StatsEventMessage { emStats :: Stats }
717+ | RequestLevelErrorMessage { emErrorCode :: Text
718+ , emErrorMessage :: Text
719+ }
720+ | RecordPayloadEventMessage { emPayloadBytes :: ByteString }
721+ deriving (Eq, Show)
722+
723+data MsgHeaderName = MessageType
724+ | EventType
725+ | ContentType
726+ | ErrorCode
727+ | ErrorMessage
728+ deriving (Eq, Show)
729+
730+msgHeaderValueType :: Word8
731+msgHeaderValueType = 7
732+
733+type MessageHeader = (MsgHeaderName, Text)
734+
735+data Progress = Progress { pBytesScanned :: Int64
736+ , pBytesProcessed :: Int64
737+ , pBytesReturned :: Int64
738+ }
739+ deriving (Eq, Show)
740+
741+type Stats = Progress
742+
743+--------------------------------------------------------------------------
744+-- Select API Related Types End
745+--------------------------------------------------------------------------
746+
514747-- | Represents different kinds of payload that are used with S3 API
515748-- requests.
516749data Payload = PayloadBS ByteString
@@ -530,8 +763,8 @@ data AdminReqInfo = AdminReqInfo {
530763 , ariQueryParams :: Query
531764 }
532765
533−data S3ReqInfo = S3ReqInfo {
534− riMethod :: Method
766+data S3ReqInfo = S3ReqInfo
767+ { riMethod :: Method
535768 , riBucket :: Maybe Bucket
536769 , riObject :: Maybe Object
537770 , riQueryParams :: Query