Feat: User Relationships and Session Members.

This commit is contained in:
2026-02-28 19:53:50 +00:00
parent c7db290aaf
commit e8e9a02e7b
73 changed files with 3818 additions and 571 deletions

View File

@@ -0,0 +1,29 @@
CREATE TABLE tcg.public.TCG_User_Relationship (
relationship_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY
, follower_user_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Game_Session_Member_follower_user_id
FOREIGN KEY (follower_user_id)
REFERENCES tcg.public.TCG_User(user_id)
, following_user_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Game_Session_Member_following_user_id
FOREIGN KEY (following_user_id)
REFERENCES tcg.public.TCG_User(user_id)
, is_following BOOLEAN NOT NULL DEFAULT TRUE
, is_blocked BOOLEAN NOT NULL DEFAULT FALSE
, active BOOLEAN NOT NULL DEFAULT TRUE
, created_on TIMESTAMP NOT NULL
, created_by_user_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Game_Session_Member_created_by_user_id
FOREIGN KEY (created_by_user_id)
REFERENCES tcg.public.TCG_User(user_id)
, updated_last_on TIMESTAMP NOT NULL
, updated_last_by_user_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Game_Session_Member_updated_last_by_user_id
FOREIGN KEY (updated_last_by_user_id)
REFERENCES tcg.public.TCG_User(user_id)
, change_set_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Game_Session_Member_change_set_id
FOREIGN KEY (change_set_id)
REFERENCES tcg.public.TCG_Change_Set(change_set_id)
);

View File

@@ -0,0 +1,15 @@
CREATE TABLE tcg.public.TCG_User_Relationship_Audit (
audit_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY
, relationship_id INT NOT NULL
, CONSTRAINT FK_TCG_User_Audit_relationship_id
FOREIGN KEY (relationship_id)
REFERENCES tcg.public.TCG_User_Relationship(relationship_id)
, name_field TEXT NOT NULL
, value_prev TEXT
, value_new TEXT
, change_set_id INT NOT NULL
, CONSTRAINT FK_TCG_User_Audit_change_set_id
FOREIGN KEY (change_set_id)
REFERENCES tcg.public.TCG_Change_Set(change_set_id)
);

View File

@@ -0,0 +1,17 @@
CREATE TABLE tcg.public.TCG_User_Relationship_Temp (
temp_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY
, relationship_id INT
, follower_user_id INT
, following_user_id INT
, is_following BOOLEAN
, is_blocked BOOLEAN
, active BOOLEAN
, created_on TIMESTAMP
, created_by_user_id INT
, updated_last_on TIMESTAMP
, updated_last_by_user_id INT
, change_set_id INT
, guid UUID NOT NULL
);

View File

