From 6e0c329b5dd33597f5dd0ecbd51e3bbd0dc322e8 Mon Sep 17 00:00:00 2001 From: Marc Scholten Date: Mon, 1 May 2023 16:03:26 +0200 Subject: [PATCH] Extracted IHP.Postgres.* into it's own ihp-postgresql-simple-extra module This helps speed up compile time for IHP builds --- .../ihp-postgresql-simple-extra.nix | 20 ++++ devenv.nix | 1 + .../IHP}/Postgres/Inet.hs | 4 +- .../IHP}/Postgres/Interval.hs | 4 +- .../IHP}/Postgres/Point.hs | 0 .../IHP}/Postgres/Polygon.hs | 1 - .../IHP}/Postgres/TSVector.hs | 6 +- .../IHP}/Postgres/TimeParser.hs | 13 +-- .../IHP}/Postgres/TypeInfo.hs | 0 ihp-postgresql-simple-extra/LICENSE | 21 +++++ ihp-postgresql-simple-extra/README.md | 9 ++ .../Test}/Postgres/Interval.hs | 2 - .../Test}/Postgres/Point.hs | 4 +- .../Test}/Postgres/Polygon.hs | 5 +- .../Test}/Postgres/Support.hs | 2 +- .../Test}/Postgres/TSVector.hs | 2 +- ihp-postgresql-simple-extra/Test/Spec.hs | 16 ++++ .../ihp-postgresql-simple-extra.cabal | 93 +++++++++++++++++++ ihp.cabal | 9 +- ihp.nix | 4 +- lib/IHP/applicationGhciConfig | 1 + 21 files changed, 180 insertions(+), 37 deletions(-) create mode 100644 NixSupport/haskell-packages/ihp-postgresql-simple-extra.nix rename {IHP => ihp-postgresql-simple-extra/IHP}/Postgres/Inet.hs (93%) rename {IHP => ihp-postgresql-simple-extra/IHP}/Postgres/Interval.hs (91%) rename {IHP => ihp-postgresql-simple-extra/IHP}/Postgres/Point.hs (100%) rename {IHP => ihp-postgresql-simple-extra/IHP}/Postgres/Polygon.hs (99%) rename {IHP => ihp-postgresql-simple-extra/IHP}/Postgres/TSVector.hs (93%) rename {IHP => ihp-postgresql-simple-extra/IHP}/Postgres/TimeParser.hs (90%) rename {IHP => ihp-postgresql-simple-extra/IHP}/Postgres/TypeInfo.hs (100%) create mode 100644 ihp-postgresql-simple-extra/LICENSE create mode 100644 ihp-postgresql-simple-extra/README.md rename {Test => ihp-postgresql-simple-extra/Test}/Postgres/Interval.hs (94%) rename {Test => ihp-postgresql-simple-extra/Test}/Postgres/Point.hs (93%) rename {Test => ihp-postgresql-simple-extra/Test}/Postgres/Polygon.hs (93%) rename {Test => ihp-postgresql-simple-extra/Test}/Postgres/Support.hs (95%) rename {Test => ihp-postgresql-simple-extra/Test}/Postgres/TSVector.hs (99%) create mode 100644 ihp-postgresql-simple-extra/Test/Spec.hs create mode 100644 ihp-postgresql-simple-extra/ihp-postgresql-simple-extra.cabal diff --git a/NixSupport/haskell-packages/ihp-postgresql-simple-extra.nix b/NixSupport/haskell-packages/ihp-postgresql-simple-extra.nix new file mode 100644 index 000000000..ecb5f3abf --- /dev/null +++ b/NixSupport/haskell-packages/ihp-postgresql-simple-extra.nix @@ -0,0 +1,20 @@ +{ mkDerivation, aeson, attoparsec, base, basic-prelude, bytestring +, hspec, hspec-discover, ip, lib, postgresql-simple, text, time +, time-compat +}: +mkDerivation { + pname = "ihp-postgresql-simple-extra"; + version = "1.0.1"; + src = ./../../ihp-postgresql-simple-extra; + libraryHaskellDepends = [ + aeson attoparsec base basic-prelude bytestring ip postgresql-simple + text time time-compat + ]; + testHaskellDepends = [ + aeson attoparsec base basic-prelude bytestring hspec hspec-discover + ip postgresql-simple text time time-compat + ]; + testToolDepends = [ hspec-discover ]; + description = "Extra data types for postgresql-simple"; + license = lib.licenses.mit; +} \ No newline at end of file diff --git a/devenv.nix b/devenv.nix index 26247f516..1a4a6f31a 100644 --- a/devenv.nix +++ b/devenv.nix @@ -77,6 +77,7 @@ mmark-cli hspec ihp-hsx + ihp-postgresql-simple-extra ]); scripts.tests.exec = '' diff --git a/IHP/Postgres/Inet.hs b/ihp-postgresql-simple-extra/IHP/Postgres/Inet.hs similarity index 93% rename from IHP/Postgres/Inet.hs rename to ihp-postgresql-simple-extra/IHP/Postgres/Inet.hs index 723da2a08..8c91094e7 100644 --- a/IHP/Postgres/Inet.hs +++ b/ihp-postgresql-simple-extra/IHP/Postgres/Inet.hs @@ -13,11 +13,11 @@ import Database.PostgreSQL.Simple.FromField import qualified Database.PostgreSQL.Simple.TypeInfo.Static as TI import Database.PostgreSQL.Simple.TypeInfo.Macro as TI import Data.Attoparsec.ByteString.Char8 as Attoparsec -import Data.String.Conversions (cs) -- We use the @ip@ package for representing IP addresses import qualified Net.IP as IP import Net.IP (IP) +import qualified Data.Text.Encoding as Text instance FromField IP where fromField f v = @@ -32,7 +32,7 @@ instance FromField IP where where parser = do ip <- Attoparsec.takeWhile (\char -> char /= ' ') - case IP.decode (cs ip) of + case IP.decode (Text.decodeUtf8 ip) of Just ip -> pure ip Nothing -> fail "Invalid IP" diff --git a/IHP/Postgres/Interval.hs b/ihp-postgresql-simple-extra/IHP/Postgres/Interval.hs similarity index 91% rename from IHP/Postgres/Interval.hs rename to ihp-postgresql-simple-extra/IHP/Postgres/Interval.hs index 57ff3401f..9f674564e 100644 --- a/IHP/Postgres/Interval.hs +++ b/ihp-postgresql-simple-extra/IHP/Postgres/Interval.hs @@ -13,10 +13,10 @@ import Database.PostgreSQL.Simple.FromField import qualified Database.PostgreSQL.Simple.TypeInfo.Static as TI import Database.PostgreSQL.Simple.TypeInfo.Macro as TI import Data.Attoparsec.ByteString.Char8 as Attoparsec -import Data.String.Conversions (cs) import Data.Aeson import IHP.Postgres.TimeParser (PGInterval(..)) +import qualified Data.Text.Encoding as Text instance FromField PGInterval where fromField f v = @@ -39,4 +39,4 @@ instance FromJSON PGInterval where parseJSON = withText "PGInterval" $ \text -> pure (PGInterval (encodeUtf8 text)) instance ToJSON PGInterval where - toJSON (PGInterval pgInterval) = String (cs pgInterval) + toJSON (PGInterval pgInterval) = String (Text.decodeUtf8 pgInterval) diff --git a/IHP/Postgres/Point.hs b/ihp-postgresql-simple-extra/IHP/Postgres/Point.hs similarity index 100% rename from IHP/Postgres/Point.hs rename to ihp-postgresql-simple-extra/IHP/Postgres/Point.hs diff --git a/IHP/Postgres/Polygon.hs b/ihp-postgresql-simple-extra/IHP/Postgres/Polygon.hs similarity index 99% rename from IHP/Postgres/Polygon.hs rename to ihp-postgresql-simple-extra/IHP/Postgres/Polygon.hs index 4e334aadf..07696e583 100644 --- a/IHP/Postgres/Polygon.hs +++ b/ihp-postgresql-simple-extra/IHP/Postgres/Polygon.hs @@ -6,7 +6,6 @@ Copyright: (c) digitally induced GmbH, 2022 -} module IHP.Postgres.Polygon where -import GHC.Float import BasicPrelude import Database.PostgreSQL.Simple.ToField diff --git a/IHP/Postgres/TSVector.hs b/ihp-postgresql-simple-extra/IHP/Postgres/TSVector.hs similarity index 93% rename from IHP/Postgres/TSVector.hs rename to ihp-postgresql-simple-extra/IHP/Postgres/TSVector.hs index 8adc5dfed..a4c84f6d4 100644 --- a/IHP/Postgres/TSVector.hs +++ b/ihp-postgresql-simple-extra/IHP/Postgres/TSVector.hs @@ -7,7 +7,6 @@ Copyright: (c) digitally induced GmbH, 2021 module IHP.Postgres.TSVector where import BasicPrelude -import Data.String.Conversions (cs) import IHP.Postgres.TypeInfo import Database.PostgreSQL.Simple.ToField import Database.PostgreSQL.Simple.FromField @@ -15,6 +14,7 @@ import Database.PostgreSQL.Simple.TypeInfo.Macro import Data.Attoparsec.ByteString.Char8 as Attoparsec hiding (Parser(..)) import Data.Attoparsec.Internal.Types (Parser) import Data.ByteString.Builder (byteString, charUtf8) +import qualified Data.Text.Encoding as Text -- | Represents a Postgres tsvector -- @@ -63,7 +63,7 @@ parseTSVector = TSVector <$> many' parseLexeme weight <- option 'D' $ choice [char 'A', char 'B', char 'C', char 'D'] pure $ LexemeRanking { position = truncate position, weight } - pure $ Lexeme { token = cs token, ranking } + pure $ Lexeme { token = Text.decodeUtf8 token, ranking } instance ToField TSVector where @@ -73,7 +73,7 @@ serializeTSVector :: TSVector -> Action serializeTSVector (TSVector lexemes) = Many $ map serializeLexeme lexemes where serializeLexeme Lexeme { token, ranking } = Many - [ Plain $ byteString $ cs token + [ Plain $ byteString $ Text.encodeUtf8 token , toField ':' , Many $ intersperse (toField ',') (map serializeLexemeRanking ranking) ] diff --git a/IHP/Postgres/TimeParser.hs b/ihp-postgresql-simple-extra/IHP/Postgres/TimeParser.hs similarity index 90% rename from IHP/Postgres/TimeParser.hs rename to ihp-postgresql-simple-extra/IHP/Postgres/TimeParser.hs index ba7c8a296..a9328f960 100644 --- a/IHP/Postgres/TimeParser.hs +++ b/ihp-postgresql-simple-extra/IHP/Postgres/TimeParser.hs @@ -3,20 +3,11 @@ module IHP.Postgres.TimeParser where import BasicPrelude hiding (takeWhile) import Data.Attoparsec.ByteString.Char8 -import Data.Attoparsec.Combinator import Data.Bits ((.&.)) -import Data.ByteString (ByteString) import Data.Char (ord) -import Control.Applicative ((<|>)) import Data.Fixed (Pico, Fixed(MkFixed)) -import Data.Int (Int64) -import Data.Maybe (fromMaybe) -import Data.Time.Calendar.Compat (Day, fromGregorianValid, addDays) -import Data.Time.Clock.Compat (UTCTime(..), NominalDiffTime) -import Data.Time.Format.ISO8601.Compat (iso8601ParseM) -import Data.Time.LocalTime.Compat (CalendarDiffTime) -import Data.String.Conversions (cs) +import Data.Time.Clock.Compat (NominalDiffTime) import qualified Data.ByteString.Char8 as B8 import qualified Data.Time.LocalTime.Compat as Local @@ -49,7 +40,7 @@ data PGTimeInterval = PGTimeInterval { pgYears :: !Integer unpackInterval :: PGInterval -> PGTimeInterval unpackInterval (PGInterval bs) = case parseOnly pPGInterval bs of - Left err -> error ("Couldn't parse PGInterval. " <> cs err) + Left err -> error ("Couldn't parse PGInterval. " <> err) Right val -> val diff --git a/IHP/Postgres/TypeInfo.hs b/ihp-postgresql-simple-extra/IHP/Postgres/TypeInfo.hs similarity index 100% rename from IHP/Postgres/TypeInfo.hs rename to ihp-postgresql-simple-extra/IHP/Postgres/TypeInfo.hs diff --git a/ihp-postgresql-simple-extra/LICENSE b/ihp-postgresql-simple-extra/LICENSE new file mode 100644 index 000000000..098a3a608 --- /dev/null +++ b/ihp-postgresql-simple-extra/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 digitally induced GmbH + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/ihp-postgresql-simple-extra/README.md b/ihp-postgresql-simple-extra/README.md new file mode 100644 index 000000000..30c0a6bbc --- /dev/null +++ b/ihp-postgresql-simple-extra/README.md @@ -0,0 +1,9 @@ +# ihp-postgres-simple-extra + +This package is included by default in IHP apps and implements support for postgres data types that are not supported by the `postgresql-simple` package by default: + +- `INET` +- `INTERVAL` +- `POINT` +- `POLYGON` +- `TSVECTOR` \ No newline at end of file diff --git a/Test/Postgres/Interval.hs b/ihp-postgresql-simple-extra/Test/Postgres/Interval.hs similarity index 94% rename from Test/Postgres/Interval.hs rename to ihp-postgresql-simple-extra/Test/Postgres/Interval.hs index cff70d627..36255cb92 100644 --- a/Test/Postgres/Interval.hs +++ b/ihp-postgresql-simple-extra/Test/Postgres/Interval.hs @@ -5,8 +5,6 @@ Copyright: (c) digitally induced GmbH, 2023 module Test.Postgres.Interval where import Test.Hspec -import Test.Postgres.Support -import IHP.Prelude import IHP.Postgres.Interval import IHP.Postgres.TimeParser import Database.PostgreSQL.Simple.ToField diff --git a/Test/Postgres/Point.hs b/ihp-postgresql-simple-extra/Test/Postgres/Point.hs similarity index 93% rename from Test/Postgres/Point.hs rename to ihp-postgresql-simple-extra/Test/Postgres/Point.hs index d740fb57a..c0fc8a042 100644 --- a/Test/Postgres/Point.hs +++ b/ihp-postgresql-simple-extra/Test/Postgres/Point.hs @@ -4,9 +4,9 @@ Copyright: (c) digitally induced GmbH, 2021 -} module Test.Postgres.Point where +import Data.Either import Test.Hspec -import Test.Postgres.Support -import IHP.Prelude +import Test.Postgres.Support () import IHP.Postgres.Point import Database.PostgreSQL.Simple.ToField import qualified Data.Attoparsec.ByteString.Char8 as Attoparsec diff --git a/Test/Postgres/Polygon.hs b/ihp-postgresql-simple-extra/Test/Postgres/Polygon.hs similarity index 93% rename from Test/Postgres/Polygon.hs rename to ihp-postgresql-simple-extra/Test/Postgres/Polygon.hs index e2f71ba98..51117fc53 100644 --- a/Test/Postgres/Polygon.hs +++ b/ihp-postgresql-simple-extra/Test/Postgres/Polygon.hs @@ -4,9 +4,10 @@ Copyright: (c) digitally induced GmbH, 2022 -} module Test.Postgres.Polygon where +import CorePrelude +import Data.Either import Test.Hspec import Test.Postgres.Support -import IHP.Prelude import IHP.Postgres.Point import IHP.Postgres.Polygon import Database.PostgreSQL.Simple.ToField @@ -17,7 +18,7 @@ tests = do let parsedPoint1 = Point { x = 100, y = 200 } let rawPoint2 = "(300,400)" let parsedPoint2 = Point { x = 300, y = 400 } - let raw = "(" ++ rawPoint1 ++ "," ++ rawPoint2 ++ ")" + let raw = "(" <> rawPoint1 <> "," <> rawPoint2 <> ")" let parsed = Polygon { points = [ parsedPoint1, parsedPoint2 ] } let serialized = Many [ Plain "polygon'" diff --git a/Test/Postgres/Support.hs b/ihp-postgresql-simple-extra/Test/Postgres/Support.hs similarity index 95% rename from Test/Postgres/Support.hs rename to ihp-postgresql-simple-extra/Test/Postgres/Support.hs index 138d15ab9..b660b29d9 100644 --- a/Test/Postgres/Support.hs +++ b/ihp-postgresql-simple-extra/Test/Postgres/Support.hs @@ -4,7 +4,7 @@ Copyright: (c) digitally induced GmbH, 2021 -} module Test.Postgres.Support where -import IHP.Prelude +import Prelude import Data.ByteString.Builder (toLazyByteString) import Database.PostgreSQL.Simple.ToField import qualified Data.ByteString.Builder as Builder diff --git a/Test/Postgres/TSVector.hs b/ihp-postgresql-simple-extra/Test/Postgres/TSVector.hs similarity index 99% rename from Test/Postgres/TSVector.hs rename to ihp-postgresql-simple-extra/Test/Postgres/TSVector.hs index 51fbf0cb1..d1ae32848 100644 --- a/Test/Postgres/TSVector.hs +++ b/ihp-postgresql-simple-extra/Test/Postgres/TSVector.hs @@ -4,9 +4,9 @@ Copyright: (c) digitally induced GmbH, 2021 -} module Test.Postgres.TSVector where +import Prelude import Test.Hspec import Test.Postgres.Support -import IHP.Prelude import IHP.Postgres.TSVector import Database.PostgreSQL.Simple.ToField import qualified Data.Attoparsec.ByteString.Char8 as Attoparsec diff --git a/ihp-postgresql-simple-extra/Test/Spec.hs b/ihp-postgresql-simple-extra/Test/Spec.hs new file mode 100644 index 000000000..2920224d7 --- /dev/null +++ b/ihp-postgresql-simple-extra/Test/Spec.hs @@ -0,0 +1,16 @@ +module Main where + +import CorePrelude +import Test.Hspec + +import qualified Test.Postgres.Point +import qualified Test.Postgres.Polygon +import qualified Test.Postgres.Interval +import qualified Test.Postgres.TSVector + +main :: IO () +main = hspec do + Test.Postgres.Point.tests + Test.Postgres.Polygon.tests + Test.Postgres.Interval.tests + Test.Postgres.TSVector.tests \ No newline at end of file diff --git a/ihp-postgresql-simple-extra/ihp-postgresql-simple-extra.cabal b/ihp-postgresql-simple-extra/ihp-postgresql-simple-extra.cabal new file mode 100644 index 000000000..b5089b232 --- /dev/null +++ b/ihp-postgresql-simple-extra/ihp-postgresql-simple-extra.cabal @@ -0,0 +1,93 @@ +cabal-version: 2.2 +name: ihp-postgresql-simple-extra +version: 1.0.1 +synopsis: Extra data types for postgresql-simple +description: This package is included by default in IHP apps and implements support for postgres data types that are not supported by the postgresql-simple package by default +license: MIT +license-file: LICENSE +author: digitally induced GmbH +maintainer: support@digitallyinduced.com +bug-reports: https://github.com/digitallyinduced/ihp/issues +category: Database +build-type: Simple +extra-source-files: README.md + +source-repository head + type: git + location: https://github.com/digitallyinduced/ihp.git + +common shared-properties + default-language: Haskell2010 + build-depends: + base + , bytestring + , attoparsec + , basic-prelude + , text + , postgresql-simple + , ip + , time + , time-compat + , aeson + default-extensions: + OverloadedStrings + , NoImplicitPrelude + , ImplicitParams + , Rank2Types + , NamedFieldPuns + , TypeSynonymInstances + , FlexibleInstances + , DisambiguateRecordFields + , DuplicateRecordFields + , OverloadedLabels + , FlexibleContexts + , DataKinds + , QuasiQuotes + , TypeFamilies + , PackageImports + , ScopedTypeVariables + , RecordWildCards + , TypeApplications + , DataKinds + , InstanceSigs + , DeriveGeneric + , MultiParamTypeClasses + , TypeOperators + , DeriveDataTypeable + , DefaultSignatures + , BangPatterns + , FunctionalDependencies + , PartialTypeSignatures + , BlockArguments + , LambdaCase + , StandaloneDeriving + , TemplateHaskell + , OverloadedRecordDot + +library + import: shared-properties + hs-source-dirs: . + exposed-modules: + IHP.Postgres.TypeInfo + , IHP.Postgres.Point + , IHP.Postgres.Interval + , IHP.Postgres.TimeParser + , IHP.Postgres.Polygon + , IHP.Postgres.Inet + , IHP.Postgres.TSVector + +test-suite spec + import: shared-properties + type: exitcode-stdio-1.0 + other-modules: + Test.Postgres.Interval + , Test.Postgres.Point + , Test.Postgres.Polygon + , Test.Postgres.Support + , Test.Postgres.TSVector + hs-source-dirs: . + main-is: Test/Spec.hs + build-depends: + hspec >= 2.7 + , hspec-discover >= 2.7 + , ihp-postgresql-simple-extra \ No newline at end of file diff --git a/ihp.cabal b/ihp.cabal index 26d65cfe6..4fb8ef251 100644 --- a/ihp.cabal +++ b/ihp.cabal @@ -49,7 +49,6 @@ common shared-properties , random-strings , uuid , time - , time-compat , attoparsec , ghc-prim , case-insensitive @@ -105,6 +104,7 @@ common shared-properties , unagi-chan , with-utf8 , ihp-hsx + , ihp-postgresql-simple-extra default-extensions: OverloadedStrings , NoImplicitPrelude @@ -248,13 +248,6 @@ library , IHP.Test.Mocking , IHP.Test.Database , IHP.Version - , IHP.Postgres.TypeInfo - , IHP.Postgres.Point - , IHP.Postgres.Interval - , IHP.Postgres.TimeParser - , IHP.Postgres.Polygon - , IHP.Postgres.Inet - , IHP.Postgres.TSVector , Paths_ihp , IHP.Job.Queue , IHP.Job.Runner diff --git a/ihp.nix b/ihp.nix index 98c9e677b..bf396cd01 100644 --- a/ihp.nix +++ b/ihp.nix @@ -51,7 +51,6 @@ , wreq , deepseq , parser-combinators -, ip , fast-logger , minio-hs , temporary @@ -64,6 +63,7 @@ , unagi-chan , with-utf8 , ihp-hsx +, ihp-postgresql-simple-extra , nix-gitignore }: mkDerivation { @@ -122,7 +122,6 @@ mkDerivation { deepseq uri-encode parser-combinators - ip fast-logger minio-hs temporary @@ -135,6 +134,7 @@ mkDerivation { unagi-chan with-utf8 ihp-hsx + ihp-postgresql-simple-extra ]; license = lib.licenses.mit; postInstall = '' diff --git a/lib/IHP/applicationGhciConfig b/lib/IHP/applicationGhciConfig index 585e974cc..e7004f054 100755 --- a/lib/IHP/applicationGhciConfig +++ b/lib/IHP/applicationGhciConfig @@ -1,6 +1,7 @@ :set prompt "\ESC[38;5;208m\STXIHP>\ESC[m\STX " :set -i. :set -iIHP/ihp-hsx +:set -iIHP/ihp-postgresql-simple-extra :set -iConfig :set -ibuild :set -iIHP