I have a an appointments table with this structure (chunked for readability):
appointments:
- id
- staff_id
- start_time
- end_time
- cancelled
I want to add a database constraint to not be able to double book appointments. I was wondering if it was possible to add a constraint along the lines of:
when staff_id = ? and cancelled = false then set a "unique" constraint on start_time
If this is not possible is there something similar I can do to achieve my end goal?
EDIT
this is the full appointments table
CREATE TABLE "appointments" (
"id" uuid,
"customer_id" uuid NOT NULL REFERENCES customers ON DELETE CASCADE ON UPDATE CASCADE,
"staff_id" uuid NOT NULL REFERENCES staff ON DELETE CASCADE ON UPDATE CASCADE,
"start_time" timestamp NOT NULL,
"end_time" timestamp NOT NULL,
"notes" text,
"cancelled" boolean NOT NULL DEFAULT false,
"created_at" timestamp with time zone NOT NULL,
"updated_at" timestamp with time zone NOT NULL,
);
With the exclusion:
CREATE TABLE "appointments" (
"id" uuid,
"customer_id" uuid NOT NULL REFERENCES customers ON DELETE CASCADE ON UPDATE CASCADE,
"staff_id" uuid NOT NULL REFERENCES staff ON DELETE CASCADE ON UPDATE CASCADE,
"start_time" timestamp NOT NULL,
"end_time" timestamp NOT NULL,
"notes" text,
"cancelled" boolean NOT NULL DEFAULT false,
"created_at" timestamp with time zone NOT NULL,
"updated_at" timestamp with time zone NOT NULL,
EXCLUDE USING gist (
staff_id WITH =,
tsrange(start_time, end_time) WITH &&
) WHERE (NOT cancelled),
PRIMARY KEY ("id")
);
Executing with exclusion error:
data type uuid has no default operator class for access method "gist"