No description
"SELECT *" in SQL may not guarantee the order in which a record's columns are
returned. For example, in my FromRow instances for Account, I make successive call
The following scenario silently and erroneously assigns:
firstName, lastName = lastName, firstName
```sql
CREATE TABLE People (
firstName TEXT NOT NULL,
lastName TEXT NOT NULL,
age INTEGER NOT NULL,
PRIMARY KEY (firstName, lastName)
)
```
```haskell
data Person = Person { firstName :: String, lastName :: String, age :: Integer }
fromRow = do
firstName <- field
lastName <- field
age <- field
pure Person{..}
getPeople :: Connection -> IO [Person]
getPeople conn = query conn "SELECT * FROM People"
```
This silently fails because both firstName and lastName are Strings, and so the
FromRow Person instance type-checks, but you should expect to receive a list of
names like "Wallace William" instead of "William Wallace".
The following won't break the type-checker, but will result in a runtime parsing
error:
```haskell
-- all code from the previous example remains the same except for:
fromRow = do
age <- field
firstName <- field
lastName <- field
```
The "SELECT *" will return records like (firstName,lastName,age), but the
FromRow instance for Person will attempt to parse firstName as
Integer.
So... what have we learned? Prefer "SELECT (firstName,lastName,age)" instead of
"SELECT *".
|
||
|---|---|---|
| client | ||
| data | ||
| src | ||
| tests | ||
| .gitignore | ||
| populate.sqlite3 | ||
| README.md | ||
| shell.nix | ||
| todo.org | ||
TopTal take-home #2
All of the commands defined herein should be run from the top-level directory of this repository (i.e. the directory in which this file exists).
Server
To create the environment that contains all of this application's dependencies, run:
$ nix-shell
To run the server interactively, run:
$ cd src/
$ ghci
Now compile and load the server with:
Prelude> :l Main.hs
*Main> main
Database
Create a new database named db.sqlite3 with:
$ sqlite3 db.sqlite3
Populate the database with:
sqlite3> .read populate.sqlite3
You can verify that everything is setup with:
sqlite3> .tables
sqlite3> .schema
sqlite3> SELECT * FROM Accounts;
sqlite3> SELECT * FROM Trips;