Skip to content

Commit

Permalink
Merge branch 'master' into clean-starters
Browse files Browse the repository at this point in the history
  • Loading branch information
jondot authored Oct 28, 2024
2 parents 2271428 + ab2956d commit d06ae4e
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 20 deletions.
22 changes: 7 additions & 15 deletions docs-site/content/docs/the-app/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,8 @@ async fn handle_create_with_password_with_duplicate() {

`Loco` enables you to work with more than one database and share instances across your application.

## Extra DB

To set up an additional database, begin with database connections and configuration. The recommended approach is to navigate to your configuration file and add the following under [settings](@/docs/the-app/your-project.md#settings):

```yaml
Expand All @@ -600,17 +602,13 @@ settings:
```


After configuring the database, import [loco-extras](https://crates.io/crates/loco-extras) and enable the `initializer-extra-db` feature in your Cargo.toml:
```toml
loco-extras = { version = "*", features = ["initializer-extra-db"] }
```

Next load this [initializer](@/docs/extras/pluggability.md#initializers) into `initializers` hook like this example
Load this [initializer](@/docs/extras/pluggability.md#initializers) into `initializers` hook like this example

```rs
async fn initializers(ctx: &AppContext) -> Result<Vec<Box<dyn Initializer>>> {
let initializers: Vec<Box<dyn Initializer>> = vec![
Box::new(loco_extras::initializers::extra_db::ExtraDbInitializer),
Box::new(loco_rs::initializers::extra_db::ExtraDbInitializer),
];
Ok(initializers)
Expand All @@ -631,14 +629,9 @@ pub async fn list(
}
```

## Configuring

To connect more than two different databases, load the feature `initializer-multi-db` in [loco-extras](https://crates.io/crates/loco-extras):
```toml
loco-extras = { version = "*", features = ["initializer-multi-db"] }
```
## Multi-DB (multi-tenant)

The database configuration should look like this:
To connect more than two different databases, the database configuration should look like this:
```yaml
settings:
multi_db:
Expand Down Expand Up @@ -669,14 +662,13 @@ Next load this [initializer](@/docs/extras/pluggability.md#initializers) into `i
```rs
async fn initializers(ctx: &AppContext) -> Result<Vec<Box<dyn Initializer>>> {
let initializers: Vec<Box<dyn Initializer>> = vec![
Box::new(loco_extras::initializers::multi_db::MultiDbInitializer),
Box::new(loco_rs::initializers::multi_db::MultiDbInitializer),
];
Ok(initializers)
}
```

## Using in controllers
Now, you can use the multiple databases in your controller:

```rust
Expand Down
4 changes: 2 additions & 2 deletions loco-cli/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ pub fn for_options(
}
match assetopt {
AssetsOption::Clientside => res.push(format!(
"{}: You've selected `{}` for your asset serving configuration (remember to build \
your frontend in `{}`)",
"{}: You've selected `{}` for your asset serving configuration.\n\nNext step, build \
your frontend:\n $ cd {}\n $ npm install && npm build\n",
"assets".underline(),
"clientside".yellow(),
"frontend/".yellow()
Expand Down
3 changes: 2 additions & 1 deletion loco-gen/src/templates/scaffold/api/controller.t
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,6 @@ pub fn routes() -> Routes {
.add("/", post(add))
.add(":id", get(get_one))
.add(":id", delete(remove))
.add(":id", post(update))
.add(":id", put(update))
.add(":id", patch(update))
}
4 changes: 3 additions & 1 deletion loco-gen/src/templates/scaffold/html/controller.t
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ pub fn routes() -> Routes {
.add("new", get(new))
.add(":id", get(show))
.add(":id/edit", get(edit))
.add(":id", post(update))
.add(":id", delete(remove))
.add(":id", put(update))
.add(":id", patch(update))
}
}
3 changes: 2 additions & 1 deletion loco-gen/src/templates/scaffold/htmx/controller.t
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ pub fn routes() -> Routes {
.add("new", get(new))
.add(":id", get(show))
.add(":id/edit", get(edit))
.add(":id", post(update))
.add(":id", delete(remove))
.add(":id", put(update))
.add(":id", patch(update))
}
34 changes: 34 additions & 0 deletions src/initializers/extra_db.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use async_trait::async_trait;
use axum::{Extension, Router as AxumRouter};

use crate::{
app::{AppContext, Initializer},
db, Error, Result,
};

#[allow(clippy::module_name_repetitions)]
pub struct ExtraDbInitializer;

#[async_trait]
impl Initializer for ExtraDbInitializer {
fn name(&self) -> String {
"extra_db".to_string()
}

async fn after_routes(&self, router: AxumRouter, ctx: &AppContext) -> Result<AxumRouter> {
let extra_db_config = ctx
.config
.initializers
.clone()
.ok_or_else(|| Error::Message("initializers config not configured".to_string()))?;

let extra_db_value = extra_db_config
.get("extra_db")
.ok_or_else(|| Error::Message("initializers config not configured".to_string()))?;

let extra_db = serde_json::from_value(extra_db_value.clone())?;

let db = db::connect(&extra_db).await?;
Ok(router.layer(Extension(db)))
}
}
5 changes: 5 additions & 0 deletions src/initializers/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#[cfg(feature = "with-db")]
pub mod extra_db;

#[cfg(feature = "with-db")]
pub mod multi_db;
32 changes: 32 additions & 0 deletions src/initializers/multi_db.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use async_trait::async_trait;
use axum::{Extension, Router as AxumRouter};

use crate::{
app::{AppContext, Initializer},
db, Error, Result,
};

#[allow(clippy::module_name_repetitions)]
pub struct MultiDbInitializer;

#[async_trait]
impl Initializer for MultiDbInitializer {
fn name(&self) -> String {
"multi_db".to_string()
}

async fn after_routes(&self, router: AxumRouter, ctx: &AppContext) -> Result<AxumRouter> {
let settings = ctx
.config
.initializers
.clone()
.ok_or_else(|| Error::Message("settings config not configured".to_string()))?;

let multi_db = settings
.get("multi_db")
.ok_or_else(|| Error::Message("multi_db not configured".to_string()))?;

let multi_db = db::MultiDb::new(serde_json::from_value(multi_db.clone())?).await?;
Ok(router.layer(Extension(multi_db)))
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub use self::errors::Error;

mod banner;
pub mod bgworker;
pub mod initializers;
pub mod prelude;

#[cfg(feature = "with-db")]
Expand Down

0 comments on commit d06ae4e

Please sign in to comment.