Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 180 additions & 0 deletions deepwell/migrations/20220906103252_deepwell.sql
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,186 @@ CREATE TABLE filter (
UNIQUE (site_id, regex, deleted_at)
);

--
-- Forums
--

-- Groups contain categories, and are site-local.
CREATE TABLE forum_group (
forum_group_id BIGSERIAL PRIMARY KEY,
site_id BIGINT NOT NULL REFERENCES site(site_id),
created_by BIGINT NOT NULL REFERENCES "user"(user_id),
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
updated_by BIGINT REFERENCES "user"(user_id),
updated_at TIMESTAMP WITH TIME ZONE,
deleted_by BIGINT REFERENCES "user"(user_id),
deleted_at TIMESTAMP WITH TIME ZONE,
name TEXT NOT NULL,
description TEXT NOT NULL,
visible BOOLEAN NOT NULL DEFAULT true,
sort_index INTEGER NOT NULL CHECK (sort_index >= 0),
from_wikidot BOOLEAN NOT NULL DEFAULT false,

UNIQUE (site_id, sort_index),
UNIQUE (forum_group_id, site_id),
CHECK ((updated_by IS NULL) = (updated_at IS NULL)),
CHECK ((deleted_by IS NULL) = (deleted_at IS NULL))
);

-- Categories belong to a group, and are site-local.
CREATE TABLE forum_category (
forum_category_id BIGSERIAL PRIMARY KEY,
forum_group_id BIGINT NOT NULL REFERENCES forum_group(forum_group_id),
site_id BIGINT NOT NULL REFERENCES site(site_id),
created_by BIGINT NOT NULL REFERENCES "user"(user_id),
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
updated_by BIGINT REFERENCES "user"(user_id),
updated_at TIMESTAMP WITH TIME ZONE,
deleted_by BIGINT REFERENCES "user"(user_id),
deleted_at TIMESTAMP WITH TIME ZONE,
name TEXT NOT NULL,
description TEXT NOT NULL,
sort_index INTEGER NOT NULL CHECK (sort_index >= 0),
from_wikidot BOOLEAN NOT NULL DEFAULT false,

-- Category settings:
max_nest_level SMALLINT CHECK (0 <= max_nest_level AND max_nest_level <= 10),
per_page_discussion BOOLEAN DEFAULT false,
layout TEXT,

UNIQUE (forum_group_id, sort_index),
UNIQUE (forum_category_id, site_id),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this for an index? I'm not sure what structural constraint this represents, given forum_category_id is unique by itself.

CHECK ((updated_by IS NULL) = (updated_at IS NULL)),
CHECK ((deleted_by IS NULL) = (deleted_at IS NULL)),
FOREIGN KEY (forum_group_id, site_id) REFERENCES forum_group(forum_group_id, site_id)
);

-- Threads live under a category.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
-- Threads live under a category.
-- Threads live in a category (but can be moved between them).

CREATE TABLE forum_thread (
forum_thread_id BIGSERIAL PRIMARY KEY,
forum_category_id BIGINT NOT NULL REFERENCES forum_category(forum_category_id),
forum_group_id BIGINT NOT NULL REFERENCES forum_group(forum_group_id),
site_id BIGINT NOT NULL REFERENCES site(site_id),
page_id BIGINT REFERENCES page(page_id) UNIQUE,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
page_id BIGINT REFERENCES page(page_id) UNIQUE,
page_id BIGINT REFERENCES page(page_id) UNIQUE, -- For page discussion threads (NULL = regular thread)

created_by BIGINT NOT NULL REFERENCES "user"(user_id),
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
updated_by BIGINT REFERENCES "user"(user_id),
updated_at TIMESTAMP WITH TIME ZONE,
deleted_by BIGINT REFERENCES "user"(user_id),
deleted_at TIMESTAMP WITH TIME ZONE,
title TEXT NOT NULL,
description TEXT NOT NULL,
from_wikidot BOOLEAN NOT NULL DEFAULT false,
sticky BOOLEAN NOT NULL DEFAULT false,

CHECK ((updated_by IS NULL) = (updated_at IS NULL)),
CHECK ((deleted_by IS NULL) = (deleted_at IS NULL)),
UNIQUE (forum_thread_id, site_id),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

FOREIGN KEY (forum_category_id, site_id) REFERENCES forum_category(forum_category_id, site_id),
FOREIGN KEY (forum_group_id, site_id) REFERENCES forum_group(forum_group_id, site_id)
);

