packages feed

selda 0.1.8.0 → 0.1.9.0

raw patch · 5 files changed

+57/−11 lines, 5 files

Files

ChangeLog.md view
@@ -1,6 +1,13 @@ # Revision history for Selda  +## 0.1.9.0 -- 2017-06-16++* Properly document semantics of order.+* Export conditional inserts.+* Fix Haste build for backends.++ ## 0.1.8.0 -- 2017-06-10  * Move SQL pretty-printing config into a single type.
selda.cabal view
@@ -1,5 +1,5 @@ name:                selda-version:             0.1.8.0+version:             0.1.9.0 synopsis:            Type-safe, high-level EDSL for interacting with relational databases. description:         This package provides an EDSL for writing portable, type-safe, high-level                      database code. Its feature set includes querying and modifying databases,@@ -11,7 +11,7 @@                      To use this package you need at least one backend package, in addition to                      this package. There are currently two different backend packages:                      selda-sqlite and selda-postgresql.-homepage:            https://github.com/valderman/selda+homepage:            https://selda.link license:             MIT license-file:        LICENSE author:              Anton Ekblad
src/Database/Selda.hs view
@@ -93,7 +93,7 @@   , count, avg, sum_, max_, min_     -- * Modifying tables   , Insert-  , insert, insert_, insertWithPK, tryInsert, def+  , insert, insert_, insertWithPK, tryInsert, insertUnless, insertWhen, def   , update, update_, upsert   , deleteFrom, deleteFrom_     -- * Prepared statements
src/Database/Selda/Frontend.hs view
@@ -3,7 +3,7 @@ module Database.Selda.Frontend   ( Result, Res, MonadIO (..), MonadSelda (..), SeldaT   , query-  , insert, insert_, insertWithPK, tryInsert, insertUnless+  , insert, insert_, insertWithPK, tryInsert, insertWhen, insertUnless   , update, update_, upsert   , deleteFrom, deleteFrom_   , createTable, tryCreateTable@@ -109,7 +109,8 @@  -- | Perform the given insert, if no rows already present in the table match --   the given predicate.---   Returns the primary key of the inserted row, if the insert was performed.+--   Returns the primary key of the last inserted row,+--   if the insert was performed. --   If called on a table which doesn't have an auto-incrementing primary key, --   @Just id@ is always returned on successful insert, where @id@ is a row --   identifier guaranteed to not match any row in any table.@@ -124,6 +125,24 @@              -> [a]              -> m (Maybe RowID) insertUnless tbl check rows = upsert tbl check id rows++-- | Like 'insertUnless', but performs the insert when at least one row matches+--   the predicate.+insertWhen :: ( MonadCatch m+              , MonadSelda m+              , Insert a+              , Columns (Cols s a)+              , Result (Cols s a)+              )+           => Table a+           -> (Cols s a -> Col s Bool)+           -> [a]+           -> m (Maybe RowID)+insertWhen tbl check rows = transaction $ do+  matches <- update tbl check id+  if matches > 0+    then Just <$> insertWithPK tbl rows+    else pure Nothing  -- | Like 'insert', but does not return anything. --   Use this when you really don't care about how many rows were inserted.
src/Database/Selda/Query.hs view
@@ -86,8 +86,8 @@ -- > -- SELECT COUNT(name) AS c, address FROM housing GROUP BY name HAVING c > 1 -- > -- > numPpl = do--- >   num_tenants :*: address <- aggregate $ do--- >     _ :*: address <- select housing+-- >   (num_tenants :*: address) <- aggregate $ do+-- >     (_ :*: address) <- select housing -- >     groupBy address -- >     return (count address :*: some address) -- >  restrict (num_tenants .> 1)@@ -121,9 +121,9 @@ -- -- > getAddresses :: Query s (Col s Text :*: Col s (Maybe Text)) -- > getAddresses = do--- >   name :*: _ <- select people--- >   _ :*: address <- leftJoin (\(n :*: _) -> n .== name)--- >                             (select addresses)+-- >   (name :*: _) <- select people+-- >   (_ :*: address) <- leftJoin (\(n :*: _) -> n .== name)+-- >                               (select addresses) -- >   return (name :*: address) leftJoin :: (Columns a, Columns (OuterCols a), Columns (LeftCols a))          => (OuterCols a -> Col s Bool)@@ -168,7 +168,7 @@ --   how many people have a pet at home: -- -- > aggregate $ do--- >   name :*: pet_name <- select people+-- >   (name :*: pet_name) <- select people -- >   name' <- groupBy name -- >   return (name' :*: count(pet_name) > 0) groupBy :: Col (Inner s) a -> Query (Inner s) (Aggr (Inner s) a)@@ -193,6 +193,26 @@   return $ unsafeCoerce res  -- | Sort the result rows in ascending or descending order on the given row.+--+--   If multiple @order@ directives are given, later directives are given+--   precedence but do not cancel out earlier ordering directives.+--   To get a list of persons sorted primarily on age and secondarily on name:+--+-- > peopleInAgeAndNameOrder = do+-- >   (name :*: age) <- select people+-- >   order name ascending+-- >   order age ascending+-- >   return name+--+--   For a table @["Alice" :*: 20, "Bob" :*: 20, "Eve" :*: 18]@, this query+--   will always return @["Eve", "Alice", "Bob"]@.+--+--   The reason for later orderings taking precedence and not the other way+--   around is composability: @order@ should always sort the current+--   result set to avoid weird surprises when a previous @order@ directive+--   is buried somewhere deep in an earlier query.+--   However, the ordering must always be stable, to ensure that previous+--   calls to order are not simply erased. order :: Col s a -> Order -> Query s () order (C c) o = Query $ do   st <- get