@@ -21,7 +21,6 @@ We'll need some imports.
21>>> import Data.Int (Int32)
21>>> import Data.Int (Int32)
22>>> import Data.Text (Text)
22>>> import Data.Text (Text)
23>>> import Squeal.PostgreSQL
23>>> import Squeal.PostgreSQL
24−>>> import qualified Data.ByteString.Char8 as Char8 (putStrLn)
26We'll use generics to easily convert between Haskell and PostgreSQL values.
25We'll use generics to easily convert between Haskell and PostgreSQL values.
@@ -81,13 +80,13 @@ let
82We can easily see the generated SQL is unsuprising looking.
81We can easily see the generated SQL is unsuprising looking.
84−>>> Char8.putStrLn $ renderDefinition setup
83+>>> printSQL setup
85CREATE TABLE "users" ("id" serial, "name" text NOT NULL, CONSTRAINT "pk_users" PRIMARY KEY ("id"));
84CREATE TABLE "users" ("id" serial, "name" text NOT NULL, CONSTRAINT "pk_users" PRIMARY KEY ("id"));
86CREATE TABLE "emails" ("id" serial, "user_id" int NOT NULL, "email" text NULL, CONSTRAINT "pk_emails" PRIMARY KEY ("id"), CONSTRAINT "fk_user_id" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE);
85CREATE TABLE "emails" ("id" serial, "user_id" int NOT NULL, "email" text NULL, CONSTRAINT "pk_emails" PRIMARY KEY ("id"), CONSTRAINT "fk_user_id" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE);
88Notice that @setup@ starts with an empty schema @'[]@ and produces @Schema@.
87Notice that @setup@ starts with an empty schema @'[]@ and produces @Schema@.
89In our `createTable` commands we included `TableConstraint`s to define
88In our `createTable` commands we included `TableConstraint`s to define
90−primary and foreign keys, making them somewhat complex. Our tear down
89+primary and foreign keys, making them somewhat complex. Our @teardown@
91`Definition` is simpler.
90`Definition` is simpler.
@@ -96,7 +95,7 @@ let
96 teardown = dropTable #emails >>> dropTable #users
95 teardown = dropTable #emails >>> dropTable #users
99−>>> Char8.putStrLn $ renderDefinition teardown
98+>>> printSQL teardown
100DROP TABLE "emails";
99DROP TABLE "emails";
101DROP TABLE "users";
100DROP TABLE "users";
@@ -130,9 +129,9 @@ let
130 OnConflictDoNothing (Returning Nil)
129 OnConflictDoNothing (Returning Nil)
133−>>> Char8.putStrLn $ renderManipulation insertUser
132+>>> printSQL insertUser
134INSERT INTO "users" ("id", "name") VALUES (DEFAULT, ($1 :: text)) ON CONFLICT DO NOTHING RETURNING "id" AS "fromOnly"
133INSERT INTO "users" ("id", "name") VALUES (DEFAULT, ($1 :: text)) ON CONFLICT DO NOTHING RETURNING "id" AS "fromOnly"
135−>>> Char8.putStrLn $ renderManipulation insertEmail
134+>>> printSQL insertEmail
136INSERT INTO "emails" ("id", "user_id", "email") VALUES (DEFAULT, ($1 :: int4), ($2 :: text)) ON CONFLICT DO NOTHING
135INSERT INTO "emails" ("id", "user_id", "email") VALUES (DEFAULT, ($1 :: int4), ($2 :: text)) ON CONFLICT DO NOTHING
138Next we write a `Query` to retrieve users from the database. We're not
137Next we write a `Query` to retrieve users from the database. We're not
@@ -152,7 +151,7 @@ let
152 (#u ! #id .== #e ! #user_id)) )
151 (#u ! #id .== #e ! #user_id)) )
155−>>> Char8.putStrLn $ renderQuery getUsers
154+>>> printSQL getUsers
156SELECT "u"."name" AS "userName", "e"."email" AS "userEmail" FROM "users" AS "u" INNER JOIN "emails" AS "e" ON ("u"."id" = "e"."user_id")
155SELECT "u"."name" AS "userName", "e"."email" AS "userEmail" FROM "users" AS "u" INNER JOIN "emails" AS "e" ON ("u"."id" = "e"."user_id")
158Now that we've defined the SQL side of things, we'll need a Haskell type
157Now that we've defined the SQL side of things, we'll need a Haskell type