From 7947b2090a2318e005a4ee2f41050f86854d266f Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Wed, 12 Mar 2025 15:48:06 +0100 Subject: [PATCH] Add skill import functionality and update database configuration --- .gitignore | 1 + config/development.yaml | 2 +- ...10_011041_add_is_highlighted_to_project.rs | 33 ++------- src/app.rs | 1 + src/services/skills.rs | 24 ++++++- src/tasks/create_skill.rs | 10 +-- src/tasks/import_skills.rs | 70 +++++++++++++++++++ src/tasks/mod.rs | 3 +- 8 files changed, 106 insertions(+), 38 deletions(-) create mode 100644 src/tasks/import_skills.rs diff --git a/.gitignore b/.gitignore index 3239570..d9c8632 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ node_modules/ *.pdb *.sqlite +*.db uploads/ assets/static/css/main.css diff --git a/config/development.yaml b/config/development.yaml index 67deee1..03d3aaf 100644 --- a/config/development.yaml +++ b/config/development.yaml @@ -88,7 +88,7 @@ mailer: # Database Configuration database: # Database connection URI - uri: {{ get_env(name="DATABASE_URL", default="postgres://postgres:postgres@localhost:5432/gabrielkaszewski_rs") }} + uri: {{ get_env(name="DATABASE_URL", default="sqlite://./database.db") }} # When enabled, the sql query will be logged. enable_logging: false # Set the timeout duration when acquiring a connection. diff --git a/migration/src/m20241110_011041_add_is_highlighted_to_project.rs b/migration/src/m20241110_011041_add_is_highlighted_to_project.rs index 5c96d94..e3a3e8a 100644 --- a/migration/src/m20241110_011041_add_is_highlighted_to_project.rs +++ b/migration/src/m20241110_011041_add_is_highlighted_to_project.rs @@ -13,47 +13,26 @@ enum Projects { #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { - // - // add column - // manager .alter_table( Table::alter() .table(Projects::Table) .add_column_if_not_exists(boolean(Projects::IsHighlighted).default(false)) - .add_column_if_not_exists(boolean(Projects::IsArchived).default(false)) .to_owned(), ) - .await + .await?; - // - // delete column - // - /* + // Add `is_archived` column manager .alter_table( Table::alter() - .table(Movies::Table) - .drop_column(Movies::Rating) + .table(Projects::Table) + .add_column_if_not_exists(boolean(Projects::IsArchived).default(false)) .to_owned(), ) - .await - */ + .await?; - // - // create index - // - /* - manager - .create_index( - Index::create() - .name("idx-movies-rating") - .table(Movies::Table) - .col(Movies::Rating) - .to_owned(), - ) - .await; - */ + Ok(()) } async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { diff --git a/src/app.rs b/src/app.rs index 932b84c..7bfa980 100644 --- a/src/app.rs +++ b/src/app.rs @@ -78,6 +78,7 @@ impl Hooks for App { tasks.register(tasks::create_user::CreateUserData); tasks.register(tasks::create_job::CreateJobData); tasks.register(tasks::create_skill::CreateSkillData); + tasks.register(tasks::import_skills::ImportSkills); tasks.register(tasks::add_data_file::AddDataFile); tasks.register(tasks::delete_data::DeleteData); tasks.register(tasks::clear_data::ClearData); diff --git a/src/services/skills.rs b/src/services/skills.rs index 967fce3..d070181 100644 --- a/src/services/skills.rs +++ b/src/services/skills.rs @@ -1,7 +1,7 @@ use loco_rs::prelude::*; use sea_orm::QueryOrder; -use crate::models::_entities::skills::{Column, Entity, Model}; +use crate::models::_entities::skills::{ActiveModel, Column, Entity, Model}; pub async fn get_all_skills(ctx: &AppContext) -> Result> { let skills = Entity::find() @@ -9,3 +9,25 @@ pub async fn get_all_skills(ctx: &AppContext) -> Result> { .all(&ctx.db).await?; Ok(skills) } + +pub async fn add_skill(ctx: &AppContext, name: String) -> Result { + let new_skill = ActiveModel { + name: Set(name), + ..Default::default() + }; + let new_skill = new_skill.insert(&ctx.db).await?; + Ok(new_skill) +} + +pub async fn add_skills(ctx: &AppContext, skills: Vec) -> Result> { + let mut new_skills = vec![]; + for skill in skills { + let new_skill = ActiveModel { + name: Set(skill), + ..Default::default() + }; + let new_skill = new_skill.insert(&ctx.db).await?; + new_skills.push(new_skill); + } + Ok(new_skills) +} \ No newline at end of file diff --git a/src/tasks/create_skill.rs b/src/tasks/create_skill.rs index d4b83b7..464c875 100644 --- a/src/tasks/create_skill.rs +++ b/src/tasks/create_skill.rs @@ -1,6 +1,6 @@ use loco_rs::prelude::*; -use crate::models::_entities::skills::ActiveModel; +use crate::services::skills::add_skill; pub struct CreateSkillData; @@ -16,13 +16,7 @@ impl Task for CreateSkillData { async fn run(&self, app_context: &AppContext, vars: &task::Vars) -> Result<()> { let name = vars.cli_arg("name")?; - let mut item = ActiveModel { - ..Default::default() - }; - - item.name = Set(name.to_string()); - - let item = item.insert(&app_context.db).await?; + let item = add_skill(app_context, name.to_string()).await?; tracing::info!( skill_id = item.id, diff --git a/src/tasks/import_skills.rs b/src/tasks/import_skills.rs new file mode 100644 index 0000000..5e330a3 --- /dev/null +++ b/src/tasks/import_skills.rs @@ -0,0 +1,70 @@ +use loco_rs::prelude::*; +use serde::Deserialize; + +use crate::services::skills::add_skills; + +pub struct ImportSkills; + +#[derive(Deserialize)] +struct Skill { + name: String, +} + +#[derive(Deserialize)] +struct Skills { + skills: Vec, +} + +#[async_trait] +impl Task for ImportSkills { + fn task(&self) -> TaskInfo { + TaskInfo { + name: "import_skills".to_string(), + detail: "Task for importing skills from json file or stdin".to_string(), + } + } + + async fn run(&self, app_context: &AppContext, vars: &task::Vars) -> Result<()> { + let from_file = vars.cli_arg("from_file").ok().map(|v| v.parse::().unwrap_or(false)).unwrap_or(false); + + match from_file { + true => { + let file_path = vars.cli_arg("file_path")?; + + let data = std::fs::read_to_string(file_path)?; + let skills: Skills = serde_json::from_str(&data)?; + process_skills(app_context, skills).await?; + + Ok(()) + }, + false => { + let raw_data = vars.cli_arg("raw_data")?; + let skills: Skills = get_skills_from_raw_data(&raw_data); + process_skills(app_context, skills).await?; + + Ok(()) + }, + } + + } +} + +fn get_skills_from_raw_data(raw_data: &str) -> Skills { + let skills = raw_data.split(',').map(|s| Skill { name: s.to_string() }).collect(); + Skills { skills } +} + +async fn process_skills(app_context: &AppContext, skills: Skills) -> Result<()> { + let skills_names = skills.skills.iter().map(|s| s.name.clone()).collect(); + let items = add_skills(app_context, skills_names).await?; + + for item in items { + tracing::info!( + skill_id = item.id, + skill_name = &item.name, + "Skill created successfully", + ); + } + + Ok(()) +} \ No newline at end of file diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index 63afb3c..ad2bf06 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -5,4 +5,5 @@ pub mod create_user; pub mod seed; pub mod clear_data; pub mod delete_data; -pub mod delete_project; \ No newline at end of file +pub mod delete_project; +pub mod import_skills; \ No newline at end of file