module Hydra.Ext.Avro.Coder where
import Hydra.All
import Hydra.Adapters.Coders
import qualified Hydra.Lib.Strings as Strings
import qualified Hydra.Impl.Haskell.Dsl.Types as Types
import qualified Hydra.Impl.Haskell.Dsl.Terms as Terms
import Hydra.Util.Codetree.Script
import Hydra.Adapters.UtilsEtc
import qualified Hydra.Ext.Avro.Schema as Avro
import qualified Hydra.Ext.Json.Model as Json
import Hydra.Ext.Json.Eliminate
import Hydra.CoreEncoding
import qualified Control.Monad as CM
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Set as S
import qualified Data.Maybe as Y
import qualified Text.Read as TR
data AvroEnvironment m = AvroEnvironment {
forall m.
AvroEnvironment m -> Map AvroQualifiedName (AvroHydraAdapter m)
avroEnvironmentNamedAdapters :: M.Map AvroQualifiedName (AvroHydraAdapter m),
forall m. AvroEnvironment m -> Maybe String
avroEnvironmentNamespace :: Maybe String,
forall m. AvroEnvironment m -> Map Name (Element m)
avroEnvironmentElements :: M.Map Name (Element m)}
type AvroHydraAdapter m = Adapter (AvroEnvironment m) (AvroEnvironment m) Avro.Schema (Type m) Json.Value (Term m)
data AvroQualifiedName = AvroQualifiedName (Maybe String) String deriving (AvroQualifiedName -> AvroQualifiedName -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AvroQualifiedName -> AvroQualifiedName -> Bool
$c/= :: AvroQualifiedName -> AvroQualifiedName -> Bool
== :: AvroQualifiedName -> AvroQualifiedName -> Bool
$c== :: AvroQualifiedName -> AvroQualifiedName -> Bool
Eq, Eq AvroQualifiedName
AvroQualifiedName -> AvroQualifiedName -> Bool
AvroQualifiedName -> AvroQualifiedName -> Ordering
AvroQualifiedName -> AvroQualifiedName -> AvroQualifiedName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: AvroQualifiedName -> AvroQualifiedName -> AvroQualifiedName
$cmin :: AvroQualifiedName -> AvroQualifiedName -> AvroQualifiedName
max :: AvroQualifiedName -> AvroQualifiedName -> AvroQualifiedName
$cmax :: AvroQualifiedName -> AvroQualifiedName -> AvroQualifiedName
>= :: AvroQualifiedName -> AvroQualifiedName -> Bool
$c>= :: AvroQualifiedName -> AvroQualifiedName -> Bool
> :: AvroQualifiedName -> AvroQualifiedName -> Bool
$c> :: AvroQualifiedName -> AvroQualifiedName -> Bool
<= :: AvroQualifiedName -> AvroQualifiedName -> Bool
$c<= :: AvroQualifiedName -> AvroQualifiedName -> Bool
< :: AvroQualifiedName -> AvroQualifiedName -> Bool
$c< :: AvroQualifiedName -> AvroQualifiedName -> Bool
compare :: AvroQualifiedName -> AvroQualifiedName -> Ordering
$ccompare :: AvroQualifiedName -> AvroQualifiedName -> Ordering
Ord, Int -> AvroQualifiedName -> ShowS
[AvroQualifiedName] -> ShowS
AvroQualifiedName -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AvroQualifiedName] -> ShowS
$cshowList :: [AvroQualifiedName] -> ShowS
show :: AvroQualifiedName -> String
$cshow :: AvroQualifiedName -> String
showsPrec :: Int -> AvroQualifiedName -> ShowS
$cshowsPrec :: Int -> AvroQualifiedName -> ShowS
Show)
data ForeignKey = ForeignKey Name (String -> Name)
data PrimaryKey = PrimaryKey FieldName (String -> Name)
emptyEnvironment :: AvroEnvironment m
emptyEnvironment = forall m.
Map AvroQualifiedName (AvroHydraAdapter m)
-> Maybe String -> Map Name (Element m) -> AvroEnvironment m
AvroEnvironment forall k a. Map k a
M.empty forall a. Maybe a
Nothing forall k a. Map k a
M.empty
avro_foreignKey :: String
avro_foreignKey = String
"@foreignKey"
avro_primaryKey :: String
avro_primaryKey = String
"@primaryKey"
avroHydraAdapter :: (Ord m, Show m) => Avro.Schema -> Flow (AvroEnvironment m) (AvroHydraAdapter m)
avroHydraAdapter :: forall m.
(Ord m, Show m) =>
Schema -> Flow (AvroEnvironment m) (AvroHydraAdapter m)
avroHydraAdapter Schema
schema = case Schema
schema of
Avro.SchemaArray (Avro.Array Schema
s) -> do
AvroHydraAdapter m
ad <- forall m.
(Ord m, Show m) =>
Schema -> Flow (AvroEnvironment m) (AvroHydraAdapter m)
avroHydraAdapter Schema
s
let coder :: Coder (AvroEnvironment m) (AvroEnvironment m) Value (Term m)
coder = Coder {
coderEncode :: Value -> Flow (AvroEnvironment m) (Term m)
coderEncode = \(Json.ValueArray [Value]
vals) -> forall m. [Term m] -> Term m
Terms.list forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
CM.mapM (forall s1 s2 v1 v2. Coder s1 s2 v1 v2 -> v1 -> Flow s1 v2
coderEncode forall a b. (a -> b) -> a -> b
$ forall s1 s2 t1 t2 v1 v2.
Adapter s1 s2 t1 t2 v1 v2 -> Coder s1 s2 v1 v2
adapterCoder AvroHydraAdapter m
ad) [Value]
vals),
coderDecode :: Term m -> Flow (AvroEnvironment m) Value
coderDecode = \(TermList [Term m]
vals) -> [Value] -> Value
Json.ValueArray forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
CM.mapM (forall s1 s2 v1 v2. Coder s1 s2 v1 v2 -> v2 -> Flow s2 v1
coderDecode forall a b. (a -> b) -> a -> b
$ forall s1 s2 t1 t2 v1 v2.
Adapter s1 s2 t1 t2 v1 v2 -> Coder s1 s2 v1 v2
adapterCoder AvroHydraAdapter m
ad) [Term m]
vals)}
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s1 s2 t1 t2 v1 v2.
Bool -> t1 -> t2 -> Coder s1 s2 v1 v2 -> Adapter s1 s2 t1 t2 v1 v2
Adapter (forall s1 s2 t1 t2 v1 v2. Adapter s1 s2 t1 t2 v1 v2 -> Bool
adapterIsLossy AvroHydraAdapter m
ad) Schema
schema (forall m. Type m -> Type m
Types.list forall a b. (a -> b) -> a -> b
$ forall s1 s2 t1 t2 v1 v2. Adapter s1 s2 t1 t2 v1 v2 -> t2
adapterTarget AvroHydraAdapter m
ad) Coder (AvroEnvironment m) (AvroEnvironment m) Value (Term m)
coder
Avro.SchemaMap (Avro.Map_ Schema
s) -> do
AvroHydraAdapter m
ad <- forall m.
(Ord m, Show m) =>
Schema -> Flow (AvroEnvironment m) (AvroHydraAdapter m)
avroHydraAdapter Schema
s
let pairToHydra :: (String, Value) -> Flow (AvroEnvironment m) (Term m, Term m)
pairToHydra (String
k, Value
v) = do
Term m
v' <- forall s1 s2 v1 v2. Coder s1 s2 v1 v2 -> v1 -> Flow s1 v2
coderEncode (forall s1 s2 t1 t2 v1 v2.
Adapter s1 s2 t1 t2 v1 v2 -> Coder s1 s2 v1 v2
adapterCoder AvroHydraAdapter m
ad) Value
v
forall (m :: * -> *) a. Monad m => a -> m a
return (forall m. String -> Term m
Terms.string String
k, Term m
v')
let coder :: Coder (AvroEnvironment m) (AvroEnvironment m) Value (Term m)
coder = Coder {
coderEncode :: Value -> Flow (AvroEnvironment m) (Term m)
coderEncode = \(Json.ValueObject Map String Value
m) -> forall m. Map (Term m) (Term m) -> Term m
Terms.map forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Ord k => [(k, a)] -> Map k a
M.fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
CM.mapM forall {m}.
(String, Value) -> Flow (AvroEnvironment m) (Term m, Term m)
pairToHydra forall a b. (a -> b) -> a -> b
$ forall k a. Map k a -> [(k, a)]
M.toList Map String Value
m),
coderDecode :: Term m -> Flow (AvroEnvironment m) Value
coderDecode = \Term m
m -> Map String Value -> Value
Json.ValueObject forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall k m s v.
(Ord k, Show m) =>
(Term m -> Flow s k)
-> (Term m -> Flow s v) -> Term m -> Flow s (Map k v)
Terms.expectMap forall m s. Show m => Term m -> Flow s String
Terms.expectString (forall s1 s2 v1 v2. Coder s1 s2 v1 v2 -> v2 -> Flow s2 v1
coderDecode (forall s1 s2 t1 t2 v1 v2.
Adapter s1 s2 t1 t2 v1 v2 -> Coder s1 s2 v1 v2
adapterCoder AvroHydraAdapter m
ad)) Term m
m}
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s1 s2 t1 t2 v1 v2.
Bool -> t1 -> t2 -> Coder s1 s2 v1 v2 -> Adapter s1 s2 t1 t2 v1 v2
Adapter (forall s1 s2 t1 t2 v1 v2. Adapter s1 s2 t1 t2 v1 v2 -> Bool
adapterIsLossy AvroHydraAdapter m
ad) Schema
schema (forall m. Type m -> Type m -> Type m
Types.map forall m. Type m
Types.string forall a b. (a -> b) -> a -> b
$ forall s1 s2 t1 t2 v1 v2. Adapter s1 s2 t1 t2 v1 v2 -> t2
adapterTarget AvroHydraAdapter m
ad) Coder (AvroEnvironment m) (AvroEnvironment m) Value (Term m)
coder
Avro.SchemaNamed Named
n -> do
let ns :: Maybe String
ns = Named -> Maybe String
Avro.namedNamespace Named
n
AvroEnvironment m
env <- forall s. Flow s s
getState
let lastNs :: Maybe String
lastNs = forall m. AvroEnvironment m -> Maybe String
avroEnvironmentNamespace AvroEnvironment m
env
let nextNs :: Maybe String
nextNs = forall b a. b -> (a -> b) -> Maybe a -> b
Y.maybe Maybe String
lastNs forall a. a -> Maybe a
Just Maybe String
ns
forall s. s -> Flow s ()
putState forall a b. (a -> b) -> a -> b
$ AvroEnvironment m
env {avroEnvironmentNamespace :: Maybe String
avroEnvironmentNamespace = Maybe String
nextNs}
let qname :: AvroQualifiedName
qname = Maybe String -> String -> AvroQualifiedName
AvroQualifiedName Maybe String
nextNs (Named -> String
Avro.namedName Named
n)
let hydraName :: Name
hydraName = AvroQualifiedName -> Name
avroNameToHydraName AvroQualifiedName
qname
AvroHydraAdapter m
ad <- case forall m.
AvroQualifiedName
-> AvroEnvironment m -> Maybe (AvroHydraAdapter m)
getAvroHydraAdapter AvroQualifiedName
qname AvroEnvironment m
env of
Just AvroHydraAdapter m
ad -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"Avro named type defined more than once: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show AvroQualifiedName
qname
Maybe (AvroHydraAdapter m)
Nothing -> do
AvroHydraAdapter m
ad <- case Named -> NamedType
Avro.namedType Named
n of
Avro.NamedTypeEnum (Avro.Enum_ [String]
syms Maybe String
mdefault) -> forall {f :: * -> *} {t2} {v1} {s1} {v2} {s2}.
Applicative f =>
t2
-> (v1 -> Flow s1 v2)
-> (v2 -> Flow s2 v1)
-> f (Adapter s1 s2 Schema t2 v1 v2)
simpleAdapter forall m. Type m
typ forall {f :: * -> *} {m}. Applicative f => Value -> f (Term m)
encode forall {m :: * -> *} {m}. Monad m => Term m -> m Value
decode
where
typ :: Type m
typ = forall m. RowType m -> Type m
TypeUnion (forall m. Name -> Maybe Name -> [FieldType m] -> RowType m
RowType Name
hydraName forall a. Maybe a
Nothing forall a b. (a -> b) -> a -> b
$ forall {m}. String -> FieldType m
toField forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [String]
syms)
where
toField :: String -> FieldType m
toField String
s = forall m. FieldName -> Type m -> FieldType m
FieldType (String -> FieldName
FieldName String
s) forall m. Type m
Types.unit
encode :: Value -> f (Term m)
encode (Json.ValueString String
s) = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall m. Union m -> Term m
TermUnion (forall m. Name -> Field m -> Union m
Union Name
hydraName forall a b. (a -> b) -> a -> b
$ forall m. FieldName -> Term m -> Field m
Field (String -> FieldName
FieldName String
s) forall m. Term m
Terms.unit)
decode :: Term m -> m Value
decode (TermUnion (Union Name
_ (Field FieldName
fn Term m
_))) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ String -> Value
Json.ValueString forall a b. (a -> b) -> a -> b
$ FieldName -> String
unFieldName FieldName
fn
Avro.NamedTypeFixed (Avro.Fixed Int
size) -> forall {f :: * -> *} {t2} {v1} {s1} {v2} {s2}.
Applicative f =>
t2
-> (v1 -> Flow s1 v2)
-> (v2 -> Flow s2 v1)
-> f (Adapter s1 s2 Schema t2 v1 v2)
simpleAdapter forall m. Type m
Types.binary forall {f :: * -> *} {m}. Applicative f => Value -> f (Term m)
encode forall {m} {s}. Show m => Term m -> Flow s Value
decode
where
encode :: Value -> f (Term m)
encode (Json.ValueString String
s) = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall m. String -> Term m
Terms.binary String
s
decode :: Term m -> Flow s Value
decode Term m
term = String -> Value
Json.ValueString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall m s. Show m => Term m -> Flow s String
Terms.expectBinary Term m
term
Avro.NamedTypeRecord Record
r -> do
let avroFields :: [Field]
avroFields = Record -> [Field]
Avro.recordFields Record
r
Map String (Field, AvroHydraAdapter m)
adaptersByFieldName <- forall k a. Ord k => [(k, a)] -> Map k a
M.fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
CM.mapM forall {m}.
(Ord m, Show m) =>
Field
-> Flow (AvroEnvironment m) (String, (Field, AvroHydraAdapter m))
prepareField [Field]
avroFields)
Maybe PrimaryKey
pk <- forall {a} {s}. Show a => a -> [Field] -> Flow s (Maybe PrimaryKey)
findPrimaryKeyField AvroQualifiedName
qname [Field]
avroFields
let encodePair :: (String, Value) -> Flow (AvroEnvironment m) (Field m)
encodePair (String
k, Value
v) = case forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup String
k Map String (Field, AvroHydraAdapter m)
adaptersByFieldName of
Maybe (Field, AvroHydraAdapter m)
Nothing -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"unrecognized field for " forall a. [a] -> [a] -> [a]
++ AvroQualifiedName -> String
showQname AvroQualifiedName
qname forall a. [a] -> [a] -> [a]
++ String
": " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show String
k
Just (Field
f, AvroHydraAdapter m
ad) -> do
Term m
v' <- forall s1 s2 v1 v2. Coder s1 s2 v1 v2 -> v1 -> Flow s1 v2
coderEncode (forall s1 s2 t1 t2 v1 v2.
Adapter s1 s2 t1 t2 v1 v2 -> Coder s1 s2 v1 v2
adapterCoder AvroHydraAdapter m
ad) Value
v
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall m. FieldName -> Term m -> Field m
Field (String -> FieldName
FieldName String
k) Term m
v'
let decodeField :: Field m -> Flow (AvroEnvironment m) (String, Value)
decodeField (Field (FieldName String
k) Term m
v) = case forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup String
k Map String (Field, AvroHydraAdapter m)
adaptersByFieldName of
Maybe (Field, AvroHydraAdapter m)
Nothing -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"unrecognized field for " forall a. [a] -> [a] -> [a]
++ AvroQualifiedName -> String
showQname AvroQualifiedName
qname forall a. [a] -> [a] -> [a]
++ String
": " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show String
k
Just (Field
f, AvroHydraAdapter m
ad) -> do
Value
v' <- forall s1 s2 v1 v2. Coder s1 s2 v1 v2 -> v2 -> Flow s2 v1
coderDecode (forall s1 s2 t1 t2 v1 v2.
Adapter s1 s2 t1 t2 v1 v2 -> Coder s1 s2 v1 v2
adapterCoder AvroHydraAdapter m
ad) Term m
v
forall (m :: * -> *) a. Monad m => a -> m a
return (String
k, Value
v')
let lossy :: Bool
lossy = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl (\Bool
b (Field
_, AvroHydraAdapter m
ad) -> Bool
b Bool -> Bool -> Bool
|| forall s1 s2 t1 t2 v1 v2. Adapter s1 s2 t1 t2 v1 v2 -> Bool
adapterIsLossy AvroHydraAdapter m
ad) Bool
False forall a b. (a -> b) -> a -> b
$ forall k a. Map k a -> [a]
M.elems Map String (Field, AvroHydraAdapter m)
adaptersByFieldName
let hfields :: [FieldType m]
hfields = forall {s1} {s2} {t1} {m} {v1} {v2}.
(Field, Adapter s1 s2 t1 (Type m) v1 v2) -> FieldType m
toHydraField forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall k a. Map k a -> [a]
M.elems Map String (Field, AvroHydraAdapter m)
adaptersByFieldName
let target :: Type m
target = forall m. RowType m -> Type m
TypeRecord forall a b. (a -> b) -> a -> b
$ forall m. Name -> Maybe Name -> [FieldType m] -> RowType m
RowType Name
hydraName forall a. Maybe a
Nothing [FieldType m]
hfields
let coder :: Coder (AvroEnvironment m) (AvroEnvironment m) Value (Term m)
coder = Coder {
coderEncode :: Value -> Flow (AvroEnvironment m) (Term m)
coderEncode = \(Json.ValueObject Map String Value
m) -> do
[Field m]
fields <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
CM.mapM (String, Value) -> Flow (AvroEnvironment m) (Field m)
encodePair forall a b. (a -> b) -> a -> b
$ forall k a. Map k a -> [(k, a)]
M.toList Map String Value
m
let term :: Term m
term = forall m. Record m -> Term m
TermRecord forall a b. (a -> b) -> a -> b
$ forall m. Name -> [Field m] -> Record m
Record Name
hydraName [Field m]
fields
forall {m} {m}.
Show m =>
Term m
-> Type m
-> Maybe PrimaryKey
-> [Field m]
-> Flow (AvroEnvironment m) ()
addElement Term m
term Type m
target Maybe PrimaryKey
pk [Field m]
fields
forall (m :: * -> *) a. Monad m => a -> m a
return Term m
term,
coderDecode :: Term m -> Flow (AvroEnvironment m) Value
coderDecode = \(TermRecord (Record Name
_ [Field m]
fields)) -> Map String Value -> Value
Json.ValueObject forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Ord k => [(k, a)] -> Map k a
M.fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
CM.mapM Field m -> Flow (AvroEnvironment m) (String, Value)
decodeField [Field m]
fields)}
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s1 s2 t1 t2 v1 v2.
Bool -> t1 -> t2 -> Coder s1 s2 v1 v2 -> Adapter s1 s2 t1 t2 v1 v2
Adapter Bool
lossy Schema
schema Type m
target Coder (AvroEnvironment m) (AvroEnvironment m) Value (Term m)
coder
where
toHydraField :: (Field, Adapter s1 s2 t1 (Type m) v1 v2) -> FieldType m
toHydraField (Field
f, Adapter s1 s2 t1 (Type m) v1 v2
ad) = forall m. FieldName -> Type m -> FieldType m
FieldType (String -> FieldName
FieldName forall a b. (a -> b) -> a -> b
$ Field -> String
Avro.fieldName Field
f) forall a b. (a -> b) -> a -> b
$ forall s1 s2 t1 t2 v1 v2. Adapter s1 s2 t1 t2 v1 v2 -> t2
adapterTarget Adapter s1 s2 t1 (Type m) v1 v2
ad
AvroEnvironment m
env <- forall s. Flow s s
getState
forall s. s -> Flow s ()
putState forall a b. (a -> b) -> a -> b
$ forall m.
AvroQualifiedName
-> AvroHydraAdapter m -> AvroEnvironment m -> AvroEnvironment m
putAvroHydraAdapter AvroQualifiedName
qname AvroHydraAdapter m
ad AvroEnvironment m
env
forall (m :: * -> *) a. Monad m => a -> m a
return AvroHydraAdapter m
ad
AvroEnvironment m
env2 <- forall s. Flow s s
getState
forall s. s -> Flow s ()
putState forall a b. (a -> b) -> a -> b
$ AvroEnvironment m
env2 {avroEnvironmentNamespace :: Maybe String
avroEnvironmentNamespace = Maybe String
lastNs}
forall (m :: * -> *) a. Monad m => a -> m a
return AvroHydraAdapter m
ad
where
addElement :: Term m
-> Type m
-> Maybe PrimaryKey
-> [Field m]
-> Flow (AvroEnvironment m) ()
addElement Term m
term Type m
typ Maybe PrimaryKey
pk [Field m]
fields = case Maybe PrimaryKey
pk of
Maybe PrimaryKey
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Just (PrimaryKey FieldName
fname String -> Name
constr) -> case forall a. (a -> Bool) -> [a] -> [a]
L.filter forall {m}. Field m -> Bool
isPkField [Field m]
fields of
[] -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
[Field m
field] -> do
String
s <- forall m s. Show m => Term m -> Flow s String
termToString forall a b. (a -> b) -> a -> b
$ forall m. Field m -> Term m
fieldTerm Field m
field
let name :: Name
name = String -> Name
constr String
s
let el :: Element m
el = forall m. Name -> Term m -> Term m -> Element m
Element Name
name (forall m. Type m -> Term m
encodeType Type m
typ) Term m
term
AvroEnvironment m
env <- forall s. Flow s s
getState
forall s. s -> Flow s ()
putState forall a b. (a -> b) -> a -> b
$ AvroEnvironment m
env {avroEnvironmentElements :: Map Name (Element m)
avroEnvironmentElements = forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Name
name Element m
el (forall m. AvroEnvironment m -> Map Name (Element m)
avroEnvironmentElements AvroEnvironment m
env)}
forall (m :: * -> *) a. Monad m => a -> m a
return ()
[Field m]
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"multiple fields named " forall a. [a] -> [a] -> [a]
++ FieldName -> String
unFieldName FieldName
fname
where
isPkField :: Field m -> Bool
isPkField Field m
field = forall m. Field m -> FieldName
fieldName Field m
field forall a. Eq a => a -> a -> Bool
== FieldName
fname
findPrimaryKeyField :: a -> [Field] -> Flow s (Maybe PrimaryKey)
findPrimaryKeyField a
qname [Field]
avroFields = do
[PrimaryKey]
keys <- forall a. [Maybe a] -> [a]
Y.catMaybes forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
CM.mapM forall s. Field -> Flow s (Maybe PrimaryKey)
primaryKey [Field]
avroFields
case [PrimaryKey]
keys of
[] -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
[PrimaryKey
k] -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just PrimaryKey
k
[PrimaryKey]
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"multiple primary key fields for " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show a
qname
prepareField :: Field
-> Flow (AvroEnvironment m) (String, (Field, AvroHydraAdapter m))
prepareField Field
f = do
Maybe ForeignKey
fk <- forall s. Field -> Flow s (Maybe ForeignKey)
foreignKey Field
f
AvroHydraAdapter m
ad <- case Maybe ForeignKey
fk of
Maybe ForeignKey
Nothing -> forall m.
(Ord m, Show m) =>
Schema -> Flow (AvroEnvironment m) (AvroHydraAdapter m)
avroHydraAdapter forall a b. (a -> b) -> a -> b
$ Field -> Schema
Avro.fieldType Field
f
Just (ForeignKey Name
name String -> Name
constr) -> do
AvroHydraAdapter m
ad <- forall m.
(Ord m, Show m) =>
Schema -> Flow (AvroEnvironment m) (AvroHydraAdapter m)
avroHydraAdapter forall a b. (a -> b) -> a -> b
$ Field -> Schema
Avro.fieldType Field
f
let decodeTerm :: Term m -> Flow (AvroEnvironment m) Value
decodeTerm = \(TermElement Name
name) -> do
Term m
term <- forall m s. Show m => Type m -> String -> Flow s (Term m)
stringToTerm (forall s1 s2 t1 t2 v1 v2. Adapter s1 s2 t1 t2 v1 v2 -> t2
adapterTarget AvroHydraAdapter m
ad) forall a b. (a -> b) -> a -> b
$ Name -> String
unName Name
name
forall s1 s2 v1 v2. Coder s1 s2 v1 v2 -> v2 -> Flow s2 v1
coderDecode (forall s1 s2 t1 t2 v1 v2.
Adapter s1 s2 t1 t2 v1 v2 -> Coder s1 s2 v1 v2
adapterCoder AvroHydraAdapter m
ad) Term m
term
let encodeValue :: Value -> Flow (AvroEnvironment m) (Term m)
encodeValue Value
v = do
String
s <- forall s1 s2 v1 v2. Coder s1 s2 v1 v2 -> v1 -> Flow s1 v2
coderEncode (forall s1 s2 t1 t2 v1 v2.
Adapter s1 s2 t1 t2 v1 v2 -> Coder s1 s2 v1 v2
adapterCoder AvroHydraAdapter m
ad) Value
v forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall m s. Show m => Term m -> Flow s String
termToString
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall m. Name -> Term m
TermElement forall a b. (a -> b) -> a -> b
$ String -> Name
constr String
s
case forall m. Type m -> Type m
stripType (forall s1 s2 t1 t2 v1 v2. Adapter s1 s2 t1 t2 v1 v2 -> t2
adapterTarget AvroHydraAdapter m
ad) of
TypeOptional (TypeLiteral LiteralType
lit) -> forall {f :: * -> *} {s1} {s2} {t1} {t2} {v1} {v2} {t2} {s1} {s2}
{v1} {v2}.
Applicative f =>
Adapter s1 s2 t1 t2 v1 v2
-> t2 -> Coder s1 s2 v1 v2 -> f (Adapter s1 s2 Schema t2 v1 v2)
forTypeAndCoder AvroHydraAdapter m
ad (forall m. Type m -> Type m
Types.optional forall m. Type m
elTyp) forall {m}.
Coder (AvroEnvironment m) (AvroEnvironment m) Value (Term m)
coder
where
coder :: Coder (AvroEnvironment m) (AvroEnvironment m) Value (Term m)
coder = Coder {
coderEncode :: Value -> Flow (AvroEnvironment m) (Term m)
coderEncode = \Value
json -> (forall m. Maybe (Term m) -> Term m
TermOptional forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {m}. Value -> Flow (AvroEnvironment m) (Term m)
encodeValue Value
json,
coderDecode :: Term m -> Flow (AvroEnvironment m) Value
coderDecode = forall {m}. Term m -> Flow (AvroEnvironment m) Value
decodeTerm}
TypeList (TypeLiteral LiteralType
lit) -> forall {f :: * -> *} {s1} {s2} {t1} {t2} {v1} {v2} {t2} {s1} {s2}
{v1} {v2}.
Applicative f =>
Adapter s1 s2 t1 t2 v1 v2
-> t2 -> Coder s1 s2 v1 v2 -> f (Adapter s1 s2 Schema t2 v1 v2)
forTypeAndCoder AvroHydraAdapter m
ad (forall m. Type m -> Type m
Types.list forall m. Type m
elTyp) forall {m}.
Coder (AvroEnvironment m) (AvroEnvironment m) Value (Term m)
coder
where
coder :: Coder (AvroEnvironment m) (AvroEnvironment m) Value (Term m)
coder = Coder {
coderEncode :: Value -> Flow (AvroEnvironment m) (Term m)
coderEncode = \Value
json -> forall m. [Term m] -> Term m
TermList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall s. Value -> Flow s [Value]
expectArray Value
json forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
CM.mapM forall {m}. Value -> Flow (AvroEnvironment m) (Term m)
encodeValue),
coderDecode :: Term m -> Flow (AvroEnvironment m) Value
coderDecode = forall {m}. Term m -> Flow (AvroEnvironment m) Value
decodeTerm}
TypeLiteral LiteralType
lit -> forall {f :: * -> *} {s1} {s2} {t1} {t2} {v1} {v2} {t2} {s1} {s2}
{v1} {v2}.
Applicative f =>
Adapter s1 s2 t1 t2 v1 v2
-> t2 -> Coder s1 s2 v1 v2 -> f (Adapter s1 s2 Schema t2 v1 v2)
forTypeAndCoder AvroHydraAdapter m
ad forall m. Type m
elTyp forall {m}.
Coder (AvroEnvironment m) (AvroEnvironment m) Value (Term m)
coder
where
coder :: Coder (AvroEnvironment m) (AvroEnvironment m) Value (Term m)
coder = Coder {
coderEncode :: Value -> Flow (AvroEnvironment m) (Term m)
coderEncode = forall {m}. Value -> Flow (AvroEnvironment m) (Term m)
encodeValue,
coderDecode :: Term m -> Flow (AvroEnvironment m) Value
coderDecode = forall {m}. Term m -> Flow (AvroEnvironment m) Value
decodeTerm}
Type m
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"unsupported type annotated as foreign key: " forall a. [a] -> [a] -> [a]
++ (forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall m. Type m -> TypeVariant
typeVariant forall a b. (a -> b) -> a -> b
$ forall s1 s2 t1 t2 v1 v2. Adapter s1 s2 t1 t2 v1 v2 -> t2
adapterTarget AvroHydraAdapter m
ad)
where
forTypeAndCoder :: Adapter s1 s2 t1 t2 v1 v2
-> t2 -> Coder s1 s2 v1 v2 -> f (Adapter s1 s2 Schema t2 v1 v2)
forTypeAndCoder Adapter s1 s2 t1 t2 v1 v2
ad t2
typ Coder s1 s2 v1 v2
coder = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall s1 s2 t1 t2 v1 v2.
Bool -> t1 -> t2 -> Coder s1 s2 v1 v2 -> Adapter s1 s2 t1 t2 v1 v2
Adapter (forall s1 s2 t1 t2 v1 v2. Adapter s1 s2 t1 t2 v1 v2 -> Bool
adapterIsLossy Adapter s1 s2 t1 t2 v1 v2
ad) (Field -> Schema
Avro.fieldType Field
f) t2
typ Coder s1 s2 v1 v2
coder
elTyp :: Type m
elTyp = forall m. Type m -> Type m
Types.element forall a b. (a -> b) -> a -> b
$ forall m. Name -> Type m
Types.nominal Name
name
forall (m :: * -> *) a. Monad m => a -> m a
return (Field -> String
Avro.fieldName Field
f, (Field
f, AvroHydraAdapter m
ad))
Avro.SchemaPrimitive Primitive
p -> case Primitive
p of
Primitive
Avro.PrimitiveNull -> forall {f :: * -> *} {t2} {v1} {s1} {v2} {s2}.
Applicative f =>
t2
-> (v1 -> Flow s1 v2)
-> (v2 -> Flow s2 v1)
-> f (Adapter s1 s2 Schema t2 v1 v2)
simpleAdapter forall m. Type m
Types.unit forall {f :: * -> *} {m}. Applicative f => Value -> f (Term m)
encode forall {m} {s}. Show m => Term m -> Flow s Value
decode
where
encode :: Value -> f (Term m)
encode (Json.ValueString String
s) = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall m. String -> Term m
Terms.string String
s
decode :: Term m -> Flow s Value
decode Term m
term = String -> Value
Json.ValueString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall m s. Show m => Term m -> Flow s String
Terms.expectString Term m
term
Primitive
Avro.PrimitiveBoolean -> forall {f :: * -> *} {t2} {v1} {s1} {v2} {s2}.
Applicative f =>
t2
-> (v1 -> Flow s1 v2)
-> (v2 -> Flow s2 v1)
-> f (Adapter s1 s2 Schema t2 v1 v2)
simpleAdapter forall m. Type m
Types.boolean forall {f :: * -> *} {m}. Applicative f => Value -> f (Term m)
encode forall {m} {s}. Show m => Term m -> Flow s Value
decode
where
encode :: Value -> f (Term m)
encode (Json.ValueBoolean Bool
b) = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall m. Bool -> Term m
Terms.boolean Bool
b
decode :: Term m -> Flow s Value
decode Term m
term = Bool -> Value
Json.ValueBoolean forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall m s. Show m => Term m -> Flow s Bool
Terms.expectBoolean Term m
term
Primitive
Avro.PrimitiveInt -> forall {f :: * -> *} {t2} {v1} {s1} {v2} {s2}.
Applicative f =>
t2
-> (v1 -> Flow s1 v2)
-> (v2 -> Flow s2 v1)
-> f (Adapter s1 s2 Schema t2 v1 v2)
simpleAdapter forall m. Type m
Types.int32 forall {f :: * -> *} {m}. Applicative f => Value -> f (Term m)
encode forall {m} {s}. Show m => Term m -> Flow s Value
decode
where
encode :: Value -> f (Term m)
encode (Json.ValueNumber Double
d) = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall m. Int -> Term m
Terms.int32 forall a b. (a -> b) -> a -> b
$ forall {a} {b}. (RealFrac a, Integral b) => a -> b
doubleToInt Double
d
decode :: Term m -> Flow s Value
decode Term m
term = Double -> Value
Json.ValueNumber forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall m s. Show m => Term m -> Flow s Int
Terms.expectInt32 Term m
term
Primitive
Avro.PrimitiveLong -> forall {f :: * -> *} {t2} {v1} {s1} {v2} {s2}.
Applicative f =>
t2
-> (v1 -> Flow s1 v2)
-> (v2 -> Flow s2 v1)
-> f (Adapter s1 s2 Schema t2 v1 v2)
simpleAdapter forall m. Type m
Types.int64 forall {f :: * -> *} {m}. Applicative f => Value -> f (Term m)
encode forall {m} {s}. Show m => Term m -> Flow s Value
decode
where
encode :: Value -> f (Term m)
encode (Json.ValueNumber Double
d) = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall m. Int64 -> Term m
Terms.int64 forall a b. (a -> b) -> a -> b
$ forall {a} {b}. (RealFrac a, Integral b) => a -> b
doubleToInt Double
d
decode :: Term m -> Flow s Value
decode Term m
term = Double -> Value
Json.ValueNumber forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall m s. Show m => Term m -> Flow s Integer
Terms.expectInt64 Term m
term
Primitive
Avro.PrimitiveFloat -> forall {f :: * -> *} {t2} {v1} {s1} {v2} {s2}.
Applicative f =>
t2
-> (v1 -> Flow s1 v2)
-> (v2 -> Flow s2 v1)
-> f (Adapter s1 s2 Schema t2 v1 v2)
simpleAdapter forall m. Type m
Types.float32 forall {f :: * -> *} {m}. Applicative f => Value -> f (Term m)
encode forall {m} {s}. Show m => Term m -> Flow s Value
decode
where
encode :: Value -> f (Term m)
encode (Json.ValueNumber Double
d) = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall m. Float -> Term m
Terms.float32 forall a b. (a -> b) -> a -> b
$ forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
d
decode :: Term m -> Flow s Value
decode Term m
term = Double -> Value
Json.ValueNumber forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Real a, Fractional b) => a -> b
realToFrac forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall m s. Show m => Term m -> Flow s Float
Terms.expectFloat32 Term m
term
Primitive
Avro.PrimitiveDouble -> forall {f :: * -> *} {t2} {v1} {s1} {v2} {s2}.
Applicative f =>
t2
-> (v1 -> Flow s1 v2)
-> (v2 -> Flow s2 v1)
-> f (Adapter s1 s2 Schema t2 v1 v2)
simpleAdapter forall m. Type m
Types.float64 forall {f :: * -> *} {m}. Applicative f => Value -> f (Term m)
encode forall {m} {s}. Show m => Term m -> Flow s Value
decode
where
encode :: Value -> f (Term m)
encode (Json.ValueNumber Double
d) = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall m. Double -> Term m
Terms.float64 Double
d
decode :: Term m -> Flow s Value
decode Term m
term = Double -> Value
Json.ValueNumber forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall m s. Show m => Term m -> Flow s Double
Terms.expectFloat64 Term m
term
Primitive
Avro.PrimitiveBytes -> forall {f :: * -> *} {t2} {v1} {s1} {v2} {s2}.
Applicative f =>
t2
-> (v1 -> Flow s1 v2)
-> (v2 -> Flow s2 v1)
-> f (Adapter s1 s2 Schema t2 v1 v2)
simpleAdapter forall m. Type m
Types.binary forall {f :: * -> *} {m}. Applicative f => Value -> f (Term m)
encode forall {m} {s}. Show m => Term m -> Flow s Value
decode
where
encode :: Value -> f (Term m)
encode (Json.ValueString String
s) = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall m. String -> Term m
Terms.binary String
s
decode :: Term m -> Flow s Value
decode Term m
term = String -> Value
Json.ValueString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall m s. Show m => Term m -> Flow s String
Terms.expectBinary Term m
term
Primitive
Avro.PrimitiveString -> forall {f :: * -> *} {t2} {v1} {s1} {v2} {s2}.
Applicative f =>
t2
-> (v1 -> Flow s1 v2)
-> (v2 -> Flow s2 v1)
-> f (Adapter s1 s2 Schema t2 v1 v2)
simpleAdapter forall m. Type m
Types.string forall {f :: * -> *} {m}. Applicative f => Value -> f (Term m)
encode forall {m} {s}. Show m => Term m -> Flow s Value
decode
where
encode :: Value -> f (Term m)
encode (Json.ValueString String
s) = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall m. String -> Term m
Terms.string String
s
decode :: Term m -> Flow s Value
decode Term m
term = String -> Value
Json.ValueString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall m s. Show m => Term m -> Flow s String
Terms.expectString Term m
term
where
doubleToInt :: a -> b
doubleToInt a
d = if a
d forall a. Ord a => a -> a -> Bool
< a
0 then forall a b. (RealFrac a, Integral b) => a -> b
ceiling a
d else forall a b. (RealFrac a, Integral b) => a -> b
floor a
d
Avro.SchemaReference String
name -> do
AvroEnvironment m
env <- forall s. Flow s s
getState
let qname :: AvroQualifiedName
qname = Maybe String -> String -> AvroQualifiedName
parseAvroName (forall m. AvroEnvironment m -> Maybe String
avroEnvironmentNamespace AvroEnvironment m
env) String
name
case forall m.
AvroQualifiedName
-> AvroEnvironment m -> Maybe (AvroHydraAdapter m)
getAvroHydraAdapter AvroQualifiedName
qname AvroEnvironment m
env of
Maybe (AvroHydraAdapter m)
Nothing -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"Referenced Avro type has not been defined: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show AvroQualifiedName
qname
forall a. [a] -> [a] -> [a]
++ String
". Defined types: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (forall k a. Map k a -> [k]
M.keys forall a b. (a -> b) -> a -> b
$ forall m.
AvroEnvironment m -> Map AvroQualifiedName (AvroHydraAdapter m)
avroEnvironmentNamedAdapters AvroEnvironment m
env)
Just AvroHydraAdapter m
ad -> forall (f :: * -> *) a. Applicative f => a -> f a
pure AvroHydraAdapter m
ad
Avro.SchemaUnion (Avro.Union [Schema]
schemas) -> if forall (t :: * -> *) a. Foldable t => t a -> Int
L.length [Schema]
nonNulls forall a. Ord a => a -> a -> Bool
> Int
1
then forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"general-purpose unions are not yet supported: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Schema
schema
else if forall (t :: * -> *) a. Foldable t => t a -> Bool
L.null [Schema]
nonNulls
then forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"cannot generate the empty type"
else if Bool
hasNull
then forall m.
(Ord m, Show m) =>
Schema -> Flow (AvroEnvironment m) (AvroHydraAdapter m)
forOptional forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
L.head [Schema]
nonNulls
else do
AvroHydraAdapter m
ad <- forall m.
(Ord m, Show m) =>
Schema -> Flow (AvroEnvironment m) (AvroHydraAdapter m)
avroHydraAdapter forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
L.head [Schema]
nonNulls
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s1 s2 t1 t2 v1 v2.
Bool -> t1 -> t2 -> Coder s1 s2 v1 v2 -> Adapter s1 s2 t1 t2 v1 v2
Adapter (forall s1 s2 t1 t2 v1 v2. Adapter s1 s2 t1 t2 v1 v2 -> Bool
adapterIsLossy AvroHydraAdapter m
ad) Schema
schema (forall s1 s2 t1 t2 v1 v2. Adapter s1 s2 t1 t2 v1 v2 -> t2
adapterTarget AvroHydraAdapter m
ad) (forall s1 s2 t1 t2 v1 v2.
Adapter s1 s2 t1 t2 v1 v2 -> Coder s1 s2 v1 v2
adapterCoder AvroHydraAdapter m
ad)
where
hasNull :: Bool
hasNull = (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> Bool
L.null forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
L.filter Schema -> Bool
isNull) [Schema]
schemas
nonNulls :: [Schema]
nonNulls = forall a. (a -> Bool) -> [a] -> [a]
L.filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Schema -> Bool
isNull) [Schema]
schemas
isNull :: Schema -> Bool
isNull Schema
schema = case Schema
schema of
Avro.SchemaPrimitive Primitive
Avro.PrimitiveNull -> Bool
True
Schema
_ -> Bool
False
forOptional :: Schema
-> Flow
(AvroEnvironment m)
(Adapter
(AvroEnvironment m)
(AvroEnvironment m)
Schema
(Type m)
Value
(Term m))
forOptional Schema
s = do
Adapter
(AvroEnvironment m)
(AvroEnvironment m)
Schema
(Type m)
Value
(Term m)
ad <- forall m.
(Ord m, Show m) =>
Schema -> Flow (AvroEnvironment m) (AvroHydraAdapter m)
avroHydraAdapter Schema
s
let coder :: Coder (AvroEnvironment m) (AvroEnvironment m) Value (Term m)
coder = Coder {
coderDecode :: Term m -> Flow (AvroEnvironment m) Value
coderDecode = \(TermOptional Maybe (Term m)
ot) -> case Maybe (Term m)
ot of
Maybe (Term m)
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Value
Json.ValueNull
Just Term m
term -> forall s1 s2 v1 v2. Coder s1 s2 v1 v2 -> v2 -> Flow s2 v1
coderDecode (forall s1 s2 t1 t2 v1 v2.
Adapter s1 s2 t1 t2 v1 v2 -> Coder s1 s2 v1 v2
adapterCoder Adapter
(AvroEnvironment m)
(AvroEnvironment m)
Schema
(Type m)
Value
(Term m)
ad) Term m
term,
coderEncode :: Value -> Flow (AvroEnvironment m) (Term m)
coderEncode = \Value
v -> case Value
v of
Value
Json.ValueNull -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall m. Maybe (Term m) -> Term m
TermOptional forall a. Maybe a
Nothing
Value
_ -> forall m. Maybe (Term m) -> Term m
TermOptional forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s1 s2 v1 v2. Coder s1 s2 v1 v2 -> v1 -> Flow s1 v2
coderEncode (forall s1 s2 t1 t2 v1 v2.
Adapter s1 s2 t1 t2 v1 v2 -> Coder s1 s2 v1 v2
adapterCoder Adapter
(AvroEnvironment m)
(AvroEnvironment m)
Schema
(Type m)
Value
(Term m)
ad) Value
v}
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s1 s2 t1 t2 v1 v2.
Bool -> t1 -> t2 -> Coder s1 s2 v1 v2 -> Adapter s1 s2 t1 t2 v1 v2
Adapter (forall s1 s2 t1 t2 v1 v2. Adapter s1 s2 t1 t2 v1 v2 -> Bool
adapterIsLossy Adapter
(AvroEnvironment m)
(AvroEnvironment m)
Schema
(Type m)
Value
(Term m)
ad) Schema
schema (forall m. Type m -> Type m
Types.optional forall a b. (a -> b) -> a -> b
$ forall s1 s2 t1 t2 v1 v2. Adapter s1 s2 t1 t2 v1 v2 -> t2
adapterTarget Adapter
(AvroEnvironment m)
(AvroEnvironment m)
Schema
(Type m)
Value
(Term m)
ad) Coder (AvroEnvironment m) (AvroEnvironment m) Value (Term m)
coder
where
simpleAdapter :: t2
-> (v1 -> Flow s1 v2)
-> (v2 -> Flow s2 v1)
-> f (Adapter s1 s2 Schema t2 v1 v2)
simpleAdapter t2
typ v1 -> Flow s1 v2
encode v2 -> Flow s2 v1
decode = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall s1 s2 t1 t2 v1 v2.
Bool -> t1 -> t2 -> Coder s1 s2 v1 v2 -> Adapter s1 s2 t1 t2 v1 v2
Adapter Bool
False Schema
schema t2
typ forall a b. (a -> b) -> a -> b
$ forall s1 s2 v1 v2.
(v1 -> Flow s1 v2) -> (v2 -> Flow s2 v1) -> Coder s1 s2 v1 v2
Coder v1 -> Flow s1 v2
encode v2 -> Flow s2 v1
decode
avroNameToHydraName :: AvroQualifiedName -> Name
avroNameToHydraName :: AvroQualifiedName -> Name
avroNameToHydraName (AvroQualifiedName Maybe String
mns String
local) = Namespace -> String -> Name
fromQname (String -> Namespace
Namespace forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a -> a
Y.fromMaybe String
"DEFAULT" Maybe String
mns) String
local
getAvroHydraAdapter :: AvroQualifiedName -> AvroEnvironment m -> Y.Maybe (AvroHydraAdapter m)
getAvroHydraAdapter :: forall m.
AvroQualifiedName
-> AvroEnvironment m -> Maybe (AvroHydraAdapter m)
getAvroHydraAdapter AvroQualifiedName
qname = forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup AvroQualifiedName
qname forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall m.
AvroEnvironment m -> Map AvroQualifiedName (AvroHydraAdapter m)
avroEnvironmentNamedAdapters
foreignKey :: Avro.Field -> Flow s (Maybe ForeignKey)
foreignKey :: forall s. Field -> Flow s (Maybe ForeignKey)
foreignKey Field
f = case forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup String
avro_foreignKey (Field -> Map String Value
Avro.fieldAnnotations Field
f) of
Maybe Value
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
Just Value
v -> do
Map String Value
m <- forall s. Value -> Flow s (Map String Value)
expectObject Value
v
Name
tname <- String -> Name
Name forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s. String -> Map String Value -> Flow s String
requireString String
"type" Map String Value
m
Maybe String
pattern <- forall s. String -> Map String Value -> Flow s (Maybe String)
optString String
"pattern" Map String Value
m
let constr :: String -> Name
constr = case Maybe String
pattern of
Maybe String
Nothing -> String -> Name
Name
Just String
pat -> String -> String -> Name
patternToNameConstructor String
pat
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Name -> (String -> Name) -> ForeignKey
ForeignKey Name
tname String -> Name
constr
patternToNameConstructor :: String -> String -> Name
patternToNameConstructor :: String -> String -> Name
patternToNameConstructor String
pat = \String
s -> String -> Name
Name forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [[a]] -> [a]
L.intercalate String
s forall a b. (a -> b) -> a -> b
$ String -> String -> [String]
Strings.splitOn String
"${}" String
pat
primaryKey :: Avro.Field -> Flow s (Maybe PrimaryKey)
primaryKey :: forall s. Field -> Flow s (Maybe PrimaryKey)
primaryKey Field
f = do
case forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup String
avro_primaryKey forall a b. (a -> b) -> a -> b
$ Field -> Map String Value
Avro.fieldAnnotations Field
f of
Maybe Value
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
Just Value
v -> do
String
s <- forall s. Value -> Flow s String
expectString Value
v
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ FieldName -> (String -> Name) -> PrimaryKey
PrimaryKey (String -> FieldName
FieldName forall a b. (a -> b) -> a -> b
$ Field -> String
Avro.fieldName Field
f) forall a b. (a -> b) -> a -> b
$ String -> String -> Name
patternToNameConstructor String
s
parseAvroName :: Maybe String -> String -> AvroQualifiedName
parseAvroName :: Maybe String -> String -> AvroQualifiedName
parseAvroName Maybe String
mns String
name = case forall a. [a] -> [a]
L.reverse forall a b. (a -> b) -> a -> b
$ String -> String -> [String]
Strings.splitOn String
"." String
name of
[String
local] -> Maybe String -> String -> AvroQualifiedName
AvroQualifiedName Maybe String
mns String
local
(String
local:[String]
rest) -> Maybe String -> String -> AvroQualifiedName
AvroQualifiedName (forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [[a]] -> [a]
L.intercalate String
"." forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
L.reverse [String]
rest) String
local
putAvroHydraAdapter :: AvroQualifiedName -> AvroHydraAdapter m -> AvroEnvironment m -> AvroEnvironment m
putAvroHydraAdapter :: forall m.
AvroQualifiedName
-> AvroHydraAdapter m -> AvroEnvironment m -> AvroEnvironment m
putAvroHydraAdapter AvroQualifiedName
qname AvroHydraAdapter m
ad AvroEnvironment m
env = AvroEnvironment m
env {avroEnvironmentNamedAdapters :: Map AvroQualifiedName (AvroHydraAdapter m)
avroEnvironmentNamedAdapters = forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert AvroQualifiedName
qname AvroHydraAdapter m
ad forall a b. (a -> b) -> a -> b
$ forall m.
AvroEnvironment m -> Map AvroQualifiedName (AvroHydraAdapter m)
avroEnvironmentNamedAdapters AvroEnvironment m
env}
rewriteAvroSchemaM :: ((Avro.Schema -> Flow s Avro.Schema) -> Avro.Schema -> Flow s Avro.Schema) -> Avro.Schema -> Flow s Avro.Schema
rewriteAvroSchemaM :: forall s.
((Schema -> Flow s Schema) -> Schema -> Flow s Schema)
-> Schema -> Flow s Schema
rewriteAvroSchemaM (Schema -> Flow s Schema) -> Schema -> Flow s Schema
f = forall a b. ((a -> b) -> a -> b) -> ((a -> b) -> a -> b) -> a -> b
rewrite forall {f :: * -> *}.
Monad f =>
(Schema -> f Schema) -> Schema -> f Schema
fsub (Schema -> Flow s Schema) -> Schema -> Flow s Schema
f
where
fsub :: (Schema -> f Schema) -> Schema -> f Schema
fsub Schema -> f Schema
recurse Schema
schema = case Schema
schema of
Avro.SchemaArray (Avro.Array Schema
els) -> Array -> Schema
Avro.SchemaArray forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Schema -> Array
Avro.Array forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Schema -> f Schema
recurse Schema
els)
Avro.SchemaMap (Avro.Map_ Schema
vschema) -> Map_ -> Schema
Avro.SchemaMap forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Schema -> Map_
Avro.Map_ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Schema -> f Schema
recurse Schema
vschema)
Avro.SchemaNamed Named
n -> do
NamedType
nt <- case Named -> NamedType
Avro.namedType Named
n of
Avro.NamedTypeRecord (Avro.Record [Field]
fields) -> Record -> NamedType
Avro.NamedTypeRecord forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ([Field] -> Record
Avro.Record forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
CM.mapM Field -> f Field
forField [Field]
fields))
NamedType
t -> forall (f :: * -> *) a. Applicative f => a -> f a
pure NamedType
t
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Named -> Schema
Avro.SchemaNamed forall a b. (a -> b) -> a -> b
$ Named
n {namedType :: NamedType
Avro.namedType = NamedType
nt}
Avro.SchemaUnion (Avro.Union [Schema]
schemas) -> Union -> Schema
Avro.SchemaUnion forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ([Schema] -> Union
Avro.Union forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
CM.mapM Schema -> f Schema
recurse [Schema]
schemas))
Schema
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Schema
schema
where
forField :: Field -> f Field
forField Field
f = do
Schema
t <- Schema -> f Schema
recurse forall a b. (a -> b) -> a -> b
$ Field -> Schema
Avro.fieldType Field
f
forall (m :: * -> *) a. Monad m => a -> m a
return Field
f {fieldType :: Schema
Avro.fieldType = Schema
t}
jsonToString :: Json.Value -> Flow s String
jsonToString :: forall s. Value -> Flow s String
jsonToString Value
v = case Value
v of
Json.ValueBoolean Bool
b -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ if Bool
b then String
"true" else String
"false"
Json.ValueString String
s -> forall (f :: * -> *) a. Applicative f => a -> f a
pure String
s
Json.ValueNumber Double
d -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ if forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a b. (RealFrac a, Integral b) => a -> b
round Double
d) forall a. Eq a => a -> a -> Bool
== Double
d
then forall a. Show a => a -> String
show (forall a b. (RealFrac a, Integral b) => a -> b
round Double
d)
else forall a. Show a => a -> String
show Double
d
Value
_ -> forall (m :: * -> *) a1 a2.
(MonadFail m, Show a1) =>
String -> a1 -> m a2
unexpected String
"string, number, or boolean" Value
v
showQname :: AvroQualifiedName -> String
showQname :: AvroQualifiedName -> String
showQname (AvroQualifiedName Maybe String
mns String
local) = (forall b a. b -> (a -> b) -> Maybe a -> b
Y.maybe String
"" (\String
ns -> String
ns forall a. [a] -> [a] -> [a]
++ String
".") Maybe String
mns) forall a. [a] -> [a] -> [a]
++ String
local
stringToTerm :: Show m => Type m -> String -> Flow s (Term m)
stringToTerm :: forall m s. Show m => Type m -> String -> Flow s (Term m)
stringToTerm Type m
typ String
s = case forall m. Type m -> Type m
stripType Type m
typ of
TypeLiteral LiteralType
lt -> forall m. Literal -> Term m
TermLiteral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> case LiteralType
lt of
LiteralType
LiteralTypeBoolean -> Bool -> Literal
LiteralBoolean forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {a} {m :: * -> *}. (Read a, MonadFail m) => String -> m a
doRead String
s
LiteralTypeInteger IntegerType
it -> IntegerValue -> Literal
LiteralInteger forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> case IntegerType
it of
IntegerType
IntegerTypeBigint -> Integer -> IntegerValue
IntegerValueBigint forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {a} {m :: * -> *}. (Read a, MonadFail m) => String -> m a
doRead String
s
IntegerType
IntegerTypeInt8 -> Int -> IntegerValue
IntegerValueInt8 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {a} {m :: * -> *}. (Read a, MonadFail m) => String -> m a
doRead String
s
IntegerType
IntegerTypeInt16 -> Int -> IntegerValue
IntegerValueInt16 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {a} {m :: * -> *}. (Read a, MonadFail m) => String -> m a
doRead String
s
IntegerType
IntegerTypeInt32 -> Int -> IntegerValue
IntegerValueInt32 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {a} {m :: * -> *}. (Read a, MonadFail m) => String -> m a
doRead String
s
IntegerType
IntegerTypeInt64 -> Integer -> IntegerValue
IntegerValueInt64 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {a} {m :: * -> *}. (Read a, MonadFail m) => String -> m a
doRead String
s
IntegerType
IntegerTypeUint8 -> Int -> IntegerValue
IntegerValueUint8 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {a} {m :: * -> *}. (Read a, MonadFail m) => String -> m a
doRead String
s
IntegerType
IntegerTypeUint16 -> Int -> IntegerValue
IntegerValueUint16 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {a} {m :: * -> *}. (Read a, MonadFail m) => String -> m a
doRead String
s
IntegerType
IntegerTypeUint32 -> Integer -> IntegerValue
IntegerValueUint32 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {a} {m :: * -> *}. (Read a, MonadFail m) => String -> m a
doRead String
s
IntegerType
IntegerTypeUint64 -> Integer -> IntegerValue
IntegerValueUint64 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {a} {m :: * -> *}. (Read a, MonadFail m) => String -> m a
doRead String
s
LiteralType
LiteralTypeString -> String -> Literal
LiteralString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (f :: * -> *) a. Applicative f => a -> f a
pure String
s
LiteralType
_ -> forall (m :: * -> *) a1 a2.
(MonadFail m, Show a1) =>
String -> a1 -> m a2
unexpected String
"literal type" LiteralType
lt
where
doRead :: String -> m a
doRead String
s = case forall a. Read a => String -> Either String a
TR.readEither String
s of
Left String
msg -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"failed to read value: " forall a. [a] -> [a] -> [a]
++ String
msg
Right a
term -> forall (f :: * -> *) a. Applicative f => a -> f a
pure a
term
termToString :: Show m => Term m -> Flow s String
termToString :: forall m s. Show m => Term m -> Flow s String
termToString Term m
term = case forall m. Term m -> Term m
stripTerm Term m
term of
TermLiteral Literal
l -> case Literal
l of
LiteralBoolean Bool
b -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Bool
b
LiteralInteger IntegerValue
iv -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ case IntegerValue
iv of
IntegerValueBigint Integer
i -> forall a. Show a => a -> String
show Integer
i
IntegerValueInt8 Int
i -> forall a. Show a => a -> String
show Int
i
IntegerValueInt16 Int
i -> forall a. Show a => a -> String
show Int
i
IntegerValueInt32 Int
i -> forall a. Show a => a -> String
show Int
i
IntegerValueInt64 Integer
i -> forall a. Show a => a -> String
show Integer
i
IntegerValueUint8 Int
i -> forall a. Show a => a -> String
show Int
i
IntegerValueUint16 Int
i -> forall a. Show a => a -> String
show Int
i
IntegerValueUint32 Integer
i -> forall a. Show a => a -> String
show Integer
i
IntegerValueUint64 Integer
i -> forall a. Show a => a -> String
show Integer
i
LiteralString String
s -> forall (f :: * -> *) a. Applicative f => a -> f a
pure String
s
Literal
_ -> forall (m :: * -> *) a1 a2.
(MonadFail m, Show a1) =>
String -> a1 -> m a2
unexpected String
"boolean, integer, or string" Literal
l
TermOptional (Just Term m
term') -> forall m s. Show m => Term m -> Flow s String
termToString Term m
term'
Term m
_ -> forall (m :: * -> *) a1 a2.
(MonadFail m, Show a1) =>
String -> a1 -> m a2
unexpected String
"literal value" Term m
term