diff --git a/bun/prepare.js b/bun/prepare.js index b293d43..a0c7ad9 100644 --- a/bun/prepare.js +++ b/bun/prepare.js @@ -1,5 +1,5 @@ -import {readFile, writeFile} from 'fs/promises' -import {execSync} from 'child_process' +import { readFile, writeFile } from 'fs/promises' +import { execSync } from 'child_process' let ver = process.argv[2] if (!ver) { @@ -19,7 +19,10 @@ const spagonew = spago.replace(/version: .+/, `version: '${ver}'`) await writeFile('./spago.yaml', spagonew) const readme = await readFile('./README.md', 'utf8') -const readmenew = readme.replace(/packages\/purescript-postgresql\/.+?\//g, `/packages/purescript-postgresql/${ver}/`) +const readmenew = readme.replace( + /packages\/purescript-postgresql\/.+?\//g, + `/packages/purescript-postgresql/${ver}/`, +) await writeFile('./README.md', readmenew) execSync(`git add spago.yaml package.json README.md`) diff --git a/src/Data.Postgres.Custom.Enum.purs b/src/Data.Postgres.Custom.Enum.purs index 431a9ba..4cac0b7 100644 --- a/src/Data.Postgres.Custom.Enum.purs +++ b/src/Data.Postgres.Custom.Enum.purs @@ -5,35 +5,23 @@ import Prelude import Control.Alt ((<|>)) import Control.Monad.Error.Class (liftMaybe) import Data.Array.NonEmpty.Internal (NonEmptyArray) -import Data.Either (hush) import Data.Foldable (intercalate) import Data.Generic.Rep (class Generic) import Data.Generic.Rep as G -import Data.Maybe (Maybe(..), fromJust) +import Data.Maybe (Maybe(..)) import Data.Newtype as Newtype -import Data.Postgres (RepT, deserialize, serialize) -import Data.Postgres.Custom (class CustomRep, quoted, typeName) +import Data.Postgres (class Rep, RepT, deserialize, serialize) +import Data.Postgres.Custom (quoted) import Data.Postgres.Query (Query, emptyQuery) import Data.Postgres.Raw (Raw) -import Data.String as String -import Data.String.Regex (Regex) -import Data.String.Regex as Regex -import Data.String.Regex.Flags as Regex.Flags import Data.Symbol (class IsSymbol) import Foreign (ForeignError(..)) -import Partial.Unsafe (unsafePartial) import Type.Prelude (Proxy(..), reflectSymbol) -upperRe :: Regex -upperRe = unsafePartial fromJust $ hush $ Regex.regex "[A-Z]" Regex.Flags.global +typeName :: forall @a ty. CustomEnum a ty => String +typeName = reflectSymbol (Proxy @ty) -leadingUnderRe :: Regex -leadingUnderRe = unsafePartial fromJust $ hush $ Regex.regex "^_" Regex.Flags.noFlags - -pascalToSnake :: String -> String -pascalToSnake = String.toLower <<< Regex.replace leadingUnderRe "" <<< Regex.replace upperRe "_$1" - -class CustomRep a ty <= CustomEnum a ty | a -> ty where +class (IsSymbol ty, Rep a) <= CustomEnum a ty | a -> ty where enumVariants :: NonEmptyArray a parseEnum :: String -> Maybe a printEnum :: a -> String diff --git a/src/Data.Postgres.Custom.purs b/src/Data.Postgres.Custom.purs index 06bfc7b..aae6826 100644 --- a/src/Data.Postgres.Custom.purs +++ b/src/Data.Postgres.Custom.purs @@ -3,27 +3,28 @@ module Data.Postgres.Custom where import Prelude import Control.Monad.Except (ExceptT) +import Data.Either (hush) import Data.List.NonEmpty (NonEmptyList) -import Data.Maybe (Maybe) +import Data.Maybe (Maybe, fromJust) import Data.Postgres.Raw (Raw) +import Data.String as String +import Data.String.Regex (Regex) +import Data.String.Regex as Regex +import Data.String.Regex.Flags as Regex.Flags import Effect (Effect) import Foreign (ForeignError) +import Partial.Unsafe (unsafePartial) import Type.Data.Symbol (reflectSymbol) import Type.Prelude (class IsSymbol, Proxy(..)) -class (IsSymbol ty) <= CustomSerialize a ty | a -> ty where - customPrintExpr :: a -> Maybe String - customSerialize :: a -> ExceptT (NonEmptyList ForeignError) Effect Raw - -class (IsSymbol ty) <= CustomDeserialize a ty | a -> ty where - customDeserialize :: Raw -> ExceptT (NonEmptyList ForeignError) Effect a - -class (IsSymbol ty, CustomSerialize a ty, CustomDeserialize a ty) <= CustomRep a ty | a -> ty - -instance (IsSymbol ty, CustomSerialize a ty, CustomDeserialize a ty) => CustomRep a ty - quoted :: String -> String quoted s = "'" <> s <> "'" -typeName :: forall @a ty. CustomRep a ty => String -typeName = reflectSymbol (Proxy @ty) +upperRe :: Regex +upperRe = unsafePartial fromJust $ hush $ Regex.regex "[A-Z]" Regex.Flags.global + +leadingUnderRe :: Regex +leadingUnderRe = unsafePartial fromJust $ hush $ Regex.regex "^_" Regex.Flags.noFlags + +pascalToSnake :: String -> String +pascalToSnake = String.toLower <<< Regex.replace leadingUnderRe "" <<< Regex.replace upperRe "_$1" diff --git a/src/Data.Postgres.purs b/src/Data.Postgres.purs index 0a5b45c..89c0cab 100644 --- a/src/Data.Postgres.purs +++ b/src/Data.Postgres.purs @@ -12,7 +12,6 @@ import Data.DateTime (DateTime) import Data.List.NonEmpty (NonEmptyList) import Data.Maybe (Maybe(..)) import Data.Newtype (class Newtype, unwrap, wrap) -import Data.Postgres.Custom (class CustomDeserialize, class CustomSerialize, customDeserialize, customSerialize) import Data.Postgres.Range (Range, __rangeFromRecord, __rangeRawFromRaw, __rangeRawFromRecord, __rangeRawToRecord, __rangeToRecord) import Data.Postgres.Raw (Null(..), Raw, jsNull) import Data.Postgres.Raw (unsafeFromForeign, asForeign) as Raw @@ -73,87 +72,84 @@ instance Serialize Raw where serialize = pure -- | `NULL` -else instance Serialize Unit where +instance Serialize Unit where serialize _ = serialize Null -- | `NULL` -else instance Serialize Null where +instance Serialize Null where serialize _ = unsafeSerializeCoerce jsNull -- | `json`, `jsonb` -else instance WriteForeign a => Serialize (JSON a) where +instance WriteForeign a => Serialize (JSON a) where serialize = serialize <<< writeJSON <<< unwrap -- | `bytea` -else instance Serialize Buffer where +instance Serialize Buffer where serialize = unsafeSerializeCoerce -- | `int2`, `int4` -else instance Serialize Int where +instance Serialize Int where serialize = unsafeSerializeCoerce -- | `int8` -else instance Serialize BigInt where +instance Serialize BigInt where serialize = serialize <<< BigInt.toString -- | `bool` -else instance Serialize Boolean where +instance Serialize Boolean where serialize = unsafeSerializeCoerce -- | `text`, `inet`, `tsquery`, `tsvector`, `uuid`, `xml`, `cidr`, `time`, `timetz` -else instance Serialize String where +instance Serialize String where serialize = unsafeSerializeCoerce -- | `float4`, `float8` -else instance Serialize Number where +instance Serialize Number where serialize = unsafeSerializeCoerce -- | `timestamp`, `timestamptz` -else instance Serialize DateTime where +instance Serialize DateTime where serialize = serialize <<< unwrap <<< DateTime.ISO.fromDateTime -- | `Just` -> `a`, `Nothing` -> `NULL` -else instance Serialize a => Serialize (Maybe a) where +instance Serialize a => Serialize (Maybe a) where serialize (Just a) = serialize a serialize Nothing = unsafeSerializeCoerce jsNull -- | postgres `array` -else instance Serialize a => Serialize (Array a) where +instance Serialize a => Serialize (Array a) where serialize = unsafeSerializeCoerce <=< traverse serialize -else instance (Ord a, Rep a) => Serialize (Range a) where +instance (Ord a, Rep a) => Serialize (Range a) where serialize = map (Raw.unsafeFromForeign <<< unsafeToForeign <<< __rangeRawFromRecord <<< __rangeToRecord) <<< traverse serialize -else instance (CustomSerialize a ty) => Serialize a where - serialize = customSerialize - instance Deserialize Raw where deserialize = pure -- | `NULL` (always succeeds) -else instance Deserialize Unit where +instance Deserialize Unit where deserialize _ = pure unit -- | `NULL` (fails if non-null) -else instance Deserialize Null where +instance Deserialize Null where deserialize = map (const Null) <<< F.readNullOrUndefined <<< Raw.asForeign -- | `json`, `jsonb` -else instance ReadForeign a => Deserialize (JSON a) where +instance ReadForeign a => Deserialize (JSON a) where deserialize = map wrap <<< (hoist (pure <<< unwrap) <<< readJSON') <=< deserialize @String -- | `bytea` -else instance Deserialize Buffer where +instance Deserialize Buffer where deserialize = (F.unsafeReadTagged "Buffer") <<< Raw.asForeign -- | `int2`, `int4` -else instance Deserialize Int where +instance Deserialize Int where deserialize = F.readInt <<< Raw.asForeign -- | `int8` -else instance Deserialize BigInt where +instance Deserialize BigInt where deserialize = let invalid s = pure $ ForeignError $ "Invalid bigint: " <> s @@ -162,30 +158,30 @@ else instance Deserialize BigInt where fromString <=< deserialize @String -- | `bool` -else instance Deserialize Boolean where +instance Deserialize Boolean where deserialize = F.readBoolean <<< Raw.asForeign -- | `text`, `inet`, `tsquery`, `tsvector`, `uuid`, `xml`, `cidr`, `time`, `timetz` -else instance Deserialize String where +instance Deserialize String where deserialize = F.readString <<< Raw.asForeign -- | `float4`, `float8` -else instance Deserialize Number where +instance Deserialize Number where deserialize = F.readNumber <<< Raw.asForeign -- | `timestamp`, `timestamptz` -else instance Deserialize DateTime where +instance Deserialize DateTime where deserialize raw = do s :: String <- deserialize raw let invalid = pure $ ForeignError $ "Not a valid ISO8601 string: `" <> s <> "`" liftMaybe invalid $ DateTime.ISO.toDateTime $ wrap s -- | postgres `array` -else instance Deserialize a => Deserialize (Array a) where +instance Deserialize a => Deserialize (Array a) where deserialize = traverse (deserialize <<< Raw.unsafeFromForeign) <=< F.readArray <<< Raw.asForeign -- | non-NULL -> `Just`, NULL -> `Nothing` -else instance Deserialize a => Deserialize (Maybe a) where +instance Deserialize a => Deserialize (Maybe a) where deserialize raw = let nothing = const Nothing <$> deserialize @Null raw @@ -193,8 +189,5 @@ else instance Deserialize a => Deserialize (Maybe a) where in just <|> nothing -else instance (Ord a, Rep a) => Deserialize (Range a) where +instance (Ord a, Rep a) => Deserialize (Range a) where deserialize = traverse deserialize <=< map (__rangeFromRecord <<< __rangeRawToRecord) <<< lift <<< __rangeRawFromRaw - -else instance (CustomDeserialize a ty) => Deserialize a where - deserialize = customDeserialize diff --git a/test/Test.Data.Postgres.Generic.purs b/test/Test.Data.Postgres.Generic.purs index 4347e41..6f3b657 100644 --- a/test/Test.Data.Postgres.Generic.purs +++ b/test/Test.Data.Postgres.Generic.purs @@ -9,8 +9,7 @@ import Data.DateTime (DateTime(..)) import Data.Generic.Rep (class Generic) import Data.Maybe (Maybe(..)) import Data.Newtype (unwrap) -import Data.Postgres (deserialize, serialize, smash) -import Data.Postgres.Custom (class CustomDeserialize, class CustomSerialize, customDeserialize) +import Data.Postgres (class Deserialize, class Serialize, deserialize, serialize, smash) import Data.Postgres.Custom.Enum (class CustomEnum, create, enumDeserialize, enumPrintExpr, enumSerialize, genericEnumVariants, genericParseEnum, genericPrintEnum, parseEnum, printEnum) import Data.Show.Generic (genericShow) import Effect.Class (liftEffect) @@ -25,12 +24,11 @@ derive instance Eq Enum1 instance Show Enum1 where show = genericShow -instance CustomSerialize Enum1 "enum_1" where - customPrintExpr a = enumPrintExpr a - customSerialize a = enumSerialize a +instance Serialize Enum1 where + serialize a = enumSerialize a -instance CustomDeserialize Enum1 "enum_1" where - customDeserialize a = enumDeserialize a +instance Deserialize Enum1 where + deserialize a = enumDeserialize a instance CustomEnum Enum1 "enum_1" where printEnum = genericPrintEnum @@ -44,12 +42,11 @@ derive instance Eq Enum2 instance Show Enum2 where show = genericShow -instance CustomSerialize Enum2 "enum_2" where - customPrintExpr a = enumPrintExpr a - customSerialize a = enumSerialize a +instance Serialize Enum2 where + serialize a = enumSerialize a -instance CustomDeserialize Enum2 "enum_2" where - customDeserialize a = enumDeserialize a +instance Deserialize Enum2 where + deserialize a = enumDeserialize a instance CustomEnum Enum2 "enum_2" where printEnum a = genericPrintEnum a @@ -63,12 +60,11 @@ derive instance Eq Enum5 instance Show Enum5 where show = genericShow -instance CustomSerialize Enum5 "enum_5" where - customPrintExpr a = enumPrintExpr a - customSerialize a = enumSerialize a +instance Serialize Enum5 where + serialize a = enumSerialize a -instance CustomDeserialize Enum5 "enum_5" where - customDeserialize a = enumDeserialize a +instance Deserialize Enum5 where + deserialize a = enumDeserialize a instance CustomEnum Enum5 "enum_5" where printEnum a = genericPrintEnum a