style: apply cargo fmt
This commit is contained in:
parent
534ed83419
commit
d205d722aa
17 changed files with 390 additions and 315 deletions
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
pub mod repositories;
|
||||
pub mod db;
|
||||
pub mod models;
|
||||
pub mod repositories;
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue