haskell-relational-record/quickstart.md

94 lines
2.9 KiB
Markdown
Raw Normal View History

2014-12-11 08:56:57 +03:00
---
layout: default
title: Quick start
---
### Preparing HRR
2014-12-11 09:29:30 +03:00
To start using [Haskell Relational Record](http://khibino.github.io/haskell-relational-record/) (HRR), you need to install:
2014-12-11 08:56:57 +03:00
2014-12-11 09:29:30 +03:00
1. [Glasgow Haskell Compiler](https://www.haskell.org/ghc/) (GHC) + the "cabal" command
- We recommend using the [Haskell Platform](https://www.haskell.org/platform/)
2014-12-11 09:29:30 +03:00
2. The Haskell ["relational-record"](http://hackage.haskell.org/package/relational-record) library
3. Relational database system
2014-12-12 09:08:00 +03:00
- In this quickstart, we assume that [SQLite](http://www.sqlite.org/) version 3 has been installed
2014-12-11 08:56:57 +03:00
To install the Haskell "relational-record" library, run the following commands:
2014-12-11 08:56:57 +03:00
% cabal update
% cabal install relational-record
### The first relation
2014-12-16 06:38:51 +03:00
Let's define our first relation. Copy the following to "hello.hs":
2014-12-11 09:05:48 +03:00
2014-12-20 09:07:08 +03:00
{% highlight haskell %}
import Data.Int (Int32)
import Database.Relational.Query
hello :: Relation () (Int32, String)
hello = relation $ return (value 0 >< value "Hello")
main :: IO ()
main = putStrLn $ show hello ++ ";"
{% endhighlight %}
2014-12-11 09:05:48 +03:00
`hello` defines our first relation. This "SELECT"s a constant tuple value (0,"Hello") from the (virtual) empty table. In other words, this relation just returns (0,"Hello").
2014-12-11 09:05:48 +03:00
Let's run the above Haskell code to show what kind of SQL statement is generated:
2014-12-11 09:05:48 +03:00
2014-12-20 09:08:39 +03:00
{% highlight sql %}
% runghc hello.hs
SELECT ALL 0 AS f0, 'Hello' AS f1;
{% endhighlight %}
2014-12-11 09:05:48 +03:00
OK. Next, let's execute the SQL produced above in SQLite:
2014-12-11 09:05:48 +03:00
2014-12-11 09:07:26 +03:00
% runghc hello.hs | sqlite3 dummy.db
0|Hello
2014-12-11 09:05:48 +03:00
We got "0\|Hello"! Note that "dummy.db" is just a dummy file.
2014-12-11 08:56:57 +03:00
### Composing relations
2014-12-11 09:12:43 +03:00
Next, let's compose relations. Copy the following to "helloworld.hs":
2014-12-20 09:07:08 +03:00
{% highlight haskell %}
import Data.Int (Int32)
import Database.Relational.Query
hello :: Relation () (Int32, String)
hello = relation $ return (value 0 >< value "Hello")
world :: Relation () (Int32, String)
world = relation $ return (value 0 >< value "World!")
helloWorld :: Relation () (Int32, (String, String))
helloWorld = relation $ do
h <- query hello
w <- query world
on $ h ! fst' .=. w ! fst'
return $ h ! fst' >< (h ! snd' >< w ! snd')
main :: IO ()
main = putStrLn $ show helloWorld ++ ";"
{% endhighlight %}
2014-12-11 08:56:57 +03:00
2014-12-20 09:04:40 +03:00
This code defines queries called `hello` and `world`. And `helloworld` composes them by joining them on the first element of the tuples.
2014-12-11 09:12:43 +03:00
This code generates the following SQL statement:
2014-12-20 09:09:34 +03:00
{% highlight sql %}
% runghc helloworld.hs
SELECT ALL T0.f0 AS f0, T0.f1 AS f1, T1.f1 AS f2 FROM (SELECT ALL 0 AS f0, 'Hello' AS f1) T0 INNER JOIN (SELECT ALL 0 AS f0, 'World!' AS f1) T1 ON (T0.f0 = T1.f0);
{% endhighlight %}
2014-12-11 08:56:57 +03:00
2014-12-11 09:29:30 +03:00
Finally, let's execute it in SQLite:
2014-12-11 08:56:57 +03:00
2014-12-11 09:12:43 +03:00
% runghc helloworld.hs | sqlite3 dummy.db
2014-12-11 09:40:08 +03:00
0|Hello|World!
Now we understand that relations are composable. Raw SQL does NOT have this feature. Moreover, relations are type safe. If our HRR code can be compiled by GHC, it always generates valid SQL statements.
2014-12-20 09:23:21 +03:00
The next step is to read the [HRR tutorial](tutorial.html).