selda 0.5.2.0 → 0.5.2.1
raw patch · 13 files changed
+337/−33 lines, 13 filesdep ~bytestringdep ~containersdep ~mtlnew-uploader
Dependency ranges changed: bytestring, containers, mtl, random, text, time
Files
- ChangeLog.md +259/−0
- LICENSE +21/−0
- selda.cabal +11/−9
- src/Database/Selda.hs +1/−1
- src/Database/Selda/Backend/Internal.hs +3/−2
- src/Database/Selda/Generic.hs +2/−1
- src/Database/Selda/SQL/Print.hs +2/−1
- src/Database/Selda/SqlRow.hs +2/−2
- src/Database/Selda/Table.hs +24/−11
- src/Database/Selda/Table/Compile.hs +5/−2
- src/Database/Selda/Table/Type.hs +3/−1
- src/Database/Selda/Table/Validation.hs +2/−2
- src/Database/Selda/Unsafe.hs +2/−1
+ ChangeLog.md view
@@ -0,0 +1,259 @@+# Revision history for Selda+++## 0.5.2.1 -- 2026-01-08++* Publish the website via GitHub pages (#201)+* Properly use cascading deletes with foreign keys (#191)+* Schema query validation fix for PostgreSQL (#183)+* Many small version compatibility fixes+++## 0.5.2.0 -- 2022-09-18++* Add support for GHC versions 8.10-9.2+* Add typed UUIDs+* Allow literal rows in update queries. (#139)+* Add support for UNION/UNION ALL. (#140)+* Support raw PostgreSQL connection strings. (#136)+* Move to Docker and GitHub actions for testing.+* Drop support for GHC versions <8.8.+* Various bugfixes.+++## 0.5.1.0 -- 2020-01-20++* Support for raw SQL fragments. (#134)+* Expose tableName.+* Document performance drawbacks of withoutForeignKeyEnforcement.+* Fix several bugs validating auto-incrementing PKs. (#133)+++## 0.5.0.0 -- 2019-09-21++* index and indexUsing now accept a Group instead of a Selector (#121)+* Custom type errors for scope mismatches.+* Provide Generic instances for ID and RowID.+* Provide To/FromJSON instances for ID and RowID (selda-json).+* Add back MonadTrans instance for SeldaT.+++## 0.4.0.0 -- 2019-06-02++* Type-safe support for backend-specific functionality. Top level query definitions now require explicit type signature. (#80)+* Native UUID support. (#47)+* Support JSON columns on all backends through aeson.+* Support JSON lookups (i.e. SELECT json_column.some_property FROM ...) on PostgreSQL.+* Multi-column primary key and uniqueness constraint support. (#25, #99)+* Switch to PostgreSQL binary protocol. (#18)+* Prevent dangerous user-defined SQL result instances.+* Expose backend internals through Database.Selda.Backend.Internal. (#109)+* Expose SQLite connection handle. (#101)+* Make MonadSelda more amenable to connection pooling. (#108)+* Add weakly auto-incrementing primary keys. (#94)+* Move compile* functions to Database.Selda.Debug.+* Remove half the tuple convenience functions.+* Remove in-process cache. (#117)+* Officially support GHC 8.6, 8.8 (SQLite only until postgres dependencies catch up with 8.8).+* Drop support for GHC 7.10. (#118)+* Manual (i.e. non record label) selectors are no longer exported by default; import Database.Selda.MakeSelectors is you need them. (#118)+* Update toolchain to use v2-style cabal commands.+* Fix date/time types for PostgreSQL. (#104)+* Fix bug when migrating tables with indexes. (#107)+* Misc. smaller bug fixes.+++## 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.+* DISTINCT can no longer produce ill-scoped queries.+++## 0.3.3.0 -- 2018-09-01++* Ad hoc selectors using OverloadedLabels.+* Shorter build times.+* Minor API updates and simplifications.+++## 0.3.2.0 -- 2018-08-07++* Some aggregates are now nullable.+* sum_ on an empty table doesn't crash anymore.+* Aggregating over an empty selectValues doesn't crash anymore.+++## 0.3.1.0 -- 2018-08-06++* Minor API fix when defining table attributes.+++## 0.3.0.0 -- 2018-08-05++* Support for Stack and GHC 8.4.+* Precedence fix for selector index (!) operator.+* Accept INT and SMALLINT columns in user-created PostgreSQL tables.+* Add combinator for turning off foreign key checking.+* Rename unsafeRowId/unsafeId to toRowId/rowId.+* Add typed row identifiers.+* More generic type for sum_.+* Table validation against current database.+* Basic migration support.+* Basic index support.+* Remove ad hoc tables; only generic tables from now on.+++## 0.2.0.0 -- 2018-04-02++* Support custom column names for generic tables.+* Scope safety fix for inner queries.+* Better type errors on GHC 8+ for inner queries.+++## 0.1.12.1 -- 2018-02-27++* New PPConfig hook for more flexibility when compiling types.+++## 0.1.12.0 -- 2018-01-11++* Allow recursive and optional foreign keys.+* Allow arbitrary enums in tables, represented as text.+* Fix RowID issues for PostgreSQL.+* Fix auto-incrementing primary keys for generic tables.+++## 0.1.11.2 -- 2017-12-14++* Fix treatment of booleans in PostgreSQL backend.+++## 0.1.11.1 -- 2017-10-10++* Fix rare infinite loop bug in in-process cache.+++## 0.1.11.0 -- 2017-09-08++* Fix name generation in the presence of isIn over queries.+* SELECT DISTINCT support.+* Conditional expressions and matchNull.+++## 0.1.10.1 -- 2017-08-11++* Fix name generation in the presence of multiple aggregates.+++## 0.1.10.0 -- 2017-08-01++* Async exception safety.+* Allow MonadSelda instances not built on SeldaT.+* Chunk very large insertions on backends that request it (i.e. SQLite).+* GHC 8.2 support.+++## 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.+* Support for binary blobs.+* Support for prepared statements.+* Support for connection reuse across Selda computations.+* Cleaner and more robust backend API.+* Stricter type constraints on comparisons.+* Allow limit on inner queries.+* Allow inspecting row identifiers.+++## 0.1.7.0 -- 2017-05-17++* Add specialized insertUnless upsert variant.+* Fix potential race condition in upserts.+* Use abstract row identifier type for auto-incrementing primary keys.+* Less strict version bounds on dependencies.+++## 0.1.6.0 -- 2017-05-07++* Conditional insert ("upsert") support.+* Support `SELECT x IN (SELECT ...)` and `SELECT x IN (a, b, ...)` queries.+* Explicit inner queries.+* Rename `inner` to `innerJoin`, more intuitive behavior for `suchThat`.+* Add `from` shorthand for `\s q -> fmap (!s) q`.+* Unique and foreign key constraints for generics.+++## 0.1.5.0 -- 2017-05-05++* Inner join support.+* More sensible names in backend API.+* Fix rounding and casts.+++## 0.1.4.1 -- 2017-05-04++* Fix cache consistency bug in the presence of multiple databases.+++## 0.1.4.0 -- 2017-05-04++* Add uniqueness constraints and foreign keys.+++## 0.1.3.3 -- 2017-05-04++* Fix cache invalidation race when using transactions.+++## 0.1.3.2 -- 2017-05-01++* Only throw well-documented, Selda-specific exceptions.+++## 0.1.3.1 -- 2017-05-01++* More Hackage-friendly README.+++## 0.1.3.0 -- 2017-04-30++* Add selectors for non-generic tables.+* Allow default insertions on all columns.+* More sensible API for LIMIT.+* Fix broken SQL being generated for pathological corner cases.+* Documentation fixes.+++## 0.1.2.0 -- 2017-04-20++* Replace `¤` with `:*:` in table definitions.+++## 0.1.1.1 -- 2017-04-20++* Minor documentation fixes.+++## 0.1.1.0 -- 2017-04-20++* Generic tables, queries and mutation.+* Select from inline tables.+* Tutorial updates.+* Minor bugfixes.+++## 0.1.0.0 -- 2017-04-14++* Initial release.
+ LICENSE view
@@ -0,0 +1,21 @@+MIT License++Copyright (c) 2017-2019 Anton Ekblad++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.
selda.cabal view
@@ -1,5 +1,5 @@ name: selda-version: 0.5.2.0+version: 0.5.2.1 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,@@ -11,14 +11,16 @@ 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://selda.link+homepage: https://valderman.github.io/selda license: MIT+license-file: LICENSE author: Anton Ekblad maintainer: anton@ekblad.cc category: Database build-type: Simple cabal-version: >=1.10-tested-with: GHC == 8.8.2, GHC == 8.10.1, GHC == 9.0.2, GHC == 9.2.3+tested-with: GHC == 8.8.2, GHC == 8.10.1, GHC == 9.2.5, GHC == 9.4.4, GHC == 9.6.7, GHC == 9.12.2+extra-source-files: ChangeLog.md source-repository head type: git@@ -72,13 +74,13 @@ FlexibleContexts build-depends: base >=4.10 && <5- , bytestring >=0.10 && <0.12+ , bytestring >=0.10 && <0.13 , exceptions >=0.8 && <0.11- , mtl >=2.0 && <2.3- , text >=1.0 && <1.3- , time >=1.5 && <1.12- , containers >=0.4 && <0.7- , random >=1.1 && <1.3+ , mtl >=2.0 && <2.4+ , text >=1.0 && <2.2+ , time >=1.5 && <1.16+ , containers >=0.4 && <0.9+ , random >=1.1 && <1.4 , uuid-types >=1.0 && <1.1 hs-source-dirs: src
src/Database/Selda.hs view
@@ -18,7 +18,7 @@ -- This includes database connection errors, uniqueness constraint errors, -- etc. ----- See <https://selda.link/tutorial> for a tutorial covering the language+-- See <https://valderman.github.io/selda/tutorial> for a tutorial covering the language -- basics. module Database.Selda ( -- * Running queries
src/Database/Selda/Backend/Internal.hs view
@@ -44,7 +44,8 @@ ( Exception, bracket, MonadCatch, MonadMask, MonadThrow(..) ) import Control.Monad.IO.Class ( MonadIO(..) ) import Control.Monad.Reader- ( MonadTrans(..), when, ReaderT(..), MonadReader(ask) )+ ( MonadTrans(..), ReaderT(..), MonadReader(ask) )+import Control.Monad (when) import Data.Dynamic ( Typeable, Dynamic ) import qualified Data.IntMap as M import Data.IORef@@ -182,7 +183,7 @@ , colFKs = map fk (Table.colFKs ci) } where- fk (Table tbl _ _ _, col) = (tbl, col)+ fk (Table tbl _ _ _, col, _) = (tbl, col) -- | Get the column information for each column in the given table. tableInfo :: Table a -> TableInfo
src/Database/Selda/Generic.hs view
@@ -9,7 +9,8 @@ , tblCols, params, def, gNew, gRow ) where import Control.Monad.State- ( liftM2, MonadState(put, get), evalState, State )+ ( MonadState(put, get), evalState, State )+import Control.Monad (liftM2) import Data.Dynamic ( Typeable ) import Data.Text as Text (Text, pack)
src/Database/Selda/SQL/Print.hs view
@@ -17,7 +17,8 @@ import Database.Selda.Types ( TableName, ColName, fromColName, fromTableName ) import Control.Monad.State- ( liftM2, MonadState(get, put), runState, State )+ ( MonadState(get, put), runState, State )+import Control.Monad (liftM2) import Data.List ( group, sort ) import Data.Text (Text) import qualified Data.Text as Text
src/Database/Selda/SqlRow.hs view
@@ -8,11 +8,11 @@ , runResultReader, next ) where import Control.Monad.State.Strict- ( liftM2,- StateT(StateT),+ ( StateT(StateT), MonadState(state, get), State, evalState )+import Control.Monad (liftM2) import Database.Selda.SqlType ( SqlValue(SqlNull), SqlType(fromSql) ) import Data.Typeable ( Typeable, Proxy(..) )
src/Database/Selda/Table.hs view
@@ -1,6 +1,6 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} {-# LANGUAGE TypeFamilies, TypeOperators, FlexibleInstances #-}-{-# LANGUAGE UndecidableInstances, MultiParamTypeClasses, OverloadedStrings #-}+{-# LANGUAGE UndecidableInstances, MultiParamTypeClasses #-} {-# LANGUAGE FlexibleContexts, ScopedTypeVariables, ConstraintKinds #-} {-# LANGUAGE GADTs, CPP, DataKinds #-} {-# LANGUAGE TypeApplications #-}@@ -16,9 +16,10 @@ , tableExpr , isAutoPrimary, isPrimary, isUnique ) where+import Data.Kind (Type) import Data.Text (Text) import Data.Typeable ( Proxy(..) )-import Database.Selda.Types ( type (:*:), TableName, ColName )+import Database.Selda.Types ( type (:*:), TableName ) import Database.Selda.Selectors ( Selector(..) ) import Database.Selda.SqlType ( ID, RowID ) import Database.Selda.Column (Row (..))@@ -27,6 +28,7 @@ ( IndexMethod(..), ColAttr(..), AutoIncType(..),+ ColForeignKey, ColInfo(..), Table(..), isAutoPrimary,@@ -97,7 +99,7 @@ -- > -- > people :: Table Person -- > people = tableFieldMod "people"--- > [#personName :- autoPrimaryGen]+-- > [#personName :- autoPrimary] -- > (fromJust . stripPrefix "person") -- -- This will create a table with the columns named@@ -163,9 +165,9 @@ -- | Some attribute that may be set on a column of type @c@, in a table of -- type @t@.-data Attribute (g :: * -> * -> *) t c+data Attribute (g :: Type -> Type -> Type) t c = Attribute [ColAttr]- | ForeignKey (Table (), ColName)+ | ForeignKey ColForeignKey -- | A primary key which does not auto-increment. primary :: Attribute Group t a@@ -206,20 +208,31 @@ unique :: Attribute Group t a unique = Attribute [Unique] -mkFK :: Table t -> Selector a b -> Attribute Selector c d-mkFK (Table tn tcs tapk tas) sel =- ForeignKey (Table tn tcs tapk tas, colName (tcs !! selectorIndex sel))+mkFK :: Bool -> Table t -> Selector a b -> Attribute Selector c d+mkFK isCascading (Table tn tcs tapk tas) sel =+ ForeignKey (Table tn tcs tapk tas, colName (tcs !! selectorIndex sel), isCascading) class ForeignKey a b where -- | A foreign key constraint referencing the given table and column. foreignKey :: Table t -> Selector t a -> Attribute Selector self b instance ForeignKey a a where- foreignKey = mkFK+ foreignKey = mkFK False instance ForeignKey (Maybe a) a where- foreignKey = mkFK+ foreignKey = mkFK False instance ForeignKey a (Maybe a) where- foreignKey = mkFK+ foreignKey = mkFK False++class ForeignKeyCascading a b where+ -- | A foreign key constraint with referential integrity referencing the given table and column.+ foreignKeyCascading :: Table t -> Selector t a -> Attribute Selector self b++instance ForeignKeyCascading a a where+ foreignKeyCascading = mkFK True+instance ForeignKeyCascading (Maybe a) a where+ foreignKeyCascading = mkFK True+instance ForeignKeyCascading a (Maybe a) where+ foreignKeyCascading = mkFK True -- | An expression representing the given table. tableExpr :: Table a -> Row s a
src/Database/Selda/Table/Compile.hs view
@@ -4,6 +4,7 @@ import Database.Selda.Table.Type ( IndexMethod, ColAttr(Indexed, Primary, Unique),+ ColForeignKey, ColInfo(colFKs, colType, colName, colAttrs), Table(Table, tableAttrs, tableName, tableCols), isAutoPrimary )@@ -110,13 +111,15 @@ ] -- | Compile a foreign key constraint.-compileFK :: ColName -> (Table (), ColName) -> Int -> Text-compileFK col (Table ftbl _ _ _, fcol) n = mconcat+compileFK :: ColName -> ColForeignKey -> Int -> Text+compileFK col (Table ftbl _ _ _, fcol, isCascading) n = mconcat [ "CONSTRAINT ", fkName, " FOREIGN KEY (", fromColName col, ") " , "REFERENCES ", fromTableName ftbl, "(", fromColName fcol, ")"+ , onDeleteCascade ] where fkName = fromColName $ addColPrefix col ("fk" <> pack (show n) <> "_")+ onDeleteCascade = if isCascading then " ON DELETE CASCADE" else "" -- | Compile a table column. compileTableCol :: PPConfig -> ColInfo -> Text
src/Database/Selda/Table/Type.hs view
@@ -23,12 +23,14 @@ , tableAttrs :: [([Int], ColAttr)] } +type ColForeignKey = (Table (), ColName, Bool)+ -- | A complete description of a database column. data ColInfo = ColInfo { colName :: ColName , colType :: SqlTypeRep , colAttrs :: [ColAttr]- , colFKs :: [(Table (), ColName)]+ , colFKs :: [ColForeignKey] , colExpr :: UntypedCol SQL }
src/Database/Selda/Table/Validation.hs view
@@ -21,7 +21,7 @@ -- -- Therefore, it is not meaningful to handle this exception in any way, -- just fix your bug instead.-data ValidationError = ValidationError String+newtype ValidationError = ValidationError String deriving (Show, Eq, Typeable) instance Exception ValidationError @@ -62,7 +62,7 @@ [ "column is used as a foreign key, but is not primary or unique: " <> fromTableName ftn <> "." <> fromColName fcn | ci <- cis- , (Table ftn fcs _ _, fcn) <- colFKs ci+ , (Table ftn fcs _ _, fcn, _) <- colFKs ci , fc <- fcs , colName fc == fcn , not $ Prelude.any isUnique (colAttrs fc)
src/Database/Selda/Unsafe.hs view
@@ -10,7 +10,8 @@ ) where import Control.Exception (throw) import Control.Monad.State.Strict- ( MonadIO(liftIO), void, MonadState(put, get) )+ ( MonadIO(liftIO), MonadState(put, get) )+import Control.Monad (void) import Database.Selda.Backend.Internal ( SqlType(mkLit, sqlType), MonadSelda,