Skip to content
Snippets Groups Projects
database.rs 1.77 KiB
Newer Older
use crate::entities::vault_account;
use crate::utils::GcliError;
use sea_orm::sea_query::IndexCreateStatement;
use sea_orm::{ConnectionTrait, Database, DatabaseConnection, Schema};
use std::fs;
use std::path::Path;

pub async fn build_sqlite_connection(
	data_dir: &Path,
	filename: &str,
) -> Result<DatabaseConnection, GcliError> {
	let sqlite_path = data_dir.join(filename);

	// Check if the file exists, and create it if it doesn't (otherwise the connection will fail)
	if !Path::new(&sqlite_path).exists() {
		fs::File::create(sqlite_path.clone())?;
	}

	let sqlite_path_str = sqlite_path
		.into_os_string()
		.into_string()
		.map_err(|_| GcliError::Input("Invalid SQLite path".to_string()))?;

	let sqlite_db_url = format!("sqlite://{}", sqlite_path_str);

	let connection = initialize_db(&sqlite_db_url).await?;
	Ok(connection)
}

pub async fn initialize_db(db_url: &str) -> Result<DatabaseConnection, GcliError> {
	let db = Database::connect(db_url).await?;
	let schema = Schema::new(db.get_database_backend());

	create_table_if_not_exists(&db, &schema, vault_account::Entity).await?;

	Ok(db)
}

async fn create_table_if_not_exists<E: sea_orm::EntityTrait>(
	db: &DatabaseConnection,
	schema: &Schema,
	entity: E,
) -> Result<(), GcliError> {
	db.execute(
		db.get_database_backend()
			.build(schema.create_table_from_entity(entity).if_not_exists()),
	)
	.await?;
	Ok(())
}

/// The only way to add composed unique index...
#[allow(dead_code)]
async fn create_table_if_not_exists_with_index<E: sea_orm::EntityTrait>(
	db: &DatabaseConnection,
	schema: &Schema,
	entity: E,
	index: &mut IndexCreateStatement,
) -> Result<(), GcliError> {
	db.execute(
		db.get_database_backend().build(
			schema
				.create_table_from_entity(entity)
				.index(index)
				.if_not_exists(),
		),
	)
	.await?;
	Ok(())
}