Adds write script for recipes, adds ingredients migrations
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,2 @@
|
|||||||
|
-- This file should undo anything in `up.sql`
|
||||||
|
DROP TABLE ingredients
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-- Your SQL goes here
|
||||||
|
CREATE TABLE ingredients (
|
||||||
|
id INTEGER PRIMARY KEY NOT NULL,
|
||||||
|
alias VARCHAR NOT NULL
|
||||||
|
)
|
||||||
@@ -16,7 +16,7 @@ fn main() {
|
|||||||
|
|
||||||
println!("Here are {} recipes :", result.len());
|
println!("Here are {} recipes :", result.len());
|
||||||
for rec in result {
|
for rec in result {
|
||||||
println!("{}", rec.title);
|
println!("*************\n{}", rec.title);
|
||||||
println!("-------------\n");
|
println!("-------------\n");
|
||||||
println!("{}", rec.ingredients);
|
println!("{}", rec.ingredients);
|
||||||
}
|
}
|
||||||
|
|||||||
69
cookbook/src/bin/write_recipe.rs
Normal file
69
cookbook/src/bin/write_recipe.rs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
extern crate cookbook;
|
||||||
|
extern crate diesel;
|
||||||
|
|
||||||
|
use self::cookbook::*;
|
||||||
|
use std::io::{Read, stdin};
|
||||||
|
use self::models::NewRecipe;
|
||||||
|
use diesel::SqliteConnection;
|
||||||
|
|
||||||
|
struct CreateRecipe<'a> {
|
||||||
|
connection: &'a SqliteConnection,
|
||||||
|
title: &'a str,
|
||||||
|
ingredients: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> CreateRecipe<'a> {
|
||||||
|
fn new(conn: &'a SqliteConnection) -> Self {
|
||||||
|
CreateRecipe{
|
||||||
|
connection: conn,
|
||||||
|
title: "",
|
||||||
|
ingredients: String::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_title(&mut self, title: &'a str) {
|
||||||
|
self.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_ingredient(&mut self, ingredient: String) {
|
||||||
|
// TODO: Validate ingredient
|
||||||
|
self.ingredients.push_str(&ingredient);
|
||||||
|
println!("+");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert(self) {
|
||||||
|
let _ = create_recipe(self.connection, self.title, &self.ingredients);
|
||||||
|
println!("Added {}", self.title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let conn = establish_connection();
|
||||||
|
let mut builder = CreateRecipe::new(&conn);
|
||||||
|
|
||||||
|
println!("Title : ");
|
||||||
|
let mut title = String::new();
|
||||||
|
stdin().read_line(&mut title).unwrap();
|
||||||
|
let title = &title[..(title.len() - 1)];
|
||||||
|
builder.set_title(title);
|
||||||
|
|
||||||
|
println!("Ingredients (empty line to finish): ");
|
||||||
|
loop {
|
||||||
|
let mut ingdts = String::new();
|
||||||
|
stdin().read_line(&mut ingdts).unwrap();
|
||||||
|
if &ingdts == "\r\n" {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
builder.add_ingredient(ingdts.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.insert();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
const EOF: &'static str = "CTRL+D";
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
const EOF: &'static str = "CTRL+Z";
|
||||||
@@ -12,6 +12,7 @@ mod importer;
|
|||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use crate::models::{Recipe, NewRecipe, Ingredient, NewIngredient};
|
||||||
|
|
||||||
pub fn establish_connection() -> SqliteConnection {
|
pub fn establish_connection() -> SqliteConnection {
|
||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
@@ -21,7 +22,27 @@ pub fn establish_connection() -> SqliteConnection {
|
|||||||
.expect(&format!("Error connecting to {}", db_url))
|
.expect(&format!("Error connecting to {}", db_url))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_recipe(conn: &SqliteConnection, title: &str, ingdts: &str) -> usize {
|
||||||
|
use self::schema::recipes;
|
||||||
|
|
||||||
|
let new_recipe = NewRecipe {
|
||||||
|
title: title,
|
||||||
|
category: 0,
|
||||||
|
ingredients: ingdts.to_string(),
|
||||||
|
preparation: &String::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
diesel::insert_into(recipes::table)
|
||||||
|
.values(&new_recipe)
|
||||||
|
.execute(conn)
|
||||||
|
.expect("Error inserting recipe")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find_ingredient(conn: &SqliteConnection, alias: &str) -> Option<Ingredient> {
|
||||||
|
// Find ingredient by alias
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
use super::schema::recipes;
|
||||||
|
use super::schema::ingredients;
|
||||||
|
|
||||||
#[derive(Queryable)]
|
#[derive(Queryable)]
|
||||||
pub struct Recipe {
|
pub struct Recipe {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
@@ -6,3 +9,24 @@ pub struct Recipe {
|
|||||||
pub ingredients: String,
|
pub ingredients: String,
|
||||||
pub preparation: String,
|
pub preparation: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Insertable)]
|
||||||
|
#[table_name="recipes"]
|
||||||
|
pub struct NewRecipe<'a> {
|
||||||
|
pub title: &'a str,
|
||||||
|
pub category: i32,
|
||||||
|
pub ingredients: String,
|
||||||
|
pub preparation: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Queryable)]
|
||||||
|
pub struct Ingredient {
|
||||||
|
pub id: i32,
|
||||||
|
pub alias: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Insertable)]
|
||||||
|
#[table_name="ingredients"]
|
||||||
|
pub struct NewIngredient<'a> {
|
||||||
|
pub alias: &'a str,
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
table! {
|
||||||
|
ingredients (id) {
|
||||||
|
id -> Integer,
|
||||||
|
alias -> Text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
table! {
|
table! {
|
||||||
recipes (id) {
|
recipes (id) {
|
||||||
id -> Integer,
|
id -> Integer,
|
||||||
@@ -7,3 +14,8 @@ table! {
|
|||||||
preparation -> Text,
|
preparation -> Text,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
allow_tables_to_appear_in_same_query!(
|
||||||
|
ingredients,
|
||||||
|
recipes,
|
||||||
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user