Non è necessario reinventare la ruota in PostgreSQL, ci sono due semplici metodi implementati per ottenere i controlli di sovrapposizione:
Abbastanza semplice,
where("(start_at, end_at) OVERLAPS (?, ?)", range.first, range.last)
Tuttavia, ciò consente a un intervallo di essere esattamente dopo l'altro
(in altre parole, controlla inizio <=ora
Anche questo è semplice, di solito. Ma PostgreSQL non ha un tipo di intervallo integrato per time
(tuttavia ci sono tsrange
, tstzrange
e daterange
per gli altri tipi temporali).
Devi creare tu stesso questo tipo di intervallo:
CREATE TYPE timerange AS RANGE (subtype = time);
Ma dopo questo, puoi controllare la sovrapposizione con
where("timerange(start_at, end_at) && timerange(?, ?)", range.first, range.last)
Pro dei tipi di gamma:
-
puoi controllarti, come vuoi gestire i limiti dell'intervallo
ad es. potresti usare
timerange(start_at, end_at, '[]')
per includere sia l'inizio che il punto finale degli intervalli. Per impostazione predefinita include l'inizio, ma esclude il punto finale degli intervalli. -
può essere indicizzato, ad es. con
CREATE INDEX events_times_idx ON events USING GIST (timerange(start_at, end_at));
-
Vincoli di esclusione :questo è essenzialmente lo stesso, quello che vuoi ottenere, ma verrà applicato a livello di DB (come,
UNIQUE
o qualsiasi altro vincolo):ALTER TABLE events ADD CONSTRAINT events_exclude_overlapping EXCLUDE USING GIST (timerange(start_at, end_at) WITH &&);