Files
meseo-staging/scripts/build-sessionid-index.mjs
Andres Resiri 70daeb214a
CI / Quality gate (push) Has been cancelled
Initial project commit for Coolify staging
2026-08-03 10:45:41 -04:00

79 lines
2.4 KiB
JavaScript

/**
* Builds the composite index SiteEvent_sessionId_timestamp_idx on the
* SiteEvent table using CREATE INDEX CONCURRENTLY.
*
* Must connect via the non-pooler (direct) Neon URL because:
* - CREATE INDEX CONCURRENTLY cannot run inside a transaction
* - The pooler enforces statement_timeout that overrides SET
*
* Usage:
* DIRECT_URL="postgres://..." node scripts/build-sessionid-index.mjs
*
* Never hardcode credentials here. Supply DIRECT_URL from the shell only.
*/
import pkg from "pg";
const { Client } = pkg;
const INDEX_NAME = "SiteEvent_sessionId_timestamp_idx";
const directUrl = process.env.DIRECT_URL;
if (!directUrl) {
console.error("[build-index] DIRECT_URL is not set. Aborting.");
process.exit(1);
}
const client = new Client({ connectionString: directUrl });
async function run() {
console.log("[build-index] Connecting via DIRECT_URL...");
await client.connect();
console.log("[build-index] Connected.");
console.log("[build-index] SET statement_timeout = 0");
await client.query("SET statement_timeout = 0;");
console.log("[build-index] SET lock_timeout = 0");
await client.query("SET lock_timeout = 0;");
console.log(`[build-index] DROP INDEX IF EXISTS "${INDEX_NAME}"`);
await client.query(`DROP INDEX IF EXISTS "${INDEX_NAME}";`);
console.log("[build-index] Drop complete (or index did not exist).");
console.log(`[build-index] CREATE INDEX CONCURRENTLY "${INDEX_NAME}" -- this may take several minutes on large tables`);
await client.query(
`CREATE INDEX CONCURRENTLY "${INDEX_NAME}" ON "public"."SiteEvent" ("sessionId", "timestamp");`,
);
console.log("[build-index] Index build complete.");
const res = await client.query(
`SELECT indisvalid
FROM pg_index
JOIN pg_class ON pg_class.oid = pg_index.indexrelid
WHERE pg_class.relname = $1;`,
[INDEX_NAME],
);
if (res.rows.length === 0) {
console.error("[build-index] Index not found after creation -- something went wrong.");
process.exit(1);
}
const { indisvalid } = res.rows[0];
if (indisvalid) {
console.log("[build-index] indisvalid = true -- index is VALID and ready.");
} else {
console.error("[build-index] indisvalid = false -- index is INVALID. Manual cleanup required.");
process.exit(1);
}
}
run()
.catch((err) => {
console.error("[build-index] Fatal error:", err.message);
process.exit(1);
})
.finally(() => {
client.end().catch(() => {});
});