Create SQL tables with a query builder

This commit is contained in:
Valentin Tolmer 2021-04-09 10:47:26 +02:00 committed by Valentin Tolmer
parent bfd7730d55
commit 9f56fd02cf
3 changed files with 103 additions and 26 deletions

View File

@ -28,6 +28,7 @@ tracing-actix-web = "0.3.0-beta.2"
tracing-log = "*" tracing-log = "*"
tracing-subscriber = "*" tracing-subscriber = "*"
async-trait = "0.1.48" async-trait = "0.1.48"
sea-query = "0.9.2"
[dependencies.figment] [dependencies.figment]
features = ["toml", "env"] features = ["toml", "env"]

View File

@ -1,42 +1,119 @@
use sea_query::*;
use sqlx::any::AnyPool; use sqlx::any::AnyPool;
#[derive(Iden)]
enum Users {
Table,
UserId,
Email,
DisplayName,
FirstName,
LastName,
Avatar,
CreationDate,
Password,
TotpSecret,
MfaType,
}
#[derive(Iden)]
enum Groups {
Table,
GroupId,
DisplayName,
}
#[derive(Iden)]
enum Memberships {
Table,
UserId,
GroupId,
}
pub async fn init_table(pool: &AnyPool) -> sqlx::Result<()> { pub async fn init_table(pool: &AnyPool) -> sqlx::Result<()> {
// SQLite needs this pragma to be turned on. Other DB might not understand this, so ignore the // SQLite needs this pragma to be turned on. Other DB might not understand this, so ignore the
// error. // error.
let _ = sqlx::query("PRAGMA foreign_keys = ON").execute(pool).await; let _ = sqlx::query("PRAGMA foreign_keys = ON").execute(pool).await;
sqlx::query( sqlx::query(
"CREATE TABLE IF NOT EXISTS users ( &Table::create()
user_id NVARCHAR(255) PRIMARY KEY, .table(Users::Table)
email NVARCHAR(255) NOT NULL, .create_if_not_exists()
display_name NVARCHAR(255) NOT NULL, .col(
first_name NVARCHAR(255) NOT NULL, ColumnDef::new(Users::UserId)
last_name NVARCHAR(255) NOT NULL, .string_len(255)
avatar Blob, .not_null()
creation_date DateTime NOT NULL, .primary_key(),
password NVARCHAR(255) NOT NULL, )
totp_secret VARCHAR(64), .col(ColumnDef::new(Users::Email).string_len(255).not_null())
mfa_type Text .col(
)", ColumnDef::new(Users::DisplayName)
.string_len(255)
.not_null(),
)
.col(ColumnDef::new(Users::FirstName).string_len(255).not_null())
.col(ColumnDef::new(Users::LastName).string_len(255).not_null())
.col(ColumnDef::new(Users::Avatar).binary())
.col(ColumnDef::new(Users::CreationDate).date_time().not_null())
.col(ColumnDef::new(Users::Password).string_len(255).not_null())
.col(ColumnDef::new(Users::TotpSecret).string_len(64))
.col(ColumnDef::new(Users::MfaType).string_len(64))
.to_string(MysqlQueryBuilder),
) )
.execute(pool) .execute(pool)
.await?; .await?;
sqlx::query( sqlx::query(
"CREATE TABLE IF NOT EXISTS groups ( &Table::create()
group_id integer PRIMARY KEY AUTOINCREMENT, .table(Groups::Table)
display_name NVARCHAR(255) NOT NULL .create_if_not_exists()
)", .col(
ColumnDef::new(Groups::GroupId)
.integer()
.not_null()
.auto_increment()
.primary_key(),
)
.col(
ColumnDef::new(Groups::DisplayName)
.string_len(255)
.not_null(),
)
.to_string(MysqlQueryBuilder),
) )
.execute(pool) .execute(pool)
.await?; .await?;
sqlx::query( sqlx::query(
"CREATE TABLE IF NOT EXISTS membership ( &Table::create()
user_id NVARCHAR(255) PRIMARY KEY, .table(Memberships::Table)
group_id integer NOT NULL, .create_if_not_exists()
FOREIGN KEY (user_id) .col(
REFERENCES users (user_id), ColumnDef::new(Memberships::UserId)
FOREIGN KEY (group_id) .string_len(255)
REFERENCES groups (group_id) .not_null()
)", .primary_key(),
)
.col(
ColumnDef::new(Memberships::GroupId)
.integer()
.not_null()
.auto_increment(),
)
.foreign_key(
ForeignKey::create()
.name("MembershipUserForeignKey")
.table(Memberships::Table, Users::Table)
.col(Memberships::UserId, Users::UserId)
.on_delete(ForeignKeyAction::Cascade)
.on_update(ForeignKeyAction::Cascade),
)
.foreign_key(
ForeignKey::create()
.name("MembershipGroupForeignKey")
.table(Memberships::Table, Groups::Table)
.col(Memberships::GroupId, Groups::GroupId)
.on_delete(ForeignKeyAction::Cascade)
.on_update(ForeignKeyAction::Cascade),
)
.to_string(MysqlQueryBuilder),
) )
.execute(pool) .execute(pool)
.await?; .await?;

View File

@ -491,8 +491,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_search_unsupported_filters() { async fn test_search_unsupported_filters() {
let mut mock = MockTestBackendHandler::new(); let mut ldap_handler = setup_bound_handler(MockTestBackendHandler::new()).await;
let mut ldap_handler = setup_bound_handler(mock).await;
let request = SearchRequest { let request = SearchRequest {
msgid: 2, msgid: 2,
base: "ou=people,dc=example,dc=com".to_string(), base: "ou=people,dc=example,dc=com".to_string(),