use anyhow::{Context, Result, bail};
use gize_core::Dialect;
use crate::migrate::{connect, runtime};
pub fn create(
database_url: &str,
dialect: Dialect,
email: &str,
name: &str,
password_hash: &str,
) -> Result<()> {
runtime()?.block_on(async {
let pool = connect(database_url).await?;
let existing = sqlx::query(&format!(
"SELECT id FROM users WHERE email = {} LIMIT 1",
dialect.placeholder(1)
))
.bind(email.to_string())
.fetch_optional(&pool)
.await
.context("querying the `users` table — does it exist? run `gize migrate` first")?;
if existing.is_some() {
bail!("an account with email `{email}` already exists");
}
let app_id = dialect.app_generates_id();
let columns = if app_id {
"id, name, email, password, is_admin"
} else {
"name, email, password, is_admin"
};
let count = if app_id { 5 } else { 4 };
let placeholders = (1..=count)
.map(|i| dialect.placeholder(i))
.collect::<Vec<_>>()
.join(", ");
let sql = format!("INSERT INTO users ({columns}) VALUES ({placeholders})");
let mut query = sqlx::query(&sql);
if app_id {
query = query.bind(uuid::Uuid::new_v4().as_bytes().to_vec());
}
query
.bind(name.to_string())
.bind(email.to_string())
.bind(password_hash.to_string())
.bind(true)
.execute(&pool)
.await
.context("inserting the admin user")?;
Ok(())
})
}