use crate::resources::{
CreatePipelineInput, CreateTaskFromPipelineInput, NewPipeline, NewTask, Pipeline,
SearchPipelineInput, Task, VariableValue,
};
use crate::Database;
use diesel::prelude::*;
use juniper::{object, Context, FieldError, FieldResult, RootNode, ID};
use std::convert::TryFrom;
impl Context for Database {}
pub(crate) type Schema = RootNode<'static, QueryRoot, MutationRoot>;
pub(crate) struct QueryRoot;
pub(crate) struct MutationRoot;
#[object(Context = Database)]
impl QueryRoot {
fn pipelines(
context: &Database,
search: Option<SearchPipelineInput>,
) -> FieldResult<Vec<Pipeline>> {
use crate::schema::pipelines::dsl::*;
let conn = &context.0;
let mut query = pipelines.order(id).into_boxed();
if let Some(search) = &search {
if let Some(search_name) = &search.name {
query = query.filter(name.ilike(format!("%{}%", search_name)));
};
if let Some(search_description) = &search.description {
query = query.or_filter(description.ilike(format!("%{}%", search_description)));
};
};
query.load(conn).map_err(Into::into)
}
fn tasks(context: &Database) -> FieldResult<Vec<Task>> {
use crate::schema::tasks::dsl::*;
tasks.order(id).load(&**context).map_err(Into::into)
}
fn pipeline(context: &Database, id: ID) -> FieldResult<Option<Pipeline>> {
use crate::schema::pipelines::dsl::{id as pid, pipelines};
pipelines
.filter(pid.eq(id.parse::<i32>()?))
.first(&**context)
.optional()
.map_err(Into::into)
}
fn task(context: &Database, id: ID) -> FieldResult<Option<Task>> {
use crate::schema::tasks::dsl::{id as tid, tasks};
tasks
.filter(tid.eq(id.parse::<i32>()?))
.first(&**context)
.optional()
.map_err(Into::into)
}
}
#[object(Context = Database)]
impl MutationRoot {
fn createPipeline(context: &Database, pipeline: CreatePipelineInput) -> FieldResult<Pipeline> {
NewPipeline::try_from(&pipeline)?
.create(context)
.map_err(Into::into)
}
fn createTaskFromPipeline(
context: &Database,
task: CreateTaskFromPipelineInput,
) -> FieldResult<Task> {
let pipeline: Pipeline = {
use crate::schema::pipelines::dsl::*;
pipelines
.filter(id.eq(task.pipeline_id.parse::<i32>()?))
.first(&**context)
}?;
let variable_values = task
.variables
.into_iter()
.map(Into::into)
.collect::<Vec<VariableValue>>();
if let Some(variable) = pipeline.get_missing_variable(context, &variable_values)? {
return Err(format!(r#"missing variable: "{}""#, variable.key).into());
};
let mut new_task = NewTask::create_from_pipeline(context, &pipeline, &variable_values)
.map_err(Into::<FieldError>::into)?;
new_task.enqueue(context).map_err(Into::into)
}
}