ensure-unique-users.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import { Client } from "@planetscale/database"
  2. import { Resource } from "sst/resource"
  3. const tables = ["geo_stat", "model_stat", "provider_stat"] as const
  4. const checkOnly = process.argv.includes("--check")
  5. const client = new Client({ url: databaseUrl() })
  6. const missing = await tables.reduce<Promise<(typeof tables)[number][]>>(async (promise, table) => {
  7. const result = await promise
  8. if (await hasUniqueUsersColumn(table)) {
  9. console.log(`unique_users column already exists on ${table}`)
  10. return result
  11. }
  12. return [...result, table]
  13. }, Promise.resolve([]))
  14. if (missing.length === 0) {
  15. console.log("unique_users columns complete")
  16. process.exit(0)
  17. }
  18. if (checkOnly) {
  19. console.log(`unique_users columns missing on ${missing.join(", ")}`)
  20. process.exit(1)
  21. }
  22. await missing.reduce((promise, table) => promise.then(() => addUniqueUsersColumn(table)), Promise.resolve())
  23. function databaseUrl() {
  24. if (
  25. process.env.PLANETSCALE_HOST &&
  26. process.env.PLANETSCALE_USERNAME &&
  27. process.env.PLANETSCALE_PASSWORD &&
  28. process.env.PLANETSCALE_DATABASE
  29. )
  30. return `mysql://${encodeURIComponent(process.env.PLANETSCALE_USERNAME)}:${encodeURIComponent(
  31. process.env.PLANETSCALE_PASSWORD,
  32. )}@${process.env.PLANETSCALE_HOST}/${process.env.PLANETSCALE_DATABASE}?ssl=${encodeURIComponent(
  33. JSON.stringify({ rejectUnauthorized: true }),
  34. )}`
  35. return process.env.DATABASE_URL ?? Resource.StatsDatabase.url
  36. }
  37. async function hasUniqueUsersColumn(table: (typeof tables)[number]) {
  38. const result = await client.execute<{ column_name: string }>(
  39. "SELECT column_name FROM information_schema.columns WHERE table_schema = database() AND table_name = ? AND column_name = 'unique_users'",
  40. [table],
  41. )
  42. return result.rows.length > 0
  43. }
  44. async function addUniqueUsersColumn(table: (typeof tables)[number]) {
  45. await client.execute(`ALTER TABLE \`${table}\` ADD \`unique_users\` bigint NOT NULL DEFAULT 0`)
  46. console.log(`added unique_users column to ${table}`)
  47. }