Skip to content

Commit

Permalink
save docs
Browse files Browse the repository at this point in the history
  • Loading branch information
levkk committed Oct 17, 2024
1 parent f772d7a commit 9f7fc38
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 11 deletions.
63 changes: 63 additions & 0 deletions docs/docs/models/connection-pool.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Connection pool

Rwf manages database connections automatically. Since Rwf apps are multi-threaded and asynchronous, a typical deployment will require multiple connections to the database to support concurrent requests. The connection pool takes care of creating and closing connections, and providing them to to the app as needed.

## Get a connection

To execute queries with the ORM, you'll need to check out a connection from the pool. You can do so as follows from anywhere in the code:

```rust
let mut conn = Pool::connection().await?;
```

Once you have a connection, you can pass it to the ORM each time you need to execute a query:

```rust
let users = User::all()
.fetch_all(&mut conn)
.await?;
```

## Return connection to the pool

Returning the connection to the pool is done automatically when the `conn` variable goes out of scope. In Rust semantics, the `conn` variable is "dropped". For example, to checkout a connection for only one query, you can do so inside its own scope:

```rust
async fn get_users() -> Result<Vec<User>, Error> {
let mut conn = Pool::connection().await?;
let users = User::all()
.fetch_all(&mut conn)
.await?;
Ok(users)
// The connection is returned to the pool here.
}
```

## Transactions

All queries are executed inside implicit transactions. If you need to execute multiple queries inside a single transaction, you need to start one explicitely:

```rust
let mut transaction = Pool::transaction().await?;
```

The transaction follows the same scope semantics as a pool connection. When it goes out scope,
the transaction is automatically rolled back and the connection is returned back to the pool. If you want to commit any changes you made inside the transaction, you need to call `commit` explcitely:

```rust
transaction.commit().await?;
```

Automatic rollbacks are a safety feature of Rwf connection management. In case an error happens in Rust mid-transaction, the changes are automatically reverted, preventing partial updates to the database.

Just like a connection, the transaction can be passed to any query generated with the ORM:

```rust
let user = User::find(15)
.fetch_one(&mut transaction)
.await?;
```

## Waiting for connections

When all available connections are checked out, the call to `Pool::connection()` will wait (and asynchronously block) until a connection is returned to the pool. If a connection is not returned in time, an timeout error will be returned, unblocking the request and allowing it to handle the situation gracefully.
22 changes: 11 additions & 11 deletions docs/docs/models/migrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,19 @@ The CLI should be available globally. You can check if it's working correctly by

## Run migrations

If it's your first time setting up a Rwf app, you should run migrations before starting the server. To run the migrations, change directory to
If it's your first time setting up a Rwf app, you should run migrations before starting the server. To run migrations, change directory to
the project root (where `Cargo.toml` is located) and run:

```
rwf-cli migrate run
```

This command will automatically read all migration files in the `migrations` folder, and run the necessary ones in the correct order. If a migration
This command will automatically read all files in the `migrations` folder, and run the necessary ones in the correct order. For instance, if a migration
is already applied to your database, Rwf will skip it and run the next one.

## Create new migration

If you're looking to change your database schema, e.g. by adding a new table, you can do so in a reproducible way by making a migration. To create a new
If you're looking to change your database schema, e.g. by adding a new table, you can do so in a reproducible way with a migration. To create a new
migration, run the following command:

=== "Command"
Expand All @@ -58,10 +58,10 @@ migration, run the following command:
created "migrations/1729119889028371278_unnamed.down.sql"
```

Migrations are placed inside the `<PROJECT_ROOT>/migrations` folder. If this folder doesn't exist, `rwf-cli` will create one automatically.
Migrations are placed inside the `<PROJECT_ROOT>/migrations` folder. If this folder doesn't exist, `rwf-cli` will create it automatically.

The migration name is optional, and by default the migration will be "unnamed", but it's nice to name it something recognizable, to help others
working on the project (and the future you) to know what's being changed.
The migration name is optional. By default the migration will be "unnamed", but it's nice to name it something recognizable; this helps others
working on your project (including future you) to know what was changed.

### Writing migrations

Expand All @@ -70,10 +70,10 @@ the desired changes to the database schema, while the "down" migration contains

!!! note
Having the "down" migration is technically optional but is
very helpful in case the migration doesn't work in production and you need to revert your changes and try again.
very helpful in case the migration doesn't work in production, and you need to revert your changes and try again.
Additionally, without the correct "down" migration, commands like `migrate flush` won't work correctly.

For example, if we want to add a `"users"` table to our database, we can write the following migration:
For example, if you want to add a `"users"` table to your database, you can write the following migration:

=== "Up migration"
```postgresql
Expand All @@ -88,7 +88,7 @@ For example, if we want to add a `"users"` table to our database, we can write t
DROP TABLE users;
```

Once finished, applying the migration can be done by running the following command:
Once finished, applying the migration can be done by running the `migrate run` command:

=== "Command"
```
Expand All @@ -114,11 +114,11 @@ If something went wrong, or you'd like to make more changes without creating ano

The `revert` command automatically executes the "down" file for the last migration. If you'd like to revert more than one migration, specify the version to which you want to revert to, by passing the `--version <VERSION>` argument.

Re-running the last migration can be done by running `rwf-cli migrate run` command again.
Re-running the last migration can be done by running `migrate run` command again.

## Flush the database

In local development, it's sometimes useful to delete everything in your database and start again. To do so, you can run the `rwf-cli migrate flush` command. This command will revert all migrations in reverse order, and re-apply them in normal order again.
In local development, it's sometimes useful to delete everything in your database and start again. To do so, you can run the `migrate flush` command. This command will revert all migrations in reverse order, and re-apply them in normal order again.

!!! warning
Running `rwf-cli migrate flush` will delete all your data. Never run this command in production.
Expand Down

0 comments on commit 9f7fc38

Please sign in to comment.