Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion github_conf/branch_protection_rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"message": "Not Found",
"documentation_url": "https://docs.github.com/rest",
"status": "404"
}
}
227 changes: 62 additions & 165 deletions procedures/get/recipe.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,193 +3,90 @@ USE smartcooking;

DELIMITER //

CREATE OR REPLACE PROCEDURE get_recipe_by_id(
IN p_recipe_id INT,
IN p_language_iso_code CHAR(2)
)
BEGIN
SELECT
r.recipe_id,
r.author_id,
p.person_name AS author_name,
r.publication_date,
r.modification_date,
r.picture_id,
r.preparation_time,
r.cook_time,
r.servings,
r.difficulty_level,
r.estimated_cost,
r.number_of_reviews,
r.recipe_source,
rs.status_name AS recipe_status,
rt.title,
rt.details,
rt.preparation,
rt.nutritional_information,
rt.video_url
FROM recipe r
INNER JOIN recipe_translation rt ON r.recipe_id = rt.recipe_id
INNER JOIN lang l ON rt.language_id = l.language_id
INNER JOIN person p ON r.author_id = p.person_id
INNER JOIN recipe_status rs ON r.recipe_status = rs.status_id
WHERE r.recipe_id = p_recipe_id
AND l.iso_code = p_language_iso_code;
END //

