Skip to content

Commit

Permalink
Add 'SQL Migrations' section
Browse files Browse the repository at this point in the history
  • Loading branch information
weavejester committed Dec 3, 2024
1 parent eb9fc2a commit 4852c5e
Showing 1 changed file with 54 additions and 4 deletions.
58 changes: 54 additions & 4 deletions index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -872,9 +872,14 @@ user=> (reset)
:resumed
----

The SQL module adds a database connection, but we need to add a ref to
our route handlers in order for them to use it. We could do this
by adding a ref to each handler:
The SQL module adds a database connection pool under the key
`:duct.database.sql/hikaricp`, which derives from the more general
`:duct.database/sql` key. We can use this connection pool as a
`javax.sql.DataSource` instance.

In order to give our route handlers access to this, we'll use a ref. We
could manually add the ref to each of the handler's option map, as
shown below.

[,clojure]
----
Expand All @@ -900,7 +905,7 @@ generates.
:routes [["/" {:get :todo.routes/index}]]}}}
----

This will add a `javax.sql.DataSource` object to the `:db` key of the
This will add the `DataSource` instance to the `:db` key of the
component options. We can access this from the route handler function we
created earlier.

Expand All @@ -915,3 +920,48 @@ created earlier.
[:head [:title "Hello World Wide Web"]]
[:body [:h1 "Hello World Wide Web"]]]))
----

Before we go further, however, we should set up the database schema via
a migration.

=== SQL Migrations

Part of the SQL module is to add a **migrator**, a component that will
manage database migrations. By default the
https://github.com/weavejester/ragtime[Ragtime] library is used, and
looks for a `migrations.edn` file in your project directory.

Let's create a migration for a table to store the todo list items.

.migrations.edn
[,clojure]
----
[[:create-table todo
[id "INTEGER PRIMARY KEY"]
[description "TEXT"]
[checked "INTEGER DEFAULT 0"]]]
----

When we reset the REPL, the migration is automatically applied.

[,shell]
----
user=> (reset)
:reloading (todo.routes)
:duct.migrator.ragtime/applying {:id "create-table-todo#336f15d4"}
:resumed
----

If the migration is modified in any way, its ID will also change. At the
REPL, this will result in the old version of the migration being rolled
back, and the new version applied in its place.

Running the application via `--main` will also apply any new migrations
to the database. However, if there is any mismatch between migrations,
an error will be raised instead.

This difference reflects the environments that `--main` and `--repl` are
anticipated to be used in. During development a REPL is used and
mistakes are expected, so the migrator will work to sync the migrations
with the database. During production migrations need to be applied with
more care, and so any discrepancies should halt the migration process.

0 comments on commit 4852c5e

Please sign in to comment.