Domény
Skočit na navigaci
Skočit na vyhledávání
CREATE OR REPLACE FUNCTION check_form_rodne_cislo(varchar, boolean) RETURNS boolean AS $$ DECLARE str_parts varchar[]; num_parts integer[]; after_1953 boolean; birthday_str varchar; BEGIN SELECT INTO str_parts regexp_matches FROM regexp_matches($1, E'^(\\d{2})(\\d{2})(\\d{2})(/)?(\\d{3,4})$'); IF FOUND THEN -- Test existence lomitka v rodnem cisle rizeny druhym parametrem, -- ve vyznamu NULL (nema vyznam), true - povinne, false - nepovinne. IF $2 <> (str_parts[4] IS NOT NULL) THEN RETURN false; END IF; -- Test modulo 11 se provadi pouze tehdy, pokud existuje -- kontrolni cislice, tj. pocinaje rokem 1954. after_1953 := char_length(str_parts[5]) = 4; IF after_1953 AND to_number($1, CASE WHEN str_parts[4] IS NULL THEN '9999999999' ELSE '999999/9999' END) % 11 <> 0 THEN RETURN false; END IF; -- Kontrola validniho datumu, po roce 2004 se mohou -- k mesici pricitat hodnoty 20 (pro muze) a 70 pro zeny. num_parts := ARRAY[to_number(str_parts[1],'99'), to_number(str_parts[2],'99'), to_number(str_parts[3],'99')]; num_parts := ARRAY[CASE WHEN NOT after_1953 THEN 1900 + num_parts[1] WHEN after_1953 AND num_parts[1] >= 54 THEN 1900 + num_parts[1] ELSE 2000 + num_parts[1] END, CASE WHEN num_parts[2] > 70 THEN num_parts[2] - 70 WHEN num_parts[2] > 50 THEN num_parts[2] - 50 WHEN num_parts[2] > 20 THEN num_parts[2] - 20 ELSE num_parts[2] END, num_parts[3]]; birthday_str := replace(to_char(num_parts[1],'9999') || to_char(num_parts[2],'09') || to_char(num_parts[3],'09'), ' ',''); RETURN birthday_str = to_char(to_date(birthday_str, 'YYYYMMDD'), 'YYYYMMDD'); END IF; RETURN false; END; $$ LANGUAGE plpgsql; -- Predpokladam validni vstup (overeny funkci check_form_rodne_cislo). -- Typ parametru varchar je zvolen proto, protoze je predkem domen rc, -- rc1 a rc2. Domeny se lisi vztahem vuci lomitku uvnitr rodneho cisla. CREATE OR REPLACE FUNCTION form_rodne_cislo_to_date(varchar) RETURNS date AS $$ DECLARE str_parts varchar[]; num_parts integer[]; after_1953 boolean; birthday_str varchar; BEGIN SELECT INTO str_parts regexp_matches FROM regexp_matches($1, E'^(\\d{2})(\\d{2})(\\d{2})(/)?(\\d{3,4})$'); IF FOUND THEN after_1953 := char_length(str_parts[5]) = 4; -- Po roce 2004 se mohou k mesici pricitat -- hodnoty 20 (pro muze) a 70 pro zeny. Pred timto rokem -- se vzdy pricita 50 pro zeny num_parts := ARRAY[to_number(str_parts[1],'99'), to_number(str_parts[2],'99'), to_number(str_parts[3],'99')]; num_parts := ARRAY[CASE WHEN NOT after_1953 THEN 1900 + num_parts[1] WHEN after_1953 AND num_parts[1] >= 54 THEN 1900 + num_parts[1] ELSE 2000 + num_parts[1] END, CASE WHEN num_parts[2] > 70 THEN num_parts[2] - 70 WHEN num_parts[2] > 50 THEN num_parts[2] - 50 WHEN num_parts[2] > 20 THEN num_parts[2] - 20 ELSE num_parts[2] END, num_parts[3]]; RETURN to_date( replace(to_char(num_parts[1],'9999') || to_char(num_parts[2],'09') || to_char(num_parts[3],'09'), ' ',''), 'YYYYMMDD'); END IF; RAISE NOTICE 'Incorrect format of type rodne cislo (value: %)', $1; END; $$ LANGUAGE plpgsql; -- Predpokladam validni vstup (overeny funkci check_form_rodne_cislo). -- Typ parametru varchar je zvolen proto, protoze je predkem domen rc, -- rc1 a rc2. Domeny se lisi vztahem vuci lomitku uvnitr rodneho cisla. CREATE OR REPLACE FUNCTION form_rodne_cislo_to_bool(varchar) RETURNS boolean AS $$ DECLARE str_part varchar[]; birthday_mm integer; BEGIN SELECT INTO str_part regexp_matches FROM regexp_matches($1, E'^\\d{2}(\\d{2})\\d{2}/?\\d{3,4}$'); IF FOUND THEN birthday_mm := to_number(str_part[1],'09'); RETURN CASE WHEN birthday_mm > 50 THEN false ELSE true END; END IF; RAISE NOTICE 'Incorrect format of type rodne cislo (value: %)', $1; END; $$ LANGUAGE plpgsql; -- Registrace domen CREATE DOMAIN rc VARCHAR CHECK (check_form_rodne_cislo(value, null::boolean)); CREATE DOMAIN rc1 VARCHAR CHECK (check_form_rodne_cislo(value, false)); CREATE DOMAIN rc2 VARCHAR CHECK (check_form_rodne_cislo(value, true));