packages feed

selda 0.3.3.1 → 0.3.4.0

raw patch · 4 files changed

+88/−2 lines, 4 files

Files

ChangeLog.md view
@@ -1,6 +1,11 @@ # Revision history for Selda  +## 0.3.4.0 -- 2018-09-29++* Added convenience functions for working with nullable columns.++ ## 0.3.3.1 -- 2018-09-04  * DISTINCT should now always return distinct results.
selda.cabal view
@@ -1,5 +1,5 @@ name:                selda-version:             0.3.3.1+version:             0.3.4.0 synopsis:            Multi-backend, high-level EDSL for interacting with SQL databases. description:         This package provides an EDSL for writing portable, type-safe, high-level                      database code. Its feature set includes querying and modifying databases,@@ -47,6 +47,7 @@     Database.Selda     Database.Selda.Backend     Database.Selda.Migrations+    Database.Selda.Nullable     Database.Selda.SqlType     Database.Selda.Unsafe     Database.Selda.Validation
+ src/Database/Selda/Nullable.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE TypeFamilies, TypeOperators, ConstraintKinds, FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+-- | Convenience facilities for working with nullable columns.+module Database.Selda.Nullable+  ( NonNull, (:?~)+  , nonNull, restrict', (?!)+  , (?==), (?/=), (?>), (?<), (?>=), (?<=), (?+), (?-), (?*), (?/)+  ) where+import Database.Selda+import Database.Selda.Unsafe (cast)+import Database.Selda.Selectors+import Database.Selda.Column+import Unsafe.Coerce++-- | Two SQL types which are identical modulo nullability.+type a :?~ b =+  ( NonNull a ~ NonNull b+  , SqlType (NonNull a)+  , SqlType (NonNull b)+  )++type family NonNull a where+  NonNull (Maybe a) = a+  NonNull a         = a++-- | Unconditionally convert a nullable value into a non-nullable one,+--   using the standard SQL null-coalescing behavior.+fromNullable :: SqlType (NonNull a) => Col s a -> Col s (NonNull a)+fromNullable = cast++(?==), (?/=) :: (a :?~ b, SqlType a) => Col s a -> Col s b -> Col s (Maybe Bool)++(?>), (?<), (?>=), (?<=) :: (a :?~ b, SqlOrd (NonNull a))+                         => Col s a -> Col s b -> Col s (Maybe Bool)++(?+), (?-), (?*) :: (a :?~ b, Num (NonNull a))+                 => Col s a -> Col s b -> Col s (Maybe (NonNull a))++(?/) :: (a :?~ b, Fractional (Col s (NonNull a)))+     => Col s a -> Col s b -> Col s (Maybe (NonNull a))++a ?== b = cast $ fromNullable a .== fromNullable b+a ?/= b = cast $ fromNullable a ./= fromNullable b+a ?>  b = cast $ fromNullable a .>  fromNullable b+a ?<  b = cast $ fromNullable a .<  fromNullable b+a ?>= b = cast $ fromNullable a .>= fromNullable b+a ?<= b = cast $ fromNullable a .<= fromNullable b+a ?+  b = cast $ fromNullable a +   fromNullable b+a ?-  b = cast $ fromNullable a -   fromNullable b+a ?*  b = cast $ fromNullable a *   fromNullable b+a ?/  b = cast $ fromNullable a /   fromNullable b+infixl 4 ?==+infixl 4 ?/=+infixl 4 ?>+infixl 4 ?<+infixl 4 ?>=+infixl 4 ?<=+infixl 6 ?++infixl 6 ?-+infixl 7 ?*+infixl 7 ?/++-- | Selector indexing, overloaded to work on nullable as well as non-nullable+--   rows.+(?!) :: forall s t a. SqlType a+     => Row s t -> Selector (NonNull t) a -> Col s (Coalesce (Maybe a))+(Many xs) ?! i = case xs !! (selectorIndex i) of Untyped x -> One (unsafeCoerce x)+infixl 9 ?!++-- | Converts a nullable column into a non-nullable one, yielding the empty+--   result set if the column is null.+nonNull :: SqlType a => Col s (Maybe a) -> Query s (Col s a)+nonNull x = do+  restrict (not_ $ isNull x)+  return (cast x)++-- | Restrict a query using a nullable expression.+--   Equivalent to @restrict . ifNull false@.+restrict' :: Col s (Maybe Bool) -> Query s ()+restrict' = restrict . cast
src/Database/Selda/Selectors.hs view
@@ -32,7 +32,7 @@ --   If a nullable column is extracted from a nullable row, the resulting --   nested @Maybe@s will be squashed into a single level of nesting. (?) :: SqlType a => Row s (Maybe t) -> Selector t a -> Col s (Coalesce (Maybe a))-Many xs ? Selector i = case xs !! i of Untyped x -> One (unsafeCoerce x)+(Many xs) ? (Selector i) = case xs !! i of Untyped x -> One (unsafeCoerce x) infixl 9 ?  upd :: Row s a -> Assignment s a -> Row s a