-- Locks on threads (one active lock per thread at a time).
CREATE TABLE forum_thread_lock (
forum_thread_lock_id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
updated_at TIMESTAMP WITH TIME ZONE,
deleted_at TIMESTAMP WITH TIME ZONE,
expires_at TIMESTAMP WITH TIME ZONE,
from_wikidot BOOLEAN NOT NULL DEFAULT false,
forum_thread_id BIGINT NOT NULL REFERENCES forum_thread(forum_thread_id),
user_id BIGINT NOT NULL REFERENCES "user"(user_id),
reason TEXT NOT NULL,
lock_type TEXT NOT NULL,
allow_new_posts BOOLEAN NOT NULL DEFAULT false,
allow_post_edits BOOLEAN NOT NULL DEFAULT false,
allow_post_deletions BOOLEAN NOT NULL DEFAULT false,

UNIQUE (forum_thread_id, deleted_at)
);

-- Posts within a thread, optionally nested.
CREATE TABLE forum_post (
forum_post_id BIGSERIAL PRIMARY KEY,
parent_post_id BIGINT REFERENCES forum_post(forum_post_id),
forum_thread_id BIGINT NOT NULL REFERENCES forum_thread(forum_thread_id),
forum_category_id BIGINT NOT NULL REFERENCES forum_category(forum_category_id),
forum_group_id BIGINT NOT NULL REFERENCES forum_group(forum_group_id),
site_id BIGINT NOT NULL REFERENCES site(site_id),
user_id BIGINT NOT NULL REFERENCES "user"(user_id),
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
updated_at TIMESTAMP WITH TIME ZONE,
deleted_by BIGINT REFERENCES "user"(user_id),
deleted_at TIMESTAMP WITH TIME ZONE,
from_wikidot BOOLEAN NOT NULL DEFAULT false,
latest_revision_id BIGINT,

CHECK ((deleted_by IS NULL) = (deleted_at IS NULL)),
UNIQUE (forum_post_id, site_id),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

FOREIGN KEY (forum_thread_id, site_id) REFERENCES forum_thread(forum_thread_id, site_id),
FOREIGN KEY (forum_category_id, site_id) REFERENCES forum_category(forum_category_id, site_id),
FOREIGN KEY (forum_group_id, site_id) REFERENCES forum_group(forum_group_id, site_id)
);

-- Locks on posts (one active lock per thread at a time).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
-- Locks on posts (one active lock per thread at a time).
-- Locks on posts (one active lock per post at a time).

CREATE TABLE forum_post_lock (
forum_post_lock_id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
updated_at TIMESTAMP WITH TIME ZONE,
deleted_at TIMESTAMP WITH TIME ZONE,
expires_at TIMESTAMP WITH TIME ZONE,
forum_thread_id BIGINT NOT NULL REFERENCES forum_thread(forum_thread_id),
user_id BIGINT NOT NULL REFERENCES "user"(user_id),
reason TEXT NOT NULL,
lock_type TEXT NOT NULL,
cascading BOOLEAN NOT NULL,

UNIQUE (forum_thread_id, deleted_at)
);

-- Revisions of posts.
CREATE TABLE forum_post_revision (
forum_post_revision_id BIGSERIAL PRIMARY KEY,
forum_post_id BIGINT NOT NULL REFERENCES forum_post(forum_post_id),
forum_thread_id BIGINT NOT NULL REFERENCES forum_thread(forum_thread_id),
forum_category_id BIGINT NOT NULL REFERENCES forum_category(forum_category_id),
forum_group_id BIGINT NOT NULL REFERENCES forum_group(forum_group_id),
site_id BIGINT NOT NULL REFERENCES site(site_id),
user_id BIGINT NOT NULL REFERENCES "user"(user_id),
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
updated_at TIMESTAMP WITH TIME ZONE,
revision_number INT NOT NULL,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
revision_number INT NOT NULL,
revision_number INTEGER NOT NULL CHECK (revision_number >= 0),

from_wikidot BOOLEAN NOT NULL DEFAULT false,
title TEXT NOT NULL,
wikitext_hash BYTEA NOT NULL REFERENCES text(hash),
compiled_html_hash BYTEA NOT NULL REFERENCES text(hash),
compiled_at TIMESTAMP WITH TIME ZONE NOT NULL,
compiled_generator TEXT NOT NULL,
comments TEXT NOT NULL,

UNIQUE (forum_post_id, revision_number),
FOREIGN KEY (forum_thread_id, site_id) REFERENCES forum_thread(forum_thread_id, site_id),
FOREIGN KEY (forum_category_id, site_id) REFERENCES forum_category(forum_category_id, site_id),
FOREIGN KEY (forum_group_id, site_id) REFERENCES forum_group(forum_group_id, site_id),
FOREIGN KEY (forum_post_id, site_id) REFERENCES forum_post(forum_post_id, site_id)
);

