on master help sign in
s/Identity/Result/ in readthedocs
6396ea1Oliver Charles
docs/concepts/dbtype.rst+18−17
@@ -11,18 +11,19 @@ though most of these primitive ``DBType``\s should already be available.
11Combining ``newtype`` and ``DBType``
11Combining ``newtype`` and ``DBType``
12------------------------------------
12------------------------------------
13
13
14−You can define new instances of ``DBType`` by using Haskell "generalized newtype
14+You can define new instances of ``DBType`` by using Haskell "generalized
15−deriving" strategy. This is useful when you have a common database type, but
15+newtype deriving" strategy. This is useful when you have a common database
16−need to interpret this type differently in different contexts. A very common
16+type, but need to interpret this type differently in different contexts. A very
17−example here is with auto-incrementing ``id`` counters. In PostgreSQL, it's
17+common example here is with auto-incrementing ``id`` counters. In PostgreSQL,
18−common for a table to have a primary key that uses the ``serial`` type, which
18+it's common for a table to have a primary key that uses the ``serial`` type,
19−means the key is an ``int8`` with a default value for ``INSERT``. In Rel8, we
19+which means the key is an ``int8`` with a default value for ``INSERT``. In
20−could use ``Int64`` (as ``Int64`` is the ``DBType`` instance for ``int8``), but
20+Rel8, we could use ``Int64`` (as ``Int64`` is the ``DBType`` instance for
21−we can be even clearer if we make a ``newtype`` for each *type* of id.
21+``int8``), but we can be even clearer if we make a ``newtype`` for each *type*
22−
22+of id.
23+
23−If our database has users and orders, these tables might both have ids, but they
24+If our database has users and orders, these tables might both have ids, but
24−are clearly not meant to be treated as a common type. Instead, we can make these
25+they are clearly not meant to be treated as a common type. Instead, we can make
25−types clearly different by writing::
26+these types clearly different by writing::
26
27
27 newtype UserId = UserId { getUserId :: Int64 }
28 newtype UserId = UserId { getUserId :: Int64 }
28 deriving newtype DBType
29 deriving newtype DBType
@@ -57,8 +58,8 @@ In our PostgreSQL we have a few choices, but for now we'll assume that they are
57stored as ``text`` values.
58stored as ``text`` values.
58
59
59In order to use this type in Rel8 queries, we need to write an instance of
60In order to use this type in Rel8 queries, we need to write an instance of
60−``DBType`` for ``OrderStatus``. One approach is to use ``parseTypeInformation``,
61+``DBType`` for ``OrderStatus``. One approach is to use
61−which allows you to refine an existing ``DBType``::
62+``parseTypeInformation``, which allows you to refine an existing ``DBType``::
62
63
63 instance DBType OrderStatus where
64 instance DBType OrderStatus where
64 typeInformation = parseTypeInformation parser printer typeInformation
65 typeInformation = parseTypeInformation parser printer typeInformation
@@ -100,9 +101,9 @@ There usage is very similar to ``ReadShow`` - simply derive ``DBType via
100JSONEncoded``, and Rel8 will use ``ToJSON`` and ``FromJSON`` instances (from
101JSONEncoded``, and Rel8 will use ``ToJSON`` and ``FromJSON`` instances (from
101``aeson``) to serialize the given type.
102``aeson``) to serialize the given type.
102
103
103−For example, a project might use event sourcing with a table of events. Each row
104+For example, a project might use event sourcing with a table of events. Each
104−in this table is an event, but this event is stored as a JSON object. We can use
105+row in this table is an event, but this event is stored as a JSON object. We
105−this type with Rel8 by writing::
106+can use this type with Rel8 by writing::
106
107
107 data Event = UserCreated UserCreatedData | OrderCreated OrderCreatedData
108 data Event = UserCreated UserCreatedData | OrderCreated OrderCreatedData
108 deriving stock Generic
109 deriving stock Generic
docs/concepts/expr.rst+2−2
@@ -58,7 +58,7 @@ Through the API reference documentation for Rel8, you might encounter the
58``Sql`` type class. For example, if we look at the type of ``litExpr``, we
58``Sql`` type class. For example, if we look at the type of ``litExpr``, we
59have::
59have::
60
60
61− litExpr :: Sql DBType a => a -> Expr a
61+ litExpr :: Sql DBType a => a -> Expr a
62
62
63Here ``Sql DBType a`` means that ``a`` can either be literally a type that has
63Here ``Sql DBType a`` means that ``a`` can either be literally a type that has
64an instance of ``DBType`` (like ``UserId`` or ``Bool``), *or* that same type
64an instance of ``DBType`` (like ``UserId`` or ``Bool``), *or* that same type
@@ -69,6 +69,6 @@ Some functions work regardless of whether or not a value is null, and in these
69cases you'll see ``Sql DBType a``. ``Sql`` can be used with any ``DBType``
69cases you'll see ``Sql DBType a``. ``Sql`` can be used with any ``DBType``
70subtype. For example, the type of ``div`` is::
70subtype. For example, the type of ``div`` is::
71
71
72− div :: Sql DBIntegral a => Expr a -> Expr a -> Expr a
72+ div :: Sql DBIntegral a => Expr a -> Expr a -> Expr a
73
73
74Which means ``div`` works on any ``DBIntegral a``, including ``Maybe a``.
74Which means ``div`` works on any ``DBIntegral a``, including ``Maybe a``.
docs/tutorial.rst+17−17
@@ -5,7 +5,7 @@ Getting Started
5
5
6In this section, we'll take a look at using Rel8 to work with a small database
6In this section, we'll take a look at using Rel8 to work with a small database
7for Haskell packages. We'll take a look at idiomatic usage of Rel8, mapping
7for Haskell packages. We'll take a look at idiomatic usage of Rel8, mapping
8−tables to Haskell, and then look at writing some simple queries.
8+tables to Haskell, and then look at writing some simple queries.
9
9
10Before we get started, we'll be using the following language extensions and
10Before we get started, we'll be using the following language extensions and
11imports throughout this guide::
11imports throughout this guide::
@@ -70,7 +70,7 @@ Following these steps for ``author``, we have::
70 { authorId :: Column f Int64
70 { authorId :: Column f Int64
71 , name :: Column f Text
71 , name :: Column f Text
72 , url :: Column f (Maybe Text)
72 , url :: Column f (Maybe Text)
73− }
73+ }
74 deriving stock (Generic)
74 deriving stock (Generic)
75 deriving anyclass (Rel8able)
75 deriving anyclass (Rel8able)
76
76
@@ -81,7 +81,7 @@ in our project, it would be too easy to accidentally mix them up and create
81nonsensical joins. As Haskell programmers, we often solve this problem by
81nonsensical joins. As Haskell programmers, we often solve this problem by
82creating ``newtype`` wrappers, and we can also use this technique with Rel8::
82creating ``newtype`` wrappers, and we can also use this technique with Rel8::
83
83
84− newtype AuthorId = AuthorId { toInt64 :: Int64 }
84+ newtype AuthorId = AuthorId { toInt64 :: Int64 }
85 deriving newtype (DBEq, DBType, Eq, Show)
85 deriving newtype (DBEq, DBType, Eq, Show)
86
86
87Now we can write our final schema mapping. First, the ``author`` table::
87Now we can write our final schema mapping. First, the ``author`` table::
@@ -90,7 +90,7 @@ Now we can write our final schema mapping. First, the ``author`` table::
90 { authorId :: Column f AuthorId
90 { authorId :: Column f AuthorId
91 , authorName :: Column f Text
91 , authorName :: Column f Text
92 , authorUrl :: Column f (Maybe Text)
92 , authorUrl :: Column f (Maybe Text)
93− }
93+ }
94 deriving stock (Generic)
94 deriving stock (Generic)
95 deriving anyclass (Rel8able)
95 deriving anyclass (Rel8able)
96
96
@@ -99,7 +99,7 @@ And similarly, the ``project`` table::
99 data Project f = Project
99 data Project f = Project
100 { projectAuthorId :: Column f AuthorId
100 { projectAuthorId :: Column f AuthorId
101 , projectName :: Column f Text
101 , projectName :: Column f Text
102− }
102+ }
103 deriving stock (Generic)
103 deriving stock (Generic)
104 deriving anyclass (Rel8able
104 deriving anyclass (Rel8able
105
105
@@ -107,8 +107,8 @@ To show query results in this documentation, we'll also need ``Show`` instances:
107Unfortunately these definitions look a bit scary, but they are essentially just
107Unfortunately these definitions look a bit scary, but they are essentially just
108``deriving (Show)``::
108``deriving (Show)``::
109
109
110− deriving stock instance f ~ Identity => Show (Author f)
110+ deriving stock instance f ~ Result => Show (Author f)
111− deriving stock instance f ~ Identity => Show (Project f)
111+ deriving stock instance f ~ Result => Show (Project f)
112
112
113These data types describe the structural mapping of the tables, but we also
113These data types describe the structural mapping of the tables, but we also
114need to specify a ``TableSchema`` for each table. A ``TableSchema`` contains
114need to specify a ``TableSchema`` for each table. A ``TableSchema`` contains
@@ -169,7 +169,7 @@ database heavy applications.
169
169
170In Rel8, ``SELECT`` statements are built using the ``Query`` monad. You can
170In Rel8, ``SELECT`` statements are built using the ``Query`` monad. You can
171think of this monad like the ordinary ``[]`` (List) monad - but this isn't
171think of this monad like the ordinary ``[]`` (List) monad - but this isn't
172−required knowledge.
172+required knowledge.
173
173
174To start, we'll look at one of the simplest queries possible - a basic ``SELECT
174To start, we'll look at one of the simplest queries possible - a basic ``SELECT
175* FROM`` statement. To select all rows from a table, we use ``each``, and
175* FROM`` statement. To select all rows from a table, we use ``each``, and
@@ -193,17 +193,17 @@ expressions of type ``a``\".
193To execute this ``Query``, we pass it to ``select``::
193To execute this ``Query``, we pass it to ``select``::
194
194
195 >>> :t select c (each projectSchema)
195 >>> :t select c (each projectSchema)
196− select c (each projectSchema) :: MonadIO m => m [Project Identity]
196+ select c (each projectSchema) :: MonadIO m => m [Project Result]
197
197
198When we ``select`` things containing ``Expr``s, Rel8 builds a new response
198When we ``select`` things containing ``Expr``s, Rel8 builds a new response
199−table with the ``Identity`` interpretation. This means you'll get back plain
199+table with the ``Result`` interpretation. This means you'll get back plain
200Haskell values. Studying ``projectAuthorId`` again, we have::
200Haskell values. Studying ``projectAuthorId`` again, we have::
201
201
202− >>> let aProjectIdentity = undefined :: Project Identity
202+ >>> let aProjectResult = undefined :: Project Result
203− >>> :t projectAuthorId aProjectIdentity
203+ >>> :t projectAuthorId aProjectResult
204− projectAuthorId aProjectIdentity :: AuthorId
204+ projectAuthorId aProjectResult :: AuthorId
205
205
206−Here ``Column Identity AuthorId`` reduces to just ``AuthorId``, with no
206+Here ``Column Result AuthorId`` reduces to just ``AuthorId``, with no
207wrappping type at all.
207wrappping type at all.
208
208
209Putting this all together, we can run our first query::
209Putting this all together, we can run our first query::
@@ -343,8 +343,8 @@ focus on the /type/ of that query::
343 where
343 where
344
344
345 >>> :t select c authorsAndProjects
345 >>> :t select c authorsAndProjects
346− select c authorsAndProjects
346+ select c authorsAndProjects
347− :: MonadIO m => m [(Author Identity, Project Identity)]
347+ :: MonadIO m => m [(Author Result, Project Result)]
348
348
349
349
350Our query gives us a single list of pairs of authors and projects. However,
350Our query gives us a single list of pairs of authors and projects. However,
@@ -352,7 +352,7 @@ with our domain knowledge of the schema, this isn't a great type - what we'd
352rather have is a list of pairs of authors and /lists/ of projects. That is,
352rather have is a list of pairs of authors and /lists/ of projects. That is,
353what we'd like is::
353what we'd like is::
354
354
355− [(Author Identity, [Project Identity])]
355+ [(Author Result, [Project Result])]
356
356
357This would be a much better type! Rel8 can produce a query with this type by
357This would be a much better type! Rel8 can produce a query with this type by
358simply wrapping the call to ``projectsForAuthor`` with either ``some`` or
358simply wrapping the call to ``projectsForAuthor`` with either ``some`` or