package BoardStreams::DBMigrations;

use Mojo::Base -strict, -signatures;

our $VERSION = "v0.0.33";

my $string = <<~'SQL';
    -- 1 up
    CREATE TABLE "bs_streams" (
        "id"            BIGINT          GENERATED BY DEFAULT AS IDENTITY,
        "name"          TEXT            NOT NULL,
        "state"         JSONB           NOT NULL    CHECK("state" != 'null'),
        "event_id"      BIGINT          NOT NULL    DEFAULT 0,
        "last_dt"       TIMESTAMPTZ     NOT NULL    DEFAULT CURRENT_TIMESTAMP,
        "type"          TEXT                NULL    CHECK(LENGTH("type") <= 50),
        "keep_events"   BOOLEAN         NOT NULL    DEFAULT true,

        PRIMARY KEY ("id")
    );
    CREATE UNIQUE INDEX "bs_streams_uidx_name" ON "bs_streams" ("name");
    CREATE INDEX ON "bs_streams" ("type");

    CREATE SEQUENCE "bs_events_id_seq";
    CREATE TABLE "bs_events" (
        "id"            BIGINT          NOT NULL    DEFAULT nextval('bs_events_id_seq'),
        "stream_id"     BIGINT          NOT NULL    REFERENCES "bs_streams" ON DELETE CASCADE,
        "datetime"      TIMESTAMPTZ     NOT NULL    DEFAULT CURRENT_TIMESTAMP,
        "data"          JSONB           NOT NULL    CHECK("data" != 'null'),

        PRIMARY KEY ("id")
    );
    CREATE INDEX ON "bs_events" ("stream_id", "id");
    CREATE INDEX ON "bs_events" ("stream_id", "datetime");

    CREATE TABLE "bs_workers" (
        "id"            TEXT            NOT NULL,
        "dt_heartbeat"  TIMESTAMPTZ     NOT NULL,
        "is_repairer"   BOOLEAN         NOT NULL    DEFAULT false,

        PRIMARY KEY ("id")
    );
    CREATE INDEX ON "bs_workers" ("dt_heartbeat");
    CREATE UNIQUE INDEX ON "bs_workers" ("is_repairer") WHERE "is_repairer" = true;

    CREATE TABLE "bs_guards" (
        "worker_id"     TEXT            NOT NULL,
        "stream_id"     BIGINT          NOT NULL    REFERENCES "bs_streams" ON DELETE CASCADE,
        "count"         BIGINT          NOT NULL    CHECK("count" >= 0),

        PRIMARY KEY ("worker_id", "stream_id")
    );
    CREATE INDEX ON "bs_guards" ("stream_id");

    -- 1 down
    DROP TABLE "bs_guards";
    DROP TABLE "bs_workers";
    DROP TABLE "bs_events";
    DROP TABLE "bs_streams";
SQL

sub apply_migrations ($class, $pg) {
    $pg->migrations
        ->name('boardstreams_library')
        ->from_string($string)
        ->migrate;
}

1;
