Make the Experimental module more prominent (#205)

* update README

* add comments

* update cabal

* update changelog
This commit is contained in:
Matt Parsons 2020-09-17 14:52:38 -06:00 committed by GitHub
parent f9a8088170
commit 583167adb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 131 additions and 31 deletions

View File

@ -129,7 +129,50 @@ WHERE Person.age >= 18
Since `age` is an optional `Person` field, we use `just` to lift`val 18 :: SqlExpr (Value Int)` into `just (val 18) ::SqlExpr (Value (Maybe Int))`. Since `age` is an optional `Person` field, we use `just` to lift`val 18 :: SqlExpr (Value Int)` into `just (val 18) ::SqlExpr (Value (Maybe Int))`.
## Joins ## Experimental/New Joins
There's a new way to write `JOIN`s in esqueleto! It has less potential for
runtime errors and is much more powerful than the old syntax. To opt in to the
new syntax, import:
```haskell
import Database.Esqueleto.Experimental
```
This will conflict with the definition of `from` and `on` in the
`Database.Esqueleto` module, so you'll want to remove that import.
This style will become the new "default" in esqueleto-4.0.0.0, so it's a good
idea to port your code to using it soon.
The module documentation in `Database.Esqueleto.Experimental` has many examples,
and they won't be repeated here. Here's a quick sample:
```haskell
select $ do
(a :& b) <-
from $
Table @BlogPost
`InnerJoin`
Table @Person
`on` do \(bp :& a) ->
bp ^. BlogPostAuthorId ==. a ^. PersonId
pure (a, b)
```
Advantages:
- `ON` clause is attached directly to the relevant join, so you never need to
worry about how they're ordered, nor will you ever run into bugs where the
`on` clause is on the wrong `JOIN`
- The `ON` clause lambda will all the available tables in it. This forbids
runtime errors where an `ON` clause refers to a table that isn't in scope yet.
- You can join on a table twice, and the aliases work out fine with the `ON`
clause.
- You can use `UNION`, `EXCEPT`, `INTERSECTION` etc with this new syntax!
- You can reuse subqueries more easily.
## Legacy Joins
Implicit joins are represented by tuples. Implicit joins are represented by tuples.
@ -387,11 +430,13 @@ This will print 16 and also erase the `bar` table. The main take away of this ex
never use any user or third party input inside an unsafe function without first parsing it or never use any user or third party input inside an unsafe function without first parsing it or
heavily sanitizing the input. heavily sanitizing the input.
### Tests and Postgres ### Tests
To run the tests, do `stack test`. This tests all the backends, so you'll need To run the tests, do `stack test`. This tests all the backends, so you'll need
to have MySQL and Postgresql installed. to have MySQL and Postgresql installed.
#### Postgres
Using apt-get, you should be able to do: Using apt-get, you should be able to do:
``` ```
@ -417,23 +462,30 @@ withConn =
You can change these if you like but to just get them working set up as follows on linux: You can change these if you like but to just get them working set up as follows on linux:
```$ sudo -u postgres createuser esqutest```
```$ sudo -u postgres createdb esqutest```
``` ```
$ sudo -u postgres createuser esqutest
$ sudo -u postgres createdb esqutest
$ sudo -u postgres psql $ sudo -u postgres psql
postgres=# \password esqutest postgres=# \password esqutest
``` ```
And on osx And on osx
```$ createuser esqutest```
```$ createdb esqutest```
``` ```
$ createuser esqutest
$ createdb esqutest
$ psql postgres $ psql postgres
postgres=# \password esqutest postgres=# \password esqutest
``` ```
#### MySQL
To test MySQL, you'll need to have a MySQL server installation.
Then, you'll need to create a database `esqutest` and a `'travis'@'localhost'`
user which can access it:
```
mysql> CREATE DATABASE esqutest;
mysql> CREATE USER 'travis'@'localhost';
mysql> GRANT ALL ON esqutest.* TO 'travis';
```

View File

@ -1,3 +1,25 @@
3.3.4.0
=======
- @parsonsmatt
- [#205](https://github.com/bitemyapp/esqueleto/pull/205)
- More documentation on the `Experimental` module
- `Database.Esqueleto.Experimental` now reexports `Database.Esqueleto`, so
the new "approved" import syntax is less verbose. Before, you'd write:
```haskell
import Database.Esqueleto hiding (from, on)
import Database.Esqueleto.Experimental
```
Now you can merely write:
```haskell
import Database.Esqueleto.Experimental
```
Users will get 'redundant import' warnings if they followed the original
syntax, the solution is evident from the error message provided.
3.3.3.3 3.3.3.3
======= =======
- @belevy - @belevy

View File

@ -1,7 +1,7 @@
cabal-version: 1.12 cabal-version: 1.12
name: esqueleto name: esqueleto
version: 3.3.3.3 version: 3.3.4.0
synopsis: Type-safe EDSL for SQL queries on persistent backends. synopsis: Type-safe EDSL for SQL queries on persistent backends.
description: @esqueleto@ is a bare bones, type-safe EDSL for SQL queries that works with unmodified @persistent@ SQL backends. Its language closely resembles SQL, so you don't have to learn new concepts, just new syntax, and it's fairly easy to predict the generated SQL and optimize it for your backend. Most kinds of errors committed when writing SQL are caught as compile-time errors---although it is possible to write type-checked @esqueleto@ queries that fail at runtime. description: @esqueleto@ is a bare bones, type-safe EDSL for SQL queries that works with unmodified @persistent@ SQL backends. Its language closely resembles SQL, so you don't have to learn new concepts, just new syntax, and it's fairly easy to predict the generated SQL and optimize it for your backend. Most kinds of errors committed when writing SQL are caught as compile-time errors---although it is possible to write type-checked @esqueleto@ queries that fail at runtime.
. .

View File

@ -27,6 +27,11 @@
-- --
-- Other than identifier name clashes, @esqueleto@ does not -- Other than identifier name clashes, @esqueleto@ does not
-- conflict with @persistent@ in any way. -- conflict with @persistent@ in any way.
--
-- Note that the faciliites for @JOIN@ have been significantly improved in the
-- "Database.Esqueleto.Experimental" module. The definition of 'from' and 'on'
-- in this module will be replaced with those at the 4.0.0.0 version, so you are
-- encouraged to migrate to the new method.
module Database.Esqueleto module Database.Esqueleto
( -- * Setup ( -- * Setup
-- $setup -- $setup

View File

@ -12,6 +12,12 @@
, PatternSynonyms , PatternSynonyms
#-} #-}
-- | This module contains a new way (introduced in 3.3.3.0) of using @FROM@ in
-- Haskell. The old method was a bit finicky and could permit runtime errors,
-- and this new way is both significantly safer and much more powerful.
--
-- Esqueleto users are encouraged to migrate to this module, as it will become
-- the default in a new major version @4.0.0.0@.
module Database.Esqueleto.Experimental module Database.Esqueleto.Experimental
( -- * Setup ( -- * Setup
-- $setup -- $setup
@ -39,9 +45,12 @@ module Database.Esqueleto.Experimental
, ToAliasT , ToAliasT
, ToAliasReference(..) , ToAliasReference(..)
, ToAliasReferenceT , ToAliasReferenceT
-- * The Normal Stuff
, module Database.Esqueleto
) )
where where
import Database.Esqueleto hiding (from, on, From(..))
import qualified Control.Monad.Trans.Writer as W import qualified Control.Monad.Trans.Writer as W
import qualified Control.Monad.Trans.State as S import qualified Control.Monad.Trans.State as S
import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Class (lift)

View File

@ -137,6 +137,12 @@ where_ expr = Q $ W.tell mempty { sdWhereClause = Where expr }
-- and tuple-joins do not need an 'on' clause, but 'InnerJoin' and the various -- and tuple-joins do not need an 'on' clause, but 'InnerJoin' and the various
-- outer joins do. -- outer joins do.
-- --
-- Note that this function will be replaced by the one in
-- "Database.Esqueleto.Experimental" in version 4.0.0.0 of the library. The
-- @Experimental@ module has a dramatically improved means for introducing
-- tables and entities that provides more power and less potential for runtime
-- errors.
--
-- If you don't include an 'on' clause (or include too many!) then a runtime -- If you don't include an 'on' clause (or include too many!) then a runtime
-- exception will be thrown. -- exception will be thrown.
-- --
@ -1397,6 +1403,12 @@ class ToBaseId ent where
-- | @FROM@ clause: bring entities into scope. -- | @FROM@ clause: bring entities into scope.
-- --
-- Note that this function will be replaced by the one in
-- "Database.Esqueleto.Experimental" in version 4.0.0.0 of the library. The
-- @Experimental@ module has a dramatically improved means for introducing
-- tables and entities that provides more power and less potential for runtime
-- errors.
--
-- This function internally uses two type classes in order to -- This function internally uses two type classes in order to
-- provide some flexibility of how you may call it. Internally -- provide some flexibility of how you may call it. Internally
-- we refer to these type classes as the two different magics. -- we refer to these type classes as the two different magics.