Skip to content

Commit

Permalink
Regenerate content
Browse files Browse the repository at this point in the history
  • Loading branch information
snoyberg committed Apr 5, 2024
1 parent bcbb42a commit 63c795e
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 31 deletions.
4 changes: 2 additions & 2 deletions book/generated-xml/deploying-your-webapp.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Edit the <literal>config/keter.yaml</literal> file in your scaffolded applicatio
</listitem>
<listitem>
<simpara>
Set up some kind of server for hosting yours apps. I recommend trying Ubuntu on Amazon EC2.
Set up some kind of server for hosting your apps. I recommend trying Ubuntu on Amazon EC2.
</simpara>
</listitem>
<listitem>
Expand Down Expand Up @@ -245,7 +245,7 @@ behind it instead.</simpara>
<simpara>Keter configuration is trivial, since it is designed to work with Yesod
applications. But if you want to instead use Nginx, how do you set it up?</simpara>
<simpara>In general, Nginx will listen on port 80 and your Yesod/Warp app will listen on
some unprivileged port (lets say 4321). You will then need to provide a
some unprivileged port (let&#8217;s say 4321). You will then need to provide a
nginx.conf file, such as:</simpara>
<screen>daemon off; # Don't run nginx in the background, good for monitoring apps
events {
Expand Down
89 changes: 60 additions & 29 deletions book/generated-xml/persistent.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ Persistent on its own.</simpara>
<section id="persistent_synopsis">
<title>Synopsis</title>
<simpara>The required dependencies for the below are: persistent, persistent-sqlite and persistent-template.</simpara>
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE EmptyDataDecls #-}
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
Expand Down Expand Up @@ -333,7 +336,10 @@ filter, the types of the filtering value match the field. There&#8217;s another
associated newtype for the database primary key of this entity.</simpara>
<simpara>We can use the generated <literal>Person</literal> type like any other Haskell type, and then
pass it off to other Persistent functions.</simpara>
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE EmptyDataDecls #-}
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
Expand All @@ -342,11 +348,6 @@ pass it off to other Persistent functions.</simpara>
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}

import Control.Monad.IO.Class (liftIO)
import Database.Persist
Expand All @@ -358,7 +359,7 @@ import Control.Monad.Reader
import Control.Monad.Logger
import Conduit

share [mkPersist sqlSettings, mkEntityDefList "entityDefs"] [persistLowerCase|
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Person
name String
age Int Maybe
Expand Down Expand Up @@ -445,7 +446,10 @@ an error message about a missing table.</simpara>
<simpara>For SQL databases, one of the major pains can be managing schema changes.
Instead of leaving this to the user, Persistent steps in to help, but you have
to <emphasis>ask</emphasis> it to help. Let&#8217;s see what this looks like:</simpara>
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE EmptyDataDecls #-}
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
Expand All @@ -454,11 +458,6 @@ to <emphasis>ask</emphasis> it to help. Let&#8217;s see what this looks like:</s
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}

import Control.Monad.IO.Class (liftIO)
import Database.Persist
Expand All @@ -470,7 +469,7 @@ import Control.Monad.Reader
import Control.Monad.Logger
import Conduit

share [mkPersist sqlSettings, mkEntityDefList "entityDefs"] [persistLowerCase|
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Person
name String
age Int Maybe
Expand All @@ -494,7 +493,10 @@ review and testing that should take place before production deployments.</simpar
<simpara>This works when dealing with just a few entities, but can quickly get tiresome
once we are dealing with a dozen entities. Instead of repeating yourself,
Persistent provides a helper function, <literal>mkMigrate</literal>:</simpara>
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE EmptyDataDecls #-}
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
Expand Down Expand Up @@ -597,7 +599,10 @@ unique.</simpara>
<simpara>While each field name must begin with a lowercase letter, the uniqueness
constraints must begin with an uppercase letter, since it will be represented
in Haskell as a data constructor.</simpara>
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE EmptyDataDecls #-}
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
Expand Down Expand Up @@ -719,8 +724,7 @@ rowsep="1" colsep="1"
<entry align="left" valign="top"><simpara>A <literal>Source</literal> containing all the IDs and values from the database. This allows you to write streaming code.</simpara>
<simpara>NOTE: A <literal>Source</literal> is a stream of data, and is part of the <literal>conduit</literal> package. I
recommend reading the
<ulink url="https://www.fpcomplete.com/user/snoyberg/library-documentation/conduit-overview">School
of Haskell conduit tutorial</ulink> to get started.</simpara></entry>
<ulink url="https://github.com/snoyberg/conduit">Official Conduit tutorial</ulink> to get started.</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>selectList</simpara></entry>
Expand Down Expand Up @@ -994,7 +998,10 @@ two words on a line.</simpara>
<simpara>Suppose we want to have a <literal>Person</literal> entity with an (optional) age and the
timestamp of when he/she was added to the system. For entities already in the
database, we want to just use the current date-time for that timestamp.</simpara>
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE EmptyDataDecls #-}
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
Expand Down Expand Up @@ -1031,7 +1038,10 @@ nullable.</simpara>
understood by the database. In this case, it uses the database&#8217;s built-in
<literal>CURRENT_TIME</literal> function. Suppose that we now want to add a field for a person&#8217;s
favorite programming language:</simpara>
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE EmptyDataDecls #-}
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
Expand Down Expand Up @@ -1064,7 +1074,10 @@ database schema and automatic migrations.</simpara></note>
properly interpret it. Finally, Persistent can use double quotes for containing
white space, so if we want to set someone&#8217;s default home country to be El
Salvador:</simpara>
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE EmptyDataDecls #-}
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
Expand Down Expand Up @@ -1111,7 +1124,10 @@ up-to-date list is maintained
<simpara>Persistent allows references between your data types in a manner that is
consistent with supporting non-SQL databases. We do this by embedding an ID in
the related entity. So if a person has many cars:</simpara>
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE EmptyDataDecls #-}
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
Expand Down Expand Up @@ -1150,7 +1166,10 @@ many-to-many relationships, we need a join entity, which has a one-to-many
relationship with each of the original tables. It is also a good idea to use
uniqueness constraints on these. For example, to model a situation where we
want to track which people have shopped in which stores:</simpara>
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE EmptyDataDecls #-}
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
Expand Down Expand Up @@ -1244,7 +1263,7 @@ Post
<simpara>We know that <literal>BlogId</literal> is just a type synonym for <literal>Key Blog</literal>, but how will <literal>Key
Blog</literal> be defined? We can&#8217;t use an <literal>Int64</literal>, since that won&#8217;t work for MongoDB.
And we can&#8217;t use <literal>ByteString</literal>, since that won&#8217;t work for SQL databases.</simpara>
<simpara>To allow for this, once <literal>mpsGeneric</literal> is set to <literal>True</literal>, out resulting datatypes have a type parameter to indicate the database backend they use, so that keys can be properly encoded. This looks like:</simpara>
<simpara>To allow for this, once <literal>mpsGeneric</literal> is set to <literal>True</literal>, our resulting datatypes have a type parameter to indicate the database backend they use, so that keys can be properly encoded. This looks like:</simpara>
<programlisting language="haskell" linenumbering="unnumbered">data BlogGeneric backend = Blog { blogTitle :: Text }
data PostGeneric backend = Post
{ postTitle :: Text
Expand Down Expand Up @@ -1281,7 +1300,10 @@ import Database.Persist.TH
data Employment = Employed | Unemployed | Retired
deriving (Show, Read, Eq)
derivePersistField "Employment"</programlisting>
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE EmptyDataDecls #-}
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
Expand Down Expand Up @@ -1330,7 +1352,10 @@ interface exclusively.)</simpara>
<note><simpara>Actually, you <emphasis>can</emphasis> express a LIKE operator directly in the normal syntax
due to a feature added in Persistent 0.6, which allows backend-specific
operators. But this is still a good example, so let&#8217;s roll with it.</simpara></note>
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE EmptyDataDecls #-}
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
Expand Down Expand Up @@ -1377,7 +1402,10 @@ here to point out how it works under the surface.</simpara>
<simpara>The yesod-persistent package provides the meeting point between Persistent and
Yesod. It provides the <literal>YesodPersist</literal> typeclass, which standardizes access to
the database via the <literal>runDB</literal> method. Let&#8217;s see this in action.</simpara>
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE EmptyDataDecls #-}
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
Expand Down Expand Up @@ -1484,7 +1512,10 @@ Persistent knowledge should transfer over easily.</simpara>
<section id="persistent_something_besides_sqlite">
<title>Something besides SQLite</title>
<simpara>To keep the examples in this chapter simple, we&#8217;ve used the SQLite backend. Just to round things out, here&#8217;s our original synopsis rewritten to work with PostgreSQL:</simpara>
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE EmptyDataDecls #-}
<programlisting language="haskell" linenumbering="unnumbered">{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
Expand Down
17 changes: 17 additions & 0 deletions book/generated-xml/routing-and-handlers.xml
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,23 @@ syntax should be preferred as it&#8217;s clearer what the goal is.</simpara></no
should <literal>/foo/bar</literal> route to <literal>Foo1R</literal> or <literal>Foo3R</literal>? And should <literal>/foo/42</literal> route to
<literal>Foo2R</literal> or <literal>Foo3R</literal>? Yesod&#8217;s rule for this is simple: first route wins.</simpara>
</section>
<section id="routing-and-handlers_empty_literal_string_literal_or_literal_text_literal_as_dynamic_piece">
<title>Empty <literal>#String</literal> or <literal>#Text</literal> as dynamic piece</title>
<simpara>Consider the following route declaration:</simpara>
<programlisting language="routes" linenumbering="unnumbered">/hello HelloR GET
/hello/#String HelloNameR GET</programlisting>
<simpara>Let&#8217;s say a user requests the path <literal>/hello/</literal> – which handler would respond to the request?</simpara>
<simpara>It will be <literal>HelloR</literal> because Yesod&#8217;s dispatch mechanism removes trailing slashes and
redirects to the canonical form of the URL (see section <xref linkend="_pieces"/>).</simpara>
<simpara>If users actually want to address the <literal>HelloNameR</literal> handler with an
empty string as argument they need to request the path <literal>/hello/-</literal>
instead. Yesod automatically converts the Minus sign to the empty string.</simpara>
<simpara>Likewise, the resulting URL for <literal>@{HelloNameR ""}</literal> would be <literal>/hello/-</literal>.</simpara>
<simpara>Also, to disambiguate a single actual <literal>-</literal>, Yesod prefixes that piece with another Minus sign when rendering the URL.
Consequently, Yesod also prefixes any string consisting only of Minus signs with one single Minus sign.</simpara>
<note><simpara>This conversion between empty string in Haskell and <literal>-</literal> in the
URL applies for <literal>#String</literal> and <literal>#Text</literal> pieces as well.</simpara></note>
</section>
</section>
<section id="routing-and-handlers_resource_name">
<title>Resource name</title>
Expand Down

0 comments on commit 63c795e

Please sign in to comment.