style: apply cargo fmt

This commit is contained in:
Matthieu Bessat 2026-01-13 20:47:19 +01:00
parent 534ed83419
commit d205d722aa
17 changed files with 390 additions and 315 deletions

View file

@ -1,11 +1,12 @@
use anyhow::Context;
use std::str::FromStr;
use std::path::PathBuf;
use anyhow::Result;
use std::path::PathBuf;
use std::str::FromStr;
use fully_pub::fully_pub;
use sqlx::{
Pool, Sqlite, sqlite::{SqliteConnectOptions, SqlitePoolOptions},
sqlite::{SqliteConnectOptions, SqlitePoolOptions},
Pool, Sqlite,
};
/// database storage interface
@ -13,7 +14,6 @@ use sqlx::{
#[derive(Clone, Debug)]
struct Database(Pool<Sqlite>);
/// Initialize database
pub async fn provide_database(sqlite_db_path: &str) -> Result<Database> {
let path = PathBuf::from(sqlite_db_path);
@ -37,5 +37,3 @@ pub async fn provide_database(sqlite_db_path: &str) -> Result<Database> {
Ok(Database(pool))
}

View file

@ -1,3 +1,3 @@
pub mod repositories;
pub mod db;
pub mod models;
pub mod repositories;

View file

@ -4,12 +4,15 @@ use chrono::Utc;
use sqlx::types::Json;
use sqlxgentools_misc::ForeignRef;
use crate::{db::provide_database, models::user::{User, UserToken}, repositories::user_token_repository::UserTokenRepository};
use crate::{
db::provide_database,
models::user::{User, UserToken},
repositories::user_token_repository::UserTokenRepository,
};
pub mod db;
pub mod models;
pub mod repositories;
pub mod db;
#[tokio::main]
async fn main() -> Result<()> {
@ -24,7 +27,7 @@ async fn main() -> Result<()> {
last_login_at: None,
status: models::user::UserStatus::Invited,
groups: Json(vec![]),
avatar_bytes: None
avatar_bytes: None,
},
User {
id: "idu2".into(),
@ -34,7 +37,7 @@ async fn main() -> Result<()> {
last_login_at: None,
status: models::user::UserStatus::Invited,
groups: Json(vec![]),
avatar_bytes: None
avatar_bytes: None,
},
User {
id: "idu3".into(),
@ -44,8 +47,8 @@ async fn main() -> Result<()> {
last_login_at: None,
status: models::user::UserStatus::Invited,
groups: Json(vec![]),
avatar_bytes: None
}
avatar_bytes: None,
},
];
let user_token = UserToken {
id: "idtoken1".into(),
@ -53,43 +56,44 @@ async fn main() -> Result<()> {
last_use_time: None,
creation_time: Utc::now(),
expiration_time: Utc::now(),
user_id: ForeignRef::new(&users.get(0).unwrap())
user_id: ForeignRef::new(&users.get(0).unwrap()),
};
let db = provide_database("tmp/db.db").await?;
let user_token_repo = UserTokenRepository::new(db);
user_token_repo.insert_many(&vec![
UserToken {
id: "idtoken2".into(),
secret: "4LP5A3F3XBV5NM8VXRGZG3QDXO9PNAC0".into(),
last_use_time: None,
creation_time: Utc::now(),
expiration_time: Utc::now(),
user_id: ForeignRef::new(&users.get(0).unwrap())
},
UserToken {
id: "idtoken3".into(),
secret: "CBHR6G41KSEMR1AI".into(),
last_use_time: None,
creation_time: Utc::now(),
expiration_time: Utc::now(),
user_id: ForeignRef::new(&users.get(1).unwrap())
},
UserToken {
id: "idtoken4".into(),
secret: "CBHR6G41KSEMR1AI".into(),
last_use_time: None,
creation_time: Utc::now(),
expiration_time: Utc::now(),
user_id: ForeignRef::new(&users.get(1).unwrap())
}
]).await?;
let user_tokens = user_token_repo.get_many_user_tokens_by_usersss(
vec!["idu2".into()]
).await?;
user_token_repo
.insert_many(&vec![
UserToken {
id: "idtoken2".into(),
secret: "4LP5A3F3XBV5NM8VXRGZG3QDXO9PNAC0".into(),
last_use_time: None,
creation_time: Utc::now(),
expiration_time: Utc::now(),
user_id: ForeignRef::new(&users.get(0).unwrap()),
},
UserToken {
id: "idtoken3".into(),
secret: "CBHR6G41KSEMR1AI".into(),
last_use_time: None,
creation_time: Utc::now(),
expiration_time: Utc::now(),
user_id: ForeignRef::new(&users.get(1).unwrap()),
},
UserToken {
id: "idtoken4".into(),
secret: "CBHR6G41KSEMR1AI".into(),
last_use_time: None,
creation_time: Utc::now(),
expiration_time: Utc::now(),
user_id: ForeignRef::new(&users.get(1).unwrap()),
},
])
.await?;
let user_tokens = user_token_repo
.get_many_user_tokens_by_usersss(vec!["idu2".into()])
.await?;
dbg!(&user_tokens);
Ok(())
}

View file

@ -1,8 +1,8 @@
use chrono::{DateTime, Utc};
use sqlx::types::Json;
use fully_pub::fully_pub;
use sqlx::types::Json;
use sqlxgentools_attrs::{SqlGeneratorDerive, SqlGeneratorModelWithId, sql_generator_model};
use sqlxgentools_attrs::{sql_generator_model, SqlGeneratorDerive, SqlGeneratorModelWithId};
use sqlxgentools_misc::{DatabaseLine, ForeignRef};
#[derive(sqlx::Type, Clone, Debug, PartialEq)]
@ -11,37 +11,36 @@ enum UserStatus {
Disabled,
Invited,
Active,
Archived
Archived,
}
#[derive(SqlGeneratorDerive, SqlGeneratorModelWithId, sqlx::FromRow, Debug, Clone)]
#[sql_generator_model(table_name="usersss")]
#[sql_generator_model(table_name = "usersss")]
#[fully_pub]
struct User {
#[sql_generator_field(is_primary=true)]
#[sql_generator_field(is_primary = true)]
id: String,
#[sql_generator_field(is_unique=true)]
#[sql_generator_field(is_unique = true)]
handle: String,
full_name: Option<String>,
prefered_color: Option<i64>,
last_login_at: Option<DateTime<Utc>>,
status: UserStatus,
groups: Json<Vec<String>>,
avatar_bytes: Option<Vec<u8>>
avatar_bytes: Option<Vec<u8>>,
}
#[derive(SqlGeneratorDerive, SqlGeneratorModelWithId, sqlx::FromRow, Debug, Clone)]
#[sql_generator_model(table_name="user_tokens")]
#[sql_generator_model(table_name = "user_tokens")]
#[fully_pub]
struct UserToken {
#[sql_generator_field(is_primary=true)]
#[sql_generator_field(is_primary = true)]
id: String,
secret: String,
last_use_time: Option<DateTime<Utc>>,
creation_time: DateTime<Utc>,
expiration_time: DateTime<Utc>,
#[sql_generator_field(reverse_relation_name="user_tokens")] // to generate get_user_tokens_of_user(&user_id)
user_id: ForeignRef<User>
#[sql_generator_field(reverse_relation_name = "user_tokens")]
// to generate get_user_tokens_of_user(&user_id)
user_id: ForeignRef<User>,
}

View file

@ -1,5 +1,5 @@
use crate::models::user::User;
use crate::db::Database;
use crate::models::user::User;
pub struct UserRepository {
db: Database,
}
@ -8,7 +8,9 @@ impl UserRepository {
UserRepository { db }
}
pub async fn get_all(&self) -> Result<Vec<User>, sqlx::Error> {
sqlx::query_as::<_, User>("SELECT * FROM usersss").fetch_all(&self.db.0).await
sqlx::query_as::<_, User>("SELECT * FROM usersss")
.fetch_all(&self.db.0)
.await
}
pub async fn get_by_id(&self, item_id: &str) -> Result<User, sqlx::Error> {
sqlx::query_as::<_, User>("SELECT * FROM usersss WHERE id = $1")
@ -16,10 +18,7 @@ impl UserRepository {
.fetch_one(&self.db.0)
.await
}
pub async fn get_many_by_id(
&self,
items_ids: &[&str],
) -> Result<Vec<User>, sqlx::Error> {
pub async fn get_many_by_id(&self, items_ids: &[&str]) -> Result<Vec<User>, sqlx::Error> {
if items_ids.is_empty() {
return Ok(vec![]);
}
@ -27,9 +26,7 @@ impl UserRepository {
.map(|i| format!("${}", i))
.collect::<Vec<String>>()
.join(",");
let query_sql = format!(
"SELECT * FROM usersss WHERE id IN ({})", placeholder_params
);
let query_sql = format!("SELECT * FROM usersss WHERE id IN ({})", placeholder_params);
let mut query = sqlx::query_as::<_, User>(&query_sql);
for id in items_ids {
query = query.bind(id);
@ -59,8 +56,11 @@ impl UserRepository {
.map(|c| c.to_vec())
.map(|x| {
format!(
"({})", x.iter().map(| i | format!("${}", i)).collect:: < Vec <
String >> ().join(", ")
"({})",
x.iter()
.map(|i| format!("${}", i))
.collect::<Vec<String>>()
.join(", ")
)
})
.collect::<Vec<String>>()
@ -84,11 +84,7 @@ impl UserRepository {
query.execute(&self.db.0).await?;
Ok(())
}
pub async fn update_by_id(
&self,
item_id: &str,
entity: &User,
) -> Result<(), sqlx::Error> {
pub async fn update_by_id(&self, item_id: &str, entity: &User) -> Result<(), sqlx::Error> {
sqlx::query(
"UPDATE usersss SET id = $2, handle = $3, full_name = $4, prefered_color = $5, last_login_at = $6, status = $7, groups = $8, avatar_bytes = $9 WHERE id = $1",
)

View file

@ -1,5 +1,5 @@
use crate::models::user::UserToken;
use crate::db::Database;
use crate::models::user::UserToken;
pub struct UserTokenRepository {
db: Database,
}
@ -18,10 +18,7 @@ impl UserTokenRepository {
.fetch_one(&self.db.0)
.await
}
pub async fn get_many_by_id(
&self,
items_ids: &[&str],
) -> Result<Vec<UserToken>, sqlx::Error> {
pub async fn get_many_by_id(&self, items_ids: &[&str]) -> Result<Vec<UserToken>, sqlx::Error> {
if items_ids.is_empty() {
return Ok(vec![]);
}
@ -30,7 +27,8 @@ impl UserTokenRepository {
.collect::<Vec<String>>()
.join(",");
let query_sql = format!(
"SELECT * FROM user_tokens WHERE id IN ({})", placeholder_params
"SELECT * FROM user_tokens WHERE id IN ({})",
placeholder_params
);
let mut query = sqlx::query_as::<_, UserToken>(&query_sql);
for id in items_ids {
@ -52,18 +50,18 @@ impl UserTokenRepository {
.await?;
Ok(())
}
pub async fn insert_many(
&self,
entities: &Vec<UserToken>,
) -> Result<(), sqlx::Error> {
pub async fn insert_many(&self, entities: &Vec<UserToken>) -> Result<(), sqlx::Error> {
let values_templates: String = (1..(6usize * entities.len() + 1))
.collect::<Vec<usize>>()
.chunks(6usize)
.map(|c| c.to_vec())
.map(|x| {
format!(
"({})", x.iter().map(| i | format!("${}", i)).collect:: < Vec <
String >> ().join(", ")
"({})",
x.iter()
.map(|i| format!("${}", i))
.collect::<Vec<String>>()
.join(", ")
)
})
.collect::<Vec<String>>()
@ -85,11 +83,7 @@ impl UserTokenRepository {
query.execute(&self.db.0).await?;
Ok(())
}
pub async fn update_by_id(
&self,
item_id: &str,
entity: &UserToken,
) -> Result<(), sqlx::Error> {
pub async fn update_by_id(&self, item_id: &str, entity: &UserToken) -> Result<(), sqlx::Error> {
sqlx::query(
"UPDATE user_tokens SET id = $2, secret = $3, last_use_time = $4, creation_time = $5, expiration_time = $6, user_id = $7 WHERE id = $1",
)
@ -132,7 +126,8 @@ impl UserTokenRepository {
.collect::<Vec<String>>()
.join(",");
let query_tmpl = format!(
"SELECT * FROM user_tokens WHERE user_id IN ({})", placeholder_params
"SELECT * FROM user_tokens WHERE user_id IN ({})",
placeholder_params
);
let mut query = sqlx::query_as::<_, UserToken>(&query_tmpl);
for id in items_ids {

View file

@ -5,7 +5,10 @@
use std::assert_matches::assert_matches;
use chrono::Utc;
use sandbox::{models::user::{User, UserStatus}, repositories::user_repository::UserRepository};
use sandbox::{
models::user::{User, UserStatus},
repositories::user_repository::UserRepository,
};
use sqlx::{types::Json, Pool, Sqlite};
#[sqlx::test(fixtures("../src/migrations/all.sql"))]
@ -22,43 +25,40 @@ async fn test_user_repository_create_read_update_delete(pool: Pool<Sqlite>) -> s
last_login_at: Some(Utc::now()),
status: UserStatus::Invited,
groups: Json(vec!["artists".into()]),
avatar_bytes: vec![0x00]
avatar_bytes: vec![0x00],
};
assert_matches!(user_repo.insert(&new_user).await, Ok(()));
assert_matches!(
user_repo.insert(&new_user).await,
Ok(())
);
assert_matches!(
user_repo.get_by_id("ffffffff-0000-4000-0000-0000000000c9".into()).await,
user_repo
.get_by_id("ffffffff-0000-4000-0000-0000000000c9".into())
.await,
Ok(User { .. })
);
assert_matches!(
user_repo.get_by_id("ffffffff-0000-4040-0000-000000000000".into()).await,
user_repo
.get_by_id("ffffffff-0000-4040-0000-000000000000".into())
.await,
Err(sqlx::Error::RowNotFound)
);
// Insert Many
let bunch_of_users: Vec<User> = (0..10).map(|pid| User {
id: format!("ffffffff-0000-4000-0010-{:0>8}", pid),
handle: format!("user num {}", pid),
full_name: None,
prefered_color: None,
last_login_at: None,
status: UserStatus::Invited,
groups: Json(vec![]),
avatar_bytes: vec![]
}).collect();
assert_matches!(
user_repo.insert_many(&bunch_of_users).await,
Ok(())
);
let bunch_of_users: Vec<User> = (0..10)
.map(|pid| User {
id: format!("ffffffff-0000-4000-0010-{:0>8}", pid),
handle: format!("user num {}", pid),
full_name: None,
prefered_color: None,
last_login_at: None,
status: UserStatus::Invited,
groups: Json(vec![]),
avatar_bytes: vec![],
})
.collect();
assert_matches!(user_repo.insert_many(&bunch_of_users).await, Ok(()));
// Read many all
let read_all_res = user_repo.get_all().await;
assert_matches!(
read_all_res,
Ok(..)
);
assert_matches!(read_all_res, Ok(..));
let all_users = read_all_res.unwrap();
assert_eq!(all_users.len(), 11);
@ -69,16 +69,18 @@ async fn test_user_repository_create_read_update_delete(pool: Pool<Sqlite>) -> s
user_repo.update_by_id(&new_user.id, &updated_user).await,
Ok(())
);
let user_from_db = user_repo.get_by_id("ffffffff-0000-4000-0000-0000000000c9".into()).await.unwrap();
let user_from_db = user_repo
.get_by_id("ffffffff-0000-4000-0000-0000000000c9".into())
.await
.unwrap();
assert_eq!(user_from_db.status, UserStatus::Disabled);
// Delete
assert_matches!(user_repo.delete_by_id(&new_user.id).await, Ok(()));
assert_matches!(
user_repo.delete_by_id(&new_user.id).await,
Ok(())
);
assert_matches!(
user_repo.get_by_id("ffffffff-0000-4000-0000-0000000000c9".into()).await,
user_repo
.get_by_id("ffffffff-0000-4000-0000-0000000000c9".into())
.await,
Err(sqlx::Error::RowNotFound)
);