Skip to content

Latest commit

 

History

History
186 lines (157 loc) · 4.69 KB

File metadata and controls

186 lines (157 loc) · 4.69 KB
-- DDL

-- "users" TABLE
CREATE TABLE "users" (
    "id" SERIAL,
    "username" VARCHAR(25) NOT NULL,
    "last_login_date" TIMESTAMP,
    CONSTRAINT "users_pk" PRIMARY KEY ("id"),
    CONSTRAINT "not_empty_username" CHECK (LENGTH(TRIM("username")) > 0)
);

CREATE INDEX "users_loggings" ON "users" ("last_login_date");
CREATE UNIQUE INDEX "unique_username" ON "users" ("username");


-- "topics" TABLE
CREATE TABLE "topics" (
    "id" SERIAL,
    "name" VARCHAR(30) NOT NULL,
    "description" VARCHAR(500),
    CONSTRAINT "topics_pk" PRIMARY KEY ("id"),
    CONSTRAINT "not_empty_topic_name" CHECK (LENGTH(TRIM("name")) > 0)
);

CREATE UNIQUE INDEX "unique_topic_name" ON "topics" ("name");


-- "posts" TABLE
CREATE TABLE "posts" (
    "id" BIGSERIAL,
    "user_id" INTEGER,
    "title" VARCHAR(100) NOT NULL,
    "url" VARCHAR(2048),
    "content" TEXT,
    "topic_id" INTEGER NOT NULL,
    "created_at" TIMESTAMP,
    CONSTRAINT "not_empty_title_post" CHECK (LENGTH(TRIM("title")) > 0),
    
    CONSTRAINT "url_or_post" CHECK (("url" IS NOT NULL AND "content" IS NULL) 
        OR ("url" IS NULL AND "content" IS NOT NULL)),

    CONSTRAINT "posts_pk" PRIMARY KEY ("id"),

    CONSTRAINT "valid_topic" 
        FOREIGN KEY ("topic_id") 
            REFERENCES "topics" ON DELETE CASCADE,
    
    CONSTRAINT "valid_user_post"
        FOREIGN KEY ("user_id") 
            REFERENCES "users" ON DELETE SET NULL
);

CREATE INDEX "users_who_posted" ON "posts" ("user_id");
CREATE INDEX "topics_with_posts" ON "posts" ("topic_id");
CREATE INDEX "find_post_by_url" ON "posts" ("url");


-- "comments" TABLE
CREATE TABLE "comments" (
    "id" BIGSERIAL,
    "content" TEXT NOT NULL,
    "parent_comment_id" BIGINT,
    "post_id" BIGINT NOT NULL,
    "user_id" INTEGER,
    "created_at" TIMESTAMP,
    CONSTRAINT "comments_pk" PRIMARY KEY ("id"),
    CONSTRAINT "not_empty_comment_text" CHECK (LENGTH(TRIM("content")) > 0),
    CONSTRAINT "valid_parent_comment" 
        FOREIGN KEY ("parent_comment_id") 
            REFERENCES "comments" ON DELETE CASCADE,
    CONSTRAINT "valid_post"
        FOREIGN KEY ("post_id") 
            REFERENCES "posts" ON DELETE CASCADE,
    CONSTRAINT "users_comments_fk" 
        FOREIGN KEY ("user_id") 
            REFERENCES "users" ON DELETE SET NULL
);

CREATE INDEX "find_top_level_comments" ON "comments" ("post_id", "parent_comment_id");
CREATE INDEX "find_direct_children_for_parent_comment" ON "comments" ("parent_comment_id");
CREATE INDEX "find_user_comments" ON "comments" ("user_id");


-- "votes" TABLE
CREATE TABLE "votes" (
    "id" BIGSERIAL,
    "post_id" BIGINT NOT NULL,
    "user_id" INTEGER,
    "vote" SMALLINT,
    CONSTRAINT "votes_pk" PRIMARY KEY ("id"),
    CONSTRAINT "unique_vote_for_given_user" UNIQUE ("user_id", "post_id"),
    CONSTRAINT "vote_is_1_or_-1" CHECK ("vote" IN (-1, 1)),
    CONSTRAINT "posts_votes_fk" 
        FOREIGN KEY ("post_id") 
            REFERENCES "posts" ON DELETE CASCADE,
    CONSTRAINT "users_votes_fk" 
        FOREIGN KEY ("user_id") 
            REFERENCES "users" ON DELETE SET NULL
);

CREATE INDEX "compute_score_of_post" ON "votes" ("post_id");


--MIGRATION (DML)

-- UPDATNG USERS TABLE
INSERT INTO "users" ("username")
  SELECT DISTINCT username 
  FROM "bad_posts"
UNION
  SELECT DISTINCT bc.username
  FROM "bad_comments" bc
  LEFT JOIN "users" u ON bc.username = u.username
  WHERE u.username IS NULL
UNION
  SELECT DISTINCT REGEXP_SPLIT_TO_TABLE(upvotes, ',')
  FROM "bad_posts"
UNION
  SELECT DISTINCT REGEXP_SPLIT_TO_TABLE(downvotes, ',')
  FROM "bad_posts";



-- UPDATING TOPICS TABLE
INSERT INTO "topics" ("name")
    SELECT
        DISTINCT topic
    FROM bad_posts;


-- UPDATING POSTS TABLE
INSERT INTO "posts" 
    ("id", "user_id", "title", "url", "content", "topic_id")
SELECT
    bp.id,
    u.id,
    LEFT(bp.title,100),
    bp.url,
    bp.text_content,
    t.id
FROM bad_posts AS bp
    INNER JOIN users as u 
        ON bp.username = u.username
    INNER JOIN topics AS t 
        ON t.name = bp.topic;

-- UPDATING COMMENTS TABLE
INSERT INTO "comments" ("user_id", "post_id", "content")
SELECT
    u.id,
    bc.post_id,
    bc.text_content
FROM bad_comments AS bc
INNER JOIN users AS u 
    ON u.username = bc.username;
    
-- UPDATING VOTES TABLE
INSERT INTO "votes" ("user_id", "post_id", "vote")
SELECT 
    u.id,
    bp.id,
    1
FROM (
    SELECT 
        id,
        REGEXP_SPLIT_TO_TABLE(upvotes, ',') AS voter_username
    FROM bad_posts
    ) AS bp 
    INNER JOIN users AS u 
        ON u.username = bp.voter_username
UNION
SELECT 
    u.id,
    bp.id,
    -1
FROM (
    SELECT 
        id,
        REGEXP_SPLIT_TO_TABLE(downvotes, ',') AS voter_username
    FROM bad_posts
    ) AS bp 
    INNER JOIN users AS u 
        ON u.username = bp.voter_username;