mirror of
https://github.com/flipstone/orville.git
synced 2024-10-05 16:17:17 +03:00
Adds guide for adding Orville to an existing reader context
This commit is contained in:
parent
16c6ecad11
commit
117d17c83e
1
.gitignore
vendored
1
.gitignore
vendored
@ -35,3 +35,4 @@ orville-docsite/site-builder/_site
|
||||
# Ignore directories created by samples
|
||||
orville-docsite/samples/getting-started/orville-getting-started
|
||||
orville-docsite/samples/adding-orville-new-readert/src
|
||||
orville-docsite/samples/adding-orville-existing-readert/src
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
<a href="./how-tos/how-to-add-orville-to-your-application-monad.html">How To Add Orville to Your Application Monad</a>
|
||||
|
||||
<a href="./how-tos/how-to-add-orville-to-an-existing-reader-context.html">How To Add Orville to an Existing Reader Context</a>
|
||||
|
||||
<a href="./how-tos/how-to-marshall-a-haskell-record.html">How To Marshall a Haskell Record (Upcoming)</a>
|
||||
|
||||
<a href="./how-tos/how-to-add-custom-marshalling-validations.html">How Add Custom Marshalling Validations (Upcoming)</a>
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-your-application-monad.html">How To Add Orville to Your Application Monad</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-an-existing-reader-context.html">How To Add Orville to an Existing Reader Context</a>
|
||||
|
||||
<a href="../how-tos/how-to-marshall-a-haskell-record.html">How To Marshall a Haskell Record (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-custom-marshalling-validations.html">How Add Custom Marshalling Validations (Upcoming)</a>
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-your-application-monad.html">How To Add Orville to Your Application Monad</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-an-existing-reader-context.html">How To Add Orville to an Existing Reader Context</a>
|
||||
|
||||
<a href="../how-tos/how-to-marshall-a-haskell-record.html">How To Marshall a Haskell Record (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-custom-marshalling-validations.html">How Add Custom Marshalling Validations (Upcoming)</a>
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-your-application-monad.html">How To Add Orville to Your Application Monad</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-an-existing-reader-context.html">How To Add Orville to an Existing Reader Context</a>
|
||||
|
||||
<a href="../how-tos/how-to-marshall-a-haskell-record.html">How To Marshall a Haskell Record (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-custom-marshalling-validations.html">How Add Custom Marshalling Validations (Upcoming)</a>
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-your-application-monad.html">How To Add Orville to Your Application Monad</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-an-existing-reader-context.html">How To Add Orville to an Existing Reader Context</a>
|
||||
|
||||
<a href="../how-tos/how-to-marshall-a-haskell-record.html">How To Marshall a Haskell Record (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-custom-marshalling-validations.html">How Add Custom Marshalling Validations (Upcoming)</a>
|
||||
|
@ -0,0 +1,353 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Orville - How To Add Orville to an Existing Reader Context</title>
|
||||
<link rel="stylesheet" href="../css/syntax.css" />
|
||||
<link rel="stylesheet" href="../css/default.css" />
|
||||
</head>
|
||||
<body>
|
||||
<section class="leftbar">
|
||||
<header>
|
||||
<h1 class="logo">
|
||||
<a href="../">
|
||||
<img alt="Orville Logo" src="../images/orville-waving-pennant.svg" />
|
||||
</a>
|
||||
</h1>
|
||||
</header>
|
||||
|
||||
<nav>
|
||||
<h3><a href="../">Home</a></h3>
|
||||
|
||||
<h3>Tutorials</h3>
|
||||
|
||||
<a href="../tutorials/getting-started.html">Getting Started</a>
|
||||
|
||||
<a href="../tutorials/using-sql-marshaller.html">Using SqlMarshaller</a>
|
||||
|
||||
<a href="../tutorials/using-migrations.html">Using Migrations</a>
|
||||
|
||||
<a href="../tutorials/using-plans.html">Using Plans</a>
|
||||
|
||||
<a href="../tutorials/using-json.html">Using JSON</a>
|
||||
|
||||
|
||||
<h3>How-To Guides</h3>
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-your-application-monad.html">How To Add Orville to Your Application Monad</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-an-existing-reader-context.html">How To Add Orville to an Existing Reader Context</a>
|
||||
|
||||
<a href="../how-tos/how-to-marshall-a-haskell-record.html">How To Marshall a Haskell Record (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-custom-marshalling-validations.html">How Add Custom Marshalling Validations (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-marshall-a-haskell-sum-type.html">How To Marshall a Haskell Sum Type (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-set-up-an-auto-incrementing-id-column.html">How To Set Up An Auto-incrementing Id Column (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-execute-raw-sql.html">How To Execute Raw SQL (Upcoming)</a>
|
||||
|
||||
|
||||
<h3>Futher Explanation</h3>
|
||||
|
||||
<a href="../explanations/the-monad-orville-typeclass.html">The MonadOrville Typeclass (Upcoming)</a>
|
||||
|
||||
<a href="../explanations/building-sql-expressions.html">Building SQL Expressions (Upcoming)</a>
|
||||
|
||||
<a href="../explanations/fighting-n-plus-one-queries-with-plans.html">Fighting N+1 Queries with Plans (Upcoming)</a>
|
||||
|
||||
|
||||
<h3>API Reference</h3>
|
||||
<a href="https://hackage.haskell.org/package/orville-postgresql">See Hackage</a>
|
||||
|
||||
<h3>Other Links</h3>
|
||||
<a href="../contact.html">Contact</a>
|
||||
</nav>
|
||||
|
||||
<footer>
|
||||
Site proudly generated by
|
||||
<a href="http://jaspervdj.be/hakyll">Hakyll</a>
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<main role="main">
|
||||
<h1>How To Add Orville to an Existing Reader Context</h1>
|
||||
<article>
|
||||
<section>
|
||||
<p>This guide will show you how to add Orville to a monad that is already using
|
||||
<code>ReaderT</code> in its monad stack. It builds conceptually on top of <a href="how-to-add-orville-to-your-application-monad.html">the previous
|
||||
guide</a>, which assumed there
|
||||
was not already a <code>ReaderT</code> in the application monad stack. It’s recommended
|
||||
that you read that guide before this one.</p>
|
||||
<p>The file listing below shows a simple application with its own <code>Application</code>
|
||||
monad that already has a reader context. When there is already a reader context
|
||||
in the application stack it’s generally perferrable to incorporate Orville into
|
||||
the existing reader context rather than adding a new <code>ReaderT</code> layer atop the
|
||||
one that’s already there.</p>
|
||||
<div class="codeblock-label">
|
||||
Main.hs (Before) : haskell
|
||||
</div>
|
||||
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE GeneralizedNewtypeDeriving #-}</span></span>
|
||||
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Main</span></span>
|
||||
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a> ( main</span>
|
||||
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a> ) <span class="kw">where</span></span>
|
||||
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Control.Monad.IO.Class</span> <span class="kw">as</span> <span class="dt">MIO</span></span>
|
||||
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Control.Monad.Reader</span> <span class="kw">as</span> <span class="dt">Reader</span></span>
|
||||
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">ApplicationContext</span> <span class="ot">=</span></span>
|
||||
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">ApplicationContext</span></span>
|
||||
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a> {<span class="ot"> applicationGreeting ::</span> <span class="dt">String</span></span>
|
||||
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a> }</span>
|
||||
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Application</span> a <span class="ot">=</span></span>
|
||||
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a> <span class="dt">Application</span> (<span class="dt">Reader.ReaderT</span> <span class="dt">ApplicationContext</span> <span class="dt">IO</span> a)</span>
|
||||
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a> <span class="kw">deriving</span></span>
|
||||
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a> ( <span class="dt">Functor</span></span>
|
||||
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a> , <span class="dt">Applicative</span></span>
|
||||
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a> , <span class="dt">Monad</span></span>
|
||||
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a> , <span class="dt">MIO.MonadIO</span></span>
|
||||
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a> )</span>
|
||||
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a><span class="ot">getGreeting ::</span> <span class="dt">Application</span> <span class="dt">String</span></span>
|
||||
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>getGreeting <span class="ot">=</span></span>
|
||||
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a> <span class="dt">Application</span> (Reader.asks applicationGreeting)</span>
|
||||
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a><span class="ot">runApplication ::</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">Application</span> a <span class="ot">-></span> <span class="dt">IO</span> a</span>
|
||||
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a>runApplication greeting (<span class="dt">Application</span> io) <span class="ot">=</span></span>
|
||||
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a> <span class="kw">let</span></span>
|
||||
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a> context <span class="ot">=</span></span>
|
||||
<span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a> <span class="dt">ApplicationContext</span></span>
|
||||
<span id="cb1-32"><a href="#cb1-32" aria-hidden="true" tabindex="-1"></a> { applicationGreeting <span class="ot">=</span> greeting</span>
|
||||
<span id="cb1-33"><a href="#cb1-33" aria-hidden="true" tabindex="-1"></a> }</span>
|
||||
<span id="cb1-34"><a href="#cb1-34" aria-hidden="true" tabindex="-1"></a> <span class="kw">in</span></span>
|
||||
<span id="cb1-35"><a href="#cb1-35" aria-hidden="true" tabindex="-1"></a> Reader.runReaderT io context</span>
|
||||
<span id="cb1-36"><a href="#cb1-36" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb1-37"><a href="#cb1-37" aria-hidden="true" tabindex="-1"></a><span class="ot">myApplication ::</span> <span class="dt">Application</span> ()</span>
|
||||
<span id="cb1-38"><a href="#cb1-38" aria-hidden="true" tabindex="-1"></a>myApplication <span class="ot">=</span> <span class="kw">do</span></span>
|
||||
<span id="cb1-39"><a href="#cb1-39" aria-hidden="true" tabindex="-1"></a> greeting <span class="ot"><-</span> getGreeting</span>
|
||||
<span id="cb1-40"><a href="#cb1-40" aria-hidden="true" tabindex="-1"></a> MIO.liftIO <span class="op">.</span> <span class="fu">putStrLn</span> <span class="op">$</span> greeting</span>
|
||||
<span id="cb1-41"><a href="#cb1-41" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb1-42"><a href="#cb1-42" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">IO</span> ()</span>
|
||||
<span id="cb1-43"><a href="#cb1-43" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span></span>
|
||||
<span id="cb1-44"><a href="#cb1-44" aria-hidden="true" tabindex="-1"></a> runApplication <span class="st">"Hello Application"</span> myApplication</span></code></pre></div>
|
||||
<p>As in <a href="how-to-add-orville-to-your-application-monad.html">the last guide</a>, we
|
||||
will first add an <code>OrvilleState</code> to our application monad. In this case we’ll
|
||||
add it as a new field to the existing <code>ApplicationContext</code>.</p>
|
||||
<div class="codeblock-label">
|
||||
Main.hs : diff
|
||||
</div>
|
||||
<div class="sourceCode" id="cb2"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">*** Main.hs (Old)</span></span>
|
||||
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="kw">--- Main.hs (New)</span></span>
|
||||
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="dt">***************</span></span>
|
||||
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="dt">*** 7,8 ****</span></span>
|
||||
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="dt">--- 7,9 ----</span></span>
|
||||
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a> import qualified Control.Monad.Reader as Reader</span>
|
||||
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="va">+ import qualified Orville.PostgreSQL as O</span></span>
|
||||
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a> </span>
|
||||
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="dt">***************</span></span>
|
||||
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a><span class="dt">*** 11,12 ****</span></span>
|
||||
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a><span class="dt">--- 12,14 ----</span></span>
|
||||
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a> { applicationGreeting :: String</span>
|
||||
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a><span class="va">+ , applicationOrvilleState :: O.OrvilleState</span></span>
|
||||
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a> }</span></code></pre></div>
|
||||
<p>This requires that the new <code>applicationOrvilleState</code> field be populated in the
|
||||
<code>runApplication</code> function using a <code>ConnectionPool</code>. The <code>ConnectionPool</code> is
|
||||
created in the <code>main</code> function and passed in where <code>runApplication</code> is called.</p>
|
||||
<div class="codeblock-label">
|
||||
Main.hs : diff
|
||||
</div>
|
||||
<div class="sourceCode" id="cb3"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">*** Main.hs (Old)</span></span>
|
||||
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="kw">--- Main.hs (New)</span></span>
|
||||
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="dt">***************</span></span>
|
||||
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="dt">*** 28,32 ****</span></span>
|
||||
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a> </span>
|
||||
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a><span class="st">! runApplication :: String -> Application a -> IO a</span></span>
|
||||
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="st">! runApplication greeting (Application io) =</span></span>
|
||||
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a> let</span>
|
||||
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a> context =</span>
|
||||
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a><span class="dt">--- 28,37 ----</span></span>
|
||||
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a> </span>
|
||||
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a><span class="va">! runApplication :: O.ConnectionPool -> String -> Application a -> IO a</span></span>
|
||||
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a><span class="va">! runApplication pool greeting (Application io) =</span></span>
|
||||
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a> let</span>
|
||||
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a><span class="va">+ orvilleState =</span></span>
|
||||
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a><span class="va">+ O.newOrvilleState</span></span>
|
||||
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a><span class="va">+ O.defaultErrorDetailLevel</span></span>
|
||||
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a><span class="va">+ pool</span></span>
|
||||
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a><span class="va">+ </span></span>
|
||||
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a> context =</span>
|
||||
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a><span class="dt">***************</span></span>
|
||||
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a><span class="dt">*** 34,35 ****</span></span>
|
||||
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true" tabindex="-1"></a><span class="dt">--- 39,41 ----</span></span>
|
||||
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true" tabindex="-1"></a> { applicationGreeting = greeting</span>
|
||||
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true" tabindex="-1"></a><span class="va">+ , applicationOrvilleState = orvilleState</span></span>
|
||||
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true" tabindex="-1"></a> }</span>
|
||||
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true" tabindex="-1"></a><span class="dt">***************</span></span>
|
||||
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true" tabindex="-1"></a><span class="dt">*** 44,46 ****</span></span>
|
||||
<span id="cb3-29"><a href="#cb3-29" aria-hidden="true" tabindex="-1"></a> main :: IO ()</span>
|
||||
<span id="cb3-30"><a href="#cb3-30" aria-hidden="true" tabindex="-1"></a><span class="st">! main =</span></span>
|
||||
<span id="cb3-31"><a href="#cb3-31" aria-hidden="true" tabindex="-1"></a><span class="st">! runApplication "Hello Application" myApplication</span></span>
|
||||
<span id="cb3-32"><a href="#cb3-32" aria-hidden="true" tabindex="-1"></a><span class="dt">--- 50,62 ----</span></span>
|
||||
<span id="cb3-33"><a href="#cb3-33" aria-hidden="true" tabindex="-1"></a> main :: IO ()</span>
|
||||
<span id="cb3-34"><a href="#cb3-34" aria-hidden="true" tabindex="-1"></a><span class="va">! main = do</span></span>
|
||||
<span id="cb3-35"><a href="#cb3-35" aria-hidden="true" tabindex="-1"></a><span class="va">! pool <-</span></span>
|
||||
<span id="cb3-36"><a href="#cb3-36" aria-hidden="true" tabindex="-1"></a><span class="va">! O.createConnectionPool</span></span>
|
||||
<span id="cb3-37"><a href="#cb3-37" aria-hidden="true" tabindex="-1"></a><span class="va">! O.ConnectionOptions</span></span>
|
||||
<span id="cb3-38"><a href="#cb3-38" aria-hidden="true" tabindex="-1"></a><span class="va">! { O.connectionString = "host=localhost user=postgres password=postgres"</span></span>
|
||||
<span id="cb3-39"><a href="#cb3-39" aria-hidden="true" tabindex="-1"></a><span class="va">! , O.connectionNoticeReporting = O.DisableNoticeReporting</span></span>
|
||||
<span id="cb3-40"><a href="#cb3-40" aria-hidden="true" tabindex="-1"></a><span class="va">! , O.connectionPoolStripes = O.OneStripePerCapability</span></span>
|
||||
<span id="cb3-41"><a href="#cb3-41" aria-hidden="true" tabindex="-1"></a><span class="va">! , O.connectionPoolLingerTime = 10</span></span>
|
||||
<span id="cb3-42"><a href="#cb3-42" aria-hidden="true" tabindex="-1"></a><span class="va">! , O.connectionPoolMaxConnections = O.MaxConnectionsPerStripe 1</span></span>
|
||||
<span id="cb3-43"><a href="#cb3-43" aria-hidden="true" tabindex="-1"></a><span class="va">! }</span></span>
|
||||
<span id="cb3-44"><a href="#cb3-44" aria-hidden="true" tabindex="-1"></a><span class="va">! </span></span>
|
||||
<span id="cb3-45"><a href="#cb3-45" aria-hidden="true" tabindex="-1"></a><span class="va">! runApplication pool "Hello Application" myApplication</span></span></code></pre></div>
|
||||
<p>Now we must declare an instance of <code>HasOrvilleState</code> to allow Orville access to
|
||||
the <code>OrvilleState</code> state that is stored in our custom <code>ApplicationContext</code>
|
||||
field. The <code>askOrvilleState</code> function is generally quite easy to implement.
|
||||
It’s the equivalent of the <code>ask</code> function from the <code>Reader</code> module. In this
|
||||
example we use the <code>asks</code> function from the <code>Reader</code> module to access the
|
||||
<code>applicationOrvilleState</code> field in the reader context.</p>
|
||||
<p>The <code>localOrvilleState</code> function is the equivalent of the <code>local</code> function from
|
||||
the <code>Reader</code> module. It’s slightly more complicated to implemented because we
|
||||
have adapt the function that Orville passes to <code>localOrvilleState</code> (which has type
|
||||
<code>OrvilleState -> OrvilleState</code>) so that the function is applied within the
|
||||
<code>ApplicationContext</code>. The adapted function is then passed <code>Reader.local</code> to
|
||||
complete our implementation of <code>localOrvilleState</code>. We’ve included a type
|
||||
signature for <code>mkLocalContext</code> in the example so you can clearly see the type
|
||||
of function being passed to <code>Reader.local</code>, but this is not necessary for the
|
||||
code to compile.</p>
|
||||
<div class="codeblock-label">
|
||||
Main.hs : diff
|
||||
</div>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">*** Main.hs (Old)</span></span>
|
||||
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="kw">--- Main.hs (New)</span></span>
|
||||
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="dt">***************</span></span>
|
||||
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="dt">*** 24,25 ****</span></span>
|
||||
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="dt">--- 24,39 ----</span></span>
|
||||
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a> </span>
|
||||
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="va">+ instance O.HasOrvilleState Application where</span></span>
|
||||
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a><span class="va">+ askOrvilleState =</span></span>
|
||||
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a><span class="va">+ Application (Reader.asks applicationOrvilleState)</span></span>
|
||||
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a><span class="va">+ </span></span>
|
||||
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a><span class="va">+ localOrvilleState f (Application reader) =</span></span>
|
||||
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a><span class="va">+ let</span></span>
|
||||
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a><span class="va">+ mkLocalContext :: ApplicationContext -> ApplicationContext</span></span>
|
||||
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a><span class="va">+ mkLocalContext ctx =</span></span>
|
||||
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a><span class="va">+ ctx</span></span>
|
||||
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a><span class="va">+ { applicationOrvilleState = f (applicationOrvilleState ctx)</span></span>
|
||||
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a><span class="va">+ }</span></span>
|
||||
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a><span class="va">+ in</span></span>
|
||||
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a><span class="va">+ Application (Reader.local mkLocalContext reader)</span></span>
|
||||
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a><span class="va">+ </span></span>
|
||||
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true" tabindex="-1"></a> getGreeting :: Application String</span></code></pre></div>
|
||||
<p>Once we have defined our instance of <code>HasOrvilleState</code> we can add
|
||||
<code>MonadOrville</code> and <code>MonadOrvilleControl</code> to the list of derived instances for
|
||||
<code>Application</code>.</p>
|
||||
<div class="codeblock-label">
|
||||
Main.hs : diff
|
||||
</div>
|
||||
<div class="sourceCode" id="cb5"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">*** Main.hs (Old)</span></span>
|
||||
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="kw">--- Main.hs (New)</span></span>
|
||||
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="dt">***************</span></span>
|
||||
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="dt">*** 22,23 ****</span></span>
|
||||
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="dt">--- 22,25 ----</span></span>
|
||||
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a> , MIO.MonadIO</span>
|
||||
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a><span class="va">+ , O.MonadOrville</span></span>
|
||||
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a><span class="va">+ , O.MonadOrvilleControl</span></span>
|
||||
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a> )</span></code></pre></div>
|
||||
<p>Now our <code>Application</code> monad is fully equipped with Orville capabilities! <a href="how-to-add-orville-to-your-application-monad.html">The
|
||||
previous guide</a> showed how
|
||||
to add a first table and Orville operation as well. That part is exactly the
|
||||
same from this point, so we won’t include it again here. We’ll conclude this
|
||||
guide with the final listing of <code>Main.hs</code> with all our changes applied.</p>
|
||||
<div class="codeblock-label">
|
||||
Main.hs (After) : haskell
|
||||
</div>
|
||||
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE GeneralizedNewtypeDeriving #-}</span></span>
|
||||
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Main</span></span>
|
||||
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a> ( main</span>
|
||||
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a> ) <span class="kw">where</span></span>
|
||||
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Control.Monad.IO.Class</span> <span class="kw">as</span> <span class="dt">MIO</span></span>
|
||||
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Control.Monad.Reader</span> <span class="kw">as</span> <span class="dt">Reader</span></span>
|
||||
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Orville.PostgreSQL</span> <span class="kw">as</span> <span class="dt">O</span></span>
|
||||
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">ApplicationContext</span> <span class="ot">=</span></span>
|
||||
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">ApplicationContext</span></span>
|
||||
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a> {<span class="ot"> applicationGreeting ::</span> <span class="dt">String</span></span>
|
||||
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a> ,<span class="ot"> applicationOrvilleState ::</span> <span class="dt">O.OrvilleState</span></span>
|
||||
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a> }</span>
|
||||
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Application</span> a <span class="ot">=</span></span>
|
||||
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a> <span class="dt">Application</span> (<span class="dt">Reader.ReaderT</span> <span class="dt">ApplicationContext</span> <span class="dt">IO</span> a)</span>
|
||||
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a> <span class="kw">deriving</span></span>
|
||||
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true" tabindex="-1"></a> ( <span class="dt">Functor</span></span>
|
||||
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true" tabindex="-1"></a> , <span class="dt">Applicative</span></span>
|
||||
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true" tabindex="-1"></a> , <span class="dt">Monad</span></span>
|
||||
<span id="cb6-22"><a href="#cb6-22" aria-hidden="true" tabindex="-1"></a> , <span class="dt">MIO.MonadIO</span></span>
|
||||
<span id="cb6-23"><a href="#cb6-23" aria-hidden="true" tabindex="-1"></a> , <span class="dt">O.MonadOrville</span></span>
|
||||
<span id="cb6-24"><a href="#cb6-24" aria-hidden="true" tabindex="-1"></a> , <span class="dt">O.MonadOrvilleControl</span></span>
|
||||
<span id="cb6-25"><a href="#cb6-25" aria-hidden="true" tabindex="-1"></a> )</span>
|
||||
<span id="cb6-26"><a href="#cb6-26" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb6-27"><a href="#cb6-27" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">O.HasOrvilleState</span> <span class="dt">Application</span> <span class="kw">where</span></span>
|
||||
<span id="cb6-28"><a href="#cb6-28" aria-hidden="true" tabindex="-1"></a> askOrvilleState <span class="ot">=</span></span>
|
||||
<span id="cb6-29"><a href="#cb6-29" aria-hidden="true" tabindex="-1"></a> <span class="dt">Application</span> (Reader.asks applicationOrvilleState)</span>
|
||||
<span id="cb6-30"><a href="#cb6-30" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb6-31"><a href="#cb6-31" aria-hidden="true" tabindex="-1"></a> localOrvilleState f (<span class="dt">Application</span> reader) <span class="ot">=</span></span>
|
||||
<span id="cb6-32"><a href="#cb6-32" aria-hidden="true" tabindex="-1"></a> <span class="kw">let</span></span>
|
||||
<span id="cb6-33"><a href="#cb6-33" aria-hidden="true" tabindex="-1"></a><span class="ot"> mkLocalContext ::</span> <span class="dt">ApplicationContext</span> <span class="ot">-></span> <span class="dt">ApplicationContext</span></span>
|
||||
<span id="cb6-34"><a href="#cb6-34" aria-hidden="true" tabindex="-1"></a> mkLocalContext ctx <span class="ot">=</span></span>
|
||||
<span id="cb6-35"><a href="#cb6-35" aria-hidden="true" tabindex="-1"></a> ctx</span>
|
||||
<span id="cb6-36"><a href="#cb6-36" aria-hidden="true" tabindex="-1"></a> { applicationOrvilleState <span class="ot">=</span> f (applicationOrvilleState ctx)</span>
|
||||
<span id="cb6-37"><a href="#cb6-37" aria-hidden="true" tabindex="-1"></a> }</span>
|
||||
<span id="cb6-38"><a href="#cb6-38" aria-hidden="true" tabindex="-1"></a> <span class="kw">in</span></span>
|
||||
<span id="cb6-39"><a href="#cb6-39" aria-hidden="true" tabindex="-1"></a> <span class="dt">Application</span> (Reader.local mkLocalContext reader)</span>
|
||||
<span id="cb6-40"><a href="#cb6-40" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb6-41"><a href="#cb6-41" aria-hidden="true" tabindex="-1"></a><span class="ot">getGreeting ::</span> <span class="dt">Application</span> <span class="dt">String</span></span>
|
||||
<span id="cb6-42"><a href="#cb6-42" aria-hidden="true" tabindex="-1"></a>getGreeting <span class="ot">=</span></span>
|
||||
<span id="cb6-43"><a href="#cb6-43" aria-hidden="true" tabindex="-1"></a> <span class="dt">Application</span> (Reader.asks applicationGreeting)</span>
|
||||
<span id="cb6-44"><a href="#cb6-44" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb6-45"><a href="#cb6-45" aria-hidden="true" tabindex="-1"></a><span class="ot">runApplication ::</span> <span class="dt">O.ConnectionPool</span> <span class="ot">-></span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">Application</span> a <span class="ot">-></span> <span class="dt">IO</span> a</span>
|
||||
<span id="cb6-46"><a href="#cb6-46" aria-hidden="true" tabindex="-1"></a>runApplication pool greeting (<span class="dt">Application</span> io) <span class="ot">=</span></span>
|
||||
<span id="cb6-47"><a href="#cb6-47" aria-hidden="true" tabindex="-1"></a> <span class="kw">let</span></span>
|
||||
<span id="cb6-48"><a href="#cb6-48" aria-hidden="true" tabindex="-1"></a> orvilleState <span class="ot">=</span></span>
|
||||
<span id="cb6-49"><a href="#cb6-49" aria-hidden="true" tabindex="-1"></a> O.newOrvilleState</span>
|
||||
<span id="cb6-50"><a href="#cb6-50" aria-hidden="true" tabindex="-1"></a> O.defaultErrorDetailLevel</span>
|
||||
<span id="cb6-51"><a href="#cb6-51" aria-hidden="true" tabindex="-1"></a> pool</span>
|
||||
<span id="cb6-52"><a href="#cb6-52" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb6-53"><a href="#cb6-53" aria-hidden="true" tabindex="-1"></a> context <span class="ot">=</span></span>
|
||||
<span id="cb6-54"><a href="#cb6-54" aria-hidden="true" tabindex="-1"></a> <span class="dt">ApplicationContext</span></span>
|
||||
<span id="cb6-55"><a href="#cb6-55" aria-hidden="true" tabindex="-1"></a> { applicationGreeting <span class="ot">=</span> greeting</span>
|
||||
<span id="cb6-56"><a href="#cb6-56" aria-hidden="true" tabindex="-1"></a> , applicationOrvilleState <span class="ot">=</span> orvilleState</span>
|
||||
<span id="cb6-57"><a href="#cb6-57" aria-hidden="true" tabindex="-1"></a> }</span>
|
||||
<span id="cb6-58"><a href="#cb6-58" aria-hidden="true" tabindex="-1"></a> <span class="kw">in</span></span>
|
||||
<span id="cb6-59"><a href="#cb6-59" aria-hidden="true" tabindex="-1"></a> Reader.runReaderT io context</span>
|
||||
<span id="cb6-60"><a href="#cb6-60" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb6-61"><a href="#cb6-61" aria-hidden="true" tabindex="-1"></a><span class="ot">myApplication ::</span> <span class="dt">Application</span> ()</span>
|
||||
<span id="cb6-62"><a href="#cb6-62" aria-hidden="true" tabindex="-1"></a>myApplication <span class="ot">=</span> <span class="kw">do</span></span>
|
||||
<span id="cb6-63"><a href="#cb6-63" aria-hidden="true" tabindex="-1"></a> greeting <span class="ot"><-</span> getGreeting</span>
|
||||
<span id="cb6-64"><a href="#cb6-64" aria-hidden="true" tabindex="-1"></a> MIO.liftIO <span class="op">.</span> <span class="fu">putStrLn</span> <span class="op">$</span> greeting</span>
|
||||
<span id="cb6-65"><a href="#cb6-65" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb6-66"><a href="#cb6-66" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">IO</span> ()</span>
|
||||
<span id="cb6-67"><a href="#cb6-67" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
|
||||
<span id="cb6-68"><a href="#cb6-68" aria-hidden="true" tabindex="-1"></a> pool <span class="ot"><-</span></span>
|
||||
<span id="cb6-69"><a href="#cb6-69" aria-hidden="true" tabindex="-1"></a> O.createConnectionPool</span>
|
||||
<span id="cb6-70"><a href="#cb6-70" aria-hidden="true" tabindex="-1"></a> <span class="dt">O.ConnectionOptions</span></span>
|
||||
<span id="cb6-71"><a href="#cb6-71" aria-hidden="true" tabindex="-1"></a> { O.connectionString <span class="ot">=</span> <span class="st">"host=localhost user=postgres password=postgres"</span></span>
|
||||
<span id="cb6-72"><a href="#cb6-72" aria-hidden="true" tabindex="-1"></a> , O.connectionNoticeReporting <span class="ot">=</span> <span class="dt">O.DisableNoticeReporting</span></span>
|
||||
<span id="cb6-73"><a href="#cb6-73" aria-hidden="true" tabindex="-1"></a> , O.connectionPoolStripes <span class="ot">=</span> <span class="dt">O.OneStripePerCapability</span></span>
|
||||
<span id="cb6-74"><a href="#cb6-74" aria-hidden="true" tabindex="-1"></a> , O.connectionPoolLingerTime <span class="ot">=</span> <span class="dv">10</span></span>
|
||||
<span id="cb6-75"><a href="#cb6-75" aria-hidden="true" tabindex="-1"></a> , O.connectionPoolMaxConnections <span class="ot">=</span> <span class="dt">O.MaxConnectionsPerStripe</span> <span class="dv">1</span></span>
|
||||
<span id="cb6-76"><a href="#cb6-76" aria-hidden="true" tabindex="-1"></a> }</span>
|
||||
<span id="cb6-77"><a href="#cb6-77" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb6-78"><a href="#cb6-78" aria-hidden="true" tabindex="-1"></a> runApplication pool <span class="st">"Hello Application"</span> myApplication</span></code></pre></div>
|
||||
</section>
|
||||
</article>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
@ -38,6 +38,8 @@
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-your-application-monad.html">How To Add Orville to Your Application Monad</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-an-existing-reader-context.html">How To Add Orville to an Existing Reader Context</a>
|
||||
|
||||
<a href="../how-tos/how-to-marshall-a-haskell-record.html">How To Marshall a Haskell Record (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-custom-marshalling-validations.html">How Add Custom Marshalling Validations (Upcoming)</a>
|
||||
@ -145,9 +147,9 @@ job. In order to use functions from the Orville package directly in your monad
|
||||
it will need to provide instances for the three typeclasses that make up a
|
||||
complete Orville monad - <code>MonadOrville</code>, <code>MonadOrvilleControl</code> and
|
||||
<code>HasOrvilleState</code>. Luckily, it’s a simple matter of adding these three
|
||||
typeclasses the the deriving list for <code>Application</code>. If you’re not using
|
||||
<code>GHC2021</code> you’ll need the <code>GeneralizedNewtypeDeriving</code> language extension, as
|
||||
in the example in this guide.</p>
|
||||
typeclasses the deriving list for <code>Application</code>. If you’re not using <code>GHC2021</code>
|
||||
you’ll need the <code>GeneralizedNewtypeDeriving</code> language extension, as in the
|
||||
example in this guide.</p>
|
||||
<div class="codeblock-label">
|
||||
Main.hs : diff
|
||||
</div>
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-your-application-monad.html">How To Add Orville to Your Application Monad</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-an-existing-reader-context.html">How To Add Orville to an Existing Reader Context</a>
|
||||
|
||||
<a href="../how-tos/how-to-marshall-a-haskell-record.html">How To Marshall a Haskell Record (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-custom-marshalling-validations.html">How Add Custom Marshalling Validations (Upcoming)</a>
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-your-application-monad.html">How To Add Orville to Your Application Monad</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-an-existing-reader-context.html">How To Add Orville to an Existing Reader Context</a>
|
||||
|
||||
<a href="../how-tos/how-to-marshall-a-haskell-record.html">How To Marshall a Haskell Record (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-custom-marshalling-validations.html">How Add Custom Marshalling Validations (Upcoming)</a>
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-your-application-monad.html">How To Add Orville to Your Application Monad</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-an-existing-reader-context.html">How To Add Orville to an Existing Reader Context</a>
|
||||
|
||||
<a href="../how-tos/how-to-marshall-a-haskell-record.html">How To Marshall a Haskell Record (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-custom-marshalling-validations.html">How Add Custom Marshalling Validations (Upcoming)</a>
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-your-application-monad.html">How To Add Orville to Your Application Monad</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-an-existing-reader-context.html">How To Add Orville to an Existing Reader Context</a>
|
||||
|
||||
<a href="../how-tos/how-to-marshall-a-haskell-record.html">How To Marshall a Haskell Record (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-custom-marshalling-validations.html">How Add Custom Marshalling Validations (Upcoming)</a>
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
<a href="./how-tos/how-to-add-orville-to-your-application-monad.html">How To Add Orville to Your Application Monad</a>
|
||||
|
||||
<a href="./how-tos/how-to-add-orville-to-an-existing-reader-context.html">How To Add Orville to an Existing Reader Context</a>
|
||||
|
||||
<a href="./how-tos/how-to-marshall-a-haskell-record.html">How To Marshall a Haskell Record (Upcoming)</a>
|
||||
|
||||
<a href="./how-tos/how-to-add-custom-marshalling-validations.html">How Add Custom Marshalling Validations (Upcoming)</a>
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-your-application-monad.html">How To Add Orville to Your Application Monad</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-an-existing-reader-context.html">How To Add Orville to an Existing Reader Context</a>
|
||||
|
||||
<a href="../how-tos/how-to-marshall-a-haskell-record.html">How To Marshall a Haskell Record (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-custom-marshalling-validations.html">How Add Custom Marshalling Validations (Upcoming)</a>
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-your-application-monad.html">How To Add Orville to Your Application Monad</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-an-existing-reader-context.html">How To Add Orville to an Existing Reader Context</a>
|
||||
|
||||
<a href="../how-tos/how-to-marshall-a-haskell-record.html">How To Marshall a Haskell Record (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-custom-marshalling-validations.html">How Add Custom Marshalling Validations (Upcoming)</a>
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-your-application-monad.html">How To Add Orville to Your Application Monad</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-an-existing-reader-context.html">How To Add Orville to an Existing Reader Context</a>
|
||||
|
||||
<a href="../how-tos/how-to-marshall-a-haskell-record.html">How To Marshall a Haskell Record (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-custom-marshalling-validations.html">How Add Custom Marshalling Validations (Upcoming)</a>
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-your-application-monad.html">How To Add Orville to Your Application Monad</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-an-existing-reader-context.html">How To Add Orville to an Existing Reader Context</a>
|
||||
|
||||
<a href="../how-tos/how-to-marshall-a-haskell-record.html">How To Marshall a Haskell Record (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-custom-marshalling-validations.html">How Add Custom Marshalling Validations (Upcoming)</a>
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-your-application-monad.html">How To Add Orville to Your Application Monad</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-orville-to-an-existing-reader-context.html">How To Add Orville to an Existing Reader Context</a>
|
||||
|
||||
<a href="../how-tos/how-to-marshall-a-haskell-record.html">How To Marshall a Haskell Record (Upcoming)</a>
|
||||
|
||||
<a href="../how-tos/how-to-add-custom-marshalling-validations.html">How Add Custom Marshalling Validations (Upcoming)</a>
|
||||
|
@ -0,0 +1,14 @@
|
||||
*** Main.hs (Old)
|
||||
--- Main.hs (New)
|
||||
***************
|
||||
*** 7,8 ****
|
||||
--- 7,9 ----
|
||||
import qualified Control.Monad.Reader as Reader
|
||||
+ import qualified Orville.PostgreSQL as O
|
||||
|
||||
***************
|
||||
*** 11,12 ****
|
||||
--- 12,14 ----
|
||||
{ applicationGreeting :: String
|
||||
+ , applicationOrvilleState :: O.OrvilleState
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
*** Main.hs (Old)
|
||||
--- Main.hs (New)
|
||||
***************
|
||||
*** 28,32 ****
|
||||
|
||||
! runApplication :: String -> Application a -> IO a
|
||||
! runApplication greeting (Application io) =
|
||||
let
|
||||
context =
|
||||
--- 28,37 ----
|
||||
|
||||
! runApplication :: O.ConnectionPool -> String -> Application a -> IO a
|
||||
! runApplication pool greeting (Application io) =
|
||||
let
|
||||
+ orvilleState =
|
||||
+ O.newOrvilleState
|
||||
+ O.defaultErrorDetailLevel
|
||||
+ pool
|
||||
+
|
||||
context =
|
||||
***************
|
||||
*** 34,35 ****
|
||||
--- 39,41 ----
|
||||
{ applicationGreeting = greeting
|
||||
+ , applicationOrvilleState = orvilleState
|
||||
}
|
||||
***************
|
||||
*** 44,46 ****
|
||||
main :: IO ()
|
||||
! main =
|
||||
! runApplication "Hello Application" myApplication
|
||||
--- 50,62 ----
|
||||
main :: IO ()
|
||||
! main = do
|
||||
! pool <-
|
||||
! O.createConnectionPool
|
||||
! O.ConnectionOptions
|
||||
! { O.connectionString = "host=localhost user=postgres password=postgres"
|
||||
! , O.connectionNoticeReporting = O.DisableNoticeReporting
|
||||
! , O.connectionPoolStripes = O.OneStripePerCapability
|
||||
! , O.connectionPoolLingerTime = 10
|
||||
! , O.connectionPoolMaxConnections = O.MaxConnectionsPerStripe 1
|
||||
! }
|
||||
!
|
||||
! runApplication pool "Hello Application" myApplication
|
@ -0,0 +1,21 @@
|
||||
*** Main.hs (Old)
|
||||
--- Main.hs (New)
|
||||
***************
|
||||
*** 24,25 ****
|
||||
--- 24,39 ----
|
||||
|
||||
+ instance O.HasOrvilleState Application where
|
||||
+ askOrvilleState =
|
||||
+ Application (Reader.asks applicationOrvilleState)
|
||||
+
|
||||
+ localOrvilleState f (Application reader) =
|
||||
+ let
|
||||
+ mkLocalContext :: ApplicationContext -> ApplicationContext
|
||||
+ mkLocalContext ctx =
|
||||
+ ctx
|
||||
+ { applicationOrvilleState = f (applicationOrvilleState ctx)
|
||||
+ }
|
||||
+ in
|
||||
+ Application (Reader.local mkLocalContext reader)
|
||||
+
|
||||
getGreeting :: Application String
|
@ -0,0 +1,9 @@
|
||||
*** Main.hs (Old)
|
||||
--- Main.hs (New)
|
||||
***************
|
||||
*** 22,23 ****
|
||||
--- 22,25 ----
|
||||
, MIO.MonadIO
|
||||
+ , O.MonadOrville
|
||||
+ , O.MonadOrvilleControl
|
||||
)
|
@ -0,0 +1,33 @@
|
||||
cabal-version: 2.2
|
||||
|
||||
name: adding-orville-existing-readert
|
||||
version: 0.1.0.0
|
||||
-- synopsis:
|
||||
-- description:
|
||||
homepage: https://github.com/flipstone/adding-orville-existing-readert#readme
|
||||
license: BSD-3-Clause
|
||||
author: Flipstone Technology Partners, Inc
|
||||
maintainer: maintainers@flipstone.com
|
||||
copyright:
|
||||
category: sample
|
||||
build-type: Simple
|
||||
|
||||
executable adding-orville-existing-readert
|
||||
hs-source-dirs: src
|
||||
main-is: Main.hs
|
||||
default-language: Haskell2010
|
||||
|
||||
build-depends: base >= 4.7 && < 5,
|
||||
mtl,
|
||||
orville-postgresql,
|
||||
text
|
||||
|
||||
ghc-options: -Wall
|
||||
-Wcompat
|
||||
-Widentities
|
||||
-Wincomplete-record-updates
|
||||
-Wincomplete-uni-patterns
|
||||
-Wmissing-export-lists
|
||||
-Wmissing-home-modules
|
||||
-Wpartial-fields
|
||||
-Wredundant-constraints
|
@ -0,0 +1 @@
|
||||
Hello Application
|
6
orville-docsite/samples/adding-orville-existing-readert/mkdiffs.sh
Executable file
6
orville-docsite/samples/adding-orville-existing-readert/mkdiffs.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
DIFF_OPTS=(-C 1 --label 'Main.hs (Old)' --label 'Main.hs (New)')
|
||||
diff "${DIFF_OPTS[@]}" snapshots/Main-1.hs snapshots/Main-2.hs > 1-add-orville-state.patch
|
||||
diff "${DIFF_OPTS[@]}" snapshots/Main-2.hs snapshots/Main-3.hs > 2-update-runApplication.patch
|
||||
diff "${DIFF_OPTS[@]}" snapshots/Main-3.hs snapshots/Main-4.hs > 3-add-HasOrvilleState.patch
|
||||
diff "${DIFF_OPTS[@]}" snapshots/Main-4.hs snapshots/Main-5.hs > 4-add-remaining-typeclasses.patch
|
@ -0,0 +1,22 @@
|
||||
set -e
|
||||
service postgresql start
|
||||
|
||||
patch --output=snapshots/Main-2.hs snapshots/Main-1.hs 1-add-orville-state.patch
|
||||
patch --output=snapshots/Main-3.hs snapshots/Main-2.hs 2-update-runApplication.patch
|
||||
patch --output=snapshots/Main-4.hs snapshots/Main-3.hs 3-add-HasOrvilleState.patch
|
||||
patch --output=snapshots/Main-5.hs snapshots/Main-4.hs 4-add-remaining-typeclasses.patch
|
||||
mkdir -p src
|
||||
cp snapshots/Main-5.hs src/Main.hs
|
||||
|
||||
stack build
|
||||
|
||||
expected=$(cat expected-output.txt)
|
||||
actual=$(stack exec adding-orville-existing-readert)
|
||||
|
||||
if [ "$expected" = "$actual" ]; then
|
||||
echo "Output matches expected"
|
||||
else
|
||||
echo "Expected output to be: $expected"
|
||||
echo "But it was actually : $actual"
|
||||
exit 1
|
||||
fi;
|
@ -0,0 +1,44 @@
|
||||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||
module Main
|
||||
( main
|
||||
) where
|
||||
|
||||
import qualified Control.Monad.IO.Class as MIO
|
||||
import qualified Control.Monad.Reader as Reader
|
||||
|
||||
data ApplicationContext =
|
||||
ApplicationContext
|
||||
{ applicationGreeting :: String
|
||||
}
|
||||
|
||||
newtype Application a =
|
||||
Application (Reader.ReaderT ApplicationContext IO a)
|
||||
deriving
|
||||
( Functor
|
||||
, Applicative
|
||||
, Monad
|
||||
, MIO.MonadIO
|
||||
)
|
||||
|
||||
getGreeting :: Application String
|
||||
getGreeting =
|
||||
Application (Reader.asks applicationGreeting)
|
||||
|
||||
runApplication :: String -> Application a -> IO a
|
||||
runApplication greeting (Application io) =
|
||||
let
|
||||
context =
|
||||
ApplicationContext
|
||||
{ applicationGreeting = greeting
|
||||
}
|
||||
in
|
||||
Reader.runReaderT io context
|
||||
|
||||
myApplication :: Application ()
|
||||
myApplication = do
|
||||
greeting <- getGreeting
|
||||
MIO.liftIO . putStrLn $ greeting
|
||||
|
||||
main :: IO ()
|
||||
main =
|
||||
runApplication "Hello Application" myApplication
|
@ -0,0 +1,46 @@
|
||||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||
module Main
|
||||
( main
|
||||
) where
|
||||
|
||||
import qualified Control.Monad.IO.Class as MIO
|
||||
import qualified Control.Monad.Reader as Reader
|
||||
import qualified Orville.PostgreSQL as O
|
||||
|
||||
data ApplicationContext =
|
||||
ApplicationContext
|
||||
{ applicationGreeting :: String
|
||||
, applicationOrvilleState :: O.OrvilleState
|
||||
}
|
||||
|
||||
newtype Application a =
|
||||
Application (Reader.ReaderT ApplicationContext IO a)
|
||||
deriving
|
||||
( Functor
|
||||
, Applicative
|
||||
, Monad
|
||||
, MIO.MonadIO
|
||||
)
|
||||
|
||||
getGreeting :: Application String
|
||||
getGreeting =
|
||||
Application (Reader.asks applicationGreeting)
|
||||
|
||||
runApplication :: String -> Application a -> IO a
|
||||
runApplication greeting (Application io) =
|
||||
let
|
||||
context =
|
||||
ApplicationContext
|
||||
{ applicationGreeting = greeting
|
||||
}
|
||||
in
|
||||
Reader.runReaderT io context
|
||||
|
||||
myApplication :: Application ()
|
||||
myApplication = do
|
||||
greeting <- getGreeting
|
||||
MIO.liftIO . putStrLn $ greeting
|
||||
|
||||
main :: IO ()
|
||||
main =
|
||||
runApplication "Hello Application" myApplication
|
@ -0,0 +1,62 @@
|
||||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||
module Main
|
||||
( main
|
||||
) where
|
||||
|
||||
import qualified Control.Monad.IO.Class as MIO
|
||||
import qualified Control.Monad.Reader as Reader
|
||||
import qualified Orville.PostgreSQL as O
|
||||
|
||||
data ApplicationContext =
|
||||
ApplicationContext
|
||||
{ applicationGreeting :: String
|
||||
, applicationOrvilleState :: O.OrvilleState
|
||||
}
|
||||
|
||||
newtype Application a =
|
||||
Application (Reader.ReaderT ApplicationContext IO a)
|
||||
deriving
|
||||
( Functor
|
||||
, Applicative
|
||||
, Monad
|
||||
, MIO.MonadIO
|
||||
)
|
||||
|
||||
getGreeting :: Application String
|
||||
getGreeting =
|
||||
Application (Reader.asks applicationGreeting)
|
||||
|
||||
runApplication :: O.ConnectionPool -> String -> Application a -> IO a
|
||||
runApplication pool greeting (Application io) =
|
||||
let
|
||||
orvilleState =
|
||||
O.newOrvilleState
|
||||
O.defaultErrorDetailLevel
|
||||
pool
|
||||
|
||||
context =
|
||||
ApplicationContext
|
||||
{ applicationGreeting = greeting
|
||||
, applicationOrvilleState = orvilleState
|
||||
}
|
||||
in
|
||||
Reader.runReaderT io context
|
||||
|
||||
myApplication :: Application ()
|
||||
myApplication = do
|
||||
greeting <- getGreeting
|
||||
MIO.liftIO . putStrLn $ greeting
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
pool <-
|
||||
O.createConnectionPool
|
||||
O.ConnectionOptions
|
||||
{ O.connectionString = "host=localhost user=postgres password=postgres"
|
||||
, O.connectionNoticeReporting = O.DisableNoticeReporting
|
||||
, O.connectionPoolStripes = O.OneStripePerCapability
|
||||
, O.connectionPoolLingerTime = 10
|
||||
, O.connectionPoolMaxConnections = O.MaxConnectionsPerStripe 1
|
||||
}
|
||||
|
||||
runApplication pool "Hello Application" myApplication
|
@ -0,0 +1,76 @@
|
||||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||
module Main
|
||||
( main
|
||||
) where
|
||||
|
||||
import qualified Control.Monad.IO.Class as MIO
|
||||
import qualified Control.Monad.Reader as Reader
|
||||
import qualified Orville.PostgreSQL as O
|
||||
|
||||
data ApplicationContext =
|
||||
ApplicationContext
|
||||
{ applicationGreeting :: String
|
||||
, applicationOrvilleState :: O.OrvilleState
|
||||
}
|
||||
|
||||
newtype Application a =
|
||||
Application (Reader.ReaderT ApplicationContext IO a)
|
||||
deriving
|
||||
( Functor
|
||||
, Applicative
|
||||
, Monad
|
||||
, MIO.MonadIO
|
||||
)
|
||||
|
||||
instance O.HasOrvilleState Application where
|
||||
askOrvilleState =
|
||||
Application (Reader.asks applicationOrvilleState)
|
||||
|
||||
localOrvilleState f (Application reader) =
|
||||
let
|
||||
mkLocalContext :: ApplicationContext -> ApplicationContext
|
||||
mkLocalContext ctx =
|
||||
ctx
|
||||
{ applicationOrvilleState = f (applicationOrvilleState ctx)
|
||||
}
|
||||
in
|
||||
Application (Reader.local mkLocalContext reader)
|
||||
|
||||
getGreeting :: Application String
|
||||
getGreeting =
|
||||
Application (Reader.asks applicationGreeting)
|
||||
|
||||
runApplication :: O.ConnectionPool -> String -> Application a -> IO a
|
||||
runApplication pool greeting (Application io) =
|
||||
let
|
||||
orvilleState =
|
||||
O.newOrvilleState
|
||||
O.defaultErrorDetailLevel
|
||||
pool
|
||||
|
||||
context =
|
||||
ApplicationContext
|
||||
{ applicationGreeting = greeting
|
||||
, applicationOrvilleState = orvilleState
|
||||
}
|
||||
in
|
||||
Reader.runReaderT io context
|
||||
|
||||
myApplication :: Application ()
|
||||
myApplication = do
|
||||
greeting <- getGreeting
|
||||
MIO.liftIO . putStrLn $ greeting
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
pool <-
|
||||
O.createConnectionPool
|
||||
O.ConnectionOptions
|
||||
{ O.connectionString = "host=localhost user=postgres password=postgres"
|
||||
, O.connectionNoticeReporting = O.DisableNoticeReporting
|
||||
, O.connectionPoolStripes = O.OneStripePerCapability
|
||||
, O.connectionPoolLingerTime = 10
|
||||
, O.connectionPoolMaxConnections = O.MaxConnectionsPerStripe 1
|
||||
}
|
||||
|
||||
runApplication pool "Hello Application" myApplication
|
@ -0,0 +1,78 @@
|
||||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||
module Main
|
||||
( main
|
||||
) where
|
||||
|
||||
import qualified Control.Monad.IO.Class as MIO
|
||||
import qualified Control.Monad.Reader as Reader
|
||||
import qualified Orville.PostgreSQL as O
|
||||
|
||||
data ApplicationContext =
|
||||
ApplicationContext
|
||||
{ applicationGreeting :: String
|
||||
, applicationOrvilleState :: O.OrvilleState
|
||||
}
|
||||
|
||||
newtype Application a =
|
||||
Application (Reader.ReaderT ApplicationContext IO a)
|
||||
deriving
|
||||
( Functor
|
||||
, Applicative
|
||||
, Monad
|
||||
, MIO.MonadIO
|
||||
, O.MonadOrville
|
||||
, O.MonadOrvilleControl
|
||||
)
|
||||
|
||||
instance O.HasOrvilleState Application where
|
||||
askOrvilleState =
|
||||
Application (Reader.asks applicationOrvilleState)
|
||||
|
||||
localOrvilleState f (Application reader) =
|
||||
let
|
||||
mkLocalContext :: ApplicationContext -> ApplicationContext
|
||||
mkLocalContext ctx =
|
||||
ctx
|
||||
{ applicationOrvilleState = f (applicationOrvilleState ctx)
|
||||
}
|
||||
in
|
||||
Application (Reader.local mkLocalContext reader)
|
||||
|
||||
getGreeting :: Application String
|
||||
getGreeting =
|
||||
Application (Reader.asks applicationGreeting)
|
||||
|
||||
runApplication :: O.ConnectionPool -> String -> Application a -> IO a
|
||||
runApplication pool greeting (Application io) =
|
||||
let
|
||||
orvilleState =
|
||||
O.newOrvilleState
|
||||
O.defaultErrorDetailLevel
|
||||
pool
|
||||
|
||||
context =
|
||||
ApplicationContext
|
||||
{ applicationGreeting = greeting
|
||||
, applicationOrvilleState = orvilleState
|
||||
}
|
||||
in
|
||||
Reader.runReaderT io context
|
||||
|
||||
myApplication :: Application ()
|
||||
myApplication = do
|
||||
greeting <- getGreeting
|
||||
MIO.liftIO . putStrLn $ greeting
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
pool <-
|
||||
O.createConnectionPool
|
||||
O.ConnectionOptions
|
||||
{ O.connectionString = "host=localhost user=postgres password=postgres"
|
||||
, O.connectionNoticeReporting = O.DisableNoticeReporting
|
||||
, O.connectionPoolStripes = O.OneStripePerCapability
|
||||
, O.connectionPoolLingerTime = 10
|
||||
, O.connectionPoolMaxConnections = O.MaxConnectionsPerStripe 1
|
||||
}
|
||||
|
||||
runApplication pool "Hello Application" myApplication
|
@ -0,0 +1,69 @@
|
||||
# This file was automatically generated by 'stack init'
|
||||
#
|
||||
# Some commonly used options have been documented as comments in this file.
|
||||
# For advanced use and comprehensive documentation of the format, please see:
|
||||
# https://docs.haskellstack.org/en/stable/yaml_configuration/
|
||||
|
||||
# Resolver to choose a 'specific' stackage snapshot or a compiler version.
|
||||
# A snapshot resolver dictates the compiler version and the set of packages
|
||||
# to be used for project dependencies. For example:
|
||||
#
|
||||
# resolver: lts-21.13
|
||||
# resolver: nightly-2023-09-24
|
||||
# resolver: ghc-9.6.2
|
||||
#
|
||||
# The location of a snapshot can be provided as a file or url. Stack assumes
|
||||
# a snapshot provided as a file might change, whereas a url resource does not.
|
||||
#
|
||||
# resolver: ./custom-snapshot.yaml
|
||||
# resolver: https://example.com/snapshots/2023-01-01.yaml
|
||||
resolver: lts-21.19
|
||||
system-ghc: true
|
||||
install-ghc: false
|
||||
|
||||
# User packages to be built.
|
||||
# Various formats can be used as shown in the example below.
|
||||
#
|
||||
# packages:
|
||||
# - some-directory
|
||||
# - https://example.com/foo/bar/baz-0.0.2.tar.gz
|
||||
# subdirs:
|
||||
# - auto-update
|
||||
# - wai
|
||||
packages:
|
||||
- .
|
||||
# Dependency packages to be pulled from upstream that are not in the resolver.
|
||||
# These entries can reference officially published versions as well as
|
||||
# forks / in-progress versions pinned to a git hash. For example:
|
||||
#
|
||||
# extra-deps:
|
||||
# - acme-missiles-0.3
|
||||
# - git: https://github.com/commercialhaskell/stack.git
|
||||
# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
|
||||
#
|
||||
extra-deps:
|
||||
- orville-postgresql-1.0.0.0
|
||||
|
||||
# Override default flag values for local packages and extra-deps
|
||||
# flags: {}
|
||||
|
||||
# Extra package databases containing global packages
|
||||
# extra-package-dbs: []
|
||||
|
||||
# Control whether we use the GHC we find on the path
|
||||
# system-ghc: true
|
||||
#
|
||||
# Require a specific version of Stack, using version ranges
|
||||
# require-stack-version: -any # Default
|
||||
# require-stack-version: ">=2.13"
|
||||
#
|
||||
# Override the architecture used by Stack, especially useful on Windows
|
||||
# arch: i386
|
||||
# arch: x86_64
|
||||
#
|
||||
# Extra directories used by Stack for building
|
||||
# extra-include-dirs: [/path/to/dir]
|
||||
# extra-lib-dirs: [/path/to/dir]
|
||||
#
|
||||
# Allow a newer minor version of GHC than the snapshot specifies
|
||||
# compiler-check: newer-minor
|
@ -0,0 +1,19 @@
|
||||
# This file was autogenerated by Stack.
|
||||
# You should not edit this file by hand.
|
||||
# For more information, please see the documentation at:
|
||||
# https://docs.haskellstack.org/en/stable/lock_files
|
||||
|
||||
packages:
|
||||
- completed:
|
||||
hackage: orville-postgresql-1.0.0.0@sha256:35e9b9f8bc0bc1ee1847bcb5340fa39bed320f1573099ec16ca394726a50593a,9018
|
||||
pantry-tree:
|
||||
sha256: b8d324f2ad94f12ac419996cc2947ee0c69c5178b2caf13dc92135118602bbd8
|
||||
size: 12020
|
||||
original:
|
||||
hackage: orville-postgresql-1.0.0.0
|
||||
snapshots:
|
||||
- completed:
|
||||
sha256: fb482b8e2d5d061cdda4ba1da2957c012740c893a5ee1c1b99001adae7b1fbe7
|
||||
size: 640046
|
||||
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/19.yaml
|
||||
original: lts-21.19
|
@ -1,7 +1,6 @@
|
||||
# SNIPPET: hidden
|
||||
set -e
|
||||
service postgresql start
|
||||
# SNIPPET: hidden
|
||||
|
||||
patch --output=snapshots/Main-2.hs snapshots/Main-1.hs 1-add-readert.patch
|
||||
patch --output=snapshots/Main-3.hs snapshots/Main-2.hs 2-add-orville-typeclasses.patch
|
||||
patch --output=snapshots/Main-4.hs snapshots/Main-3.hs 3-update-runApplication.patch
|
||||
@ -10,9 +9,9 @@ patch --output=snapshots/Main-6.hs snapshots/Main-5.hs 5-add-table.patch
|
||||
patch --output=snapshots/Main-7.hs snapshots/Main-6.hs 6-add-migrations.patch
|
||||
mkdir -p src
|
||||
cp snapshots/Main-7.hs src/Main.hs
|
||||
# SNIPPET: buildAndExecute
|
||||
|
||||
stack build
|
||||
# SNIPPET: hidden
|
||||
|
||||
expected=$(cat expected-output.txt)
|
||||
actual=$(stack exec adding-orville-new-readert)
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: How Add Custom Marshalling Validations (Upcoming)
|
||||
navOrder: 3
|
||||
navOrder: 4
|
||||
---
|
||||
|
||||
Coming Soon
|
||||
|
@ -0,0 +1,63 @@
|
||||
---
|
||||
title: How To Add Orville to an Existing Reader Context
|
||||
navOrder: 2
|
||||
---
|
||||
|
||||
This guide will show you how to add Orville to a monad that is already using
|
||||
`ReaderT` in its monad stack. It builds conceptually on top of [the previous
|
||||
guide](how-to-add-orville-to-your-application-monad.html), which assumed there
|
||||
was not already a `ReaderT` in the application monad stack. It's recommended
|
||||
that you read that guide before this one.
|
||||
|
||||
The file listing below shows a simple application with its own `Application`
|
||||
monad that already has a reader context. When there is already a reader context
|
||||
in the application stack it's generally perferrable to incorporate Orville into
|
||||
the existing reader context rather than adding a new `ReaderT` layer atop the
|
||||
one that's already there.
|
||||
|
||||
$sample("adding-orville-existing-readert/snapshots/Main-1.hs", "filename=Main.hs (Before)")$
|
||||
|
||||
As in [the last guide](how-to-add-orville-to-your-application-monad.html), we
|
||||
will first add an `OrvilleState` to our application monad. In this case we'll
|
||||
add it as a new field to the existing `ApplicationContext`.
|
||||
|
||||
$sample("adding-orville-existing-readert/1-add-orville-state.patch", "filename=Main.hs")$
|
||||
|
||||
This requires that the new `applicationOrvilleState` field be populated in the
|
||||
`runApplication` function using a `ConnectionPool`. The `ConnectionPool` is
|
||||
created in the `main` function and passed in where `runApplication` is called.
|
||||
|
||||
$sample("adding-orville-existing-readert/2-update-runApplication.patch", "filename=Main.hs")$
|
||||
|
||||
Now we must declare an instance of `HasOrvilleState` to allow Orville access to
|
||||
the `OrvilleState` state that is stored in our custom `ApplicationContext`
|
||||
field. The `askOrvilleState` function is generally quite easy to implement.
|
||||
It's the equivalent of the `ask` function from the `Reader` module. In this
|
||||
example we use the `asks` function from the `Reader` module to access the
|
||||
`applicationOrvilleState` field in the reader context.
|
||||
|
||||
The `localOrvilleState` function is the equivalent of the `local` function from
|
||||
the `Reader` module. It's slightly more complicated to implemented because we
|
||||
have adapt the function that Orville passes to `localOrvilleState` (which has type
|
||||
`OrvilleState -> OrvilleState`) so that the function is applied within the
|
||||
`ApplicationContext`. The adapted function is then passed `Reader.local` to
|
||||
complete our implementation of `localOrvilleState`. We've included a type
|
||||
signature for `mkLocalContext` in the example so you can clearly see the type
|
||||
of function being passed to `Reader.local`, but this is not necessary for the
|
||||
code to compile.
|
||||
|
||||
$sample("adding-orville-existing-readert/3-add-HasOrvilleState.patch", "filename=Main.hs")$
|
||||
|
||||
Once we have defined our instance of `HasOrvilleState` we can add
|
||||
`MonadOrville` and `MonadOrvilleControl` to the list of derived instances for
|
||||
`Application`.
|
||||
|
||||
$sample("adding-orville-existing-readert/4-add-remaining-typeclasses.patch", "filename=Main.hs")$
|
||||
|
||||
Now our `Application` monad is fully equipped with Orville capabilities! [The
|
||||
previous guide](how-to-add-orville-to-your-application-monad.html) showed how
|
||||
to add a first table and Orville operation as well. That part is exactly the
|
||||
same from this point, so we won't include it again here. We'll conclude this
|
||||
guide with the final listing of `Main.hs` with all our changes applied.
|
||||
|
||||
$sample("adding-orville-existing-readert/snapshots/Main-5.hs", "filename=Main.hs (After)")$
|
@ -28,9 +28,9 @@ job. In order to use functions from the Orville package directly in your monad
|
||||
it will need to provide instances for the three typeclasses that make up a
|
||||
complete Orville monad - `MonadOrville`, `MonadOrvilleControl` and
|
||||
`HasOrvilleState`. Luckily, it's a simple matter of adding these three
|
||||
typeclasses the the deriving list for `Application`. If you're not using
|
||||
`GHC2021` you'll need the `GeneralizedNewtypeDeriving` language extension, as
|
||||
in the example in this guide.
|
||||
typeclasses the deriving list for `Application`. If you're not using `GHC2021`
|
||||
you'll need the `GeneralizedNewtypeDeriving` language extension, as in the
|
||||
example in this guide.
|
||||
|
||||
$sample("adding-orville-new-readert/2-add-orville-typeclasses.patch", "filename=Main.hs")$
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: How To Execute Raw SQL (Upcoming)
|
||||
navOrder: 6
|
||||
navOrder: 7
|
||||
---
|
||||
|
||||
Coming Soon
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: How To Marshall a Haskell Record (Upcoming)
|
||||
navOrder: 2
|
||||
navOrder: 3
|
||||
---
|
||||
|
||||
Coming Soon
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: How To Marshall a Haskell Sum Type (Upcoming)
|
||||
navOrder: 4
|
||||
navOrder: 5
|
||||
---
|
||||
|
||||
Coming Soon
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: How To Set Up An Auto-incrementing Id Column (Upcoming)
|
||||
navOrder: 5
|
||||
navOrder: 6
|
||||
---
|
||||
|
||||
Coming Soon
|
||||
|
Loading…
Reference in New Issue
Block a user