granger 0.1.0

An opinionated Kanban Board for the solo developer
Documentation
use crate::database::get_connection;
use crate::state::model::State;
use crate::ticket::model::Ticket;
use rusqlite::{params, Result};

pub fn add(ticket: &Ticket) -> Result<usize> {
    let connection = get_connection()?;

    connection.execute(
        "
        INSERT INTO ticket (board_id, number, title, description, state, blocked_by)
        VALUES(?1, ?2, ?3, ?4, ?5, ?6);
        ",
        params![
            ticket.board_id,
            ticket.number,
            ticket.title,
            ticket.description,
            ticket.state.to_string(),
            ticket.blocked_by,
        ],
    )?;

    Ok(ticket.number)
}

pub fn get_by_number(board_id: usize, number: usize) -> Result<Ticket> {
    let connection = get_connection()?;

    let mut statement =
        connection.prepare("SELECT * FROM ticket WHERE board_id=?1 and number=?2;")?;

    let row = statement.query_row(params![board_id, number], |row| {
        let state: String = row.get(5)?;

        let state_as_str: &str = state.as_str();

        Ok(Ticket {
            id: row.get(0)?,
            board_id: row.get(1)?,
            number: row.get(2)?,
            title: row.get(3)?,
            description: row.get(4)?,
            state: State::from_string(state_as_str),
            blocked_by: row.get(6)?,
        })
    })?;

    Ok(row)
}

pub fn get_all_by_board_id(board_id: usize) -> Result<Vec<Ticket>> {
    let connection = get_connection()?;

    let mut statement = connection.prepare("SELECT * FROM ticket where board_id=?;")?;

    let ticket_iter = statement.query_map(params![board_id], |row| {
        let state: String = row.get(5)?;

        let state_as_str: &str = state.as_str();

        Ok(Ticket {
            id: row.get(0)?,
            board_id: row.get(1)?,
            number: row.get(2)?,
            title: row.get(3)?,
            description: row.get(4)?,
            state: State::from_string(state_as_str),
            blocked_by: row.get(6)?,
        })
    })?;

    let mut tickets = Vec::new();

    for ticket_result in ticket_iter {
        match ticket_result {
            Ok(ticket) => tickets.push(ticket),
            Err(value) => println!("Error while fetching tickets: {}", value),
        }
    }

    Ok(tickets)
}

pub fn update(board_id: usize, number: usize, title: &str, description: &str) -> Result<()> {
    let connection = get_connection()?;

    connection.execute(
        "
        UPDATE ticket
        SET title=?3, description=?4
        WHERE board_id=?1 AND number=?2;
        ",
        params![board_id, number, title, description],
    )?;

    Ok(())
}

pub fn delete(board_id: usize, number: usize) -> Result<()> {
    let connection = get_connection()?;

    connection.execute(
        "DELETE FROM ticket WHERE board_id=?1 and number=?2;",
        params![board_id, number],
    )?;

    Ok(())
}

pub fn get_state_count_by_state(board_id: usize, state: &State) -> Result<usize> {
    let connection = get_connection()?;

    let mut statement =
        connection.prepare("SELECT COUNT(*) FROM ticket WHERE board_id=?1 AND state=?2;")?;

    let state = state.to_string();

    let count = statement.query_row(params![board_id, state], |row| {
        let row: usize = row.get(0)?;
        Ok(row)
    })?;

    Ok(count)
}

pub fn move_state(board_id: usize, number: usize, state: &State) -> Result<()> {
    let connection = get_connection()?;

    let state = state.to_string();

    connection.execute(
        "
        UPDATE ticket
        SET state=?3
        WHERE board_id=?1 AND number=?2;
        ",
        params![board_id, number, state],
    )?;

    Ok(())
}

pub fn block_ticket(board_id: usize, number: usize, blocking_ticket: usize) -> Result<()> {
    let connection = get_connection()?;

    connection.execute(
        "
        UPDATE ticket
        SET blocked_by=?3
        WHERE board_id=?1 AND number=?2;
        ",
        params![board_id, number, blocking_ticket],
    )?;

    Ok(())
}

pub fn remove_blocked_by(board_id: usize, number: usize) -> Result<()> {
    let connection = get_connection()?;

    connection.execute(
        "
        UPDATE ticket
        SET blocked_by=0
        WHERE board_id=?1 AND number=?2;
        ",
        params![board_id, number],
    )?;

    Ok(())
}