{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Database.Bolt.Extras.Internal.Cypher
(
ToCypher (..)
) where
import Data.Text as T (Text, concat, cons,
intercalate, pack,
replace, toUpper)
import Database.Bolt (Value (..))
import Database.Bolt.Extras.Internal.Types (Label, Property)
import Database.Bolt.Extras.Utils (currentLoc)
import NeatInterpolation (text)
class ToCypher a where
toCypher :: a -> Text
instance ToCypher Value where
toCypher :: Value -> Text
toCypher (N ()) = Text
""
toCypher (B Bool
bool) = Text -> Text
toUpper (Text -> Text) -> (Bool -> Text) -> Bool -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack (String -> Text) -> (Bool -> String) -> Bool -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> String
forall a. Show a => a -> String
show (Bool -> Text) -> Bool -> Text
forall a b. (a -> b) -> a -> b
$ Bool
bool
toCypher (I Int
int) = String -> Text
pack (String -> Text) -> (Int -> String) -> Int -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String
forall a. Show a => a -> String
show (Int -> Text) -> Int -> Text
forall a b. (a -> b) -> a -> b
$ Int
int
toCypher (F Double
double) = String -> Text
pack (String -> Text) -> (Double -> String) -> Double -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> String
forall a. Show a => a -> String
show (Double -> Text) -> Double -> Text
forall a b. (a -> b) -> a -> b
$ Double
double
toCypher (T Text
t) = Text
"\"" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
escapeSpecSymbols Text
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\""
toCypher (L [Value]
values) = let cvalues :: Text
cvalues = Text -> [Text] -> Text
T.intercalate Text
"," ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ (Value -> Text) -> [Value] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Value -> Text
forall a. ToCypher a => a -> Text
toCypher [Value]
values
in [text|[$cvalues]|]
toCypher Value
_ = String -> Text
forall a. HasCallStack => String -> a
error (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ String
$currentLoc String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"unacceptable Value type"
escapeSpecSymbols :: Text -> Text
escapeSpecSymbols :: Text -> Text
escapeSpecSymbols = Text -> Text -> Text -> Text
replace Text
"\"" Text
"\\\"" (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> Text -> Text
replace Text
"\\" Text
"\\\\"
instance ToCypher Label where
toCypher :: Text -> Text
toCypher = Char -> Text -> Text
cons Char
':'
instance ToCypher [Label] where
toCypher :: [Text] -> Text
toCypher = [Text] -> Text
T.concat ([Text] -> Text) -> ([Text] -> [Text]) -> [Text] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Text
forall a. ToCypher a => a -> Text
toCypher
instance ToCypher Property where
toCypher :: Property -> Text
toCypher (Text
propTitle, Value
value) = [Text] -> Text
T.concat [Text
propTitle, String -> Text
pack String
":", Value -> Text
forall a. ToCypher a => a -> Text
toCypher Value
value]
instance ToCypher (Text, Text) where
toCypher :: (Text, Text) -> Text
toCypher (Text
propTitle, Text
param) = Text
propTitle Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
":$" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
param
instance ToCypher [Property] where
toCypher :: [Property] -> Text
toCypher = Text -> [Text] -> Text
T.intercalate Text
"," ([Text] -> Text) -> ([Property] -> [Text]) -> [Property] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Property -> Text) -> [Property] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Property -> Text
forall a. ToCypher a => a -> Text
toCypher
instance ToCypher [(Text, Text)] where
toCypher :: [(Text, Text)] -> Text
toCypher = Text -> [Text] -> Text
T.intercalate Text
"," ([Text] -> Text)
-> ([(Text, Text)] -> [Text]) -> [(Text, Text)] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Text, Text) -> Text) -> [(Text, Text)] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Text, Text) -> Text
forall a. ToCypher a => a -> Text
toCypher