check
テーブル定義を変更し、いくつかの制約を追加する必要があります。
CREATE TABLE schedule (
id serial primary key,
during tsrange not null check(
(lower(during)::date = upper(during)::date) and
(date_trunc('hour', upper(during)) + INTERVAL '30 min' * ROUND(date_part('minute', upper(during)) / 30.0) = upper(during)) and
(date_trunc('hour', lower(during)) + INTERVAL '30 min' * ROUND(date_part('minute', lower(during)) / 30.0) = lower(during)) and
(lower(during)::time >= '8:00'::time and upper(during)::time <= '18:00'::time) and
(date_part('dow', lower(during)) in (1,2,3,4,5) and date_part('dow', upper(during)) in (1,2,3,4,5))
),
EXCLUDE USING gist (during WITH &&)
);
チェックはこの順番で
- 開始日と終了日が同じ
- 開始/終了は 30 分の境界上にある必要があります
- および 8:00 ~ 18:00 の間
- 平日のみ
テーブルに何かが必要ですholiday
: 休日の値 ('2012-11-28') に挿入します。
check
他のテーブルを参照できないため、トリガー関数が必要です (すべてのチェックをこの関数に入れる、つまり 1 か所にまとめておく方がよい場合があります)。
create function holiday_check() returns trigger language plpgsql stable as $$
begin
if exists (select * from holiday where day in (lower(NEW.during)::date, upper(NEW.during)::date)) then
raise exception 'public holiday';
else
return NEW;
end if;
end;
$$;
insert
次に、 /の前にトリガーを作成する必要がありますupdate
。
create trigger holiday_check_i before insert on schedule for each row execute procedure holiday_check();
create trigger holiday_check_u before update on schedule for each row execute procedure holiday_check();
最後に、いくつかのテスト:
-- OK
insert into schedule(during) values (tsrange('2012-11-26 08:00', '2012-11-26 09:00'));
INSERT 0 1
-- out of business hours
insert into schedule(during) values (tsrange('2012-11-26 04:00', '2012-11-26 05:00'));
ERROR: new row for relation "schedule" violates check constraint "schedule_during_check"
DETAIL: Failing row contains (12, ["2012-11-26 04:00:00","2012-11-26 05:00:00")).
-- End time can be only 8:30, 9:00, 9:30, ... 16:00, 16:30, 17:00, 17:30 or 18:00 exclusive
insert into schedule(during) values (tsrange('2012-11-26 08:00', '2012-11-26 09:10'));
ERROR: new row for relation "schedule" violates check constraint "schedule_during_check"
DETAIL: Failing row contains (13, ["2012-11-26 08:00:00","2012-11-26 09:10:00")).
-- Start time can be only 8:00 , 8:30, 9:00, 9:30, ... 16:00, 16:30, 17:00 or 17:30 inclusive
insert into schedule(during) values (tsrange('2012-11-26 11:24', '2012-11-26 13:00'));
ERROR: new row for relation "schedule" violates check constraint "schedule_during_check"
DETAIL: Failing row contains (14, ["2012-11-26 11:24:00","2012-11-26 13:00:00")).
-- holiday
insert into schedule(during) values (tsrange('2012-11-28 10:00', '2012-11-28 13:00'));
ERROR: public holiday