mirror of
https://github.com/ilyakooo0/squeal.git
synced 2024-09-11 13:57:29 +03:00
Update and rename squeal-presentation-2018-09-12.html to squeal-presentation-raveline.md
This commit is contained in:
parent
b59425a7d7
commit
a16da6dd89
@ -1,46 +1,8 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Title</title>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<style>
|
|
||||||
@import url(https://fonts.googleapis.com/css?family=PT+Sans+Narrow);
|
|
||||||
@import url(https://fonts.googleapis.com/css?family=Montserrat:400,700,400italic);
|
|
||||||
@import url(https://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic);
|
|
||||||
|
|
||||||
body { font-family: 'Montserrat'; }
|
|
||||||
h1, h2, h3 {
|
|
||||||
font-family: 'PT Sans Narrow';
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note {
|
|
||||||
background-color: #ccc;
|
|
||||||
padding: 1rem;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
.remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; }
|
|
||||||
|
|
||||||
.signature {
|
|
||||||
position: absolute;
|
|
||||||
top: 1%;
|
|
||||||
right: 1%;
|
|
||||||
font-size:.6em;
|
|
||||||
opacity: .5;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<textarea id="source">
|
|
||||||
|
|
||||||
class: center, middle
|
|
||||||
count: false
|
|
||||||
|
|
||||||
# Squeal
|
# Squeal
|
||||||
|
|
||||||
_A bridge between SQL and Haskell_
|
_A bridge between SQL and Haskell_
|
||||||
|
|
||||||
.signature[2018/09/12 - by @Raveline]
|
by [@Raveline](https://github.com/raveline)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -62,9 +24,6 @@ Using `postgresql-simple` you have a typical "Trial, error, despair" workflow:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
class: center, middle
|
|
||||||
count: false
|
|
||||||
|
|
||||||
![Can't take this anymore](http://gif.eraveline.eu/static/img/0x16e.gif)
|
![Can't take this anymore](http://gif.eraveline.eu/static/img/0x16e.gif)
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -85,9 +44,6 @@ However, it's not an ORM. There's no caching, lazy loading - you retain control
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
class: center, middle
|
|
||||||
count: false
|
|
||||||
|
|
||||||
# Part I. Schema & migration
|
# Part I. Schema & migration
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -107,16 +63,13 @@ type Schema = '[ "mp" ::: 'Table MemberOfParliament
|
|||||||
, "groupp" ::: 'Table ParliamentGroup ]
|
, "groupp" ::: 'Table ParliamentGroup ]
|
||||||
```
|
```
|
||||||
|
|
||||||
--
|
---
|
||||||
|
|
||||||
.note[*
|
> _note_ We need the `DataKinds` extension to be able to express heterogenous lists containing
|
||||||
We need the `DataKinds` extension to be able to express heterogenous lists containing
|
> specific types like this one.
|
||||||
specific types like this one.
|
|
||||||
|
|
||||||
*
|
> You can perfectly call your table "group" and not "groupp" even though it is a
|
||||||
You can perfectly call your table "group" and not "groupp" even though it is a
|
> keyword in SQL - Squeal queries will be properly escaped.
|
||||||
keyword in SQL - Squeal queries will be properly escaped.
|
|
||||||
]
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -139,16 +92,12 @@ type ParliamentaryGroup =
|
|||||||
|
|
||||||
- Let's split constraints and column to study the syntax a bit more.
|
- Let's split constraints and column to study the syntax a bit more.
|
||||||
|
|
||||||
--
|
|
||||||
|
|
||||||
.note[*
|
|
||||||
We are using `:::` and `:=>` to quickly express associations when writing
|
|
||||||
our schema. We need the `TypeOperators` extension.]
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
class: center, middle
|
> _note_ We are using `:::` and `:=>` to quickly express associations when writing
|
||||||
count: false
|
> our schema. We need the `TypeOperators` extension.]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
![What does this means ?!](http://gif.eraveline.eu/static/img/0x27e.gif)
|
![What does this means ?!](http://gif.eraveline.eu/static/img/0x27e.gif)
|
||||||
|
|
||||||
@ -195,10 +144,10 @@ type MpCols =
|
|||||||
|
|
||||||
* the type (obviously).
|
* the type (obviously).
|
||||||
|
|
||||||
--
|
---
|
||||||
|
|
||||||
.note[*
|
> _note_ GHC is already helping. If I named the "mp_id" column differently,
|
||||||
GHC is already helping. If I named the "mp_id" column differently, GHC would yell because I promised a primary key constraint on a column named `mp_id`, so there must be one.]
|
> GHC would yell because I promised a primary key constraint on a column named `mp_id`, so there must be one.]
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -208,7 +157,7 @@ GHC is already helping. If I named the "mp_id" column differently, GHC would yel
|
|||||||
|
|
||||||
- But before we play with this schema, we need to implement it.
|
- But before we play with this schema, we need to implement it.
|
||||||
|
|
||||||
--
|
---
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
setup :: Definition '[] Schema
|
setup :: Definition '[] Schema
|
||||||
@ -240,15 +189,14 @@ setup =
|
|||||||
|
|
||||||
- You use `>>>` to compose table creation.
|
- You use `>>>` to compose table creation.
|
||||||
|
|
||||||
- Note that the compiler will catch any mistype between Schema and
|
> _note_ The compiler will catch any mistype between Schema and
|
||||||
definition; wrong nullability, wrong type, wrong name, etc.
|
> definition; wrong nullability, wrong type, wrong name, etc.
|
||||||
|
|
||||||
--
|
---
|
||||||
|
|
||||||
.note[*
|
> _note_ You'll also need `OverloadedLabels`, for naming stuff.
|
||||||
You'll also need `OverloadedLabels`, for naming stuff.
|
> This is mostly to avoid having to write manual proxies all
|
||||||
This is mostly to avoid having to write manual proxies all
|
> the time and for convenience.
|
||||||
the time and for convenience.]
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -283,8 +231,8 @@ tearDown :: Definition Schema '[]
|
|||||||
tearDown = dropTable #mp >>> dropTable #groupp
|
tearDown = dropTable #mp >>> dropTable #groupp
|
||||||
```
|
```
|
||||||
|
|
||||||
- Note that GHC will also detect the _proper_ order of what you typed in
|
> _note_ GHC will also detect the _proper_ order of what you typed in
|
||||||
downgrade and upgrade should there be any conflict (with foreign keys).
|
> downgrade and upgrade should there be any conflict (with foreign keys).
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
initDB :: Migration IO '[] Schema
|
initDB :: Migration IO '[] Schema
|
||||||
@ -314,16 +262,10 @@ main = do
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
class: center, middle
|
|
||||||
count: false
|
|
||||||
|
|
||||||
![That was easy](http://gif.eraveline.eu/static/img/0x47f.gif)
|
![That was easy](http://gif.eraveline.eu/static/img/0x47f.gif)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
class: center, middle
|
|
||||||
count: false
|
|
||||||
|
|
||||||
# Part II. Insertions
|
# Part II. Insertions
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -369,9 +311,8 @@ data MemberOfParliament =
|
|||||||
, lastName :: Text }
|
, lastName :: Text }
|
||||||
```
|
```
|
||||||
|
|
||||||
- You'll note that we didn't use anything from Squeal.
|
> _note_ We didn't use anything from Squeal.
|
||||||
|
> The model can be entirely separated from the persistence layer.
|
||||||
- The model can be entirely separated from the persistence layer.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -386,7 +327,7 @@ type GroupInsertionParams = '[ 'NotNull 'PGuuid
|
|||||||
|
|
||||||
- Params are not named, but they are indexed. You just need nullability and type.
|
- Params are not named, but they are indexed. You just need nullability and type.
|
||||||
|
|
||||||
--
|
---
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
groupInsertion :: Manipulation Schema GroupInsertionParams '[]
|
groupInsertion :: Manipulation Schema GroupInsertionParams '[]
|
||||||
@ -395,7 +336,7 @@ groupInsertion =
|
|||||||
:* Set (param @2) `as` #name )
|
:* Set (param @2) `as` #name )
|
||||||
```
|
```
|
||||||
|
|
||||||
--
|
---
|
||||||
|
|
||||||
- `TypeApplication` lets us use the index of parameters (counting from 1).
|
- `TypeApplication` lets us use the index of parameters (counting from 1).
|
||||||
|
|
||||||
@ -410,19 +351,19 @@ _Inserting a Member of Parliament_
|
|||||||
|
|
||||||
- We could create a naive query that takes MP uuid, first name, last name and group uuid...
|
- We could create a naive query that takes MP uuid, first name, last name and group uuid...
|
||||||
|
|
||||||
--
|
---
|
||||||
|
|
||||||
- But that's boring. So let's use the `INSERT INTO ... SELECT`.
|
- But that's boring. So let's use the `INSERT INTO ... SELECT`.
|
||||||
|
|
||||||
--
|
---
|
||||||
|
|
||||||
- We will build a query that will return as constants our MP's uuid, first name and last name...
|
- We will build a query that will return as constants our MP's uuid, first name and last name...
|
||||||
|
|
||||||
--
|
---
|
||||||
|
|
||||||
- ... and fetch the uuid of a group given the name of the group.
|
- ... and fetch the uuid of a group given the name of the group.
|
||||||
|
|
||||||
--
|
---
|
||||||
|
|
||||||
- There's a `insertQuery` utility function for that. All we have to do is write the `select` !
|
- There's a `insertQuery` utility function for that. All we have to do is write the `select` !
|
||||||
|
|
||||||
@ -572,16 +513,11 @@ insertParliament = traverse_ insertGroup
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
class: center, middle
|
|
||||||
count: false
|
|
||||||
|
|
||||||
![Very simple](https://media1.tenor.com/images/0188c63209aced59f1583e1ca94e509e/tenor.gif?itemid=3550689)
|
![Very simple](https://media1.tenor.com/images/0188c63209aced59f1583e1ca94e509e/tenor.gif?itemid=3550689)
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
class: center, middle
|
|
||||||
|
|
||||||
# Part III. Selects
|
# Part III. Selects
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -653,7 +589,7 @@ type BaseParliamentSelection =
|
|||||||
, "m" ::: TableToRow MpCols ]
|
, "m" ::: TableToRow MpCols ]
|
||||||
```
|
```
|
||||||
|
|
||||||
- Note that we've also put everything with table aliases: "g" and "m".
|
> _note_ We've also put everything with table aliases: "g" and "m".
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -831,16 +767,10 @@ getGroupMembers =
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
class: center, middle
|
|
||||||
count: false
|
|
||||||
|
|
||||||
![Eazy](https://media.tenor.com/images/8fc7c4077efe11b4a3a3b9ae4e643e87/tenor.gif)
|
![Eazy](https://media.tenor.com/images/8fc7c4077efe11b4a3a3b9ae4e643e87/tenor.gif)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
class: center, middle
|
|
||||||
count: false
|
|
||||||
|
|
||||||
# Conclusion
|
# Conclusion
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -860,17 +790,5 @@ count: false
|
|||||||
- Typesafe. 'nuff said.
|
- Typesafe. 'nuff said.
|
||||||
|
|
||||||
---
|
---
|
||||||
class: center, middle
|
|
||||||
count: false
|
|
||||||
|
|
||||||
# Thank you !
|
# Thank you !
|
||||||
|
|
||||||
|
|
||||||
</textarea>
|
|
||||||
<script src="https://remarkjs.com/downloads/remark-latest.min.js">
|
|
||||||
</script>
|
|
||||||
<script>
|
|
||||||
var slideshow = remark.create({countIncrementalSlides: false});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
Reference in New Issue
Block a user