=> CREATE TABLE animals( id serial PRIMARY KEY, root boolean DEFAULT false, yes_id integer REFERENCES animals(id), no_id integer REFERENCES animals(id), name text );
CREATE TABLE
=> INSERT INTO animals(name) VALUES ('слон'), ('черепаха');
INSERT 0 2
=> INSERT INTO animals(name,root,yes_id,no_id) VALUES ('млекопитающее',true,1,2);
INSERT 0 1
=> SELECT * FROM animals;
id | root | yes_id | no_id | name ----+------+--------+-------+--------------- 1 | f | | | слон 2 | f | | | черепаха 3 | t | 1 | 2 | млекопитающее (3 rows)
=> CREATE FUNCTION start_game(OUT context integer, OUT question text) AS $$ BEGIN SELECT id, name||'?' INTO context, question FROM animals WHERE root; END; $$ LANGUAGE plpgsql;
CREATE FUNCTION
=> CREATE FUNCTION continue_game(INOUT context integer, answer boolean, OUT you_win boolean, OUT question text) AS $$ DECLARE new_context integer; BEGIN SELECT CASE WHEN answer THEN yes_id ELSE no_id END INTO new_context FROM animals where id = context; IF new_context IS NULL THEN you_win := NOT answer; question := 'Вы ' || CASE WHEN you_win THEN 'выиграли' ELSE 'проиграли' END; ELSE SELECT id, null, name||'?' into context, you_win, question from animals where id = new_context; END IF; END; $$ LANGUAGE plpgsql;
CREATE FUNCTION
=> CREATE FUNCTION end_game(context integer, name text, question text) RETURNS void AS $$ DECLARE new_animal_id integer; new_question_id integer; BEGIN INSERT INTO animals(name) VALUES (name) RETURNING id INTO new_animal_id; INSERT INTO animals(name) VALUES (question) RETURNING id INTO new_question_id; UPDATE animals SET yes_id = new_question_id WHERE yes_id = context; UPDATE animals SET no_id = new_question_id WHERE no_id = context; UPDATE animals SET yes_id = new_animal_id, no_id = context WHERE id = new_question_id; END; $$ LANGUAGE plpgsql;
CREATE FUNCTION
=> SELECT * FROM start_game();
context | question ---------+---------------- 3 | млекопитающее? (1 row)
=> SELECT * FROM continue_game(3,true);
context | you_win | question ---------+---------+---------- 1 | | слон? (1 row)
=> SELECT * FROM continue_game(1,false);
context | you_win | question ---------+---------+------------- 1 | t | Вы выиграли (1 row)
=> SELECT * FROM end_game(1,'кит','живет в воде');
end_game ---------- (1 row)
Теперь в таблице:
=> SELECT * FROM animals;
id | root | yes_id | no_id | name ----+------+--------+-------+--------------- 1 | f | | | слон 2 | f | | | черепаха 4 | f | | | кит 3 | t | 5 | 2 | млекопитающее 5 | f | 4 | 1 | живет в воде (5 rows)
=> SELECT * FROM start_game();
context | question ---------+---------------- 3 | млекопитающее? (1 row)
=> SELECT * FROM continue_game(3,true);
context | you_win | question ---------+---------+--------------- 5 | | живет в воде? (1 row)
=> SELECT * FROM continue_game(5,true);
context | you_win | question ---------+---------+---------- 4 | | кит? (1 row)
=> SELECT * FROM continue_game(4,true);
context | you_win | question ---------+---------+-------------- 4 | f | Вы проиграли (1 row)