Feat(SQL, UI): 1. Perfected architecture for modular Search functionality across heirarchical Get Many and Calc Stored Procedures that allows text search filtering on different fields as well as by record Id with control over how the filters are applied. \n 2. Updated User Calc and Get Many Stored Procedures with new Search functionality. \n 3. Improved styles on Dog Command Link page.

This commit is contained in:
2025-07-05 23:17:07 +01:00
parent 0d1e644e6c
commit 8cb8508dcd
51 changed files with 4161 additions and 1292 deletions

View File

@@ -11,6 +11,10 @@ CREATE PROCEDURE parts.p_dog_calc_dog (
, IN a_get_inactive_dog BIT
, IN a_ids_dog TEXT
, IN a_names_dog TEXT
, IN a_require_all_id_search_filters_met BIT
, IN a_require_any_id_search_filters_met BIT
, IN a_require_all_non_id_search_filters_met BIT
, IN a_require_any_non_id_search_filters_met BIT
, IN a_show_errors BIT
, IN a_debug BIT
)
@@ -20,6 +24,7 @@ BEGIN
DECLARE v_code_type_error_no_permission VARCHAR(100);
DECLARE v_has_filter_dog_id BIT;
DECLARE v_has_filter_dog_name BIT;
DECLARE v_id_access_level_view INT;
DECLARE v_id_minimum INT;
DECLARE v_id_permission_dog_view INT;
DECLARE v_id_type_error_bad_data INT;
@@ -40,7 +45,7 @@ BEGIN
id_error INT NOT NULL PRIMARY KEY AUTO_INCREMENT
, id_type INT NULL
, code VARCHAR(100) NOT NULL
, msg VARCHAR(4000) NOT NULL
, msg TEXT NOT NULL
);
INSERT INTO tmp_Msg_Error_Calc_Dog (
@@ -79,7 +84,7 @@ BEGIN
SET v_id_type_error_bad_data := (SELECT ERROR_TYPE.id_type FROM parts.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_bad_data LIMIT 1);
SET v_id_type_error_no_permission := (SELECT ERROR_TYPE.id_type FROM parts.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_no_permission LIMIT 1);
SET v_id_permission_dog_view := (SELECT PERMISSION.id_permission FROM parts.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1);
SET v_id_access_level_view := (SELECT ACCESS_LEVEL.id_access_level FROM parts.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'VIEW' LIMIT 1);
CALL parts.p_core_validate_guid ( a_guid );
@@ -88,6 +93,10 @@ BEGIN
SET a_get_inactive_dog := IFNULL(a_get_inactive_dog, 0);
SET a_ids_dog := TRIM(IFNULL(a_ids_dog, ''));
SET a_names_dog := TRIM(IFNULL(a_names_dog, ''));
SET a_require_all_id_search_filters_met := IFNULL(a_require_all_id_search_filters_met, 1);
SET a_require_any_id_search_filters_met := IFNULL(a_require_any_id_search_filters_met, 1);
SET a_require_all_non_id_search_filters_met := IFNULL(a_require_all_non_id_search_filters_met, 0);
SET a_require_any_non_id_search_filters_met := IFNULL(a_require_any_non_id_search_filters_met, 1);
SET a_show_errors := IFNULL(a_show_errors, 0);
SET a_debug := IFNULL(a_debug, 0);
@@ -99,6 +108,10 @@ BEGIN
, a_get_inactive_dog
, a_ids_dog
, a_names_dog
, a_require_all_id_search_filters_met
, a_require_any_id_search_filters_met
, a_require_all_non_id_search_filters_met
, a_require_any_non_id_search_filters_met
, a_show_errors
, a_debug
;
@@ -118,13 +131,15 @@ BEGIN
CREATE TEMPORARY TABLE tmp_Dog_Calc_Dog (
id_dog INT NOT NULL
, does_meet_id_filters BIT NOT NULL
, does_meet_non_id_filters BIT NOT NULL
);
CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error_Calc_Dog (
id_error INT NOT NULL PRIMARY KEY AUTO_INCREMENT
, id_type INT NULL
, code VARCHAR(100) NOT NULL
, msg VARCHAR(4000) NOT NULL
, msg TEXT NOT NULL
);
CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Split_Id_Calc_Dog (
@@ -145,6 +160,23 @@ BEGIN
-- Dogs
IF v_has_filter_dog_id = 1 THEN
CALL parts.p_core_split(a_guid, a_ids_dog, ',', a_debug);
SET sql_mode = '';
IF a_debug = 1 THEN
SELECT *
FROM parts.CORE_Split_Temp SPLIT_T
WHERE
SPLIT_T.GUID = a_guid
AND IFNULL(SPLIT_T.substring, '') <> ''
;
SELECT COUNT(*) AS count_split_ids
FROM parts.CORE_Split_Temp SPLIT_T
WHERE
SPLIT_T.GUID = a_guid
AND IFNULL(SPLIT_T.substring, '') <> ''
;
END IF;
INSERT INTO tmp_Split_Id_Calc_Dog (
substring
@@ -152,7 +184,7 @@ BEGIN
)
SELECT
SPLIT_T.substring
, CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int
, CAST(SPLIT_T.substring AS DECIMAL(10,0)) AS as_int
FROM parts.CORE_Split_Temp SPLIT_T
WHERE
SPLIT_T.GUID = a_guid
@@ -164,6 +196,23 @@ BEGIN
IF v_has_filter_dog_name = 1 THEN
CALL parts.p_core_split(a_guid, a_names_dog, ',', a_debug);
SET sql_mode = '';
IF a_debug = 1 THEN
SELECT *
FROM parts.CORE_Split_Temp SPLIT_T
WHERE
SPLIT_T.GUID = a_guid
AND IFNULL(SPLIT_T.substring, '') <> ''
;
SELECT COUNT(*) AS count_split_names
FROM parts.CORE_Split_Temp SPLIT_T
WHERE
SPLIT_T.GUID = a_guid
AND IFNULL(SPLIT_T.substring, '') <> ''
;
END IF;
INSERT INTO tmp_Split_Name_Calc_Dog (
substring
@@ -171,7 +220,7 @@ BEGIN
)
SELECT
SPLIT_T.substring
, CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int
, CAST(SPLIT_T.substring AS DECIMAL(10,0)) AS as_int
FROM parts.CORE_Split_Temp SPLIT_T
WHERE
SPLIT_T.GUID = a_guid
@@ -180,6 +229,15 @@ BEGIN
CALL parts.p_core_clear_split( a_guid );
END IF;
IF a_debug = 1 THEN
SELECT *
FROM tmp_Split_Id_Calc_Dog
;
SELECT *
FROM tmp_Split_Name_Calc_Dog
;
END IF;
IF NOT EXISTS (SELECT * FROM tmp_Msg_Error_Calc_Dog t_ERROR INNER JOIN parts.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN
IF EXISTS (
@@ -214,78 +272,70 @@ BEGIN
)
;
/* Don't error on names not found
ELSEIF EXISTS (
SELECT *
FROM tmp_Split t_SPLIT
LEFT JOIN parts.DOG_Dog DOG ON t_SPLIT.as_int = DOG.id_dog
WHERE
ISNULL(t_SPLIT.as_int)
OR ISNULL(DOG.id_dog)
OR (
DOG.active = 0
AND a_get_inactive_dog = 0
)
) THEN
INSERT INTO tmp_Msg_Error_Calc_Dog (
id_type
, code
, msg
)
SELECT
v_id_type_error_bad_data
, v_code_type_error_bad_data
, CONCAT('Invalid or inactive Dog IDs: ', IFNULL(GROUP_CONCAT(t_SPLIT.substring SEPARATOR ', '), 'NULL'))
FROM tmp_Split t_SPLIT
LEFT JOIN parts.DOG_Dog DOG ON t_SPLIT.as_int = DOG.id_dog
WHERE
ISNULL(t_SPLIT.as_int)
OR ISNULL(DOG.id_dog)
OR (
DOG.active = 0
AND a_get_inactive_dog = 0
)
;
ELSEIF EXISTS ()
*/
ELSE
INSERT INTO tmp_Dog_Calc_Dog (
id_dog
, does_meet_id_filters
, does_meet_non_id_filters
)
WITH
Dog_Id_Filter AS (
SELECT DOG.id_dog
FROM tmp_Split_Id_Calc_Dog t_SPLIT_ID
RIGHT JOIN parts.DOG_Dog DOG ON t_SPLIT_ID.as_int = DOG.id_dog
WHERE t_SPLIT_ID.as_int IS NOT NULL
INNER JOIN parts.DOG_Dog DOG ON t_SPLIT_ID.as_int = DOG.id_dog
)
, Dog_Name_Filter AS (
SELECT DOG.id_dog
FROM tmp_Split_Name_Calc_Dog t_SPLIT_NAME
RIGHT JOIN parts.DOG_Dog DOG ON DOG.name LIKE CONCAT('%', t_SPLIT_NAME.substring, '%')
WHERE
t_SPLIT_NAME.substring IS NOT NULL
AND t_SPLIT_NAME.substring <> ''
INNER JOIN parts.DOG_Dog DOG ON DOG.name LIKE CONCAT('%', t_SPLIT_NAME.substring, '%')
WHERE IFNULL(t_SPLIT_NAME.substring, '') <> ''
)
, Dog_Filters AS (
SELECT DISTINCT DOG_COMBINED.id_dog
SELECT
DOG_COMBINED.id_dog
, MAX(DOG_COMBINED.does_meet_id_filter) AS does_meet_id_filter
, MAX(DOG_COMBINED.does_meet_name_filter) AS does_meet_name_filter
FROM (
SELECT DOG_ID_FILTER.id_dog FROM Dog_Id_Filter DOG_ID_FILTER
SELECT
DOG_ID_FILTER.id_dog
, 1 AS does_meet_id_filter
, 0 AS does_meet_name_filter
FROM Dog_Id_Filter DOG_ID_FILTER
UNION
SELECT DOG_NAME_FILTER.id_dog FROM Dog_Name_Filter DOG_NAME_FILTER
SELECT
DOG_NAME_FILTER.id_dog
, 0 AS does_meet_id_filter
, 1 AS does_meet_name_filter
FROM Dog_Name_Filter DOG_NAME_FILTER
) DOG_COMBINED
GROUP BY DOG_COMBINED.id_dog
)
SELECT
DOG.id_dog
, CASE WHEN
v_has_filter_dog_id = 0
OR IFNULL(DOG_FILTERS.does_meet_id_filter, 0) = 1
THEN 1 ELSE 0 END AS does_meet_id_filters
, CASE WHEN
(
v_has_filter_dog_name = 0
)
OR IFNULL(DOG_FILTERS.does_meet_name_filter, 0) = 1
THEN 1 ELSE 0 END AS does_meet_non_id_filters
FROM parts.DOG_Dog DOG
LEFT JOIN Dog_Filters DOG_FILTERS ON DOG.id_dog = DOG_FILTERS.id_dog
WHERE
(
a_get_all_dog = 1
OR (
v_has_filter_dog_id = 1
AND DOG_FILTERS.does_meet_id_filter = 1
)
OR (
(
v_has_filter_dog_id = 1
OR v_has_filter_dog_name = 1
)
AND DOG_FILTERS.id_dog IS NOT NULL
v_has_filter_dog_name = 1
AND DOG_FILTERS.does_meet_name_filter = 1
)
)
AND (
@@ -299,23 +349,50 @@ BEGIN
DELETE FROM tmp_Split_Id_Calc_Dog;
DELETE FROM tmp_Split_Name_Calc_Dog;
-- Filter records
IF NOT EXISTS (SELECT * FROM tmp_Msg_Error_Calc_Dog t_ERROR INNER JOIN parts.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN
DELETE t_DOG
FROM tmp_Dog_Calc_Dog t_DOG
WHERE
(
a_require_all_id_search_filters_met = 1
AND t_DOG.does_meet_id_filters = 0
)
OR (
a_require_all_non_id_search_filters_met = 1
AND t_DOG.does_meet_non_id_filters = 0
)
OR (
a_require_any_id_search_filters_met = 1
AND t_DOG.does_meet_id_filters = 0
)
OR (
a_require_any_non_id_search_filters_met = 1
AND t_DOG.does_meet_non_id_filters = 0
)
;
END IF;
-- Permissions
IF a_debug = 1 THEN
SELECT
a_guid
, a_id_user
a_guid -- a_guid
, a_id_user -- a_id_user
, FALSE -- a_get_inactive_user
, v_id_permission_dog_view
, v_id_permission_dog_view -- ids_permission
, v_id_access_level_view -- ids_access_level
, 0 -- a_show_errors
, 0 -- a_debug
;
END IF;
CALL parts.p_dog_calc_user(
a_guid
, a_id_user
a_guid -- a_guid
, a_id_user -- a_id_user
, FALSE -- a_get_inactive_user
, v_id_permission_dog_view
, v_id_permission_dog_view -- ids_permission
, v_id_access_level_view -- ids_access_level
, 0 -- a_show_errors
, 0 -- a_debug
);
@@ -345,7 +422,7 @@ BEGIN
VALUES (
v_id_type_error_no_permission
, v_code_type_error_no_permission
, 'You do not have permission to view Commands.'
, 'You do not have permission to view Dog.'
)
;
END IF;
@@ -364,7 +441,7 @@ BEGIN
END IF;
-- Outputs
-- Commands
-- Dogs
INSERT INTO parts.DOG_Dog_Temp (
guid
, id_dog
@@ -373,6 +450,9 @@ BEGIN
, mass_kg
, notes
, active
, does_meet_id_filters
, does_meet_non_id_filters
)
SELECT
a_guid
@@ -382,24 +462,29 @@ BEGIN
, DOG.mass_kg
, DOG.notes
, DOG.active
, t_DOG.does_meet_id_filters
, t_DOG.does_meet_non_id_filters
FROM parts.DOG_Dog DOG
INNER JOIN tmp_Dog_Calc_Dog t_DOG ON DOG.id_dog = t_DOG.id_dog
;
-- Errors
SELECT
t_ERROR.id_error
, t_ERROR.id_type
, t_ERROR.code
, ERROR_TYPE.name
, ERROR_TYPE.description
, ERROR_TYPE.is_breaking_error
, ERROR_TYPE.background_colour
, ERROR_TYPE.text_colour
, t_ERROR.msg
FROM tmp_Msg_Error_Calc_Dog t_ERROR
INNER JOIN parts.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type
;
IF a_show_errors = 1 THEN
SELECT
t_ERROR.id_error
, t_ERROR.id_type
, t_ERROR.code
, ERROR_TYPE.name
, ERROR_TYPE.description
, ERROR_TYPE.is_breaking_error
, ERROR_TYPE.background_colour
, ERROR_TYPE.text_colour
, t_ERROR.msg
FROM tmp_Msg_Error_Calc_Dog t_ERROR
INNER JOIN parts.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type
;
END IF;
IF a_debug = 1 AND v_can_view = 1 THEN
SELECT * FROM tmp_Dog_Calc_Dog;
@@ -427,10 +512,30 @@ CALL parts.p_dog_calc_dog (
, 0 -- a_get_inactive_dog
, '' -- a_ids_dog
, '' -- a_names_dog
, 1 -- a_require_all_id_search_filters_met
, 1 -- a_require_any_id_search_filters_met
, 0 -- a_require_all_non_id_search_filters_met
, 1 -- a_require_any_non_id_search_filters_met
, 1 -- a_show_errors
, 1 -- a_debug
);
CALL parts.p_dog_calc_dog (
'slips ' -- a_guid
, 1 -- 'auth0|6582b95c895d09a70ba10fef', -- a_id_user
, 1 -- a_get_all_dog
, 0 -- a_get_inactive_dog
, '' -- a_ids_dog
, 'pat' -- a_names_dog
, 1 -- a_require_all_id_search_filters_met
, 1 -- a_require_any_id_search_filters_met
, 0 -- a_require_all_non_id_search_filters_met
, 1 -- a_require_any_non_id_search_filters_met
, 0 -- a_show_errors
, 0 -- a_debug
);
SELECT *
FROM parts.DOG_Dog_Temp
;