def up(cursor, context):
    cursor.execute(
        """
    CREATE TABLE "user" (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        username TEXT NOT NULL UNIQUE,
        username_raw TEXT,
        level INT NOT NULL,
        points INT NOT NULL,
        subscriber BOOLEAN NOT NULL,
        minutes_in_chat_online INT NOT NULL,
        minutes_in_chat_offline INT NOT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE INDEX ON "user" (username)
    """
    )

    cursor.execute(
        """
    CREATE TABLE banphrase (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        name TEXT NOT NULL,
        phrase TEXT NOT NULL,
        length INT NOT NULL,
        permanent BOOLEAN NOT NULL,
        warning BOOLEAN NOT NULL,
        notify BOOLEAN NOT NULL,
        case_sensitive BOOLEAN NOT NULL,
        enabled BOOLEAN NOT NULL,
        operator TEXT NOT NULL DEFAULT 'contains',
        sub_immunity BOOLEAN NOT NULL DEFAULT FALSE,
        remove_accents BOOLEAN NOT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE TABLE banphrase_data (
        banphrase_id INT PRIMARY KEY NOT NULL REFERENCES banphrase(id),
        num_uses INT NOT NULL,
        added_by INT DEFAULT NULL,
        edited_by INT DEFAULT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE TABLE command (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        level INT NOT NULL,
        action TEXT DEFAULT NULL,
        extra_args TEXT DEFAULT NULL,
        command TEXT NOT NULL,
        description TEXT DEFAULT NULL,
        delay_all INT NOT NULL,
        delay_user INT NOT NULL,
        enabled BOOLEAN NOT NULL,
        cost INT NOT NULL,
        can_execute_with_whisper BOOLEAN DEFAULT NULL,
        sub_only BOOLEAN NOT NULL,
        mod_only BOOLEAN NOT NULL,
        tokens_cost INT NOT NULL DEFAULT 0,
        run_through_banphrases BOOLEAN NOT NULL DEFAULT FALSE
    )
    """
    )

    cursor.execute(
        """
    CREATE TABLE command_data (
        command_id INT PRIMARY KEY NOT NULL REFERENCES command(id),
        num_uses INT NOT NULL,
        added_by INT DEFAULT NULL,
        edited_by INT DEFAULT NULL,
        last_date_used TIMESTAMPTZ DEFAULT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE TABLE command_example (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        command_id INT NOT NULL REFERENCES command(id),
        title TEXT NOT NULL,
        chat TEXT NOT NULL,
        description TEXT NOT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE TABLE deck (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        name TEXT DEFAULT NULL,
        class TEXT DEFAULT NULL,
        link TEXT NOT NULL,
        first_used TIMESTAMPTZ NOT NULL,
        last_used TIMESTAMPTZ NOT NULL,
        times_used INT NOT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE TYPE hsbet_outcome AS ENUM('win', 'loss');
    """
    )

    cursor.execute(
        """
    CREATE TABLE hsbet_game (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        internal_id INT NOT NULL,
        outcome hsbet_outcome NOT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE TABLE hsbet_bet (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        game_id INT NOT NULL REFERENCES hsbet_game(id),
        user_id INT NOT NULL REFERENCES "user"(id),
        outcome hsbet_outcome NOT NULL,
        points INT NOT NULL,
        profit INT NOT NULL
    )
    """
    )

    cursor.execute("CREATE INDEX ON hsbet_bet(game_id)")
    cursor.execute("CREATE INDEX ON hsbet_bet(user_id)")

    cursor.execute(
        """
    CREATE TABLE link_blacklist (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        domain TEXT DEFAULT NULL,
        path TEXT DEFAULT NULL,
        level INT DEFAULT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE TABLE link_whitelist (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        domain TEXT DEFAULT NULL,
        path TEXT DEFAULT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE TABLE link_data (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        url TEXT DEFAULT NULL,
        times_linked INT DEFAULT NULL,
        first_linked TIMESTAMPTZ DEFAULT NULL,
        last_linked TIMESTAMPTZ DEFAULT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE TABLE module (
        id TEXT PRIMARY KEY NOT NULL,
        enabled BOOLEAN NOT NULL DEFAULT FALSE,
        settings TEXT DEFAULT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE TABLE playsound (
        name TEXT PRIMARY KEY NOT NULL,
        link TEXT NOT NULL,
        volume INT NOT NULL,
        cooldown INT DEFAULT NULL,
        enabled BOOLEAN NOT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE TABLE pleblist_song (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        stream_id INT NOT NULL,
        youtube_id TEXT NOT NULL,
        date_added TIMESTAMPTZ NOT NULL,
        date_played TIMESTAMPTZ DEFAULT NULL,
        skip_after INT DEFAULT NULL,
        user_id INT DEFAULT NULL
    )
    """
    )

    cursor.execute("CREATE INDEX ON pleblist_song(stream_id)")
    cursor.execute("CREATE INDEX ON pleblist_song(youtube_id)")

    cursor.execute(
        """
    CREATE TABLE pleblist_song_info (
        pleblist_song_youtube_id TEXT PRIMARY KEY NOT NULL,
        title TEXT NOT NULL,
        duration INT NOT NULL,
        default_thumbnail TEXT NOT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE TABLE prediction_run (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        winner_id INT DEFAULT NULL,
        started TIMESTAMPTZ DEFAULT NULL,
        ended TIMESTAMPTZ DEFAULT NULL,
        open BOOLEAN NOT NULL DEFAULT TRUE,
        type INT NOT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE TABLE prediction_run_entry (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        prediction_run_id INT NOT NULL,
        user_id INT NOT NULL,
        prediction INT NOT NULL
    )
    """
    )

    cursor.execute("CREATE INDEX ON prediction_run_entry(prediction_run_id)")

    cursor.execute(
        """
    CREATE TABLE roulette (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        user_id INT NOT NULL,
        created_at TIMESTAMPTZ NOT NULL,
        points INT NOT NULL
    )
    """
    )

    cursor.execute("CREATE INDEX ON roulette(user_id)")

    cursor.execute(
        """
    CREATE TABLE stream (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        title TEXT NOT NULL,
        stream_start TIMESTAMPTZ NOT NULL,
        stream_end TIMESTAMPTZ,
        ended BOOLEAN NOT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE TABLE stream_chunk (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        stream_id INT NOT NULL,
        broadcast_id BIGINT NOT NULL,
        video_url TEXT DEFAULT NULL,
        chunk_start TIMESTAMPTZ NOT NULL,
        chunk_end TIMESTAMPTZ DEFAULT NULL,
        video_preview_image_url TEXT DEFAULT NULL
    )
    """
    )

    cursor.execute("""CREATE INDEX ON stream_chunk(stream_id)""")

    cursor.execute(
        """
    CREATE TABLE timer (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        name TEXT NOT NULL,
        action TEXT NOT NULL,
        interval_online INT NOT NULL,
        interval_offline INT NOT NULL,
        enabled BOOLEAN NOT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE TABLE twitter_following (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        username TEXT DEFAULT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE TABLE user_duel_stats (
        user_id INT PRIMARY KEY NOT NULL REFERENCES "user"(id),
        duels_won INT NOT NULL,
        duels_total INT NOT NULL,
        points_won INT NOT NULL,
        points_lost INT NOT NULL,
        last_duel TIMESTAMPTZ DEFAULT NULL,
        current_streak INT NOT NULL,
        longest_losestreak INT NOT NULL,
        longest_winstreak INT NOT NULL
    )
    """
    )

    cursor.execute(
        """
    CREATE TABLE web_content (
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        page TEXT NOT NULL,
        content TEXT NOT NULL
    )
    """
    )

@@ -447,24 +447,31 @@
 %0A    CREATE 
+UNIQUE 
 INDEX ON %22us

create unique index on user(username)