Files
mnemosyne/src/database/migrations/0001_init.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);