import { runSchemaMigrations, } from "../../../db/migration.js";
import { cvrSchema } from "../../../types/shards.js";
import { createRowsVersionTable, setupCVRTables } from "./cvr.js";
export async function initViewSyncerSchema(log, db, shard) {
    const schema = cvrSchema(shard);
    const setupMigration = {
        migrateSchema: (lc, tx) => setupCVRTables(lc, tx, shard),
        minSafeVersion: 1,
    };
    const migrateV1toV2 = {
        migrateSchema: async (_, tx) => {
            await tx `ALTER TABLE ${tx(schema)}.instances ADD "replicaVersion" TEXT`;
        },
    };
    const migrateV2ToV3 = {
        migrateSchema: async (_, tx) => {
            await tx.unsafe(createRowsVersionTable(shard));
        },
        /** Populates the cvr.rowsVersion table with versions from cvr.instances. */
        migrateData: async (lc, tx) => {
            const pending = [];
            for await (const versions of tx `
      SELECT "clientGroupID", "version" FROM ${tx(schema)}.instances`.cursor(5000)) {
                for (const version of versions) {
                    pending.push(tx `INSERT INTO ${tx(schema)}."rowsVersion" ${tx(version)} 
               ON CONFLICT ("clientGroupID")
               DO UPDATE SET ${tx(version)}`.execute());
                }
            }
            lc.info?.(`initializing rowsVersion for ${pending.length} cvrs`);
            await Promise.all(pending);
        },
    };
    const migrateV3ToV4 = {
        migrateSchema: async (_, tx) => {
            await tx `ALTER TABLE ${tx(schema)}.instances ADD "owner" TEXT`;
            await tx `ALTER TABLE ${tx(schema)}.instances ADD "grantedAt" TIMESTAMPTZ`;
        },
    };
    const migrateV5ToV6 = {
        migrateSchema: async (_, tx) => {
            await tx `
      ALTER TABLE ${tx(schema)}."rows"
        DROP CONSTRAINT fk_rows_client_group`;
            await tx `
      ALTER TABLE ${tx(schema)}."rowsVersion"
        DROP CONSTRAINT fk_rows_version_client_group`;
        },
    };
    const migrateV6ToV7 = {
        migrateSchema: async (_, tx) => {
            await tx `ALTER TABLE ${tx(schema)}.desires ADD "expiresAt" TIMESTAMPTZ`;
            await tx `ALTER TABLE ${tx(schema)}.desires ADD "inactivatedAt" TIMESTAMPTZ`;
            await tx `ALTER TABLE ${tx(schema)}.desires ADD "ttl" INTERVAL`;
            await tx `CREATE INDEX desires_expires_at ON ${tx(schema)}.desires ("expiresAt")`;
            await tx `CREATE INDEX desires_inactivated_at ON ${tx(schema)}.desires ("inactivatedAt")`;
        },
    };
    const migrateV7ToV8 = {
        migrateSchema: async (_, tx) => {
            await tx `ALTER TABLE ${tx(schema)}."desires" DROP CONSTRAINT fk_desires_client`;
        },
    };
    const migrateV8ToV9 = {
        migrateSchema: async (_, tx) => {
            await tx `ALTER TABLE ${tx(schema)}.instances ADD "clientSchema" JSONB`;
        },
    };
    const migrateV9ToV10 = {
        migrateSchema: async (_, tx) => {
            await tx `ALTER TABLE ${tx(schema)}.queries ADD "queryName" TEXT`;
            await tx `ALTER TABLE ${tx(schema)}.queries ADD "queryArgs" JSONB`;
            await tx `ALTER TABLE ${tx(schema)}.queries ALTER COLUMN "clientAST" DROP NOT NULL`;
        },
    };
    const migrateV10ToV11 = {
        migrateSchema: async (_, tx) => {
            await tx `DROP INDEX IF EXISTS ${tx(schema)}.desires_expires_at`;
            await tx `ALTER TABLE ${tx(schema)}.desires DROP COLUMN "expiresAt"`;
            await tx `DROP INDEX IF EXISTS ${tx(schema)}.client_patch_version`;
            await tx `ALTER TABLE ${tx(schema)}.clients DROP COLUMN "patchVersion"`;
            await tx `ALTER TABLE ${tx(schema)}.clients DROP COLUMN "deleted"`;
        },
    };
    const migratedV11ToV12 = {
        migrateSchema: async (_, tx) => {
            await tx `ALTER TABLE ${tx(schema)}.queries ALTER COLUMN "queryArgs" TYPE JSON USING "queryArgs"::JSON`;
        },
    };
    const migratedV12ToV13 = {
        migrateSchema: async (_, tx) => {
            await tx `ALTER TABLE ${tx(schema)}.instances ADD COLUMN "ttlClock" DOUBLE PRECISION NOT NULL DEFAULT 0`;
        },
    };
    const migratedV13ToV14 = {
        migrateSchema: async (_, sql) => {
            await sql `
        CREATE INDEX instances_last_active ON ${sql(schema)}.instances ("lastActive");
      `;
            // Update / add foreign key constraints to cascade deletes.
            for (const [table, reference] of [
                ['clients', 'instances'],
                ['queries', 'instances'],
                ['rows', 'rowsVersion'],
            ]) {
                const constraint = sql(`fk_${table}_client_group`);
                await sql `
          ALTER TABLE ${sql(schema)}.${sql(table)} DROP CONSTRAINT IF EXISTS ${constraint}`;
                await sql `
          ALTER TABLE ${sql(schema)}.${sql(table)} ADD CONSTRAINT ${constraint}
            FOREIGN KEY("clientGroupID")
            REFERENCES ${sql(schema)}.${sql(reference)} ("clientGroupID")
            ON DELETE CASCADE;
        `;
            }
        },
    };
    const schemaVersionMigrationMap = {
        2: migrateV1toV2,
        3: migrateV2ToV3,
        4: migrateV3ToV4,
        // v5 enables asynchronous row-record flushing, and thus relies on
        // the logic that updates and checks the rowsVersion table in v3.
        5: { minSafeVersion: 3 },
        6: migrateV5ToV6,
        7: migrateV6ToV7,
        8: migrateV7ToV8,
        9: migrateV8ToV9,
        // v10 adds queryName and queryArgs to the queries table to support
        // custom queries. clientAST is now optional to support migrating
        // off client queries.
        10: migrateV9ToV10,
        // V11 removes the deprecated queries."expiresAt", clients."patchVersion",
        // clients."deleted" columns.
        11: migrateV10ToV11,
        12: migratedV11ToV12,
        // V13 adds instances."ttlClock"
        13: migratedV12ToV13,
        // V14 adds an index on instances."lastActive" and a FK constraint
        // from rows."clientGroupID" to rowsVersion."clientGroupID" for
        // garbage collection
        14: migratedV13ToV14,
    };
    await runSchemaMigrations(log, 'view-syncer', cvrSchema(shard), db, setupMigration, schemaVersionMigrationMap);
}
//# sourceMappingURL=init.js.map