Skip to content

Commit

Permalink
Added basic support for Point types in DataSync
Browse files Browse the repository at this point in the history
  • Loading branch information
mpscholten committed Feb 4, 2022
1 parent df18327 commit 1c38e4a
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 1 deletion.
3 changes: 3 additions & 0 deletions IHP/DataSync/DynamicQuery.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ data DynamicValue
| BoolValue !Bool
| UUIDValue !UUID
| DateTimeValue !UTCTime
| PointValue !Point
| Null
deriving (Show, Eq)

Expand Down Expand Up @@ -84,6 +85,7 @@ instance {-# OVERLAPS #-} ToJSON [Field] where
fieldValueToJSON (BoolValue value) = toJSON value
fieldValueToJSON (UUIDValue value) = toJSON value
fieldValueToJSON (DateTimeValue value) = toJSON value
fieldValueToJSON (PointValue value) = toJSON value
fieldValueToJSON IHP.DataSync.DynamicQuery.Null = toJSON Data.Aeson.Null

instance PG.FromField Field where
Expand All @@ -101,6 +103,7 @@ instance PG.FromField Field where
<|> (UUIDValue <$> PG.fromField field fieldValue')
<|> (DoubleValue <$> PG.fromField field fieldValue')
<|> (DateTimeValue <$> PG.fromField field fieldValue')
<|> (PointValue <$> PG.fromField field fieldValue')
<|> (PG.fromField @PG.Null field fieldValue' >> pure IHP.DataSync.DynamicQuery.Null)
<|> fromFieldCustomEnum field fieldValue'

Expand Down
1 change: 1 addition & 0 deletions IHP/DataSync/DynamicQueryCompiler.hs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ compileCondition (LiteralExpression literal) = ("?", [toValue literal])
toValue (BoolValue bool) = PG.toField bool
toValue (UUIDValue uuid) = PG.toField uuid
toValue (DateTimeValue utcTime) = PG.toField utcTime
toValue (PointValue point) = PG.toField point
toValue Null = PG.toField PG.Null

compileOperator :: ConditionOperator -> PG.Query
Expand Down
20 changes: 19 additions & 1 deletion IHP/DataSync/REST/Controller.hs
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,22 @@ aesonValueToPostgresValue (Number value) = case Scientific.floatingOrInteger val
Left (floating :: Double) -> PG.toField floating
Right (integer :: Integer) -> PG.toField integer
aesonValueToPostgresValue Data.Aeson.Null = PG.toField PG.Null
aesonValueToPostgresValue object@(Object values) = PG.toField (toJSON object)
aesonValueToPostgresValue object@(Object values) =
let
tryDecodeAsPoint :: Maybe Point
tryDecodeAsPoint = do
xValue <- HashMap.lookup "x" values
yValue <- HashMap.lookup "y" values
x <- case xValue of
Number number -> pure (Scientific.toRealFloat number)
otherwise -> Nothing
y <- case yValue of
Number number -> pure (Scientific.toRealFloat number)
otherwise -> Nothing
pure Point { x, y }
in
-- This is really hacky and is mostly duck typing. We should refactor this in the future to
-- become more type aware by passing the DDL of the table to 'aesonValueToPostgresValue'.
if HashMap.size values == 2
then fromMaybe (PG.toField $ toJSON object) (PG.toField <$> tryDecodeAsPoint)
else PG.toField (toJSON object)
10 changes: 10 additions & 0 deletions IHP/Postgres/Point.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Database.PostgreSQL.Simple.TypeInfo.Macro as TI
import Data.ByteString.Builder (byteString, char8)
import Data.Attoparsec.ByteString.Char8 hiding (Result, char8, Parser(..))
import Data.Attoparsec.Internal.Types (Parser)
import Data.Aeson

-- | Represents a Postgres Point
--
Expand Down Expand Up @@ -59,3 +60,12 @@ serializePoint Point { x, y } = Many
, toField y
, Plain (char8 ')')
]


instance FromJSON Point where
parseJSON = withObject "Point" $ \v -> Point
<$> v .: "x"
<*> v .: "y"

instance ToJSON Point where
toJSON Point { x, y } = object [ "x" .= x, "y" .= y ]

0 comments on commit 1c38e4a

Please sign in to comment.