Skip to content

Commit bd22ee5

Browse files
committed
docs
1 parent eaf6e56 commit bd22ee5

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,75 @@ tutorial](tutorial/tutorial/Main.hs).
6464
| Server: stream updates over WebSocket | | |
6565
| Server: permission checks | | |
6666
| Reflex (client-side) MonadDb instance | | |
67+
68+
## Documentation
69+
70+
The following attempts to descibe how the library works, and the various type
71+
classes involved. However it is recommended to begin by reading through the code
72+
in the [runnable tutorial](tutorial/tutorial/Main.hs), and only come back and
73+
read this if you feel you need to.
74+
75+
### Necessary Instances
76+
77+
The easiest way to use a data type with this library is to:
78+
- ensure the data type only has one constructor
79+
- derive a `Generic` instance
80+
- derive a `PrimaryKey` instance
81+
- ensure each field has a `FromDbValues` instance (for reading)
82+
- ensure each field has a `HasDbType` instance (for schema)
83+
- ensure each field has a `ToDbValues` instance (for writing)
84+
85+
Here is a simple example which meets all of the criteria:
86+
``` hs
87+
data Person = Person { age :: !Int64, name :: !String, ownsDog :: !(Maybe Bool) }
88+
deriving (Generic, PrimaryKey "name")
89+
```
90+
91+
Since `Person` meets all of the critera, a few type classes will be
92+
automatically derived for `Person` via `Generic`:
93+
- `HasDbColumns Person`: to provide a database schema
94+
- `HasEntityName Person`: to provide a database schema
95+
- `FromDbValues Person`: to convert from database values
96+
- `ToDbValues Person`: to convert to database values
97+
98+
### HasDbColumns
99+
100+
`HasDbColumns` is responsible for converting each field into a named field along
101+
with type information. Here is the definition of `HasDbColumns`:
102+
``` hs
103+
class HasDbColumns a where
104+
dbColumns :: [(FieldName, DbTypeN)]
105+
```
106+
107+
For our `Person` data type, `dbColumns` will return:
108+
``` hs
109+
[ (FieldName "age" , DbTypeN False (DbInt64 Unit))
110+
, (FieldName "name" , DbTypeN False (DbString Unit))
111+
, (FieldName "ownsdog", DbTypeN True (DbBool Unit))
112+
]
113+
```
114+
115+
To customize column names just create an instance of `FieldNameTransformation`.
116+
``` hs
117+
instance FieldNameTransformation Person where
118+
fieldNameT = toSnakeCase
119+
```
120+
121+
### HasEntityName
122+
123+
When using the provided `PostgreSQL` database type, a `createTable @Person`
124+
statement will be translated to the following SQL:
125+
126+
``` sql
127+
CREATE TABLE (age BIGINT NOT NULL, name VARCHAR NOT NULL PRIMARY KEY, ownsdog BOOLEAN);
128+
```
129+
130+
### FromDBValues
131+
132+
Above we mentioned that each field of a data type needs to have a `FromDbValues`
133+
instance. This is to ensure that each field can be parsed from a column value
134+
read from the database.
135+
136+
However `FromDbValues dbv a` is actually a multi-parameter type class. When
137+
using the provided `PostgreSQL` database the `dbv` will be instantiated to
138+
the library provided `DbValueN` type.

database-generic/src/Database/Generic/Entity/DbColumns.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ instance (HasDbType f, GHasDbColumns a [String] fs)
3232
=> GHasDbColumns a [String] (f, fs) where
3333
gDbColumns [] = error "impossible"
3434
gDbColumns (f:fs) =
35-
(fieldNameT $ FieldName f, dbType @f) : gDbColumns @a @_ @fs fs
35+
(fieldNameT @a $ FieldName f, dbType @f) : gDbColumns @a @_ @fs fs
3636

3737
instance GHasDbColumns a [String] () where
3838
gDbColumns [] = []

0 commit comments

Comments
 (0)