Skip to content

Commit ab32c0e

Browse files
committed
Merge branch 'dev' of https://github.com/morphismtech/squeal into dev
2 parents d7cdd01 + d0381e8 commit ab32c0e

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

squeal-postgresql/src/Squeal/PostgreSQL/Expression/Array.hs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@ module Squeal.PostgreSQL.Expression.Array
3737
, unnest
3838
, arrAny
3939
, arrAll
40+
, arrayAppend
41+
, arrayPrepend
42+
, arrayCat
43+
, arrayPosition
44+
, arrayPositionBegins
45+
, arrayPositions
46+
, arrayRemoveNull
47+
, arrayReplace
48+
, trimArray
4049
) where
4150

4251
import Data.String
@@ -47,6 +56,7 @@ import qualified Generics.SOP as SOP
4756

4857
import Squeal.PostgreSQL.Expression
4958
import Squeal.PostgreSQL.Expression.Logic
59+
import Squeal.PostgreSQL.Expression.Null
5060
import Squeal.PostgreSQL.Expression.Type
5161
import Squeal.PostgreSQL.Query.From.Set
5262
import Squeal.PostgreSQL.Render
@@ -240,3 +250,42 @@ arrAny
240250
-> Expression grp lat with db params from (null ('PGvararray ty2)) -- ^ array
241251
-> Condition grp lat with db params from
242252
arrAny x (?) xs = x ? (UnsafeExpression $ "ANY" <+> parenthesized (renderSQL xs))
253+
254+
arrayAppend :: '[null ('PGvararray ty), ty] ---> null ('PGvararray ty)
255+
arrayAppend = unsafeFunctionN "array_append"
256+
257+
arrayPrepend :: '[ty, null ('PGvararray ty)] ---> null ('PGvararray ty)
258+
arrayPrepend = unsafeFunctionN "array_prepend"
259+
260+
arrayCat
261+
:: '[null ('PGvararray ty), null ('PGvararray ty)]
262+
---> null ('PGvararray ty)
263+
arrayCat = unsafeFunctionN "array_cat"
264+
265+
arrayPosition :: '[null ('PGvararray ty), ty] ---> 'Null 'PGint8
266+
arrayPosition = unsafeFunctionN "array_position"
267+
268+
arrayPositionBegins
269+
:: '[null ('PGvararray ty), ty, null 'PGint8] ---> 'Null 'PGint8
270+
arrayPositionBegins = unsafeFunctionN "array_position"
271+
272+
arrayPositions
273+
:: '[null ('PGvararray ty), ty]
274+
---> null ('PGvararray ('NotNull 'PGint8))
275+
arrayPositions = unsafeFunctionN "array_positions"
276+
277+
arrayRemove :: '[null ('PGvararray ty), ty] ---> null ('PGvararray ty)
278+
arrayRemove = unsafeFunctionN "array_remove"
279+
280+
arrayRemoveNull :: null ('PGvararray ('Null ty)) --> null ('PGvararray ('NotNull ty))
281+
arrayRemoveNull arr = UnsafeExpression (renderSQL (arrayRemove (arr *: null_)))
282+
283+
arrayReplace
284+
:: '[null ('PGvararray ty), ty, ty]
285+
---> null ('PGvararray ty)
286+
arrayReplace = unsafeFunctionN "array_replace"
287+
288+
trimArray
289+
:: '[null ('PGvararray ty), 'NotNull 'PGint8]
290+
---> null ('PGvararray ty)
291+
trimArray = unsafeFunctionN "trim_array"

squeal-postgresql/src/Squeal/PostgreSQL/Session/Decode.hs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ module Squeal.PostgreSQL.Session.Decode
4343
, genericProductRow
4444
, appendRows
4545
, consRow
46+
, ArrayField (..)
4647
-- * Decoding Classes
4748
, FromValue (..)
4849
, FromField (..)
@@ -540,6 +541,42 @@ instance {-# OVERLAPPABLE #-} IsLabel fld (MaybeT (DecodeRow row) y)
540541
fromLabel = MaybeT . decodeRow $ \(_ SOP.:* bs) ->
541542
runDecodeRow (runMaybeT (fromLabel @fld)) bs
542543

544+
{- | Utility for decoding array fields in a `DecodeRow`,
545+
accessed via overloaded labels.
546+
-}
547+
newtype ArrayField row y = ArrayField
548+
{ runArrayField
549+
:: StateT Strict.ByteString (Except Strict.Text) y
550+
-> DecodeRow row [y]
551+
}
552+
instance {-# OVERLAPPING #-}
553+
( KnownSymbol fld
554+
, PG y ~ ty
555+
, arr ~ 'NotNull ('PGvararray ('NotNull ty))
556+
) => IsLabel fld (ArrayField (fld ::: arr ': row) y) where
557+
fromLabel = ArrayField $ \yval ->
558+
decodeRow $ \(SOP.K bytesMaybe SOP.:* _) -> do
559+
let
560+
flderr = mconcat
561+
[ "field name: "
562+
, "\"", fromString (symbolVal (SOP.Proxy @fld)), "\"; "
563+
]
564+
yarr
565+
= devalue
566+
. array
567+
. dimensionArray replicateM
568+
. valueArray
569+
. revalue
570+
$ yval
571+
case bytesMaybe of
572+
Nothing -> Left (flderr <> "encountered unexpected NULL")
573+
Just bytes -> runExcept (evalStateT yarr bytes)
574+
instance {-# OVERLAPPABLE #-} IsLabel fld (ArrayField row y)
575+
=> IsLabel fld (ArrayField (field ': row) y) where
576+
fromLabel = ArrayField $ \yval ->
577+
decodeRow $ \(_ SOP.:* bytess) ->
578+
runDecodeRow (runArrayField (fromLabel @fld) yval) bytess
579+
543580
-- | A `GenericRow` constraint to ensure that a Haskell type
544581
-- is a record type,
545582
-- has a `RowPG`,

0 commit comments

Comments
 (0)