99 lines
3.5 KiB
SQL
99 lines
3.5 KiB
SQL
CREATE EXTENSION citext;
|
|
CREATE TABLE users(
|
|
id UUID NOT NULL PRIMARY KEY,
|
|
handle CITEXT NOT NULL UNIQUE,
|
|
password TEXT,
|
|
profpic TEXT
|
|
);
|
|
CREATE TABLE sessions (
|
|
id UUID NOT NULL PRIMARY KEY,
|
|
token BYTEA NOT NULL UNIQUE,
|
|
user_id UUID NOT NULL REFERENCES users(id),
|
|
expiry TIMESTAMPTZ NOT NULL,
|
|
|
|
revoked BOOLEAN NOT NULL DEFAULT FALSE,
|
|
revoked_at TIMESTAMPTZ DEFAULT NULL,
|
|
revoked_by UUID DEFAULT NULL REFERENCES users(id),
|
|
|
|
CHECK(
|
|
(revoked = FALSE AND revoked_at IS NULL AND revoked_by IS NULL) OR
|
|
(revoked = TRUE AND revoked_at IS NOT NULL AND revoked_by IS NOT NULL)
|
|
)
|
|
);
|
|
CREATE INDEX sessions_by_userid ON sessions(user_id);
|
|
CREATE TABLE user_permissions (
|
|
user_id UUID NOT NULL REFERENCES users(id),
|
|
permission TEXT NOT NULL,
|
|
state BOOLEAN NOT NULL,
|
|
PRIMARY KEY (user_id, permission)
|
|
);
|
|
|
|
CREATE TABLE quotes (
|
|
id UUID NOT NULL PRIMARY KEY,
|
|
timestamp TIMESTAMP NOT NULL,
|
|
location TEXT DEFAULT NULL,
|
|
context TEXT DEFAULT NULL,
|
|
created_by UUID REFERENCES users(id),
|
|
public BOOLEAN DEFAULT FALSE,
|
|
fts TSVECTOR NOT NULL DEFAULT ''::tsvector -- TODO: trigger??
|
|
);
|
|
CREATE INDEX quotes_by_creation_user ON quotes(created_by);
|
|
CREATE TABLE persons (
|
|
id UUID NOT NULL PRIMARY KEY,
|
|
bio TEXT DEFAULT NULL,
|
|
profpic TEXT DEFAULT NULL
|
|
);
|
|
CREATE TABLE names (
|
|
id UUID NOT NULL PRIMARY KEY,
|
|
name CITEXT NOT NULL,
|
|
is_primary BOOLEAN NOT NULL DEFAULT FALSE,
|
|
person_id UUID NOT NULL REFERENCES persons(id)
|
|
);
|
|
CREATE INDEX names_by_personid ON names(person_id);
|
|
CREATE UNIQUE INDEX no_name_duplicate_for_same_person ON names(person_id, name);
|
|
CREATE UNIQUE INDEX primary_name_uniqueness ON names(person_id) WHERE is_primary = TRUE;
|
|
CREATE TABLE lines (
|
|
id UUID NOT NULL PRIMARY KEY,
|
|
quote_id UUID NOT NULL REFERENCES quotes(id),
|
|
ordering SMALLINT NOT NULL,
|
|
content TEXT NOT NULL
|
|
);
|
|
CREATE INDEX lines_by_quoteid ON lines(quote_id);
|
|
CREATE UNIQUE INDEX lines_unique_ordering ON lines(quote_id, ordering);
|
|
CREATE TABLE line_authors (
|
|
line_id UUID REFERENCES lines(id),
|
|
name_id UUID REFERENCES names(id),
|
|
PRIMARY KEY (line_id, name_id)
|
|
);
|
|
|
|
CREATE TABLE tags (
|
|
id UUID NOT NULL PRIMARY KEY,
|
|
name CITEXT NOT NULL UNIQUE
|
|
);
|
|
|
|
CREATE TABLE user_quote_likes (
|
|
quote_id UUID NOT NULL REFERENCES quotes(id),
|
|
user_id UUID NOT NULL REFERENCES users(id),
|
|
PRIMARY KEY (quote_id, user_id)
|
|
);
|
|
CREATE INDEX quote_likes_by_user ON user_quote_likes(user_id);
|
|
CREATE INDEX quote_likes_by_quote ON user_quote_likes(quote_id);
|
|
|
|
CREATE TABLE quote_tags (
|
|
quote_id UUID NOT NULL REFERENCES quotes(id),
|
|
tag_id UUID NOT NULL REFERENCES tags(id),
|
|
PRIMARY KEY (quote_id, tag_id)
|
|
);
|
|
CREATE INDEX quote_tags_by_quote ON quote_tags(quote_id);
|
|
CREATE INDEX quote_tags_by_tag ON quote_tags(tag_id);
|
|
|
|
CREATE TABLE logs (
|
|
id UUID NOT NULL PRIMARY KEY,
|
|
actor UUID NOT NULL REFERENCES users(id),
|
|
target UUID,
|
|
actiontype TEXT NOT NULL,
|
|
payload JSONB
|
|
);
|
|
CREATE INDEX logs_by_actor ON logs(actor);
|
|
CREATE INDEX logs_by_target ON logs(target);
|