-- Centralized procedure for fetching paginated recipes with filtering
CREATE OR REPLACE PROCEDURE get_recipes_paginated(
IN p_filter_condition TEXT,
CREATE OR REPLACE PROCEDURE search_recipes_flexible(
IN p_filters JSON,
IN p_limit INT,
IN p_offset INT,
IN p_language_iso_code CHAR(2),
IN p_group_by TEXT,
IN p_having_condition TEXT,
IN p_order_by TEXT,
IN p_filter_param TEXT
IN p_language_iso_code CHAR(2)
)
BEGIN
DECLARE v_limit INT;
DECLARE v_offset INT;

SET v_limit = enforce_row_limit(p_limit);
SET v_offset = calculate_offset(p_offset, v_limit);

SET @query = 'SELECT r.recipe_id, r.author_id, p.person_name AS author_name, '
'r.picture_id, r.cook_time, r.difficulty_level, r.number_of_reviews, '
'r.recipe_status, rt.title '
'FROM recipe r '
'INNER JOIN recipe_translation rt ON r.recipe_id = rt.recipe_id '
'INNER JOIN lang l ON rt.language_id = l.language_id '
'INNER JOIN person p ON r.author_id = p.person_id '
'WHERE l.iso_code = ? ';
SET @sql = '
SELECT DISTINCT r.recipe_id,
r.author_id,
p.person_name AS author_name,
r.picture_id,
r.cook_time,
r.difficulty_level,
r.number_of_reviews,
rs.status_name AS recipe_status,
rt.title
FROM recipe r
INNER JOIN recipe_translation rt ON r.recipe_id = rt.recipe_id
INNER JOIN lang l ON rt.language_id = l.language_id
INNER JOIN person p ON r.author_id = p.person_id
INNER JOIN recipe_status rs ON r.recipe_status = rs.status_id
WHERE l.iso_code = ?
';

IF p_filter_condition IS NOT NULL THEN
SET @query = CONCAT(@query, ' ', p_filter_condition);
-- Handle dynamic filters
IF JSON_CONTAINS_PATH(p_filters, 'one', '$.title') THEN
SET @sql = CONCAT(@sql, ' AND rt.title LIKE CONCAT("%", JSON_UNQUOTE(JSON_EXTRACT(p_filters, "$.title")), "%")');
END IF;

IF p_group_by IS NOT NULL THEN
SET @query = CONCAT(@query, ' ', p_group_by);
IF JSON_CONTAINS_PATH(p_filters, 'one', '$.author_id') THEN
SET @sql = CONCAT(@sql, ' AND r.author_id = JSON_EXTRACT(p_filters, "$.author_id")');
END IF;

IF p_having_condition IS NOT NULL THEN
SET @query = CONCAT(@query, ' ', p_having_condition);
IF JSON_CONTAINS_PATH(p_filters, 'one', '$.difficulty_max') THEN
SET @sql = CONCAT(@sql, ' AND r.difficulty_level <= JSON_EXTRACT(p_filters, "$.difficulty_max")');
END IF;

IF p_order_by IS NOT NULL THEN
SET @query = CONCAT(@query, ' ', p_order_by);
IF JSON_CONTAINS_PATH(p_filters, 'one', '$.category') THEN
SET @sql = CONCAT(@sql, '
AND EXISTS (
SELECT 1 FROM recipe_category rc
JOIN category c ON rc.category_id = c.category_id
WHERE rc.recipe_id = r.recipe_id
AND c.category_name = JSON_UNQUOTE(JSON_EXTRACT(p_filters, "$.category"))
)
');
END IF;

SET @query = CONCAT(@query, ' LIMIT ? OFFSET ?');

PREPARE stmt FROM @query;

IF p_filter_param IS NOT NULL THEN
EXECUTE stmt USING p_language_iso_code, p_filter_param, v_limit, v_offset;
ELSE
EXECUTE stmt USING p_language_iso_code, v_limit, v_offset;
IF JSON_CONTAINS_PATH(p_filters, 'one', '$.tags') THEN
SET @sql = CONCAT(@sql, '
AND EXISTS (
SELECT 1 FROM recipe_tag rtg
JOIN tag t ON rtg.tag_id = t.tag_id
WHERE rtg.recipe_id = r.recipe_id
AND JSON_CONTAINS(p_filters, JSON_QUOTE(t.tag_name), "$.tags")
)
');
END IF;

DEALLOCATE PREPARE stmt;
END //

-- Procedure for retrieving all recipes with optional pagination
CREATE OR REPLACE PROCEDURE get_all_recipes_paginated(
IN p_limit INT,
IN p_offset INT,
IN p_language_iso_code CHAR(2)
)
BEGIN
CALL get_recipes_paginated(
NULL, p_limit, p_offset, p_language_iso_code, NULL, NULL, NULL, NULL
);
END //

-- Procedure for retrieving recipes by author with pagination
CREATE OR REPLACE PROCEDURE get_recipes_by_author_paginated(
IN p_author_id INT,
IN p_limit INT,
IN p_offset INT,
IN p_language_iso_code CHAR(2)
)
BEGIN
CALL get_recipes_paginated(
'AND r.author_id = ?', p_limit, p_offset, p_language_iso_code, NULL, NULL, NULL, p_author_id
);
END //

-- Procedure for retrieving recipes liked by a person with pagination
CREATE OR REPLACE PROCEDURE get_recipes_liked_by_person_paginated(
IN p_person_id INT,
IN p_limit INT,
IN p_offset INT
)
BEGIN
DECLARE v_limit INT;
DECLARE v_offset INT;
SET v_limit = enforce_row_limit(p_limit);
SET v_offset = calculate_offset(p_offset, v_limit);

SELECT
r.recipe_id,
r.author_id,
p.person_name AS author_name,
r.picture_id,
r.cook_time,
r.difficulty_level,
r.number_of_reviews,
r.recipe_status
FROM
recipe r
INNER JOIN recipe_engagement re ON r.recipe_id = re.recipe_id
INNER JOIN person p ON r.author_id = p.person_id
WHERE re.person_id = p_person_id AND re.engagement_type = 'like'
LIMIT v_limit OFFSET v_offset;
END //

-- Procedure for retrieving recipes by category with pagination
CREATE OR REPLACE PROCEDURE get_recipes_by_category_paginated(
IN p_category_id INT,
IN p_limit INT,
IN p_offset INT,
IN p_language_iso_code CHAR(2)
)
BEGIN
CALL get_recipes_paginated(
'INNER JOIN recipe_category rc ON r.recipe_id = rc.recipe_id AND rc.category_id = ?',
p_limit, p_offset, p_language_iso_code, NULL, NULL, NULL, p_category_id
);
END //

-- Procedure for retrieving recipes by tags with pagination
CREATE OR REPLACE PROCEDURE get_recipes_by_tags_paginated(
IN p_tags JSON,
IN p_limit INT,
IN p_offset INT,
IN p_language_iso_code CHAR(2)
)
BEGIN
CALL get_recipes_paginated(
'INNER JOIN recipe_tag rtg ON r.recipe_id = rtg.recipe_id AND JSON_CONTAINS(?, JSON_QUOTE(rtg.tag))',
p_limit, p_offset, p_language_iso_code, NULL, NULL, NULL, p_tags
);
END //
IF JSON_CONTAINS_PATH(p_filters, 'one', '$.ingredient') THEN
SET @sql = CONCAT(@sql, '
AND EXISTS (
SELECT 1 FROM recipe_ingredient ri
JOIN ingredient i ON ri.ingredient_id = i.ingredient_id
JOIN ingredient_translation it ON i.ingredient_id = it.ingredient_id
WHERE ri.recipe_id = r.recipe_id
AND it.translated_name LIKE CONCAT("%", JSON_UNQUOTE(JSON_EXTRACT(p_filters, "$.ingredient")), "%")
AND it.language_id = l.language_id
)
');
END IF;

-- Procedure for retrieving recipes by name with pagination
CREATE OR REPLACE PROCEDURE get_recipes_by_name_paginated(
IN p_name VARCHAR(255),
IN p_limit INT,
IN p_offset INT,
IN p_language_iso_code CHAR(2)
)
BEGIN
DECLARE v_safe_recipe_name VARCHAR(255);
SET v_safe_recipe_name = sanitize_string(p_name);
SET @sql = CONCAT(@sql, ' LIMIT ? OFFSET ?');

CALL get_recipes_paginated(
'AND rt.title LIKE ?',
p_limit, p_offset, p_language_iso_code, NULL, NULL, NULL,
v_safe_recipe_name
);
PREPARE stmt FROM @sql;
EXECUTE stmt USING p_language_iso_code, v_limit, v_offset;
DEALLOCATE PREPARE stmt;
END //

-- Procedure for retrieving recipes by status with pagination
Expand Down
4 changes: 4 additions & 0 deletions super-linter-output/super-linter-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
| JSCPD | Pass ✅ |
| JSON | Pass ✅ |
| JSON_PRETTIER | Pass ✅ |
| MARKDOWN | Pass ✅ |
| MARKDOWN_PRETTIER | Pass ✅ |
| NATURAL_LANGUAGE | Pass ✅ |
| SQLFLUFF | Pass ✅ |
| YAML | Pass ✅ |
| YAML_PRETTIER | Pass ✅ |

Expand Down