-- Latest revision FK on posts, now that the revision table exists.
ALTER TABLE forum_post
ADD CONSTRAINT forum_post_latest_revision_fk
FOREIGN KEY (latest_revision_id) REFERENCES forum_post_revision(forum_post_revision_id);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


-- Forum indexes
CREATE INDEX forum_group_sort_idx ON forum_group (site_id, sort_index);
CREATE INDEX forum_category_sort_idx ON forum_category (forum_group_id, sort_index);
CREATE INDEX forum_category_site_sort_idx ON forum_category (site_id, sort_index);
CREATE INDEX forum_thread_activity_idx ON forum_thread (forum_category_id, sticky DESC, COALESCE(updated_at, created_at) DESC);
CREATE INDEX forum_thread_created_idx ON forum_thread (forum_category_id, created_at DESC);
CREATE INDEX forum_post_thread_created_idx ON forum_post (forum_thread_id, created_at);
CREATE INDEX forum_post_parent_idx ON forum_post (parent_post_id);
CREATE INDEX forum_post_latest_revision_idx ON forum_post (latest_revision_id);
CREATE INDEX forum_post_revision_lookup_idx ON forum_post_revision (forum_post_id, revision_number DESC);

--
-- Audit Log
--
Expand Down
15 changes: 8 additions & 7 deletions deepwell/src/database/seeder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -460,13 +460,14 @@ pub async fn seed(state: &ServerState) -> Result<()> {
restart_sequence_with(&txn, "page_page_id_seq", 3000000000).await?;
restart_sequence_with(&txn, "page_revision_revision_id_seq", 3000000000).await?;
restart_sequence_with(&txn, "page_category_category_id_seq", 100000000).await?;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/*
* TODO: tables which don't exist yet:
* restart_sequence_with(&txn, < forum category seq >, 9000000).await?;
* restart_sequence_with(&txn, < forum thread seq >, 30000000).await?;
* restart_sequence_with(&txn, < forum post seq >, 7000000).await?;
*/
restart_sequence_with(&txn, "forum_group_forum_group_id_seq", 8000000).await?;
restart_sequence_with(&txn, "forum_category_forum_category_id_seq", 9000000).await?;
restart_sequence_with(&txn, "forum_thread_forum_thread_id_seq", 30000000).await?;
restart_sequence_with(&txn, "forum_post_forum_post_id_seq", 7000000).await?;
restart_sequence_with(&txn, "forum_post_revision_forum_post_revision_id_seq", 3000000000)
.await?;
restart_sequence_with(&txn, "forum_thread_lock_forum_thread_lock_id_seq", 20000000).await?;
restart_sequence_with(&txn, "forum_post_lock_forum_post_lock_id_seq", 20000000).await?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wikidot doesn't expose IDs for forum groups and forum post revisions publicly, so we don't have compatibility IDs for those. Forum thread and post lock history is a Wikijump concept so compatibility IDs don't apply.


txn.commit().await?;
info!("Finished running seeder.");
Expand Down
11 changes: 9 additions & 2 deletions deepwell/src/services/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use crate::models::message_draft::{self, Entity as MessageDraft};
use crate::models::message_record::{self, Entity as MessageRecord};
use crate::models::page_revision::{self, Entity as PageRevision};
use crate::models::text::{self, Entity as Text};
use sea_query::Query;
use sea_query::{Alias, Query};

#[derive(Debug)]
pub struct TextService;
Expand Down Expand Up @@ -150,8 +150,15 @@ impl TextService {
.add(not_in_column!(
MessageRecord,
message_record::Column::CompiledHash,
))
.add(not_in_column!(
Alias::new("forum_post_revision"),
Alias::new("wikitext_hash"),
))
.add(not_in_column!(
Alias::new("forum_post_revision"),
Alias::new("compiled_html_hash"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see, temporary measure until new src/models files are generated. I'll do that in a separate PR because the autogen tool needs some manual correction unfortunately.

)),
// TODO add forum_post_revision
)
.exec(txn)
.await?;
Expand Down
Loading