@@ -3,17 +3,8 @@ CREATE TABLE tcg.public.TCG_MTG_Inventory_Temp (
temp_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY
, inventory_id INT
, card_id INT
, CONSTRAINT FK_TCG_MTG_Inventory_Temp_card_id
FOREIGN KEY (card_id)
REFERENCES tcg.public.TCG_MTG_Card(card_id)
, finish_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Inventory_Temp_finish_id
FOREIGN KEY (finish_id)
REFERENCES tcg.public.TCG_MTG_Finish(finish_id)
, condition_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Inventory_Temp_condition_id
FOREIGN KEY (condition_id)
REFERENCES tcg.public.TCG_Condition(condition_id)
, sleeve_colour_name TEXT
, location_name TEXT
, acquired_from TEXT
@@ -31,40 +22,22 @@ CREATE TABLE tcg.public.TCG_MTG_Inventory_Temp (
, miscut_errors TEXT
, playability TEXT
, owner_user_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Inventory_Temp_owner_user_id
FOREIGN KEY (owner_user_id)
REFERENCES tcg.public.TCG_User(user_id)
, ownership_status_name TEXT
, trading_status_name TEXT
, loaned_to_user_id INT
, CONSTRAINT FK_TCG_MTG_Inventory_Temp_loaned_to_user_id
FOREIGN KEY (loaned_to_user_id)
REFERENCES tcg.public.TCG_User(user_id)
, loan_start_on TIMESTAMP
, loan_end_on TIMESTAMP
, provenance TEXT
, signed_by_names TEXT
, signature_condition_name TEXT
, token_rear_side_card_id INT
, CONSTRAINT FK_TCG_MTG_Inventory_token_rear_side_card_id
FOREIGN KEY (token_rear_side_card_id)
REFERENCES tcg.public.TCG_MTG_Card(card_id)
, display_order INT NOT NULL
, active BOOLEAN NOT NULL DEFAULT TRUE
-- , created_on TIMESTAMP NOT NULL
, created_by_user_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Inventory_Temp_created_by_user_id
FOREIGN KEY (created_by_user_id)
REFERENCES tcg.public.TCG_User(user_id)
-- , updated_last_on TIMESTAMP NOT NULL
, updated_last_by_user_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Inventory_Temp_updated_last_by_user_id
FOREIGN KEY (updated_last_by_user_id)
REFERENCES tcg.public.TCG_User(user_id)
, change_set_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Inventory_Temp_change_set_id
FOREIGN KEY (change_set_id)
REFERENCES tcg.public.TCG_Change_Set(change_set_id)
, guid UUID NOT NULL
, set_code TEXT

View File

@@ -0,0 +1,28 @@
CREATE TABLE tcg.public.TCG_MTG_Game_Session_Member (
member_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY
, game_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Game_Session_Member_game_id
FOREIGN KEY (game_id)
REFERENCES tcg.public.TCG_MTG_Game(game_id)
, user_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Game_Session_Member_user_id
FOREIGN KEY (user_id)
REFERENCES tcg.public.TCG_User(user_id)
, is_permitted BOOLEAN NOT NULL DEFAULT FALSE
, active BOOLEAN NOT NULL DEFAULT TRUE
, created_on TIMESTAMP NOT NULL
, created_by_user_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Game_Session_Member_created_by_user_id
FOREIGN KEY (created_by_user_id)
REFERENCES tcg.public.TCG_User(user_id)
, updated_last_on TIMESTAMP NOT NULL
, updated_last_by_user_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Game_Session_Member_updated_last_by_user_id
FOREIGN KEY (updated_last_by_user_id)
REFERENCES tcg.public.TCG_User(user_id)
, change_set_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Game_Session_Member_change_set_id
FOREIGN KEY (change_set_id)
REFERENCES tcg.public.TCG_Change_Set(change_set_id)
);

View File

@@ -0,0 +1,15 @@
CREATE TABLE tcg.public.TCG_MTG_Game_Session_Member_Audit (
audit_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY
, member_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Game_Session_Member_Audit_member_id
FOREIGN KEY (member_id)
REFERENCES tcg.public.TCG_MTG_Game_Session_Member(member_id)
, name_field TEXT NOT NULL
, value_prev TEXT
, value_new TEXT
, change_set_id INT NOT NULL
, CONSTRAINT FK_TCG_MTG_Game_Session_Member_Audit_change_set_id
FOREIGN KEY (change_set_id)
REFERENCES tcg.public.TCG_Change_Set(change_set_id)
);

View File

@@ -0,0 +1,16 @@
CREATE TABLE tcg.public.TCG_MTG_Game_Session_Member_Temp (
temp_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY
, member_id INT
, game_id INT
, user_id INT
, is_permitted BOOLEAN
, active BOOLEAN
, created_on TIMESTAMP
, created_by_user_id INT
, updated_last_on TIMESTAMP
, updated_last_by_user_id INT
, change_set_id INT
, guid UUID NOT NULL
);

View File

@@ -0,0 +1,84 @@
CREATE OR REPLACE FUNCTION tcg.public.FN_before_insert_TCG_User_Relationship()
RETURNS TRIGGER AS $$
DECLARE
r_change_set RECORD;
BEGIN
NEW.created_on = COALESCE(NEW.created_on, CURRENT_TIMESTAMP);
NEW.updated_last_on = COALESCE(NEW.updated_last_on, CURRENT_TIMESTAMP);
IF NEW.change_set_id IS NULL THEN
RAISE EXCEPTION 'Change Set ID must be provided.';
END IF;
SELECT *
INTO r_change_set
FROM tcg.public.TCG_Change_Set CHANGE_SET
WHERE NEW.change_set_id = CHANGE_SET.change_set_id
;
IF FOUND THEN
NEW.created_by_user_id := COALESCE(NEW.created_by_user_id, r_change_set.updated_last_by_user_id);
NEW.updated_last_by_user_id := COALESCE(NEW.updated_last_by_user_id, r_change_set.updated_last_by_user_id);
NEW.created_on := COALESCE(NEW.created_on, r_change_set.updated_last_on);
ELSE
RAISE EXCEPTION 'Change Set % not found.', NEW.change_set_id;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql
;
CREATE OR REPLACE FUNCTION tcg.public.FN_before_update_TCG_User_Relationship()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_last_on = CURRENT_TIMESTAMP;
IF OLD.change_set_id IS NOT DISTINCT FROM NEW.change_set_id THEN
RAISE EXCEPTION 'New Change Set ID must be provided.';
END IF;
INSERT INTO tcg.public.TCG_User_Relationship_Audit (
relationship_id
, name_field
, value_prev
, value_new
, change_set_id
)
-- Changed follower_user_id
SELECT NEW.relationship_id, 'follower_user_id', OLD.follower_user_id::TEXT, NEW.follower_user_id::TEXT, NEW.change_set_id
WHERE OLD.follower_user_id IS NOT DISTINCT FROM NEW.follower_user_id
UNION
-- Changed following_user_id
SELECT NEW.relationship_id, 'following_user_id', OLD.following_user_id::TEXT, NEW.following_user_id::TEXT, NEW.change_set_id
WHERE OLD.following_user_id IS NOT DISTINCT FROM NEW.following_user_id
UNION
-- Changed is_following
SELECT NEW.relationship_id, 'is_following', OLD.is_following::TEXT, NEW.is_following::TEXT, NEW.change_set_id
WHERE OLD.is_following IS NOT DISTINCT FROM NEW.is_following
UNION
-- Changed is_blocked
SELECT NEW.relationship_id, 'is_blocked', OLD.is_blocked::TEXT, NEW.is_blocked::TEXT, NEW.change_set_id
WHERE OLD.is_blocked IS NOT DISTINCT FROM NEW.is_blocked
UNION
-- Changed active
SELECT NEW.relationship_id, 'active', OLD.active::TEXT, NEW.active::TEXT, NEW.change_set_id
WHERE OLD.active IS NOT DISTINCT FROM NEW.active
;
RETURN NEW;
END;
$$ LANGUAGE plpgsql
;
CREATE TRIGGER TRI_before_insert_TCG_User_Relationship
BEFORE INSERT ON tcg.public.TCG_User_Relationship
FOR EACH ROW
EXECUTE FUNCTION tcg.public.FN_before_insert_TCG_User_Relationship()
;
CREATE TRIGGER TRI_before_update_TCG_User_Relationship
BEFORE UPDATE ON tcg.public.TCG_User_Relationship
FOR EACH ROW
EXECUTE FUNCTION tcg.public.FN_before_update_TCG_User_Relationship()
;

View File

@@ -0,0 +1,76 @@
CREATE OR REPLACE FUNCTION tcg.public.FN_before_insert_TCG_MTG_Game_Session_Member()
RETURNS TRIGGER AS $$
DECLARE
r_change_set RECORD;
BEGIN
NEW.created_on = COALESCE(NEW.created_on, CURRENT_TIMESTAMP);
NEW.updated_last_on = COALESCE(NEW.updated_last_on, CURRENT_TIMESTAMP);
IF NEW.change_set_id IS NULL THEN
RAISE EXCEPTION 'Change Set ID must be provided.';
END IF;
SELECT *
INTO r_change_set
FROM tcg.public.TCG_Change_Set CHANGE_SET
WHERE NEW.change_set_id = CHANGE_SET.change_set_id
;
IF FOUND THEN
NEW.created_by_user_id := COALESCE(NEW.created_by_user_id, r_change_set.updated_last_by_user_id);
NEW.updated_last_by_user_id := COALESCE(NEW.updated_last_by_user_id, r_change_set.updated_last_by_user_id);
NEW.created_on := COALESCE(NEW.created_on, r_change_set.updated_last_on);
ELSE
RAISE EXCEPTION 'Change Set % not found.', NEW.change_set_id;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql
;
CREATE OR REPLACE FUNCTION tcg.public.FN_before_update_TCG_MTG_Game_Session_Member()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_last_on = CURRENT_TIMESTAMP;
IF OLD.change_set_id IS NOT DISTINCT FROM NEW.change_set_id THEN
RAISE EXCEPTION 'New Change Set ID must be provided.';
END IF;
INSERT INTO tcg.public.TCG_MTG_Game_Session_Member_Audit (
member_id
, name_field
, value_prev
, value_new
, change_set_id
)
-- Changed user_id
SELECT NEW.member_id, 'user_id', OLD.user_id::TEXT, NEW.user_id::TEXT, NEW.change_set_id
WHERE OLD.user_id IS NOT DISTINCT FROM NEW.user_id
UNION
-- Changed is_permitted
SELECT NEW.member_id, 'is_permitted', OLD.is_permitted::TEXT, NEW.is_permitted::TEXT, NEW.change_set_id
WHERE OLD.is_permitted IS NOT DISTINCT FROM NEW.is_permitted
UNION
-- Changed active
SELECT NEW.member_id, 'active', OLD.active::TEXT, NEW.active::TEXT, NEW.change_set_id
WHERE OLD.active IS NOT DISTINCT FROM NEW.active
;
RETURN NEW;
END;
$$ LANGUAGE plpgsql
;
CREATE TRIGGER TRI_before_insert_TCG_MTG_Game_Session_Member
BEFORE INSERT ON tcg.public.TCG_MTG_Game_Session_Member
FOR EACH ROW
EXECUTE FUNCTION tcg.public.FN_before_insert_TCG_MTG_Game_Session_Member()
;
CREATE TRIGGER TRI_before_update_TCG_MTG_Game_Session_Member
BEFORE UPDATE ON tcg.public.TCG_MTG_Game_Session_Member
FOR EACH ROW
EXECUTE FUNCTION tcg.public.FN_before_update_TCG_MTG_Game_Session_Member()
;

View File

@@ -32,9 +32,10 @@ BEGIN
o_success := FALSE;
DROP TABLE IF EXISTS Temp_User_Save_User;
-- DROP TABLE IF EXISTS Temp_User_Save_User;
DROP TABLE IF EXISTS Temp_User_Save_Error;
/*
CREATE TEMP TABLE Temp_User_Save_User (
user_id INT NOT NULL
, user_auth0_id TEXT
@@ -50,6 +51,7 @@ BEGIN
, updated_last_by_user_id INT
, change_set_id INT
);
*/
CREATE TEMP TABLE Temp_User_Save_Error (
temp_id INT GENERATED ALWAYS AS IDENTITY
@@ -68,6 +70,7 @@ BEGIN
);
END IF;
/*
INSERT INTO Temp_User_Save_User (
user_id
, user_auth0_id
@@ -85,7 +88,7 @@ BEGIN
)
SELECT
TCG_USER.user_id
, TCG_USER.user_auth0_id
, v_user_auth0_id
, TCG_USER.firstname
, TCG_USER.surname
, TCG_USER.email
@@ -98,8 +101,11 @@ BEGIN
, COALESCE(TCG_USER.updated_last_by_user_id, v_bot_user_id) -- updated_last_by_user_id
, TCG_USER.change_set_id
FROM tcg.public.TCG_User TCG_USER
WHERE TCG_USER.user_auth0_id = v_user_auth0_id
WHERE
TCG_USER.user_auth0_id = v_user_auth0_id
OR TCG_USER.email = v_email
;
*/
-- Outputs
-- Change Set
@@ -116,7 +122,14 @@ BEGIN
IF NOT EXISTS (SELECT * FROM Temp_User_Save_Error T_ERROR WHERE T_ERROR.error_type_id <> v_warning_error_type_id LIMIT 1) THEN
IF NOT EXISTS (SELECT * FROM Temp_User_Save_User T_USER LIMIT 1) THEN
IF NOT EXISTS (
SELECT *
FROM tcg.public.TCG_User TCG_USER
WHERE
TCG_USER.user_auth0_id = v_user_auth0_id
OR TCG_USER.email = v_email
LIMIT 1
) THEN
-- RAISE EXCEPTION 'Valid User Auth0 ID required.';
-- New User
@@ -148,7 +161,19 @@ BEGIN
, v_bot_user_id -- updated_last_by_user_id
, v_change_set_id -- change_set_id
);
ELSEIF NOT EXISTS (
SELECT *
FROM tcg.public.TCG_User TCG_USER
WHERE TCG_USER.user_auth0_id = v_user_auth0_id
) THEN
UPDATE tcg.public.TCG_User TCG_USER
SET
user_auth0_id = v_user_auth0_id
, change_set_id = v_change_set_id
WHERE
TCG_USER.email = v_email
AND TCG_USER.active
;
END IF;
ELSE
-- Error
@@ -252,3 +277,33 @@ SELECT *
FROM tcg.public.TCG_User TCG_USER
ORDER BY TCG_USER.user_id DESC
;
/*
SELECT *
FROM tcg.public.TCG_User TCG_USER
;
INSERT INTO tcg.public.tcg_change_set (
COMMENT, updated_last_by_user_id
)
VALUES ( 'Clear Auth0 id from Teddy.', 3);
SELECT *
FROM tcg.public.tcg_change_set cs
ORDER BY cs.change_set_id DESC
;
UPDATE tcg.public.TCG_User TCG_USER
SET
user_auth0_id = NULL
, change_set_id = 224
WHERE TCG_USER.user_id = 3
;
DELETE FROM tcg.public.TCG_User TCG_USER
WHERE TCG_USER.user_id = 13
;
*/

View File

@@ -0,0 +1,131 @@
CREATE OR REPLACE FUNCTION tcg.public.FN_TCG_User_Relationship_Get_Many (
a_get_inactive_user_relationship BOOLEAN
, a_get_all_user_follower BOOLEAN
, a_user_follower_ids TEXT
, a_get_all_user_following BOOLEAN
, a_user_following_ids TEXT
, a_get_inactive_user BOOLEAN
, a_require_all_id_filters_met BOOLEAN
, a_require_any_id_filters_met BOOLEAN
)
RETURNS TABLE (
relationship_id INT
, follower_user_id INT
, following_user_id INT
, is_following BOOLEAN
, is_blocked BOOLEAN
, active BOOLEAN
, created_on TIMESTAMP
, created_by_user_id INT
, updated_last_on TIMESTAMP
, updated_last_by_user_id INT
, change_set_id INT
)
LANGUAGE plpgsql
AS $$
DECLARE
v_get_inactive_user_relationship BOOLEAN;
v_get_all_user_follower BOOLEAN;
v_user_follower_ids TEXT;
v_get_all_user_following BOOLEAN;
v_user_following_ids TEXT;
v_get_inactive_user BOOLEAN;
v_require_all_id_filters_met BOOLEAN;
v_require_any_id_filters_met BOOLEAN;
BEGIN
v_get_inactive_user_relationship := COALESCE(a_get_inactive_user_relationship, FALSE);
v_get_all_user_follower := COALESCE(a_get_all_user_follower, FALSE);
v_user_follower_ids := TRIM(COALESCE(a_user_follower_ids, ''));
v_get_all_user_following := COALESCE(a_get_all_user_following, FALSE);
v_user_following_ids := TRIM(COALESCE(a_user_following_ids, ''));
v_get_inactive_user := COALESCE(a_get_inactive_user, FALSE);
v_require_all_id_filters_met := COALESCE(a_require_all_id_filters_met, FALSE);
v_require_any_id_filters_met := COALESCE(a_require_any_id_filters_met, FALSE);
-- Outputs
RETURN QUERY SELECT
RELATIONSHIP.relationship_id
, RELATIONSHIP.follower_user_id
, RELATIONSHIP.following_user_id
, RELATIONSHIP.is_following
, RELATIONSHIP.is_blocked
, RELATIONSHIP.active
, RELATIONSHIP.created_on
, RELATIONSHIP.created_by_user_id
, RELATIONSHIP.updated_last_on
, RELATIONSHIP.updated_last_by_user_id
, RELATIONSHIP.change_set_id
FROM tcg.public.TCG_User_Relationship RELATIONSHIP
INNER JOIN tcg.public.TCG_User USER_FOLLOWER ON RELATIONSHIP.follower_user_id = USER_FOLLOWER.user_id
INNER JOIN tcg.public.TCG_User USER_FOLLOWING ON RELATIONSHIP.following_user_id = USER_FOLLOWING.user_id
WHERE
(
(
NOT v_require_all_id_filters_met
AND NOT v_require_any_id_filters_met
)
OR (
v_require_all_id_filters_met
AND (
v_get_all_user_follower
OR USER_FOLLOWER.user_id = ANY(string_to_array(v_user_follower_ids, ',')::INT[])
)
AND (
v_get_all_user_following
OR USER_FOLLOWING.user_id = ANY(string_to_array(v_user_following_ids, ',')::INT[])
)
)
OR (
NOT v_require_all_id_filters_met
AND v_require_any_id_filters_met
AND (
(
v_get_all_user_follower
OR USER_FOLLOWER.user_id = ANY(string_to_array(v_user_follower_ids, ',')::INT[])
)
OR (
v_get_all_user_following
OR USER_FOLLOWING.user_id = ANY(string_to_array(v_user_following_ids, ',')::INT[])
)
)
)
)
AND (
v_get_inactive_user_relationship
OR RELATIONSHIP.active
)
AND (
v_get_inactive_user
OR (
USER_FOLLOWER.active
AND USER_FOLLOWING.active
)
)
ORDER BY
RELATIONSHIP.follower_user_id
, NOT RELATIONSHIP.is_following
, NOT RELATIONSHIP.is_blocked
, RELATIONSHIP.following_user_id
;
END;
$$;
SELECT *
FROM tcg.public.FN_TCG_User_Relationship_Get_Many (
a_get_inactive_user_relationship := FALSE
, a_get_all_user_follower := TRUE
, a_user_follower_ids := ''
, a_get_all_user_following := TRUE
, a_user_following_ids := ''
, a_get_inactive_user := FALSE
, a_require_all_id_filters_met := TRUE
, a_require_any_id_filters_met := FALSE
)
;
SELECT *
FROM tcg.public.TCG_User_Relationship
;

View File

@@ -0,0 +1,532 @@
CREATE OR REPLACE PROCEDURE tcg.public.USP_TCG_User_Relationship_Save (
a_comment TEXT
, a_guid UUID
, a_user_id INT
, OUT o_success BOOLEAN
)
LANGUAGE plpgsql
AS $$
DECLARE
v_bad_data_error_type_id INT;
v_change_set_id INT;
v_comment TEXT;
-- v_error_message TEXT;
v_guid UUID;
v_time_start TIMESTAMP;
v_user_id INT;
v_warning_error_type_id INT;
BEGIN
v_comment := TRIM(COALESCE(a_comment, ''));
v_guid := a_guid;
v_user_id := a_user_id;
v_bad_data_error_type_id := (SELECT ERROR_TYPE.error_type_id FROM tcg.public.Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = 'BAD_DATA' LIMIT 1);
v_warning_error_type_id := (SELECT ERROR_TYPE.error_type_id FROM tcg.public.Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = 'WARNING' LIMIT 1);
v_time_start := CURRENT_TIMESTAMP;
DROP TABLE IF EXISTS Temp_User_Relationship_Save_User;
DROP TABLE IF EXISTS Temp_User_Relationship_Save_User_Relationship;
DROP TABLE IF EXISTS Temp_User_Relationship_Save_Error;
CREATE TEMP TABLE Temp_User_Relationship_Save_User (
user_id INT NOT NULL
, user_auth0_id TEXT
, firstname TEXT
, surname TEXT
, email TEXT
, is_email_verified BOOLEAN
, is_super_user BOOLEAN
, active BOOLEAN
, created_on TIMESTAMP
, created_by_user_id INT
, updated_last_on TIMESTAMP
, updated_last_by_user_id INT
, change_set_id INT
);
CREATE TEMP TABLE Temp_User_Relationship_Save_User_Relationship (
temp_id INT NOT NULL
, relationship_id INT
, follower_user_id INT
, following_user_id INT
, is_following BOOLEAN
, is_blocked BOOLEAN
, active BOOLEAN
, created_on TIMESTAMP
, created_by_user_id INT
, updated_last_on TIMESTAMP
, updated_last_by_user_id INT
, change_set_id INT
, is_new BOOLEAN
, error_name TEXT
, is_duplicate BOOLEAN
);
CREATE TEMP TABLE Temp_User_Relationship_Save_Error (
temp_id INT GENERATED ALWAYS AS IDENTITY
, error_type_id INT
, message TEXT
);
WITH Temp_User_Relationship AS (
SELECT
RELATIONSHIP_T.temp_id
, CASE WHEN COALESCE(RELATIONSHIP_T.relationship_id, 0) < 1
THEN RELATIONSHIP.relationship_id
ELSE RELATIONSHIP_T.relationship_id
END AS relationship_id
, RELATIONSHIP_T.follower_user_id
, RELATIONSHIP_T.following_user_id
, COALESCE(RELATIONSHIP_T.is_following, TRUE) AS is_following
, COALESCE(RELATIONSHIP_T.is_blocked, FALSE) AS is_blocked
, COALESCE(RELATIONSHIP_T.active, TRUE) AS active
, COALESCE(RELATIONSHIP_T.created_on, v_time_start) AS created_on
, COALESCE(RELATIONSHIP_T.created_by_user_id, v_user_id) AS created_by_user_id
, COALESCE(RELATIONSHIP_T.updated_last_on, v_time_start) AS updated_last_on
, COALESCE(RELATIONSHIP_T.updated_last_by_user_id, v_user_id) AS updated_last_by_user_id
, RELATIONSHIP_T.change_set_id
, CASE WHEN RELATIONSHIP.relationship_id IS NULL THEN TRUE ELSE FALSE END AS is_new
FROM tcg.public.TCG_User_Relationship_Temp RELATIONSHIP_T
LEFT JOIN tcg.public.TCG_User_Relationship RELATIONSHIP
ON RELATIONSHIP_T.relationship_id = RELATIONSHIP.relationship_id
OR (
COALESCE(RELATIONSHIP_T.relationship_id, 0) < 1
AND RELATIONSHIP_T.follower_user_id = RELATIONSHIP.follower_user_id
AND RELATIONSHIP_T.following_user_id = RELATIONSHIP.following_user_id
)
)
INSERT INTO Temp_User_Relationship_Save_User_Relationship (
temp_id
, relationship_id
, follower_user_id
, following_user_id
, is_following
, is_blocked
, active
, created_on
, created_by_user_id
, updated_last_on
, updated_last_by_user_id
, change_set_id
, is_new
, error_name
)
SELECT
T_RELATIONSHIP.temp_id
, T_RELATIONSHIP.relationship_id
, T_RELATIONSHIP.follower_user_id
, T_RELATIONSHIP.following_user_id
, T_RELATIONSHIP.is_following
, T_RELATIONSHIP.is_blocked
, T_RELATIONSHIP.active
, T_RELATIONSHIP.created_on
, T_RELATIONSHIP.created_by_user_id
, T_RELATIONSHIP.updated_last_on
, T_RELATIONSHIP.updated_last_by_user_id
, T_RELATIONSHIP.change_set_id
, T_RELATIONSHIP.is_new
, CONCAT(
'User Relationship { id: '
, CAST(T_RELATIONSHIP.relationship_id AS VARCHAR)
, ', follower user id: '
, CAST(T_RELATIONSHIP.follower_user_id AS VARCHAR)
, ', following user id: '
, CAST(T_RELATIONSHIP.following_user_id AS VARCHAR)
, ', is following: '
, CAST(T_RELATIONSHIP.is_following AS VARCHAR)
, ', is blocked: '
, CAST(T_RELATIONSHIP.is_blocked AS VARCHAR)
, ' }'
) -- error_name
FROM Temp_User_Relationship T_RELATIONSHIP -- tcg.public.TCG_User_Relationship_Temp RELATIONSHIP_T
-- LEFT JOIN tcg.public.TCG_User_Relationship RELATIONSHIP ON RELATIONSHIP_T.relationship_id = RELATIONSHIP.relationship_id
;
INSERT INTO Temp_User_Relationship_Save_User (
user_id
, user_auth0_id
, firstname
, surname
, email
, is_email_verified
, is_super_user
, active
, created_on
, created_by_user_id
, updated_last_on
, updated_last_by_user_id
, change_set_id
)
SELECT
TCG_USER.user_id
, TCG_USER.user_auth0_id
, TCG_USER.firstname
, TCG_USER.surname
, TCG_USER.email
, TCG_USER.is_email_verified
, TCG_USER.is_super_user
, TCG_USER.active
, TCG_USER.created_on
, TCG_USER.created_by_user_id
, TCG_USER.updated_last_on
, TCG_USER.updated_last_by_user_id
, TCG_USER.change_set_id
FROM tcg.public.TCG_User TCG_USER
INNER JOIN Temp_User_Relationship_Save_User_Relationship T_RELATIONSHIP
ON TCG_USER.user_id = T_RELATIONSHIP.follower_user_id
OR TCG_USER.user_id = T_RELATIONSHIP.following_user_id
;
-- Missing fields
WITH Relationship_Missing_Field AS (
SELECT
T_RELATIONSHIP.temp_id
, 'follower_user_id' AS field
FROM Temp_User_Relationship_Save_User_Relationship T_RELATIONSHIP
WHERE T_RELATIONSHIP.follower_user_id IS NULL
UNION
SELECT
T_RELATIONSHIP.temp_id
, 'following_user_id' AS field
FROM Temp_User_Relationship_Save_User_Relationship T_RELATIONSHIP
WHERE T_RELATIONSHIP.following_user_id IS NULL
)
INSERT INTO Temp_User_Relationship_Save_Error (
error_type_id
, message
)
SELECT
v_bad_data_error_type_id -- error_type_id
, CONCAT(
'Missing mandatory field: '
, RELATIONSHIP_MISSING_FIELD.field
, ' on '
, T_RELATIONSHIP.error_name
, '.'
) -- message
FROM Temp_User_Relationship_Save_User_Relationship T_RELATIONSHIP
INNER JOIN Relationship_Missing_Field RELATIONSHIP_MISSING_FIELD ON T_RELATIONSHIP.temp_id = RELATIONSHIP_MISSING_FIELD.temp_id
;
-- Failed join fields
WITH Relationship_Failed_Join_Field AS (
SELECT
T_RELATIONSHIP.temp_id
, 'follower_user_id' AS field
FROM Temp_User_Relationship_Save_User_Relationship T_RELATIONSHIP
LEFT JOIN Temp_User_Relationship_Save_User T_USER ON T_RELATIONSHIP.follower_user_id = T_USER.user_id
WHERE T_USER.user_id IS NULL
UNION
SELECT
T_RELATIONSHIP.temp_id
, 'following_user_id' AS field
FROM Temp_User_Relationship_Save_User_Relationship T_RELATIONSHIP
LEFT JOIN Temp_User_Relationship_Save_User T_USER ON T_RELATIONSHIP.following_user_id = T_USER.user_id
WHERE T_USER.user_id IS NULL
)
INSERT INTO Temp_User_Relationship_Save_Error (
error_type_id
, message
)
SELECT
v_bad_data_error_type_id -- error_type_id
, CONCAT(
'Failed relationship: '
, RELATIONSHIP_FAILED_JOIN_FIELD.field
, ' on '
, T_RELATIONSHIP.error_name
, '.'
) -- message
FROM Temp_User_Relationship_Save_User_Relationship T_RELATIONSHIP
INNER JOIN Relationship_Failed_Join_Field RELATIONSHIP_FAILED_JOIN_FIELD ON T_RELATIONSHIP.temp_id = RELATIONSHIP_FAILED_JOIN_FIELD.temp_id
;
-- Duplicate Relationship
WITH
All_Relationship AS (
SELECT
T_RELATIONSHIP.temp_id
, T_RELATIONSHIP.follower_user_id
, T_RELATIONSHIP.following_user_id
, TRUE AS is_save_record
FROM Temp_User_Relationship_Save_User_Relationship T_RELATIONSHIP
UNION
SELECT
NULL AS temp_id
, RELATIONSHIP.follower_user_id
, RELATIONSHIP.following_user_id
, FALSE AS is_save_record
FROM tcg.public.TCG_User_Relationship RELATIONSHIP
LEFT JOIN Temp_User_Relationship_Save_User_Relationship T_RELATIONSHIP ON RELATIONSHIP.relationship_id = T_RELATIONSHIP.relationship_id
WHERE
T_RELATIONSHIP.relationship_id IS NULL
AND RELATIONSHIP.active
)
, Relationship_Follow_Pair AS (
SELECT
ALL_RELATIONSHIP.follower_user_id
, ALL_RELATIONSHIP.following_user_id
, COUNT(*) AS count_pair
FROM All_Relationship ALL_RELATIONSHIP
GROUP BY
ALL_RELATIONSHIP.follower_user_id
, ALL_RELATIONSHIP.following_user_id
)
, Duplicate_Relationship AS (
SELECT
ALL_RELATIONSHIP.temp_id
, ALL_RELATIONSHIP.follower_user_id
, ALL_RELATIONSHIP.following_user_id
, CASE WHEN RELATIONSHIP_PAIR.count_pair = 1 THEN TRUE ELSE FALSE END AS is_unique
FROM All_Relationship ALL_RELATIONSHIP
INNER JOIN Relationship_Follow_Pair RELATIONSHIP_PAIR
ON ALL_RELATIONSHIP.follower_user_id = RELATIONSHIP_PAIR.follower_user_id
AND ALL_RELATIONSHIP.following_user_id = RELATIONSHIP_PAIR.following_user_id
)
UPDATE Temp_User_Relationship_Save_User_Relationship T_RELATIONSHIP
SET is_duplicate = NOT DUPLICATE_RELATIONSHIP.is_unique
FROM Duplicate_Relationship DUPLICATE_RELATIONSHIP
WHERE T_RELATIONSHIP.temp_id = DUPLICATE_RELATIONSHIP.temp_id
;
IF EXISTS (
SELECT *
FROM Temp_User_Relationship_Save_User_Relationship T_RELATIONSHIP
WHERE T_RELATIONSHIP.is_duplicate
LIMIT 1
) THEN
INSERT INTO Temp_User_Relationship_Save_Error (
error_type_id
, message
)
SELECT
v_bad_data_error_type_id -- error_type_id
, CONCAT(
'Duplicate on '
, T_RELATIONSHIP.error_name
) -- message
FROM Temp_User_Relationship_Save_User_Relationship T_RELATIONSHIP
WHERE T_RELATIONSHIP.is_duplicate
;
END IF;
-- Nothing to save
IF NOT EXISTS (SELECT * FROM Temp_User_Relationship_Save_User_Relationship LIMIT 1) THEN
INSERT INTO Temp_User_Relationship_Save_Error (
error_type_id
, message
)
VALUES (
v_warning_error_type_id
, 'Nothing to save.'
);
END IF;
-- Outputs
-- Change Set
INSERT INTO tcg.public.TCG_Change_Set (
comment
, updated_last_by_user_id
)
VALUES (
v_comment
, v_user_id
)
RETURNING change_set_id INTO v_change_set_id
;
IF NOT EXISTS (SELECT * FROM Temp_User_Relationship_Save_Error T_ERROR WHERE T_ERROR.error_type_id <> v_warning_error_type_id LIMIT 1) THEN
-- User relationship
INSERT INTO tcg.public.TCG_User_Relationship (
follower_user_id
, following_user_id
, is_following
, is_blocked
, active
, created_on
, created_by_user_id
, updated_last_on
, updated_last_by_user_id
, change_set_id
)
SELECT
T_RELATIONSHIP.follower_user_id
, T_RELATIONSHIP.following_user_id
, T_RELATIONSHIP.is_following
, T_RELATIONSHIP.is_blocked
, T_RELATIONSHIP.active
, T_RELATIONSHIP.created_on
, T_RELATIONSHIP.created_by_user_id
, T_RELATIONSHIP.updated_last_on
, T_RELATIONSHIP.updated_last_by_user_id
, v_change_set_id -- change_set_id
FROM Temp_User_Relationship_Save_User_Relationship T_RELATIONSHIP
WHERE
T_RELATIONSHIP.is_new = TRUE
AND T_RELATIONSHIP.active = TRUE
ORDER BY
T_RELATIONSHIP.is_following
, T_RELATIONSHIP.is_blocked
, T_RELATIONSHIP.follower_user_id
, T_RELATIONSHIP.following_user_id
;
UPDATE tcg.public.TCG_User_Relationship RELATIONSHIP
SET
follower_user_id = T_RELATIONSHIP.follower_user_id
, following_user_id = T_RELATIONSHIP.following_user_id
, is_following = T_RELATIONSHIP.is_following
, is_blocked = T_RELATIONSHIP.is_blocked
, active = T_RELATIONSHIP.active
, updated_last_on = v_time_start
, updated_last_by_user_id = v_user_id
, change_set_id = v_change_set_id
FROM Temp_User_Relationship_Save_User_Relationship T_RELATIONSHIP
WHERE
RELATIONSHIP.relationship_id = T_RELATIONSHIP.relationship_id
AND NOT T_RELATIONSHIP.is_new
;
ELSE
-- Error
INSERT INTO tcg.public.Error (
guid
, error_type_id
, message
, display_order
, created_on
, created_by_user_id
, updated_last_on
, updated_last_by_user_id
, change_set_id
)
SELECT
v_guid
, T_ERROR.error_type_id
, T_ERROR.message
, T_ERROR.temp_id
, v_time_start
, v_user_id
, v_time_start
, v_user_id
, v_change_set_id
FROM Temp_User_Relationship_Save_Error T_ERROR
LEFT JOIN tcg.public.Error_Type ERROR_TYPE ON T_ERROR.error_type_id = ERROR_TYPE.error_type_id
ORDER BY T_ERROR.temp_id
;
END IF;
COMMIT;
o_success := NOT EXISTS (
SELECT *
FROM Temp_User_Relationship_Save_Error T_ERROR
WHERE T_ERROR.error_type_id <> v_warning_error_type_id
LIMIT 1
);
DELETE FROM tcg.public.TCG_User_Relationship_Temp RELATIONSHIP_T WHERE RELATIONSHIP_T.guid = v_guid;
DROP TABLE IF EXISTS Temp_User_Relationship_Save_User;
DROP TABLE IF EXISTS Temp_User_Relationship_Save_User_Relationship;
DROP TABLE IF EXISTS Temp_User_Relationship_Save_Error;
END;
$$;
-- Call it with:
DO $$
DECLARE
v_comment TEXT := 'User Relationship Save.';
v_guid UUID;
v_user_id INT := 3;
v_success BOOLEAN;
BEGIN
v_guid := gen_random_uuid();
INSERT INTO tcg.public.TCG_User_Relationship_Temp (
guid
, relationship_id
, follower_user_id
, following_user_id
, is_following
, is_blocked
, active
)
VALUES
(
v_guid
, NULL -- relationship_id
, 3 -- follower_user_id
, 4 -- following_user_id
, TRUE -- is_following
, FALSE -- is_blocked
, TRUE -- active
)
, (
v_guid
, NULL -- relationship_id
, 3 -- follower_user_id
, 5 -- following_user_id
, FALSE -- is_following
, TRUE -- is_blocked
, TRUE -- active
)
, (
v_guid
, NULL -- relationship_id
, 4 -- follower_user_id
, 3 -- following_user_id
, TRUE -- is_following
, FALSE -- is_blocked
, TRUE -- active
)
;
CALL tcg.public.USP_TCG_User_Relationship_Save (
v_comment -- a_comment
, v_guid -- a_guid
, v_user_id -- a_user_id
, v_success -- o_success
);
RAISE NOTICE 'Success: %', CASE WHEN v_success THEN 'TRUE' ELSE 'FALSE' END;
END;
$$;
SELECT *
-- DELETE
FROM tcg.public.Error ERROR
LEFT JOIN tcg.public.Error_Type ERROR_TYPE ON ERROR.error_type_id = ERROR_TYPE.error_type_id
;
SELECT *
FROM tcg.public.Error_Type ERROR_TYPE
;
SELECT *
FROM tcg.public.TCG_Change_Set CHANGE_SET
ORDER BY CHANGE_SET.change_set_id DESC
;
/*
SELECT *
FROM tcg.public.TCG_MTG_Game
;
*/
SELECT *
-- DELETE
FROM tcg.public.TCG_User_Relationship_Temp RELATIONSHIP_T
;
SELECT *
-- DELETE
FROM tcg.public.TCG_User_Relationship RELATIONSHIP
;

View File

@@ -79,7 +79,7 @@ BEGIN
, missing_mandatory_fields TEXT
);
CREATE TABLE Temp_MTG_Inventory_Save_Card (
CREATE TEMP TABLE Temp_MTG_Inventory_Save_Card (
card_id INT NOT NULL
, all_parts TEXT
, arena_id INTEGER

View File

@@ -5,8 +5,13 @@ CREATE OR REPLACE FUNCTION tcg.public.FN_TCG_MTG_Deck_Get_Many (
, a_deck_ids TEXT
, a_deck_names TEXT
, a_commander_bracket_ids TEXT
, a_created_by_user_ids TEXT
, a_include_commander_option BOOLEAN
, a_require_all_id_filters_met BOOLEAN
, a_get_all_game BOOLEAN
, a_get_inactive_game BOOLEAN
, a_game_ids TEXT
, a_filter_by_game_session_not_player BOOLEAN
, a_require_all_id_filters_met BOOLEAN
, a_require_any_id_filters_met BOOLEAN
, a_require_all_non_id_filters_met BOOLEAN
, a_require_any_non_id_filters_met BOOLEAN
@@ -30,7 +35,12 @@ DECLARE
v_get_inactive_deck BOOLEAN;
v_deck_ids TEXT;
v_deck_names TEXT;
v_created_by_user_ids TEXT;
v_include_commander_option BOOLEAN;
v_get_all_game BOOLEAN;
v_get_inactive_game BOOLEAN;
v_game_ids TEXT;
v_filter_by_game_session_not_player BOOLEAN;
v_require_all_id_filters_met BOOLEAN;
v_require_any_id_filters_met BOOLEAN;
v_require_all_non_id_filters_met BOOLEAN;
@@ -41,13 +51,19 @@ BEGIN
v_deck_ids := TRIM(COALESCE(a_deck_ids, ''));
v_deck_names := TRIM(COALESCE(a_deck_names, ''));
v_include_commander_option := COALESCE(a_include_commander_option, TRUE);
v_created_by_user_ids := TRIM(COALESCE(a_created_by_user_ids, ''));
v_get_all_game := COALESCE(a_get_all_game, FALSE);
v_get_inactive_game := COALESCE(a_get_inactive_game, FALSE);
v_game_ids := TRIM(COALESCE(a_game_ids, ''));
v_filter_by_game_session_not_player := COALESCE(a_filter_by_game_session_not_player, TRUE);
v_require_all_id_filters_met := COALESCE(a_require_all_id_filters_met, FALSE);
v_require_any_id_filters_met := COALESCE(a_require_any_id_filters_met, FALSE);
v_require_all_non_id_filters_met := COALESCE(a_require_all_non_id_filters_met, FALSE);
v_require_any_non_id_filters_met := COALESCE(a_require_any_non_id_filters_met, FALSE);
-- Outputs
RETURN QUERY SELECT
RETURN QUERY
SELECT DISTINCT
DECK.deck_id
, DECK.name
, DECK.is_commander
@@ -59,6 +75,9 @@ BEGIN
, DECK.updated_last_by_user_id
, DECK.change_set_id
FROM tcg.public.TCG_MTG_Deck DECK
LEFT JOIN tcg.public.TCG_MTG_Game SESSION_GAME ON DECK.game_id = SESSION_GAME.game_id
LEFT JOIN tcg.public.TCG_MTG_Game_Player PLAYER ON DECK.deck_id = PLAYER.deck_id
LEFT JOIN tcg.public.TCG_MTG_Game PLAYER_GAME ON PLAYER.game_id = PLAYER_GAME.game_id
WHERE
(
(
@@ -69,7 +88,21 @@ BEGIN
v_require_all_id_filters_met
AND (
v_get_all_deck
OR DECK.deck_id = ANY(string_to_array(v_deck_ids, ',')::INT[])
OR (
DECK.deck_id = ANY(string_to_array(v_deck_ids, ',')::INT[])
AND DECK.created_by_user_id = ANY(string_to_array(v_created_by_user_ids, ',')::INT[])
AND (
v_get_all_game
OR (
v_filter_by_game_session_not_player
AND SESSION_GAME.game_id = ANY(string_to_array(v_game_ids, ',')::INT[])
)
OR (
NOT v_filter_by_game_session_not_player
AND PLAYER.game_id = ANY(string_to_array(v_game_ids, ',')::INT[])
)
)
)
)
)
OR (
@@ -78,6 +111,18 @@ BEGIN
AND (
v_get_all_deck
OR DECK.deck_id = ANY(string_to_array(v_deck_ids, ',')::INT[])
OR DECK.created_by_user_id = ANY(string_to_array(v_created_by_user_ids, ',')::INT[])
OR (
v_get_all_game
OR (
v_filter_by_game_session_not_player
AND SESSION_GAME.game_id = ANY(string_to_array(v_game_ids, ',')::INT[])
)
OR (
NOT v_filter_by_game_session_not_player
AND PLAYER.game_id = ANY(string_to_array(v_game_ids, ',')::INT[])
)
)
)
)
)
@@ -113,6 +158,17 @@ BEGIN
v_get_inactive_deck
OR DECK.active
)
AND (
v_get_inactive_game
OR (
v_filter_by_game_session_not_player
AND SESSION_GAME.active
)
OR (
NOT v_filter_by_game_session_not_player
AND PLAYER_GAME.active
)
)
ORDER BY DECK.name
;
END;
@@ -126,8 +182,13 @@ FROM tcg.public.FN_TCG_MTG_Deck_Get_Many (
, a_deck_ids := CAST(NULL AS TEXT)
, a_deck_names := CAST(NULL AS TEXT)
, a_commander_bracket_ids := CAST(NULL AS TEXT)
, a_include_commander_option := TRUE
, a_require_all_id_filters_met := FALSE
, a_include_commander_option := true
, a_created_by_user_ids := '3'
, a_get_all_game := FALSE
, a_get_inactive_game := FALSE
, a_game_ids := CAST(NULL AS TEXT)
, a_filter_by_game_session_not_player := TRUE
, a_require_all_id_filters_met := TRUE
, a_require_any_id_filters_met := FALSE
, a_require_all_non_id_filters_met := FALSE
, a_require_any_non_id_filters_met := FALSE

View File

@@ -22,6 +22,8 @@ RETURNS TABLE (
, active BOOLEAN
, created_on TIMESTAMP
, created_by_user_id INT
, updated_last_on TIMESTAMP
, updated_last_by_user_id INT
)
LANGUAGE plpgsql
AS $$
@@ -65,6 +67,8 @@ BEGIN
, GAME.active
, GAME.created_on
, GAME.created_by_user_id
, GAME.updated_last_on
, GAME.updated_last_by_user_id
FROM tcg.public.TCG_MTG_Game GAME
INNER JOIN tcg.public.TCG_User CREATOR_USER ON GAME.created_by_user_id = CREATOR_USER.user_id
WHERE

View File

@@ -37,7 +37,7 @@ BEGIN
v_require_any_id_filters_met := COALESCE(a_require_any_id_filters_met, FALSE);
-- Outputs
RETURN QUERY
WITH User_Name AS (
SELECT
TCG_USER.user_id
@@ -46,31 +46,31 @@ BEGIN
TRIM(COALESCE(TCG_USER.firstname, '')) <> ''
AND TRIM(COALESCE(TCG_USER.surname, '')) <> ''
THEN CONCAT(
TRIM(COALESCE(TCG_USER.firstname, '')) <> ''
TRIM(COALESCE(TCG_USER.firstname, ''))
, ' '
, TRIM(COALESCE(TCG_USER.surname, '')) <> ''
, TRIM(COALESCE(TCG_USER.surname, ''))
)
WHEN TRIM(COALESCE(TCG_USER.firstname, '')) <> ''
THEN TRIM(COALESCE(TCG_USER.firstname, '')) <> ''
ELSE TRIM(COALESCE(TCG_USER.surname, '')) <> ''
THEN TRIM(COALESCE(TCG_USER.firstname, ''))
ELSE TRIM(COALESCE(TCG_USER.surname, ''))
END AS name
FROM tcg.public.TCG_User TCG_USER
)
RETURN QUERY SELECT
SELECT
PLAYER.player_id
, PLAYER.game_id
, PLAYER.user_id
, PLAYER.deck_id
, CASE
WHEN TRIM(COALESCE(PLAYER.name, '')) <> ''
THEN TRIM(COALESCE(PLAYER.name, '')) <> ''
THEN TRIM(COALESCE(PLAYER.name, ''))
WHEN
USER_NAME.name <> ''
AND TRIM(COALESCE(DECK.name, '')) <> ''
THEN CONCAT(
USER_NAME.name <> ''
USER_NAME.name
, ' - '
, TRIM(COALESCE(DECK.name, '')) <> ''
, TRIM(COALESCE(DECK.name, ''))
)
ELSE CONCAT(
'Player '

View File

@@ -10,10 +10,17 @@ AS $$
DECLARE
v_bad_data_error_type_id INT;
v_change_set_id INT;
v_comment TEXT;
-- v_error_message TEXT;
v_guid UUID;
v_time_start TIMESTAMP;
v_user_id INT;
v_warning_error_type_id INT;
BEGIN
v_comment := TRIM(COALESCE(a_comment, ''));
v_guid := a_guid;
v_user_id := a_user_id;
v_bad_data_error_type_id := (SELECT ERROR_TYPE.error_type_id FROM tcg.public.Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = 'BAD_DATA' LIMIT 1);
v_warning_error_type_id := (SELECT ERROR_TYPE.error_type_id FROM tcg.public.Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = 'WARNING' LIMIT 1);
v_time_start := CURRENT_TIMESTAMP;
@@ -22,9 +29,10 @@ BEGIN
DROP TABLE IF EXISTS Temp_MTG_Player_Save_User;
DROP TABLE IF EXISTS Temp_MTG_Player_Save_Deck;
DROP TABLE IF EXISTS Temp_MTG_Player_Save_Player;
DROP TABLE IF EXISTS Temp_MTG_Player_Save_User_Relationship;
DROP TABLE IF EXISTS Temp_MTG_Player_Save_Error;
CREATE TABLE Temp_MTG_Player_Save_Game (
CREATE TEMP TABLE Temp_MTG_Player_Save_Game (
game_id INT NOT NULL
, notes TEXT
, is_commander BOOLEAN
@@ -33,6 +41,7 @@ BEGIN
, location_name TEXT
, start_on TIMESTAMP
, end_on TIMESTAMP
, starting_life INT
, active BOOLEAN
, created_on TIMESTAMP
, created_by_user_id INT
@@ -41,7 +50,7 @@ BEGIN
, change_set_id INT
);
CREATE TABLE Temp_MTG_Player_Save_User (
CREATE TEMP TABLE Temp_MTG_Player_Save_User (
user_id INT NOT NULL
, user_auth0_id TEXT
, firstname TEXT
@@ -57,7 +66,7 @@ BEGIN
, change_set_id INT
);
CREATE TABLE Temp_MTG_Player_Save_Deck (
CREATE TEMP TABLE Temp_MTG_Player_Save_Deck (
deck_id INT NOT NULL
, name TEXT
, is_commander BOOLEAN
@@ -70,7 +79,7 @@ BEGIN
, change_set_id INT
);
CREATE TABLE Temp_MTG_Player_Save_Player (
CREATE TEMP TABLE Temp_MTG_Player_Save_Player (
temp_id INT NOT NULL
, player_id INT
, game_id INT
@@ -90,12 +99,57 @@ BEGIN
, is_duplicate BOOLEAN
);
CREATE TEMP TABLE Temp_MTG_Player_Save_User_Relationship (
relationship_id INT
, follower_user_id INT
, following_user_id INT
, is_following BOOLEAN
, is_blocked BOOLEAN
, active BOOLEAN
, created_on TIMESTAMP
, created_by_user_id INT
, updated_last_on TIMESTAMP
, updated_last_by_user_id INT
, change_set_id INT
, is_new BOOLEAN
, error_name TEXT
);
CREATE TEMP TABLE Temp_MTG_Player_Save_Error (
temp_id INT GENERATED ALWAYS AS IDENTITY
, error_type_id INT
, message TEXT
);
WITH Temp_Player AS (
SELECT
PLAYER_T.temp_id
, CASE WHEN COALESCE(PLAYER_T.player_id, 0) < 1
THEN PLAYER.player_id
ELSE PLAYER_T.player_id
END AS player_id
, PLAYER_T.game_id
, PLAYER_T.user_id
, PLAYER_T.deck_id
, PLAYER_T.name
, PLAYER_T.notes
, PLAYER_T.display_order
, COALESCE(PLAYER_T.active, TRUE) AS active
, COALESCE(PLAYER_T.created_on, v_time_start) AS created_on
, COALESCE(PLAYER_T.created_by_user_id, v_user_id) AS created_by_user_id
, COALESCE(PLAYER_T.updated_last_on, v_time_start) AS updated_last_on
, COALESCE(PLAYER_T.updated_last_by_user_id, v_user_id) AS updated_last_by_user_id
FROM tcg.public.TCG_MTG_Game_Player_Temp PLAYER_T
LEFT JOIN tcg.public.TCG_MTG_Game_Player PLAYER
ON PLAYER_T.player_id = PLAYER.player_id
OR (
COALESCE(PLAYER_T.player_id, 0) < 1
AND PLAYER_T.game_id = PLAYER.game_id
AND PLAYER_T.display_order = PLAYER.display_order
)
WHERE PLAYER_T.guid = v_guid
)
INSERT INTO Temp_MTG_Player_Save_Player (
temp_id
, player_id
@@ -115,37 +169,35 @@ BEGIN
, error_name
)
SELECT
PLAYER_T.temp_id
, PLAYER_T.player_id
, PLAYER_T.game_id
, PLAYER_T.user_id
, PLAYER_T.deck_id
, PLAYER_T.name
, PLAYER_T.notes
, PLAYER_T.display_order
, COALESCE(PLAYER_T.active, TRUE)
, COALESCE(PLAYER_T.created_on, v_time_start) -- created_on
, COALESCE(PLAYER_T.created_by_user_id, a_user_id) -- created_by_user_id
, COALESCE(PLAYER_T.updated_last_on, v_time_start) -- updated_last_on
, COALESCE(PLAYER_T.updated_last_by_user_id, a_user_id) -- updated_last_by_user_id
T_PLAYER.temp_id
, T_PLAYER.player_id
, T_PLAYER.game_id
, T_PLAYER.user_id
, T_PLAYER.deck_id
, T_PLAYER.name
, T_PLAYER.notes
, T_PLAYER.display_order
, T_PLAYER.active
, T_PLAYER.created_on
, T_PLAYER.created_by_user_id
, T_PLAYER.updated_last_on
, T_PLAYER.updated_last_by_user_id
, CASE WHEN PLAYER.player_id IS NULL THEN TRUE ELSE FALSE END AS is_new
, CASE WHEN T_PLAYER.player_id IS NULL THEN TRUE ELSE FALSE END AS is_new
, CONCAT(
'Player { id: '
, CAST(PLAYER_T.player_id AS VARCHAR)
, CAST(T_PLAYER.player_id AS VARCHAR)
, ', temp id: '
, CAST(PLAYER_T.temp_id AS VARCHAR)
, CAST(T_PLAYER.temp_id AS VARCHAR)
, ', display order: '
, CAST(PLAYER_T.display_order AS VARCHAR)
, CAST(T_PLAYER.display_order AS VARCHAR)
, ', game id: '
, CAST(PLAYER_T.game_id AS VARCHAR)
, CAST(T_PLAYER.game_id AS VARCHAR)
, ', name: '
, PLAYER_T.name
, T_PLAYER.name
, ' }'
) -- error_name
FROM tcg.public.TCG_MTG_Game_Player_Temp PLAYER_T
LEFT JOIN tcg.public.TCG_MTG_Game_Player PLAYER ON PLAYER_T.player_id = PLAYER.player_id
WHERE PLAYER_T.guid = a_guid
FROM Temp_Player T_PLAYER
;
INSERT INTO Temp_MTG_Player_Save_Game (
@@ -157,6 +209,7 @@ BEGIN
, location_name
, start_on
, end_on
, starting_life
, active
, created_on
, created_by_user_id
@@ -164,7 +217,7 @@ BEGIN
, updated_last_by_user_id
, change_set_id
)
SELECT
SELECT DISTINCT
GAME.game_id
, GAME.notes
, GAME.is_commander
@@ -173,6 +226,7 @@ BEGIN
, GAME.location_name
, GAME.start_on
, GAME.end_on
, GAME.starting_life
, GAME.active
, GAME.created_on
, GAME.created_by_user_id
@@ -180,7 +234,7 @@ BEGIN
, GAME.updated_last_by_user_id
, GAME.change_set_id
FROM tcg.public.TCG_MTG_Game GAME
INNER JOIN Temp_MTG_Player_Save_Player PLAYER ON GAME.game_id = PLAYER.game_id
INNER JOIN Temp_MTG_Player_Save_Player PLAYER_T ON GAME.game_id = PLAYER_T.game_id
;
INSERT INTO Temp_MTG_Player_Save_User (
@@ -198,7 +252,7 @@ BEGIN
, updated_last_by_user_id
, change_set_id
)
SELECT
SELECT DISTINCT
TCG_USER.user_id
, TCG_USER.user_auth0_id
, TCG_USER.firstname
@@ -213,7 +267,7 @@ BEGIN
, TCG_USER.updated_last_by_user_id
, TCG_USER.change_set_id
FROM tcg.public.TCG_User TCG_USER
INNER JOIN Temp_MTG_Player_Save_Player PLAYER ON TCG_USER.user_id = PLAYER.user_id
INNER JOIN Temp_MTG_Player_Save_Player PLAYER_T ON TCG_USER.user_id = PLAYER_T.user_id
;
INSERT INTO Temp_MTG_Player_Save_Deck (
@@ -243,6 +297,90 @@ BEGIN
INNER JOIN Temp_MTG_Player_Save_Player PLAYER ON DECK.deck_id = DECK.deck_id
;
WITH
All_Game_User_Link AS (
SELECT
T_GAME.game_id
, T_USER.user_id
FROM Temp_MTG_Player_Save_Game T_GAME
CROSS JOIN Temp_MTG_Player_Save_User T_USER
WHERE
T_GAME.active
AND T_USER.active
)
, All_User_Relationship AS (
SELECT DISTINCT
RELATIONSHIP.relationship_id
, GAME_USER_FOLLOWER.user_id AS follower_user_id
, GAME_USER_FOLLOWING.user_id AS following_user_id
, COALESCE(RELATIONSHIP.is_following, TRUE) AS is_following
, COALESCE(RELATIONSHIP.is_blocked, FALSE) AS is_blocked
, COALESCE(RELATIONSHIP.active, TRUE) AS active
, COALESCE(RELATIONSHIP.created_on, v_time_start) AS created_on
, COALESCE(RELATIONSHIP.created_by_user_id, v_user_id) AS created_by_user_id
, COALESCE(RELATIONSHIP.updated_last_on, v_time_start) AS updated_last_on
, COALESCE(RELATIONSHIP.updated_last_by_user_id, v_user_id) AS updated_last_by_user_id
, RELATIONSHIP.change_set_id
, CASE WHEN RELATIONSHIP.relationship_id IS NULL THEN TRUE ELSE FALSE END AS Is_New
FROM All_Game_User_Link GAME_USER_FOLLOWER
CROSS JOIN All_Game_User_Link GAME_USER_FOLLOWING
LEFT JOIN tcg.public.TCG_User_Relationship RELATIONSHIP
ON GAME_USER_FOLLOWER.user_id = RELATIONSHIP.follower_user_id
AND GAME_USER_FOLLOWING.user_id = RELATIONSHIP.following_user_id
WHERE
GAME_USER_FOLLOWER.user_id <> GAME_USER_FOLLOWING.user_id
AND GAME_USER_FOLLOWER.game_id = GAME_USER_FOLLOWING.game_id
)
INSERT INTO Temp_MTG_Player_Save_User_Relationship (
relationship_id
, follower_user_id
, following_user_id
, is_following
, is_blocked
, active
, created_on
, created_by_user_id
, updated_last_on
, updated_last_by_user_id
, change_set_id
, is_new
, error_name
)
SELECT
ALL_RELATIONSHIP.relationship_id
, ALL_RELATIONSHIP.follower_user_id
, ALL_RELATIONSHIP.following_user_id
, ALL_RELATIONSHIP.is_following
, ALL_RELATIONSHIP.is_blocked
, ALL_RELATIONSHIP.active
, ALL_RELATIONSHIP.created_on
, ALL_RELATIONSHIP.created_by_user_id
, ALL_RELATIONSHIP.updated_last_on
, ALL_RELATIONSHIP.updated_last_by_user_id
, ALL_RELATIONSHIP.change_set_id
, ALL_RELATIONSHIP.Is_New
, CONCAT(
'User Relationship { id: '
, CAST(ALL_RELATIONSHIP.relationship_id AS VARCHAR)
, ', follower user id: '
, CAST(ALL_RELATIONSHIP.follower_user_id AS VARCHAR)
, ', following user id: '
, CAST(ALL_RELATIONSHIP.following_user_id AS VARCHAR)
, ', is following: '
, CAST(ALL_RELATIONSHIP.is_following AS VARCHAR)
, ', is blocked: '
, CAST(ALL_RELATIONSHIP.is_blocked AS VARCHAR)
, ' is new: '
, CAST(ALL_RELATIONSHIP.is_new AS VARCHAR)
, ' }'
) -- error_name
FROM All_User_Relationship ALL_RELATIONSHIP
-- WHERE ALL_RELATIONSHIP.Is_New
;
-- Missing fields
WITH Player_Missing_Field AS (
SELECT
@@ -354,7 +492,7 @@ BEGIN
SELECT
ALL_PLAYER.game_id
, ALL_PLAYER.display_order
, COUNT(*) AS count
, COUNT(*) AS count_display_order
FROM All_Player ALL_PLAYER
GROUP BY
ALL_PLAYER.game_id
@@ -364,7 +502,7 @@ BEGIN
SELECT
ALL_PLAYER.game_id
, ALL_PLAYER.deck_id
, COUNT(*) AS count
, COUNT(*) AS count_deck
FROM All_Player ALL_PLAYER
GROUP BY
ALL_PLAYER.game_id
@@ -377,14 +515,21 @@ BEGIN
, ALL_PLAYER.deck_id
, ALL_PLAYER.display_order
-- , CASE WHEN CARD.temp_id IS NULL THEN TRUE ELSE FALSE END AS is_unique
, CASE WHEN PLAYER_DECK.count = 1 THEN TRUE ELSE FALSE END AS is_unique_deck
, CASE WHEN PLAYER_DISPLAY_ORDER.count = 1 THEN TRUE ELSE FALSE END AS is_unique_display_order
, CASE WHEN PLAYER_DECK.count_deck = 1 THEN TRUE ELSE FALSE END AS is_unique_deck
, CASE WHEN PLAYER_DISPLAY_ORDER.count_display_order = 1 THEN TRUE ELSE FALSE END AS is_unique_display_order
FROM All_Player ALL_PLAYER
INNER JOIN Player_Deck PLAYER_DECK ON PLAYER.deck_id = PLAYER_DECK.deck_id
INNER JOIN Player_Display_Order PLAYER_DISPLAY_ORDER ON PLAYER.display_order = PLAYER_DISPLAY_ORDER.display_order
INNER JOIN Player_Deck PLAYER_DECK
ON ALL_PLAYER.game_id = PLAYER_DECK.game_id
AND ALL_PLAYER.deck_id = PLAYER_DECK.deck_id
INNER JOIN Player_Display_Order PLAYER_DISPLAY_ORDER
ON ALL_PLAYER.game_id = PLAYER_DISPLAY_ORDER.game_id
AND ALL_PLAYER.display_order = PLAYER_DISPLAY_ORDER.display_order
)
UPDATE Temp_MTG_Player_Save_Player T_PLAYER
SET is_duplicate = CASE WHEN NOT ( is_unique_deck AND is_unique_display_order ) THEN TRUE ELSE FALSE END
SET is_duplicate = CASE WHEN NOT (
DUPLICATE_PLAYER.is_unique_deck
AND DUPLICATE_PLAYER.is_unique_display_order
) THEN TRUE ELSE FALSE END
FROM Duplicate_Player DUPLICATE_PLAYER
WHERE T_PLAYER.temp_id = DUPLICATE_PLAYER.temp_id
;
@@ -422,6 +567,29 @@ BEGIN
);
END IF;
/*
INSERT INTO Temp_MTG_Player_Save_Error (
error_type_id
, message
)
SELECT
v_warning_error_type_id AS error_type_id
, CONCAT(
'Users: '
, STRING_AGG(T_PLAYER.error_name, ', ')
) AS message
FROM Temp_MTG_Player_Save_Player T_PLAYER
UNION
SELECT
v_warning_error_type_id AS error_type_id
, CONCAT(
'User relationships: '
, STRING_AGG(T_RELATIONSHIP.error_name, ', ')
) AS message
FROM Temp_MTG_Player_Save_User_Relationship T_RELATIONSHIP
;
*/
-- Outputs
-- Change Set
INSERT INTO tcg.public.TCG_Change_Set (
@@ -429,14 +597,42 @@ BEGIN
, updated_last_by_user_id
)
VALUES (
a_comment
, a_user_id
v_comment
, v_user_id
)
RETURNING change_set_id INTO v_change_set_id
;
IF NOT EXISTS (SELECT * FROM Temp_MTG_Player_Save_Error T_ERROR WHERE T_ERROR.error_type_id <> v_warning_error_type_id LIMIT 1) THEN
-- User relationship
INSERT INTO tcg.public.TCG_User_Relationship (
follower_user_id
, following_user_id
, is_following
, is_blocked
, active
, created_on
, created_by_user_id
, updated_last_on
, updated_last_by_user_id
, change_set_id
)
SELECT
T_RELATIONSHIP.follower_user_id
, T_RELATIONSHIP.following_user_id
, T_RELATIONSHIP.is_following
, T_RELATIONSHIP.is_blocked
, T_RELATIONSHIP.active
, T_RELATIONSHIP.created_on
, T_RELATIONSHIP.created_by_user_id
, T_RELATIONSHIP.updated_last_on
, T_RELATIONSHIP.updated_last_by_user_id
, v_change_set_id -- change_set_id
FROM Temp_MTG_Player_Save_User_Relationship T_RELATIONSHIP
WHERE T_RELATIONSHIP.is_new
;
-- Player
INSERT INTO tcg.public.TCG_MTG_Game_Player (
game_id
@@ -460,11 +656,11 @@ BEGIN
, T_PLAYER.notes
, T_PLAYER.display_order
, T_PLAYER.active
, v_time_start -- created_on
, a_user_id -- created_by_user_id
, v_time_start -- updated_last_on
, a_user_id -- updated_last_by_user_id
, v_change_set_id -- change_set_id
, T_PLAYER.created_on
, T_PLAYER.created_by_user_id
, T_PLAYER.updated_last_on
, T_PLAYER.updated_last_by_user_id
, v_change_set_id -- change_set_id
FROM Temp_MTG_Player_Save_Player T_PLAYER
LEFT JOIN Temp_MTG_Player_Save_Game T_GAME ON T_PLAYER.game_id = T_GAME.game_id
WHERE
@@ -485,42 +681,43 @@ BEGIN
, display_order = T_PLAYER.display_order
, active = T_PLAYER.active
, updated_last_on = v_time_start
, updated_last_by_user_id = a_user_id
, updated_last_by_user_id = v_user_id
, change_set_id = v_change_set_id
FROM Temp_MTG_Player_Save_Player T_PLAYER
WHERE
PLAYER.player_id = T_PLAYER.player_id
AND NOT T_PLAYER.is_new
;
ELSE
-- Error
INSERT INTO tcg.public.Error (
guid
, error_type_id
, message
, display_order
, created_on
, created_by_user_id
, updated_last_on
, updated_last_by_user_id
, change_set_id
)
SELECT
a_guid
, T_ERROR.error_type_id
, T_ERROR.message
, T_ERROR.temp_id
, v_time_start
, a_user_id
, v_time_start
, a_user_id
, v_change_set_id
FROM Temp_MTG_Player_Save_Error T_ERROR
LEFT JOIN tcg.public.Error_Type ERROR_TYPE ON T_ERROR.error_type_id = ERROR_TYPE.error_type_id
ORDER BY T_ERROR.temp_id
;
END IF;
-- Error
INSERT INTO tcg.public.Error (
guid
, error_type_id
, message
, display_order
, created_on
, created_by_user_id
, updated_last_on
, updated_last_by_user_id
, change_set_id
)
SELECT
v_guid
, T_ERROR.error_type_id
, T_ERROR.message
, T_ERROR.temp_id
, v_time_start
, v_user_id
, v_time_start
, v_user_id
, v_change_set_id
FROM Temp_MTG_Player_Save_Error T_ERROR
LEFT JOIN tcg.public.Error_Type ERROR_TYPE ON T_ERROR.error_type_id = ERROR_TYPE.error_type_id
ORDER BY T_ERROR.temp_id
;
COMMIT;
o_success := NOT EXISTS (
@@ -530,12 +727,13 @@ BEGIN
LIMIT 1
);
DELETE FROM tcg.public.TCG_MTG_Game_Player_Temp PLAYER_T WHERE PLAYER_T.guid = a_guid;
DELETE FROM tcg.public.TCG_MTG_Game_Player_Temp PLAYER_T WHERE PLAYER_T.guid = v_guid;
DROP TABLE IF EXISTS Temp_MTG_Player_Save_Game;
DROP TABLE IF EXISTS Temp_MTG_Player_Save_User;
DROP TABLE IF EXISTS Temp_MTG_Player_Save_Deck;
DROP TABLE IF EXISTS Temp_MTG_Player_Save_Player;
DROP TABLE IF EXISTS Temp_MTG_Player_Save_User_Relationship;
DROP TABLE IF EXISTS Temp_MTG_Player_Save_Error;
END;
$$;
@@ -657,5 +855,14 @@ FROM tcg.public.TCG_MTG_Game_Player PLAYER
LEFT JOIN tcg.public.TCG_MTG_Game GAME ON PLAYER.game_id = GAME.game_id
;
SELECT *
-- DELETE
FROM tcg.public.TCG_User_Relationship_Audit RELATIONSHIP_AUDIT
;
SELECT *
-- DELETE
FROM tcg.public.TCG_User_Relationship RELATIONSHIP
;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,140 @@
CREATE OR REPLACE FUNCTION tcg.public.FN_TCG_MTG_Game_Session_Member_Get_Many (
a_get_inactive_session_member BOOLEAN
, a_get_all_game BOOLEAN
, a_get_inactive_game BOOLEAN
, a_game_ids TEXT
, a_get_all_user BOOLEAN
, a_get_inactive_user BOOLEAN
, a_user_ids TEXT
, a_require_all_id_filters_met BOOLEAN
, a_require_any_id_filters_met BOOLEAN
)
RETURNS TABLE (
member_id INT
, game_id INT
, user_id INT
, is_permitted BOOLEAN
, active BOOLEAN
, created_on TIMESTAMP
, created_by_user_id INT
, updated_last_on TIMESTAMP
, updated_last_by_user_id INT
)
LANGUAGE plpgsql
AS $$
DECLARE
v_get_inactive_session_member BOOLEAN;
v_get_all_game BOOLEAN;
v_get_inactive_game BOOLEAN;
v_game_ids TEXT;
v_get_all_user BOOLEAN;
v_get_inactive_user BOOLEAN;
v_user_ids TEXT;
v_require_all_id_filters_met BOOLEAN;
v_require_any_id_filters_met BOOLEAN;
-- , v_require_all_non_id_filters_met BOOLEAN
-- , v_require_any_non_id_filters_met BOOLEAN
BEGIN
v_get_inactive_session_member := COALESCE(a_get_inactive_session_member, FALSE);
v_get_all_game := COALESCE(a_get_all_game, FALSE);
v_get_inactive_game := COALESCE(a_get_inactive_game, FALSE);
v_game_ids := TRIM(COALESCE(a_game_ids, ''));
v_get_all_user := COALESCE(a_get_all_user, FALSE);
v_get_inactive_user := COALESCE(a_get_inactive_user, FALSE);
v_user_ids := TRIM(COALESCE(a_user_ids, ''));
v_require_all_id_filters_met := COALESCE(a_require_all_id_filters_met, FALSE);
v_require_any_id_filters_met := COALESCE(a_require_any_id_filters_met, FALSE);
-- Outputs
RETURN QUERY SELECT
SESSION_MEMBER.member_id
, SESSION_MEMBER.game_id
, SESSION_MEMBER.user_id
, SESSION_MEMBER.is_permitted
, SESSION_MEMBER.active
, SESSION_MEMBER.created_on
, SESSION_MEMBER.created_by_user_id
, SESSION_MEMBER.updated_last_on
, SESSION_MEMBER.updated_last_by_user_id
FROM tcg.public.TCG_MTG_Game_Session_Member SESSION_MEMBER
INNER JOIN tcg.public.TCG_MTG_Game GAME ON SESSION_MEMBER.game_id = GAME.game_id
INNER JOIN tcg.public.TCG_User MEMBER_USER ON SESSION_MEMBER.user_id = MEMBER_USER.user_id
WHERE
(
(
NOT v_require_all_id_filters_met
AND NOT v_require_any_id_filters_met
)
OR (
v_require_all_id_filters_met
AND (
v_get_all_game
OR SESSION_MEMBER.game_id = ANY(string_to_array(v_game_ids, ',')::INT[])
)
AND (
a_get_all_user
OR MEMBER_USER.user_id = ANY(string_to_array(v_user_ids, ',')::INT[])
)
)
OR (
NOT v_require_all_id_filters_met
AND v_require_any_id_filters_met
AND (
v_get_all_game
OR SESSION_MEMBER.game_id = ANY(string_to_array(v_game_ids, ',')::INT[])
)
AND (
v_get_all_user
OR MEMBER_USER.user_id = ANY(string_to_array(v_user_ids, ',')::INT[])
)
)
)
AND (
v_get_inactive_session_member
OR SESSION_MEMBER.active
)
AND (
v_get_inactive_game
OR GAME.active
)
AND (
v_get_inactive_user
OR MEMBER_USER.active
)
ORDER BY
GAME.game_id
, MEMBER_USER.firstname
, MEMBER_USER.surname
;
END;
$$;
SELECT *
FROM tcg.public.FN_TCG_MTG_Game_Session_Member_Get_Many (
a_get_inactive_session_member := FALSE
, a_get_all_game := TRUE
, a_get_inactive_game := FALSE
, a_game_ids := ''
, a_get_all_user := TRUE
, a_get_inactive_user := FALSE
, a_user_ids := ''
, a_require_all_id_filters_met := TRUE
, a_require_any_id_filters_met := FALSE
)
;
/*
SELECT *
FROM tcg.public.TCG_MTG_Game_Session_Member
;
SELECT *
FROM tcg.public.TCG_User
;
SELECT *
FROM tcg.public.TCG_MTG_Deck
;
*/

View File

@@ -0,0 +1,532 @@
CREATE OR REPLACE PROCEDURE tcg.public.USP_TCG_MTG_Game_Session_Member_Save (
a_comment TEXT
, a_guid UUID
, a_user_id INT
, OUT o_success BOOLEAN
)
LANGUAGE plpgsql
AS $$
DECLARE
v_bad_data_error_type_id INT;
v_change_set_id INT;
-- v_error_message TEXT;
v_time_start TIMESTAMP;
v_warning_error_type_id INT;
BEGIN
v_bad_data_error_type_id := (SELECT ERROR_TYPE.error_type_id FROM tcg.public.Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = 'BAD_DATA' LIMIT 1);
v_warning_error_type_id := (SELECT ERROR_TYPE.error_type_id FROM tcg.public.Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = 'WARNING' LIMIT 1);
v_time_start := CURRENT_TIMESTAMP;
DROP TABLE IF EXISTS Temp_User_Relationship_Save_Game;
DROP TABLE IF EXISTS Temp_User_Relationship_Save_User;
DROP TABLE IF EXISTS Temp_User_Relationship_Save_Session_Member;
DROP TABLE IF EXISTS Temp_User_Relationship_Save_Error;
CREATE TEMP TABLE Temp_User_Relationship_Save_Game (
game_id INT NOT NULL
, notes TEXT
, is_commander BOOLEAN
, is_draft BOOLEAN
, is_sealed BOOLEAN
, location_name TEXT
, start_on TIMESTAMP
, end_on TIMESTAMP
, active BOOLEAN
, created_on TIMESTAMP
, created_by_user_id INT
, updated_last_on TIMESTAMP
, updated_last_by_user_id INT
, change_set_id INT
);
CREATE TEMP TABLE Temp_User_Relationship_Save_User (
user_id INT NOT NULL
, user_auth0_id TEXT
, firstname TEXT
, surname TEXT
, email TEXT
, is_email_verified BOOLEAN
, is_super_user BOOLEAN
, active BOOLEAN
, created_on TIMESTAMP
, created_by_user_id INT
, updated_last_on TIMESTAMP
, updated_last_by_user_id INT
, change_set_id INT
);
CREATE TEMP TABLE Temp_User_Relationship_Save_Session_Member (
temp_id INT NOT NULL
, member_id INT
, game_id INT
, user_id INT
, is_permitted BOOLEAN
, active BOOLEAN
, created_on TIMESTAMP
, created_by_user_id INT
, updated_last_on TIMESTAMP
, updated_last_by_user_id INT
, is_new BOOLEAN
, error_name TEXT
, is_duplicate BOOLEAN
);
CREATE TEMP TABLE Temp_User_Relationship_Save_Error (
temp_id INT GENERATED ALWAYS AS IDENTITY
, error_type_id INT
, message TEXT
);
INSERT INTO Temp_User_Relationship_Save_Session_Member (
temp_id
, member_id
, game_id
, user_id
, is_permitted
, active
, created_on
, created_by_user_id
, updated_last_on
, updated_last_by_user_id
, is_new
, error_name
)
SELECT
SESSION_MEMBER_T.temp_id
, SESSION_MEMBER_T.member_id
, SESSION_MEMBER_T.game_id
, SESSION_MEMBER_T.user_id
, COALESCE(SESSION_MEMBER_T.is_permitted, FALSE) -- is_permitted
, COALESCE(SESSION_MEMBER_T.active, TRUE) -- active
, COALESCE(SESSION_MEMBER_T.created_on, v_time_start) -- created_on
, COALESCE(SESSION_MEMBER_T.created_by_user_id, a_user_id) -- created_by_user_id
, COALESCE(SESSION_MEMBER_T.updated_last_on, v_time_start) -- updated_last_on
, COALESCE(SESSION_MEMBER_T.updated_last_by_user_id, a_user_id) -- updated_last_by_user_id
, CASE WHEN SESSION_MEMBER .member_id IS NULL THEN TRUE ELSE FALSE END AS is_new
, CONCAT(
'Member { id: '
, CAST(SESSION_MEMBER_T.member_id AS VARCHAR)
, ', temp id: '
, CAST(SESSION_MEMBER_T.temp_id AS VARCHAR)
, ', game id: '
, CAST(SESSION_MEMBER_T.game_id AS VARCHAR)
, ', user id: '
, CAST(SESSION_MEMBER_T.user_id AS VARCHAR)
, ' }'
) -- error_name
FROM tcg.public.TCG_MTG_Game_Session_Member_Temp SESSION_MEMBER_T
LEFT JOIN tcg.public.TCG_MTG_Game_Session_Member SESSION_MEMBER ON SESSION_MEMBER_T.member_id = SESSION_MEMBER.member_id
WHERE SESSION_MEMBER_T.guid = a_guid
;
INSERT INTO Temp_User_Relationship_Save_Game (
game_id
, notes
, is_commander
, is_draft
, is_sealed
, location_name
, start_on
, end_on
, active
, created_on
, created_by_user_id
, updated_last_on
, updated_last_by_user_id
, change_set_id
)
SELECT DISTINCT
GAME.game_id
, GAME.notes
, GAME.is_commander
, GAME.is_draft
, GAME.is_sealed
, GAME.location_name
, GAME.start_on
, GAME.end_on
, GAME.active
, GAME.created_on
, GAME.created_by_user_id
, GAME.updated_last_on
, GAME.updated_last_by_user_id
, GAME.change_set_id
FROM tcg.public.TCG_MTG_Game GAME
INNER JOIN Temp_User_Relationship_Save_Session_Member SESSION_MEMBER_T ON GAME.game_id = SESSION_MEMBER_T.game_id
;
INSERT INTO Temp_User_Relationship_Save_User (
user_id
, user_auth0_id
, firstname
, surname
, email
, is_email_verified
, is_super_user
, active
, created_on
, created_by_user_id
, updated_last_on
, updated_last_by_user_id
, change_set_id
)
SELECT DISTINCT
TCG_USER.user_id
, TCG_USER.user_auth0_id
, TCG_USER.firstname
, TCG_USER.surname
, TCG_USER.email
, TCG_USER.is_email_verified
, TCG_USER.is_super_user
, TCG_USER.active
, TCG_USER.created_on
, TCG_USER.created_by_user_id
, TCG_USER.updated_last_on
, TCG_USER.updated_last_by_user_id
, TCG_USER.change_set_id
FROM tcg.public.TCG_User TCG_USER
INNER JOIN Temp_User_Relationship_Save_Session_Member SESSION_MEMBER_T ON TCG_USER.user_id = SESSION_MEMBER_T.user_id
;
-- Missing fields
WITH Session_Member_Missing_Field AS (
SELECT
SESSION_MEMBER_T.temp_id
, 'game_id' AS field
FROM Temp_User_Relationship_Save_Session_Member SESSION_MEMBER_T
WHERE SESSION_MEMBER_T.game_id IS NULL
UNION
SELECT
SESSION_MEMBER_T.temp_id
, 'user_id' AS field
FROM Temp_User_Relationship_Save_Session_Member SESSION_MEMBER_T
WHERE SESSION_MEMBER_T.user_id IS NULL
)
INSERT INTO Temp_User_Relationship_Save_Error (
error_type_id
, message
)
SELECT
v_bad_data_error_type_id -- error_type_id
, CONCAT(
'Missing mandatory field: '
, SESSION_MEMBER_MISSING_FIELD.field
, ' on '
, SESSION_MEMBER_T.error_name
, '.'
) -- message
FROM Temp_User_Relationship_Save_Session_Member SESSION_MEMBER_T
INNER JOIN Session_Member_Missing_Field SESSION_MEMBER_MISSING_FIELD ON SESSION_MEMBER_T.temp_id = SESSION_MEMBER_MISSING_FIELD.temp_id
;
-- Failed join fields
WITH Session_Member_Failed_Join_Field AS (
SELECT
SESSION_MEMBER_T.temp_id
, 'game_id' AS field
FROM Temp_User_Relationship_Save_Session_Member SESSION_MEMBER_T
LEFT JOIN Temp_User_Relationship_Save_Game T_GAME ON SESSION_MEMBER_T.game_id = T_GAME.game_id
WHERE T_GAME.game_id IS NULL
UNION
SELECT
SESSION_MEMBER_T.temp_id
, 'user_id' AS field
FROM Temp_User_Relationship_Save_Session_Member SESSION_MEMBER_T
LEFT JOIN Temp_User_Relationship_Save_User T_USER ON SESSION_MEMBER_T.user_id = T_USER.user_id
WHERE T_USER.user_id IS NULL
)
INSERT INTO Temp_User_Relationship_Save_Error (
error_type_id
, message
)
SELECT
v_bad_data_error_type_id -- error_type_id
, CONCAT(
'Failed relationship: '
, SESSION_MEMBER_FAILED_JOIN_FIELD.field
, ' on '
, SESSION_MEMBER_T.error_name
, '.'
) -- message
FROM Temp_User_Relationship_Save_Session_Member SESSION_MEMBER_T
INNER JOIN Session_Member_Failed_Join_Field SESSION_MEMBER_FAILED_JOIN_FIELD ON SESSION_MEMBER_T.temp_id = SESSION_MEMBER_FAILED_JOIN_FIELD.temp_id
;
-- Duplicate Session Member
-- By game and user
WITH
All_Session_Member AS (
SELECT
SESSION_MEMBER_T.temp_id
, SESSION_MEMBER_T.game_id
, SESSION_MEMBER_T.user_id
, TRUE AS is_save_record
FROM Temp_User_Relationship_Save_Session_Member SESSION_MEMBER_T
UNION
SELECT
NULL AS temp_id
, SESSION_MEMBER.game_id
, SESSION_MEMBER.user_id
, FALSE AS is_save_record
FROM tcg.public.TCG_MTG_Game_Session_Member SESSION_MEMBER
LEFT JOIN Temp_User_Relationship_Save_Session_Member SESSION_MEMBER_T ON SESSION_MEMBER.member_id = SESSION_MEMBER_T.member_id
WHERE
SESSION_MEMBER_T.member_id IS NULL
AND SESSION_MEMBER.active
)
, Session_Member_Count AS (
SELECT
ALL_SESSION_MEMBER.game_id
, ALL_SESSION_MEMBER.user_id
, COUNT(*) AS count_members
FROM All_Session_Member ALL_SESSION_MEMBER
GROUP BY
ALL_SESSION_MEMBER.game_id
, ALL_SESSION_MEMBER.user_id
)
, Duplicate_Session_Member AS (
SELECT
ALL_SESSION_MEMBER.temp_id
, ALL_SESSION_MEMBER.game_id
, ALL_SESSION_MEMBER.user_id
, CASE WHEN SESSION_MEMBER_COUNT.count_members = 1 THEN TRUE ELSE FALSE END AS is_unique_member
FROM All_Session_Member ALL_SESSION_MEMBER
INNER JOIN Session_Member_Count SESSION_MEMBER_COUNT
ON ALL_SESSION_MEMBER.game_id = SESSION_MEMBER_COUNT.game_id
AND ALL_SESSION_MEMBER.user_id = SESSION_MEMBER_COUNT.user_id
)
UPDATE Temp_User_Relationship_Save_Session_Member SESSION_MEMBER_T
SET is_duplicate = CASE WHEN NOT DUPLICATE_SESSION_MEMBER.is_unique_member THEN TRUE ELSE FALSE END
FROM Duplicate_Session_Member DUPLICATE_SESSION_MEMBER
WHERE SESSION_MEMBER_T.temp_id = DUPLICATE_SESSION_MEMBER.temp_id
;
IF EXISTS (
SELECT *
FROM Temp_User_Relationship_Save_Session_Member SESSION_MEMBER_T
WHERE SESSION_MEMBER_T.is_duplicate
LIMIT 1
) THEN
INSERT INTO Temp_User_Relationship_Save_Error (
error_type_id
, message
)
SELECT
v_bad_data_error_type_id -- error_type_id
, CONCAT(
'Duplicate on '
, SESSION_MEMBER_T.error_name
) -- message
FROM Temp_User_Relationship_Save_Session_Member SESSION_MEMBER_T
WHERE SESSION_MEMBER_T.is_duplicate
;
END IF;
-- Nothing to save
IF NOT EXISTS (SELECT * FROM Temp_User_Relationship_Save_Session_Member LIMIT 1) THEN
INSERT INTO Temp_User_Relationship_Save_Error (
error_type_id
, message
)
VALUES (
v_warning_error_type_id
, 'Nothing to save.'
);
END IF;
-- Outputs
-- Change Set
INSERT INTO tcg.public.TCG_Change_Set (
comment
, updated_last_by_user_id
)
VALUES (
a_comment
, a_user_id
)
RETURNING change_set_id INTO v_change_set_id
;
IF NOT EXISTS (SELECT * FROM Temp_User_Relationship_Save_Error T_ERROR WHERE T_ERROR.error_type_id <> v_warning_error_type_id LIMIT 1) THEN
-- Session Member
INSERT INTO tcg.public.TCG_MTG_Game_Session_Member (
game_id
, user_id
, is_permitted
, active
, created_on
, created_by_user_id
, updated_last_on
, updated_last_by_user_id
, change_set_id
)
SELECT
SESSION_MEMBER_T.game_id
, SESSION_MEMBER_T.user_id
, SESSION_MEMBER_T.is_permitted
, SESSION_MEMBER_T.active
, v_time_start -- created_on
, a_user_id -- created_by_user_id
, v_time_start -- updated_last_on
, a_user_id -- updated_last_by_user_id
, v_change_set_id -- change_set_id
FROM Temp_User_Relationship_Save_Session_Member SESSION_MEMBER_T
LEFT JOIN Temp_User_Relationship_Save_Game T_GAME ON SESSION_MEMBER_T.game_id = T_GAME.game_id
WHERE
SESSION_MEMBER_T.is_new = TRUE
AND SESSION_MEMBER_T.active = TRUE
ORDER BY
T_GAME.created_on
, T_GAME.game_id
, SESSION_MEMBER_T.is_permitted
, SESSION_MEMBER_T.user_id
;
UPDATE tcg.public.TCG_MTG_Game_Session_Member SESSION_MEMBER
SET
game_id = SESSION_MEMBER_T.game_id
, user_id = SESSION_MEMBER_T.user_id
, is_permitted = SESSION_MEMBER_T.is_permitted
, active = SESSION_MEMBER_T.active
, updated_last_on = v_time_start
, updated_last_by_user_id = a_user_id
, change_set_id = v_change_set_id
FROM Temp_User_Relationship_Save_Session_Member SESSION_MEMBER_T
WHERE
SESSION_MEMBER.member_id = SESSION_MEMBER_T.member_id
AND NOT SESSION_MEMBER_T.is_new
;
END IF;
-- Error
INSERT INTO tcg.public.Error (
guid
, error_type_id
, message
, display_order
, created_on
, created_by_user_id
, updated_last_on
, updated_last_by_user_id
, change_set_id
)
SELECT
a_guid
, T_ERROR.error_type_id
, T_ERROR.message
, T_ERROR.temp_id
, v_time_start
, a_user_id
, v_time_start
, a_user_id
, v_change_set_id
FROM Temp_User_Relationship_Save_Error T_ERROR
LEFT JOIN tcg.public.Error_Type ERROR_TYPE ON T_ERROR.error_type_id = ERROR_TYPE.error_type_id
ORDER BY T_ERROR.temp_id
;
COMMIT;
o_success := NOT EXISTS (
SELECT *
FROM Temp_User_Relationship_Save_Error T_ERROR
WHERE T_ERROR.error_type_id <> v_warning_error_type_id
LIMIT 1
);
DELETE FROM tcg.public.TCG_MTG_Game_Session_Member_Temp SESSION_MEMBER_T WHERE SESSION_MEMBER_T.guid = a_guid;
DROP TABLE IF EXISTS Temp_User_Relationship_Save_Game;
DROP TABLE IF EXISTS Temp_User_Relationship_Save_User;
DROP TABLE IF EXISTS Temp_User_Relationship_Save_Session_Member;
DROP TABLE IF EXISTS Temp_User_Relationship_Save_Error;
END;
$$;
-- Call it with:
DO $$
DECLARE
v_comment TEXT := 'MTG Game Session Member Save.';
v_guid UUID;
v_user_id INT := 3;
v_success BOOLEAN;
BEGIN
v_guid := gen_random_uuid();
INSERT INTO tcg.public.TCG_MTG_Game_Session_Member_Temp (
guid
, member_id
, game_id
, user_id
, is_permitted
, active
)
VALUES
(
v_guid
, NULL -- member_id
, 4 -- game_id
, 3 -- user_id
, TRUE -- is_permitted
, TRUE -- active
)
, (
v_guid
, NULL -- member_id
, 4 -- game_id
, 4 -- user_id
, FALSE -- is_permitted
, TRUE -- active
)
/*
, (
v_guid
, NULL -- member_id
, 4 -- game_id
, 3 -- user_id
, FALSE -- is_permitted
, TRUE -- active
)
*/
;
CALL tcg.public.USP_TCG_MTG_Game_Session_Member_Save (
v_comment -- a_comment
, v_guid -- a_guid
, v_user_id -- a_user_id
, v_success -- o_success
);
RAISE NOTICE 'Success: %', CASE WHEN v_success THEN 'TRUE' ELSE 'FALSE' END;
END;
$$;
SELECT *
-- DELETE
FROM tcg.public.Error ERROR
LEFT JOIN tcg.public.Error_Type ERROR_TYPE ON ERROR.error_type_id = ERROR_TYPE.error_type_id
;
SELECT *
FROM tcg.public.Error_Type ERROR_TYPE
;
SELECT *
FROM tcg.public.TCG_Change_Set CHANGE_SET
ORDER BY CHANGE_SET.change_set_id DESC
;
SELECT *
-- DELETE
FROM tcg.public.TCG_MTG_Game_Session_Member_Temp
;
SELECT *
-- DELETE
FROM tcg.public.TCG_MTG_Game_Session_Member SESSION_MEMBER
LEFT JOIN tcg.public.TCG_MTG_Game GAME ON SESSION_MEMBER.game_id = GAME.game_id
;

View File

@@ -854,6 +854,7 @@ BEGIN
AND T_ROUND_PLAYER.display_order >= T_ROUND_DAMAGE.display_order
INNER JOIN Temp_Statistic_Calc_Round_Player_Damage T_PLAYER_DAMAGE
ON T_ROUND_DAMAGE.round_id = T_PLAYER_DAMAGE.round_id
AND ALL_PLAYER_ROUND.player_id = T_PLAYER_DAMAGE.player_id
AND T_PLAYER_DAMAGE.received_from_commander_player_id IS NOT NULL
GROUP BY
ALL_PLAYER_ROUND.game_id
@@ -889,6 +890,7 @@ BEGIN
AND T_ROUND_PLAYER.display_order >= T_ROUND_DAMAGE.display_order
INNER JOIN Temp_Statistic_Calc_Round_Player_Damage T_PLAYER_DAMAGE
ON T_ROUND_DAMAGE.round_id = T_PLAYER_DAMAGE.round_id
AND ALL_PLAYER_ROUND.player_id = T_PLAYER_DAMAGE.player_id
AND T_PLAYER_DAMAGE.received_from_commander_player_id = ALL_PLAYER_ROUND.player_id
GROUP BY
ALL_PLAYER_ROUND.game_id
@@ -910,6 +912,7 @@ BEGIN
AND T_ROUND_PLAYER.display_order >= T_ROUND_DAMAGE.display_order
INNER JOIN Temp_Statistic_Calc_Round_Player_Damage T_PLAYER_DAMAGE
ON T_ROUND_DAMAGE.round_id = T_PLAYER_DAMAGE.round_id
AND ALL_PLAYER_ROUND.player_id = T_PLAYER_DAMAGE.player_id
AND T_PLAYER_DAMAGE.life_loss > 0
GROUP BY
ALL_PLAYER_ROUND.game_id
@@ -931,6 +934,7 @@ BEGIN
AND T_ROUND_PLAYER.display_order >= T_ROUND_DAMAGE.display_order
INNER JOIN Temp_Statistic_Calc_Round_Player_Damage T_PLAYER_DAMAGE
ON T_ROUND_DAMAGE.round_id = T_PLAYER_DAMAGE.round_id
AND ALL_PLAYER_ROUND.player_id = T_PLAYER_DAMAGE.player_id
GROUP BY
ALL_PLAYER_ROUND.game_id
, ALL_PLAYER_ROUND.player_id
@@ -951,6 +955,7 @@ BEGIN
AND T_ROUND_PLAYER.display_order >= T_ROUND_DAMAGE.display_order
INNER JOIN Temp_Statistic_Calc_Round_Player_Damage T_PLAYER_DAMAGE
ON T_ROUND_DAMAGE.round_id = T_PLAYER_DAMAGE.round_id
AND ALL_PLAYER_ROUND.player_id = T_PLAYER_DAMAGE.player_id
AND T_PLAYER_DAMAGE.life_gain > 0
GROUP BY
ALL_PLAYER_ROUND.game_id
@@ -1010,7 +1015,7 @@ BEGIN
INNER JOIN Temp_Statistic_Calc_Game T_GAME ON T_PLAYER_ROUND_LINK.game_id = T_GAME.game_id
WHERE
T_PLAYER_ROUND_LINK.max_total_commander_damage_received >= v_commander_damage_limit
OR T_PLAYER_ROUND_LINK.total_damage_received >= T_GAME.starting_life
OR T_PLAYER_ROUND_LINK.total_damage_received - T_PLAYER_ROUND_LINK.total_life_gained >= T_GAME.starting_life
OR T_PLAYER_ROUND_LINK.is_eliminated
GROUP BY
T_PLAYER_ROUND_LINK.player_id
@@ -9376,6 +9381,8 @@ BEGIN
IF NOT EXISTS (SELECT * FROM Temp_Statistic_Calc_Error T_ERROR WHERE T_ERROR.error_type_id <> v_warning_error_type_id LIMIT 1) THEN
DELETE FROM tcg.public.TCG_Statistic;
-- Statistic
INSERT INTO tcg.public.TCG_Statistic (
entity_type_code

View File

@@ -1,8 +1,7 @@
.tcg-card {
margin-top: 1vh;
margin-bottom: 0;
margin: 1vh 0 auto;
}

View File

@@ -1,5 +1,9 @@
/* MTG Single Game Page Styles */
.tcg-title.dirty {
background-color: var(--tcg-accent-purple);
}
#buttonHamburger {
display: none;
}
@@ -100,7 +104,7 @@
.control-group {
display: flex;
align-items: center;
gap: 1rem;
gap: 0.5rem;
}
.control-group .tcg-input {
@@ -113,7 +117,7 @@
.player-names-grid {
display: flex;
flex-wrap: wrap;
gap: 1rem;
gap: 0.5rem;
max-width: 800px;
margin: 0 auto 2rem;
justify-content: center;
@@ -230,7 +234,7 @@
transition: all 0.4s ease;
animation: tcg-scaleIn 0.5s ease-out backwards;
width: fit-content;
max-width: 38vw;
max-width: 35vw;
min-width: 20vw;
margin: 0 auto;
}
@@ -256,7 +260,7 @@
align-items: center;
margin-bottom: 1.5rem;
flex-wrap: wrap;
gap: 1rem;
gap: 0.5rem;
}
.player-info {
@@ -353,7 +357,7 @@
.life-gain-controls,
.life-loss-controls {
display: flex;
gap: 1rem;
gap: 0.5rem;
justify-content: center;
margin-bottom: 1vh;
}
@@ -364,7 +368,7 @@
border: 2px solid var(--tcg-border-color);
color: var(--tcg-text-primary);
width: 60px;
height: 60px;
height: 45px;
border-radius: 12px;
font-family: 'Cinzel', serif;
font-size: 1.8rem;

View File

@@ -16,7 +16,7 @@
#pageBody {
max-height: 82vh;
padding: 0 5vw;
margin: 0;
margin: 0 auto;
border: 0;
align-content: center;
justify-content: flex-start;
@@ -25,7 +25,6 @@
align-items: flex-start;
overflow-y: auto;
overflow-x: hidden;
position: absolute;
width: 90vw;
color: var(--colour-text);
}

View File

@@ -16,7 +16,7 @@
#pageBody {
max-height: 82vh;
padding: 0 5vw;
margin: 0;
margin: 0 auto;
border: 0;
align-content: center;
justify-content: flex-start;
@@ -25,7 +25,6 @@
align-items: flex-start;
overflow-y: auto;
overflow-x: hidden;
position: absolute;
width: 90vw;
color: var(--colour-text);
}
@@ -67,8 +66,7 @@
.tcg-card {
margin-top: 1vh;
margin-bottom: 0;
margin: 1vh 0 auto;
}

View File

@@ -1 +1 @@
{"version":3,"file":"css/tcg_decks.bundle.css","mappings":";;AAEA;IACI,gBAAgB;IAChB,oBAAoB;IACpB,cAAc;AAClB;;;AAGA,iBAAiB;AACjB;IACI,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,gBAAgB;IAChB,cAAc;IACd,SAAS;IACT,SAAS;IACT,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,kBAAkB;IAClB,WAAW;IACX,yBAAyB;AAC7B;;;AAGA,WAAW;AACX;IACI,gBAAgB;IAChB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,sCAAsC;IACtC,kBAAkB;IAClB,SAAS;IACT,WAAW;AACf;;AAEA;IACI;QACI,eAAe;QACf,mBAAmB;QACnB,eAAe;QACf,WAAW;QACX,eAAe;IACnB;IACA;QACI,eAAe;IACnB;IACA;QACI,cAAc;IAClB;AACJ;;AAEA;IACI,UAAU;IACV,SAAS;AACb,C;;;AC/DA;IACI,eAAe;IACf,gBAAgB;AACpB;;;AAGA;IACI,gBAAgB;IAChB,gBAAgB;AACpB;;AAEA;IACI,aAAa;AACjB;AACA;IACI,yCAAyC;AAC7C;AACA;IACI,gBAAgB;IAChB,gBAAgB;AACpB;AACA;;IAEI,eAAe;IACf,eAAe;AACnB;AACA;;IAEI,eAAe;IACf,eAAe;AACnB;AACA;;IAEI,eAAe;IACf,eAAe;AACnB,C","sources":["webpack://app/./static/css/sections/tcg.css","webpack://app/./static/css/pages/tcg/decks.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 82vh;\n padding: 0 5vw;\n margin: 0;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n position: absolute;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}","\n\n.tcg-card {\n margin-top: 1vh;\n margin-bottom: 0;\n}\n\n\ntable.table-main tbody {\n max-height: 30vh;\n overflow-y: auto;\n}\n\ntable.statistics {\n margin-top: 0;\n}\ntable.statistics thead {\n background-color: var(--background-color);\n}\ntable.statistics tbody {\n max-height: 30vh;\n overflow-y: auto;\n}\ntable.statistics thead tr th.deck,\ntable.statistics tbody tr td.deck_id {\n min-width: 20vh;\n max-width: 20vh;\n}\ntable.statistics thead tr th.name,\ntable.statistics tbody tr td.name {\n min-width: 40vh;\n max-width: 40vh;\n}\ntable.statistics thead tr th.value,\ntable.statistics tbody tr td.value {\n min-width: 10vh;\n max-width: 10vh;\n}"],"names":[],"sourceRoot":""}
{"version":3,"file":"css/tcg_decks.bundle.css","mappings":";;AAEA;IACI,gBAAgB;IAChB,oBAAoB;IACpB,cAAc;AAClB;;;AAGA,iBAAiB;AACjB;IACI,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,gBAAgB;IAChB,cAAc;IACd,cAAc;IACd,SAAS;IACT,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,WAAW;IACX,yBAAyB;AAC7B;;;AAGA,WAAW;AACX;IACI,gBAAgB;IAChB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,sCAAsC;IACtC,kBAAkB;IAClB,SAAS;IACT,WAAW;AACf;;AAEA;IACI;QACI,eAAe;QACf,mBAAmB;QACnB,eAAe;QACf,WAAW;QACX,eAAe;IACnB;IACA;QACI,eAAe;IACnB;IACA;QACI,cAAc;IAClB;AACJ;;AAEA;IACI,UAAU;IACV,SAAS;AACb,C;;;AC9DA;IACI,kBAAkB;AACtB;;;AAGA;IACI,gBAAgB;IAChB,gBAAgB;AACpB;;AAEA;IACI,aAAa;AACjB;AACA;IACI,yCAAyC;AAC7C;AACA;IACI,gBAAgB;IAChB,gBAAgB;AACpB;AACA;;IAEI,eAAe;IACf,eAAe;AACnB;AACA;;IAEI,eAAe;IACf,eAAe;AACnB;AACA;;IAEI,eAAe;IACf,eAAe;AACnB,C","sources":["webpack://app/./static/css/sections/tcg.css","webpack://app/./static/css/pages/tcg/decks.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 82vh;\n padding: 0 5vw;\n margin: 0 auto;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}","\n\n.tcg-card {\n margin: 1vh 0 auto;\n}\n\n\ntable.table-main tbody {\n max-height: 30vh;\n overflow-y: auto;\n}\n\ntable.statistics {\n margin-top: 0;\n}\ntable.statistics thead {\n background-color: var(--background-color);\n}\ntable.statistics tbody {\n max-height: 30vh;\n overflow-y: auto;\n}\ntable.statistics thead tr th.deck,\ntable.statistics tbody tr td.deck_id {\n min-width: 20vh;\n max-width: 20vh;\n}\ntable.statistics thead tr th.name,\ntable.statistics tbody tr td.name {\n min-width: 40vh;\n max-width: 40vh;\n}\ntable.statistics thead tr th.value,\ntable.statistics tbody tr td.value {\n min-width: 10vh;\n max-width: 10vh;\n}"],"names":[],"sourceRoot":""}

View File

@@ -16,7 +16,7 @@
#pageBody {
max-height: 82vh;
padding: 0 5vw;
margin: 0;
margin: 0 auto;
border: 0;
align-content: center;
justify-content: flex-start;
@@ -25,7 +25,6 @@
align-items: flex-start;
overflow-y: auto;
overflow-x: hidden;
position: absolute;
width: 90vw;
color: var(--colour-text);
}
@@ -66,6 +65,10 @@
}
/* MTG Single Game Page Styles */
.tcg-title.dirty {
background-color: var(--tcg-accent-purple);
}
#buttonHamburger {
display: none;
}
@@ -166,7 +169,7 @@
.control-group {
display: flex;
align-items: center;
gap: 1rem;
gap: 0.5rem;
}
.control-group .tcg-input {
@@ -179,7 +182,7 @@
.player-names-grid {
display: flex;
flex-wrap: wrap;
gap: 1rem;
gap: 0.5rem;
max-width: 800px;
margin: 0 auto 2rem;
justify-content: center;
@@ -296,7 +299,7 @@
transition: all 0.4s ease;
animation: tcg-scaleIn 0.5s ease-out backwards;
width: fit-content;
max-width: 38vw;
max-width: 35vw;
min-width: 20vw;
margin: 0 auto;
}
@@ -322,7 +325,7 @@
align-items: center;
margin-bottom: 1.5rem;
flex-wrap: wrap;
gap: 1rem;
gap: 0.5rem;
}
.player-info {
@@ -419,7 +422,7 @@
.life-gain-controls,
.life-loss-controls {
display: flex;
gap: 1rem;
gap: 0.5rem;
justify-content: center;
margin-bottom: 1vh;
}
@@ -430,7 +433,7 @@
border: 2px solid var(--tcg-border-color);
color: var(--tcg-text-primary);
width: 60px;
height: 60px;
height: 45px;
border-radius: 12px;
font-family: 'Cinzel', serif;
font-size: 1.8rem;

File diff suppressed because one or more lines are too long

View File

@@ -16,7 +16,7 @@
#pageBody {
max-height: 82vh;
padding: 0 5vw;
margin: 0;
margin: 0 auto;
border: 0;
align-content: center;
justify-content: flex-start;
@@ -25,7 +25,6 @@
align-items: flex-start;
overflow-y: auto;
overflow-x: hidden;
position: absolute;
width: 90vw;
color: var(--colour-text);
}

File diff suppressed because one or more lines are too long

View File

@@ -16,7 +16,7 @@
#pageBody {
max-height: 82vh;
padding: 0 5vw;
margin: 0;
margin: 0 auto;
border: 0;
align-content: center;
justify-content: flex-start;
@@ -25,7 +25,6 @@
align-items: flex-start;
overflow-y: auto;
overflow-x: hidden;
position: absolute;
width: 90vw;
color: var(--colour-text);
}

View File

@@ -1 +1 @@
{"version":3,"file":"css/tcg_home.bundle.css","mappings":";;AAEA;IACI,gBAAgB;IAChB,oBAAoB;IACpB,cAAc;AAClB;;;AAGA,iBAAiB;AACjB;IACI,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,gBAAgB;IAChB,cAAc;IACd,SAAS;IACT,SAAS;IACT,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,kBAAkB;IAClB,WAAW;IACX,yBAAyB;AAC7B;;;AAGA,WAAW;AACX;IACI,gBAAgB;IAChB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,sCAAsC;IACtC,kBAAkB;IAClB,SAAS;IACT,WAAW;AACf;;AAEA;IACI;QACI,eAAe;QACf,mBAAmB;QACnB,eAAe;QACf,WAAW;QACX,eAAe;IACnB;IACA;QACI,eAAe;IACnB;IACA;QACI,cAAc;IAClB;AACJ;;AAEA;IACI,UAAU;IACV,SAAS;AACb,C;ACjEA;IACI,iBAAiB;AACrB;AACA;IACI,iBAAiB;IACjB,kBAAkB;AACtB,C","sources":["webpack://app/./static/css/sections/tcg.css","webpack://app/./static/css/pages/tcg/home.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 82vh;\n padding: 0 5vw;\n margin: 0;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n position: absolute;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}","#pageBody .column .row {\n margin-top: 0.5vh;\n}\n#pageBody .column .row .button {\n margin-left: auto;\n margin-right: auto;\n}"],"names":[],"sourceRoot":""}
{"version":3,"file":"css/tcg_home.bundle.css","mappings":";;AAEA;IACI,gBAAgB;IAChB,oBAAoB;IACpB,cAAc;AAClB;;;AAGA,iBAAiB;AACjB;IACI,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,gBAAgB;IAChB,cAAc;IACd,cAAc;IACd,SAAS;IACT,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,WAAW;IACX,yBAAyB;AAC7B;;;AAGA,WAAW;AACX;IACI,gBAAgB;IAChB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,sCAAsC;IACtC,kBAAkB;IAClB,SAAS;IACT,WAAW;AACf;;AAEA;IACI;QACI,eAAe;QACf,mBAAmB;QACnB,eAAe;QACf,WAAW;QACX,eAAe;IACnB;IACA;QACI,eAAe;IACnB;IACA;QACI,cAAc;IAClB;AACJ;;AAEA;IACI,UAAU;IACV,SAAS;AACb,C;AChEA;IACI,iBAAiB;AACrB;AACA;IACI,iBAAiB;IACjB,kBAAkB;AACtB,C","sources":["webpack://app/./static/css/sections/tcg.css","webpack://app/./static/css/pages/tcg/home.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 82vh;\n padding: 0 5vw;\n margin: 0 auto;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}","#pageBody .column .row {\n margin-top: 0.5vh;\n}\n#pageBody .column .row .button {\n margin-left: auto;\n margin-right: auto;\n}"],"names":[],"sourceRoot":""}

View File

@@ -16,7 +16,7 @@
#pageBody {
max-height: 82vh;
padding: 0 5vw;
margin: 0;
margin: 0 auto;
border: 0;
align-content: center;
justify-content: flex-start;
@@ -25,7 +25,6 @@
align-items: flex-start;
overflow-y: auto;
overflow-x: hidden;
position: absolute;
width: 90vw;
color: var(--colour-text);
}

View File

@@ -1 +1 @@
{"version":3,"file":"css/user_account.bundle.css","mappings":";;AAEA;IACI,gBAAgB;IAChB,oBAAoB;IACpB,cAAc;AAClB;;;AAGA,iBAAiB;AACjB;IACI,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,gBAAgB;IAChB,cAAc;IACd,SAAS;IACT,SAAS;IACT,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,kBAAkB;IAClB,WAAW;IACX,yBAAyB;AAC7B;;;AAGA,WAAW;AACX;IACI,gBAAgB;IAChB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,sCAAsC;IACtC,kBAAkB;IAClB,SAAS;IACT,WAAW;AACf;;AAEA;IACI;QACI,eAAe;QACf,mBAAmB;QACnB,eAAe;QACf,WAAW;QACX,eAAe;IACnB;IACA;QACI,eAAe;IACnB;IACA;QACI,cAAc;IAClB;AACJ;;AAEA;IACI,UAAU;IACV,SAAS;AACb,C;;;AChEA;IACI,aAAa;AACjB;;AAEA;IACI,eAAe;IACf,SAAS;IACT,WAAW;AACf;;AAEA;IACI,cAAc;AAClB;AACA;IACI,iBAAiB;AACrB;AACA;IACI,gBAAgB;AACpB;;AAEA;;;IAGI,kCAAkC;IAClC,2CAA2C;AAC/C,C","sources":["webpack://app/./static/css/sections/tcg.css","webpack://app/./static/css/pages/user/user.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 82vh;\n padding: 0 5vw;\n margin: 0;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n position: absolute;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}","\n#formFilters {\n display: none;\n}\n\n.container.save.button-cancel {\n position: fixed;\n top: 10vh;\n right: 10vh;\n}\n\n.container-input {\n margin: 0 auto;\n}\nlabel {\n font-weight: bold;\n}\n.container-input input {\n max-width: 250px;\n}\n\ninput.dirty, \ntextarea.dirty, \nselect.dirty {\n border-color: var(--primary-color);\n background-color: var(--background-color-2);\n}"],"names":[],"sourceRoot":""}
{"version":3,"file":"css/user_account.bundle.css","mappings":";;AAEA;IACI,gBAAgB;IAChB,oBAAoB;IACpB,cAAc;AAClB;;;AAGA,iBAAiB;AACjB;IACI,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,gBAAgB;IAChB,cAAc;IACd,cAAc;IACd,SAAS;IACT,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,WAAW;IACX,yBAAyB;AAC7B;;;AAGA,WAAW;AACX;IACI,gBAAgB;IAChB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,sCAAsC;IACtC,kBAAkB;IAClB,SAAS;IACT,WAAW;AACf;;AAEA;IACI;QACI,eAAe;QACf,mBAAmB;QACnB,eAAe;QACf,WAAW;QACX,eAAe;IACnB;IACA;QACI,eAAe;IACnB;IACA;QACI,cAAc;IAClB;AACJ;;AAEA;IACI,UAAU;IACV,SAAS;AACb,C;;;AC/DA;IACI,aAAa;AACjB;;AAEA;IACI,eAAe;IACf,SAAS;IACT,WAAW;AACf;;AAEA;IACI,cAAc;AAClB;AACA;IACI,iBAAiB;AACrB;AACA;IACI,gBAAgB;AACpB;;AAEA;;;IAGI,kCAAkC;IAClC,2CAA2C;AAC/C,C","sources":["webpack://app/./static/css/sections/tcg.css","webpack://app/./static/css/pages/user/user.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 82vh;\n padding: 0 5vw;\n margin: 0 auto;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}","\n#formFilters {\n display: none;\n}\n\n.container.save.button-cancel {\n position: fixed;\n top: 10vh;\n right: 10vh;\n}\n\n.container-input {\n margin: 0 auto;\n}\nlabel {\n font-weight: bold;\n}\n.container-input input {\n max-width: 250px;\n}\n\ninput.dirty, \ntextarea.dirty, \nselect.dirty {\n border-color: var(--primary-color);\n background-color: var(--background-color-2);\n}"],"names":[],"sourceRoot":""}

View File

@@ -17,7 +17,7 @@
#pageBody {
max-height: 82vh;
padding: 0 5vw;
margin: 0;
margin: 0 auto;
border: 0;
align-content: center;
justify-content: flex-start;
@@ -26,7 +26,6 @@
align-items: flex-start;
overflow-y: auto;
overflow-x: hidden;
position: absolute;
width: 90vw;
color: var(--colour-text);
}

View File

@@ -1 +1 @@
{"version":3,"file":"css/user_accounts.bundle.css","mappings":";;;AAEA;IACI,gBAAgB;IAChB,oBAAoB;IACpB,cAAc;AAClB;;;AAGA,iBAAiB;AACjB;IACI,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,gBAAgB;IAChB,cAAc;IACd,SAAS;IACT,SAAS;IACT,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,kBAAkB;IAClB,WAAW;IACX,yBAAyB;AAC7B;;;AAGA,WAAW;AACX;IACI,gBAAgB;IAChB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,sCAAsC;IACtC,kBAAkB;IAClB,SAAS;IACT,WAAW;AACf;;AAEA;IACI;QACI,eAAe;QACf,mBAAmB;QACnB,eAAe;QACf,WAAW;QACX,eAAe;IACnB;IACA;QACI,eAAe;IACnB;IACA;QACI,cAAc;IAClB;AACJ;;AAEA;IACI,UAAU;IACV,SAAS;AACb,C","sources":["webpack://app/./static/css/sections/tcg.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 82vh;\n padding: 0 5vw;\n margin: 0;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n position: absolute;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}"],"names":[],"sourceRoot":""}
{"version":3,"file":"css/user_accounts.bundle.css","mappings":";;;AAEA;IACI,gBAAgB;IAChB,oBAAoB;IACpB,cAAc;AAClB;;;AAGA,iBAAiB;AACjB;IACI,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,gBAAgB;IAChB,cAAc;IACd,cAAc;IACd,SAAS;IACT,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,WAAW;IACX,yBAAyB;AAC7B;;;AAGA,WAAW;AACX;IACI,gBAAgB;IAChB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,sCAAsC;IACtC,kBAAkB;IAClB,SAAS;IACT,WAAW;AACf;;AAEA;IACI;QACI,eAAe;QACf,mBAAmB;QACnB,eAAe;QACf,WAAW;QACX,eAAe;IACnB;IACA;QACI,eAAe;IACnB;IACA;QACI,cAAc;IAClB;AACJ;;AAEA;IACI,UAAU;IACV,SAAS;AACb,C","sources":["webpack://app/./static/css/sections/tcg.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 82vh;\n padding: 0 5vw;\n margin: 0 auto;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}"],"names":[],"sourceRoot":""}

View File

@@ -417,6 +417,12 @@ class API {
}
// MTG Game API methods
static async getIsGameDataOutdated(game) {
const url = `/mtg/api/game/${game[attrGameId]}/is-outdated`;
let dataRequest = {};
dataRequest[flagGame] = game;
return await API.request(url, 'POST', dataRequest);
}
static async saveGame(game, formFilters, comment) {
let dataRequest = {};
dataRequest[flagFormFilters] = DOM.convertForm2JSON(formFilters);
@@ -1616,6 +1622,7 @@ class PageMtgDecks extends TableBasePage {
class PageMtgGame extends TableBasePage {
static hash = hashPageMtgGame;
static attrIdRowObject = attrGameId;
@@ -1630,6 +1637,9 @@ class PageMtgGame extends TableBasePage {
hookupFilters() {
// this.sharedHookupFilters();
}
callFilterTableContent() {
window.location.reload();
}
loadRowTable(rowJson) {
return;
}
@@ -1667,6 +1677,8 @@ class PageMtgGame extends TableBasePage {
this.hookupPlayerLifeIncrementButtons();
this.hookupCommanderDamageIncrementButtons();
*/
PageMtgGame.hookupOverlayGameOutdated();
PageMtgGame.hookupGameUpdateCheck();
}
static hookupResetButton() {
const resetGameButton = document.querySelector('header.game-header .header-right .btn-tcg.btn-tcg-secondary');
@@ -1722,7 +1734,55 @@ class PageMtgGame extends TableBasePage {
}
}
*/
static hookupGameUpdateCheck() {
const intervalId = setInterval(async () => {
const isGameDataOutdated = await PageMtgGame.checkLastGameUpdate();
if (isGameDataOutdated) {
clearInterval(intervalId);
}
}, 30000);
}
static async checkLastGameUpdate() {
try {
// Fetch players, rounds, and damage records from API
const isGameDataOutdatedResponse = await API.getIsGameDataOutdated(game);
const isGameDataOutdated = isGameDataOutdatedResponse[flagData];
console.log({
isGameDataOutdatedResponse,
isGameDataOutdated
});
if (isGameDataOutdated) {
// const gameDataOutdatedLabel = document.querySelector(gameDataOutdatedLabelId);
// gameDataOutdatedLabel.classList.remove(flagIsCollapsed);
const pageTitleElement = document.querySelector('.topnav .tcg-title');
pageTitleElement.classList.add(flagDirty);
PageMtgGame.showOverlayGameOutdated();
}
return isGameDataOutdated;
} catch (error) {
console.error('Error checking for game update from server:', error);
}
}
static hookupOverlayGameOutdated() {
Events.initialiseEventHandler(idOverlayGameOutdated + ' button.' + flagCancel, flagInitialised, buttonCancel => {
buttonCancel.addEventListener('click', () => {
let overlay = document.querySelector(idOverlayGameOutdated);
overlay.style.visibility = 'hidden';
});
});
Events.initialiseEventHandler(idOverlayGameOutdated + ' button.' + flagSubmit, flagInitialised, buttonConfirm => {
buttonConfirm.addEventListener('click', () => {
let overlay = document.querySelector(idOverlayGameOutdated);
overlay.style.visibility = 'hidden';
window.location.reload();
});
});
}
static showOverlayGameOutdated() {
let overlay = document.querySelector(idOverlayGameOutdated);
overlay.classList.remove(flagIsCollapsed);
overlay.style.visibility = 'visible';
}
async loadGameFromServer() {
console.log("loading game from server");
try {
@@ -1805,7 +1865,7 @@ class PageMtgGame extends TableBasePage {
maxCommanderDamageReceived = Math.max(maxCommanderDamageReceived, damageRecords.filter(damage => damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] == sourceId && damage[attrReceivedFromCommanderPlayerId] != null && previousRoundIds.includes(damage[attrRoundId])).map(damage => damage[flagLifeLoss]).reduce((a, b) => a + b, 0));
});
const totalDamage = damageRecords.filter(damage => damage[attrPlayerId] == playerId && previousRoundIds.includes(damage[attrRoundId])).map(damage => damage[flagLifeLoss] - damage[flagLifeGain]).reduce((a, b) => a + b, 0);
let life = startingLife - totalDamage;
let life = game[flagStartingLife] - totalDamage;
let isEliminatedByForce = damageRecords.filter(damage => damage[attrPlayerId] == playerId && previousRoundIds.includes(damage[attrRoundId])).map(damage => damage[flagIsEliminated]).some(Boolean);
console.log("renderPlayers");
console.log({
@@ -1887,7 +1947,6 @@ class PageMtgGame extends TableBasePage {
if (damage[flagActive] && (damage[flagCommanderDeaths] > 0 || damage[flagLifeGain] != 0 || damage[flagLifeLoss] != 0 || damage[flagIsEliminated])
// && rounds.filter(r => r[attrRoundId] == damage[attrRoundId])[0][flagDisplayOrder] <= currentRoundDisplayOrder
&& previousRoundIds.includes(damage[attrRoundId])) {
debugger;
let round = rounds.filter(r => r[attrRoundId] == damage[attrRoundId])[0];
let player = players.filter(p => p[attrPlayerId] == damage[attrPlayerId])[0];
let receivedFromPlayer = damage[attrReceivedFromCommanderPlayerId] == null ? {
@@ -2020,7 +2079,6 @@ class PageMtgGame extends TableBasePage {
// Life gain buttons
let lifeGainButtonSelector = '.life-gain-btn';
Events.hookupEventHandler("click", lifeGainButtonSelector, (event, button) => {
debugger;
const playerId = parseInt(button.dataset.playerId);
const amount = parseInt(button.dataset.amount);
const activeRoundId = PageMtgGame.getActiveRoundId();
@@ -2120,7 +2178,7 @@ class PageMtgGame extends TableBasePage {
damageRecords[damageIndex][flagLifeLoss] += amount;
let isLifeGainNotLoss = false;
this.changeLife(playerId // playerId
, -amount // amount
, amount // amount
, isLifeGainNotLoss // isLifeGainNotLoss
, false // updateDamage
, damageIndex // damageIndex
@@ -2228,7 +2286,7 @@ class PageMtgGame extends TableBasePage {
maxDamageFromOtherCommander,
totalDamageTaken
});
return hasDamageWithIsEliminated || maxDamageFromOtherCommander >= 21 || totalDamageTaken >= startingLife;
return hasDamageWithIsEliminated || maxDamageFromOtherCommander >= 21 || totalDamageTaken >= game[flagStartingLife];
}
static updatePlayerSetup() {
const playerCountInput = document.getElementById('playerCount');
@@ -2384,6 +2442,19 @@ class PageMtgGame extends TableBasePage {
alert(message);
}
}
updateAndToggleShowButtonsSaveCancel() {
// let pageBody = document.querySelector(idPageBody);
let isDirty = DOM.hasDirtyChildrenContainer(pageBody);
let buttonContainerSelector = '.' + flagContainer + '.' + flagSave + '.' + flagCancel;
let buttonSave = document.querySelector(buttonContainerSelector + ' ' + idButtonSave);
let areVisibleSaveCancelButtons = !buttonSave.classList.contains(flagIsCollapsed);
console.log({
pageBody,
isDirty,
areVisibleSaveCancelButtons
});
this.toggleShowButtonsSaveCancel(isDirty || areVisibleSaveCancelButtons);
}
leave() {
super.leave();
}

File diff suppressed because one or more lines are too long

View File

@@ -81,6 +81,13 @@ export default class API {
}
// MTG Game API methods
static async getIsGameDataOutdated(game) {
const url = `/mtg/api/game/${game[attrGameId]}/is-outdated`;
let dataRequest = {};
dataRequest[flagGame] = game;
return await API.request(url, 'POST', dataRequest);
}
static async saveGame(game, formFilters, comment) {
let dataRequest = {};
dataRequest[flagFormFilters] = DOM.convertForm2JSON(formFilters);

View File

@@ -4,6 +4,7 @@ import API from "../../api.js";
import TableBasePage from "../base_table.js";
import DOM from "../../dom.js";
import Events from "../../lib/events.js";
import OverlayConfirm from "../../components/common/temporary/overlay_confirm.js";
export default class PageMtgGame extends TableBasePage {
static hash = hashPageMtgGame;
@@ -21,6 +22,9 @@ export default class PageMtgGame extends TableBasePage {
hookupFilters() {
// this.sharedHookupFilters();
}
callFilterTableContent() {
window.location.reload();
}
loadRowTable(rowJson) {
return;
}
@@ -64,6 +68,8 @@ export default class PageMtgGame extends TableBasePage {
this.hookupPlayerLifeIncrementButtons();
this.hookupCommanderDamageIncrementButtons();
*/
PageMtgGame.hookupOverlayGameOutdated();
PageMtgGame.hookupGameUpdateCheck();
}
static hookupResetButton() {
const resetGameButton = document.querySelector('header.game-header .header-right .btn-tcg.btn-tcg-secondary');
@@ -117,6 +123,55 @@ export default class PageMtgGame extends TableBasePage {
}
}
*/
static hookupGameUpdateCheck() {
const intervalId = setInterval(async () => {
const isGameDataOutdated = await PageMtgGame.checkLastGameUpdate();
if (isGameDataOutdated) {
clearInterval(intervalId);
}
}, 30000);
}
static async checkLastGameUpdate() {
try {
// Fetch players, rounds, and damage records from API
const isGameDataOutdatedResponse = await API.getIsGameDataOutdated(game);
const isGameDataOutdated = isGameDataOutdatedResponse[flagData];
console.log({ isGameDataOutdatedResponse, isGameDataOutdated });
if (isGameDataOutdated) {
// const gameDataOutdatedLabel = document.querySelector(gameDataOutdatedLabelId);
// gameDataOutdatedLabel.classList.remove(flagIsCollapsed);
const pageTitleElement = document.querySelector('.topnav .tcg-title');
pageTitleElement.classList.add(flagDirty);
PageMtgGame.showOverlayGameOutdated();
}
return isGameDataOutdated;
} catch (error) {
console.error('Error checking for game update from server:', error);
}
}
static hookupOverlayGameOutdated() {
Events.initialiseEventHandler(idOverlayGameOutdated + ' button.' + flagCancel, flagInitialised, (buttonCancel) => {
buttonCancel.addEventListener('click', () => {
let overlay = document.querySelector(idOverlayGameOutdated);
overlay.style.visibility = 'hidden';
});
});
Events.initialiseEventHandler(idOverlayGameOutdated + ' button.' + flagSubmit, flagInitialised, (buttonConfirm) => {
buttonConfirm.addEventListener('click', () => {
let overlay = document.querySelector(idOverlayGameOutdated);
overlay.style.visibility = 'hidden';
window.location.reload();
});
});
}
static showOverlayGameOutdated() {
let overlay = document.querySelector(idOverlayGameOutdated);
overlay.classList.remove(flagIsCollapsed);
overlay.style.visibility = 'visible';
}
async loadGameFromServer() {
console.log("loading game from server");
@@ -244,7 +299,7 @@ export default class PageMtgGame extends TableBasePage {
))
.map(damage => damage[flagLifeLoss] - damage[flagLifeGain])
.reduce((a, b) => a + b, 0);
let life = startingLife - totalDamage;
let life = game[flagStartingLife] - totalDamage;
let isEliminatedByForce = damageRecords.filter(damage => (
damage[attrPlayerId] == playerId
@@ -482,7 +537,7 @@ export default class PageMtgGame extends TableBasePage {
, [flagActive]: true
};
}
hookupPlayerCardEvents() {
hookupPlayerCardEvents() {
// Life gain buttons
let lifeGainButtonSelector = '.life-gain-btn';
Events.hookupEventHandler("click", lifeGainButtonSelector, (event, button) => {
@@ -609,7 +664,7 @@ export default class PageMtgGame extends TableBasePage {
let isLifeGainNotLoss = false;
this.changeLife(
playerId // playerId
, -amount // amount
, amount // amount
, isLifeGainNotLoss // isLifeGainNotLoss
, false // updateDamage
, damageIndex // damageIndex
@@ -757,7 +812,7 @@ export default class PageMtgGame extends TableBasePage {
return (
hasDamageWithIsEliminated
|| maxDamageFromOtherCommander >= 21
|| totalDamageTaken >= startingLife
|| totalDamageTaken >= game[flagStartingLife]
);
}
@@ -936,6 +991,19 @@ export default class PageMtgGame extends TableBasePage {
}
}
updateAndToggleShowButtonsSaveCancel() {
// let pageBody = document.querySelector(idPageBody);
let isDirty = DOM.hasDirtyChildrenContainer(pageBody);
let buttonContainerSelector = '.' + flagContainer + '.' + flagSave + '.' + flagCancel;
let buttonSave = document.querySelector(buttonContainerSelector + ' ' + idButtonSave);
let areVisibleSaveCancelButtons = !buttonSave.classList.contains(flagIsCollapsed);
console.log({ pageBody, isDirty, areVisibleSaveCancelButtons });
this.toggleShowButtonsSaveCancel(isDirty || areVisibleSaveCancelButtons);
}
leave() {
super.leave();
}