Skip to content

Commit 61da526

Browse files
committed
run_migrations
1 parent 3b26f2a commit 61da526

File tree

8 files changed

+47
-29
lines changed

8 files changed

+47
-29
lines changed

Cargo.lock

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/bencher_schema/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ uuid = { workspace = true, features = ["v4", "serde"] }
5353
aws-credential-types = "1.2"
5454
aws-sdk-s3 = { version = "1.57", features = ["behavior-version-latest"] }
5555
css-inline = "0.14"
56+
diesel_migrations = "2.2"
5657
mail-send = "0.5"
5758
sentry = { version = "0.36", optional = true, default-features = false, features = [
5859
"reqwest",

lib/bencher_schema/src/lib.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
// Needed for distroless builds
44
use libsqlite3_sys as _;
55

6+
use diesel::connection::SimpleConnection;
7+
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
8+
69
pub mod context;
710
pub mod error;
811
pub mod headers;
@@ -14,3 +17,36 @@ pub mod schema;
1417
pub mod view;
1518

1619
pub const API_VERSION: &str = env!("CARGO_PKG_VERSION");
20+
21+
const MIGRATIONS: EmbeddedMigrations = embed_migrations!("./migrations");
22+
23+
#[derive(Debug, thiserror::Error)]
24+
pub enum MigrationError {
25+
#[error("Failed to run database migrations: {0}")]
26+
Migrations(Box<dyn std::error::Error + Send + Sync>),
27+
#[error("Failed to run database pragma off: {0}")]
28+
PragmaOff(diesel::result::Error),
29+
#[error("Failed to run database pragma on: {0}")]
30+
PragmaOn(diesel::result::Error),
31+
}
32+
33+
pub fn run_migrations(database: &mut context::DbConnection) -> Result<(), MigrationError> {
34+
// It is not possible to enable or disable foreign key constraints in the middle of a multi-statement transaction
35+
// (when SQLite is not in autocommit mode).
36+
// Attempting to do so does not return an error; it simply has no effect.
37+
// https://www.sqlite.org/foreignkeys.html#fk_enable
38+
// Therefore, we must run all migrations with foreign key constraints disabled.
39+
// Still use `PRAGMA foreign_keys = OFF` in the migration scripts to disable foreign key constraints when using the CLI.
40+
database
41+
.batch_execute("PRAGMA foreign_keys = OFF")
42+
.map_err(MigrationError::PragmaOff)?;
43+
database
44+
.run_pending_migrations(MIGRATIONS)
45+
.map(|_| ())
46+
.map_err(MigrationError::Migrations)?;
47+
database
48+
.batch_execute("PRAGMA foreign_keys = ON")
49+
.map_err(MigrationError::PragmaOn)?;
50+
51+
Ok(())
52+
}

lib/bencher_token/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ chrono.workspace = true
1212
jsonwebtoken.workspace = true
1313
serde.workspace = true
1414
thiserror.workspace = true
15+
uuid = { workspace = true, features = ["v4"] }
1516

1617
[lints]
1718
workspace = true

lib/bencher_token/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use std::sync::LazyLock;
22

3+
#[cfg(debug_assertions)]
4+
use uuid as _;
5+
36
use bencher_json::Secret;
47

58
mod audience;

services/api/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ url.workspace = true
4545
uuid = { workspace = true, features = ["v4", "serde"] }
4646
# Crate
4747
async-compression = { version = "0.4", features = ["tokio", "gzip"] }
48-
diesel_migrations = "2.2"
4948
paste = "1.0"
5049
sentry = { version = "0.36", optional = true, default-features = false, features = [
5150
"reqwest",

services/api/src/config/config_tx.rs

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use bencher_schema::context::{ApiContext, Database, DbConnection};
1515
use bencher_schema::model::server::QueryServer;
1616
use bencher_token::TokenKey;
1717
use diesel::{connection::SimpleConnection, Connection};
18-
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
1918
use dropshot::{
2019
ApiDescription, ConfigDropshot, ConfigLogging, ConfigLoggingIfExists, ConfigLoggingLevel,
2120
ConfigTls, HttpServer,
@@ -29,7 +28,6 @@ use super::{plus::Plus, DEFAULT_BUSY_TIMEOUT};
2928
use crate::endpoints::Api;
3029

3130
const DATABASE_URL: &str = "DATABASE_URL";
32-
const MIGRATIONS: EmbeddedMigrations = embed_migrations!("../../lib/bencher_schema/migrations");
3331

3432
pub struct ConfigTx {
3533
pub config: Config,
@@ -40,8 +38,8 @@ pub struct ConfigTx {
4038
pub enum ConfigTxError {
4139
#[error("Failed to create server logger: {0}")]
4240
CreateLogger(std::io::Error),
43-
#[error("Failed to run database migrations: {0}")]
44-
Migrations(Box<dyn std::error::Error + Send + Sync>),
41+
#[error("{0}")]
42+
Migrations(#[from] bencher_schema::MigrationError),
4543
#[error("Failed to run database pragma: {0}")]
4644
Pragma(diesel::result::Error),
4745
#[error("Failed to parse role based access control (RBAC) rules: {0}")]
@@ -172,7 +170,7 @@ fn into_context(
172170
}
173171

174172
info!(&log, "Running database migrations");
175-
run_migrations(&mut database_connection)?;
173+
bencher_schema::run_migrations(&mut database_connection)?;
176174

177175
let data_store = if let Some(data_store) = json_database.data_store {
178176
Some(data_store.try_into().map_err(ConfigTxError::DataStore)?)
@@ -243,27 +241,6 @@ fn diesel_database_url(log: &Logger, database_path: &str) {
243241
std::env::set_var(DATABASE_URL, database_path);
244242
}
245243

246-
fn run_migrations(database: &mut DbConnection) -> Result<(), ConfigTxError> {
247-
// It is not possible to enable or disable foreign key constraints in the middle of a multi-statement transaction
248-
// (when SQLite is not in autocommit mode).
249-
// Attempting to do so does not return an error; it simply has no effect.
250-
// https://www.sqlite.org/foreignkeys.html#fk_enable
251-
// Therefore, we must run all migrations with foreign key constraints disabled.
252-
// Still use `PRAGMA foreign_keys = OFF` in the migration scripts to disable foreign key constraints when using the CLI.
253-
database
254-
.batch_execute("PRAGMA foreign_keys = OFF")
255-
.map_err(ConfigTxError::Pragma)?;
256-
database
257-
.run_pending_migrations(MIGRATIONS)
258-
.map(|_| ())
259-
.map_err(ConfigTxError::Migrations)?;
260-
database
261-
.batch_execute("PRAGMA foreign_keys = ON")
262-
.map_err(ConfigTxError::Pragma)?;
263-
264-
Ok(())
265-
}
266-
267244
#[cfg(feature = "plus")]
268245
fn run_litestream(
269246
database: &mut DbConnection,

services/api/src/endpoints/endpoint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ pub struct Delete;
219219
impl_method!(Delete, DELETE);
220220

221221
impl Delete {
222-
pub fn response_deleted<T>(auth: bool) -> ResponseDeleted {
222+
pub fn response_deleted(auth: bool) -> ResponseDeleted {
223223
if auth {
224224
Self::auth_response_deleted()
225225
} else {

0 commit comments

Comments
 (0)