/* * This file is part of anycook. The new internet cookbook * Copyright (C) 2014 Jan Graßegger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see [http://www.gnu.org/licenses/]. */ package de.anycook.db.mysql; import de.anycook.recipe.ingredient.Ingredient; import org.apache.lucene.queryparser.classic.ParseException; import java.io.IOException; import java.sql.*; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; public class DBIngredient extends DBHandler { public DBIngredient() throws SQLException { super(); } /** * Nutzt {@link de.anycook.db.mysql.DBIngredient#get(String)} um Existenz der Zutat zu ueberpruefen. Wenn Zutat existiert true, sonst false. * * @param q String mit Zutatenname * @return boolean Wenn vorhanden true, sonst false */ public boolean exists(String q) throws SQLException { try { get(q); return true; } catch (IngredientNotFoundException e) { return false; } } /** * Ueberprueft, ob eine Zutat in der Datenbank vorhanden ist und gibt diese in der richtigen Schreibweise zurueck. * * @param q String mit dem Zutatenname * @return String mit dem Zutatenname aus der Datenbank oder null */ public String get(String q) throws SQLException, IngredientNotFoundException { PreparedStatement pStatement = connection.prepareStatement("SELECT name from zutaten WHERE name = ? OR singular = ?"); pStatement.setString(1, q); pStatement.setString(2, q); ResultSet data = pStatement.executeQuery(); if (data.next()) return data.getString("name"); throw new IngredientNotFoundException(q); } public Ingredient getIngredient(String ingredientName) throws SQLException, IngredientNotFoundException { if (ingredientName == null) return null; PreparedStatement pStatement = connection.prepareStatement("SELECT name, singular FROM zutaten WHERE name = ?"); pStatement.setString(1, ingredientName); ResultSet data = pStatement.executeQuery(); if (data.next()) { String name = data.getString("name"); String singular = data.getString("singular"); List<String> recipes = getRecipesForIngredient(name); return new Ingredient(name, singular, recipes); } throw new IngredientNotFoundException(ingredientName); } public Ingredient get(String ingredientName, String amount) throws SQLException, IngredientNotFoundException { if (ingredientName == null) return null; PreparedStatement pStatement = connection.prepareStatement("SELECT name, singular, " + "COUNT(versions_gerichte_name) AS recipes FROM zutaten " + "LEFT JOIN versions_has_zutaten ON name = zutaten_name " + "WHERE name = ?"); pStatement.setString(1, ingredientName); ResultSet data = pStatement.executeQuery(); if (data.next()) { String name = data.getString("name"); String singular = data.getString("singular"); int recipes = data.getInt("recipes"); return new Ingredient(name, singular, amount, recipes); } throw new IngredientNotFoundException(ingredientName); } public List<String> getRecipesForIngredient(String ingredientName) throws SQLException { if (ingredientName == null) return null; List<String> recipes = new LinkedList<>(); PreparedStatement pStatement = connection.prepareStatement("SELECT gerichte.name FROM gerichte " + "INNER JOIN versions ON gerichte.name = versions.gerichte_name AND gerichte.active_id = versions.id " + "INNER JOIN versions_has_zutaten ON versions.gerichte_name = versions_gerichte_name AND id = versions_id " + "WHERE zutaten_name = ? GROUP BY gerichte.name"); pStatement.setString(1, ingredientName); ResultSet data = pStatement.executeQuery(); while (data.next()) { String name = data.getString("gerichte.name"); recipes.add(name); } return recipes; } public List<Ingredient> getIngredientsByParent(String parent) throws SQLException { List<Ingredient> ingredients = new LinkedList<>(); PreparedStatement pStatement = connection.prepareStatement("SELECT name FROM zutaten " + "WHERE parent_zutaten_name = ? GROUP BY name ORDER BY name"); if (parent == null) pStatement.setNull(1, Types.VARCHAR); else pStatement.setString(1, parent); ResultSet data = pStatement.executeQuery(); while (data.next()) { Ingredient ingredient = new Ingredient(data.getString("name")); ingredients.add(ingredient); } return ingredients; } public List<Ingredient> getAllIngredients() throws SQLException { List<Ingredient> ingredients = new ArrayList<>(); PreparedStatement pStatement = connection.prepareStatement("SELECT name, singular, parent_zutaten_name FROM zutaten"); ResultSet data = pStatement.executeQuery(); while (data.next()) { Ingredient ingredient = new Ingredient(data.getString("name")); ingredient.setSingular(data.getString("singular")); ingredient.setParent(data.getString("parent_zutaten_name")); ingredients.add(ingredient); } return ingredients; } public List<Ingredient> getParent() throws SQLException { List<Ingredient> ingredients = new ArrayList<>(); PreparedStatement pStatement = connection.prepareStatement("SELECT name FROM zutaten " + "WHERE parent_zutaten_name IS NULL GROUP BY name ORDER BY name"); ResultSet data = pStatement.executeQuery(); while (data.next()) { Ingredient ingredient = new Ingredient(data.getString("name")); ingredients.add(ingredient); } return ingredients; } public void newIngredient(String ingredient) throws IOException, ParseException, SQLException { PreparedStatement pStatement = connection.prepareStatement("INSERT INTO zutaten(name) VALUES(?)"); pStatement.setString(1, ingredient); pStatement.executeUpdate(); logger.info("added Ingredient '" + ingredient + "'"); } /** * Gibt eine Liste von Zutaten und deren Menge zurueck. * * @param recipeName {@link String} mit dem Gerichtenamen. * @return {@link java.util.List} Liste, die Listen von Strings enthaelt. In den einzelnen Unterlisten stehen jeweils der Name und die Menge einer Zutat. */ public List<Ingredient> getRecipeIngredients(String recipeName) throws SQLException { List<Ingredient> ingredients = new LinkedList<>(); PreparedStatement pStatement = connection.prepareStatement("SELECT zutaten_name, singular, menge FROM gerichte " + "INNER JOIN versions_has_zutaten ON gerichte.active_id = versions_id " + "AND gerichte.name = versions_gerichte_name " + "INNER JOIN zutaten ON zutaten_name = zutaten.name " + "WHERE versions_gerichte_name = ? ORDER BY position ASC"); pStatement.setString(1, recipeName); ResultSet data = pStatement.executeQuery(); while (data.next()) { String name = data.getString("zutaten_name"); String singular = data.getString("singular"); String menge = data.getString("menge"); if (menge == null) menge = ""; Ingredient ingredient = new Ingredient(name, singular, menge); ingredients.add(ingredient); } return ingredients; } /** * Gibt eine Liste von Zutaten und deren Menge zurueck. * * @param recipeName {@link String} mit dem Gerichtenamen. * @return {@link java.util.List} Liste, die Listen von Strings enthaelt. In den einzelnen Unterlisten stehen jeweils der Name und die Menge einer Zutat. */ public List<Ingredient> getRecipeIngredients(String recipeName, int versionId) throws SQLException { List<Ingredient> ingredients = new LinkedList<>(); PreparedStatement pStatement = connection.prepareStatement( "SELECT zutaten_name, singular, menge FROM versions_has_zutaten " + "INNER JOIN zutaten ON zutaten_name = name " + "WHERE versions_gerichte_name = ? AND versions_id = ? ORDER BY position ASC"); pStatement.setString(1, recipeName); pStatement.setInt(2, versionId); ResultSet data = pStatement.executeQuery(); while (data.next()) { String amount = data.getString("menge"); if (amount == null) amount = ""; Ingredient ingredient = new Ingredient(data.getString("zutaten_name"), data.getString("singular"), amount); ingredients.add(ingredient); } return ingredients; } public static class IngredientNotFoundException extends Exception { public IngredientNotFoundException(String queryIngredient) { super("ingredient does not exist: " + queryIngredient); } } }