fix(stats): make unique users migration idempotent
This commit is contained in:
parent
233d065dd5
commit
6f0e934573
5 changed files with 31 additions and 4 deletions
2
.github/workflows/deploy.yml
vendored
2
.github/workflows/deploy.yml
vendored
|
|
@ -47,7 +47,7 @@ jobs:
|
||||||
VITE_SENTRY_DSN: ${{ vars.WEB_SENTRY_DSN }}
|
VITE_SENTRY_DSN: ${{ vars.WEB_SENTRY_DSN }}
|
||||||
VITE_SENTRY_RELEASE: web@${{ github.sha }}
|
VITE_SENTRY_RELEASE: web@${{ github.sha }}
|
||||||
|
|
||||||
- run: bun sst shell --stage=${{ github.ref_name }} -- bun run --cwd packages/stats/core db:migrate
|
- run: bun sst shell --stage=${{ github.ref_name }} -- bun run --cwd packages/stats/core db:ensure-unique-users
|
||||||
env:
|
env:
|
||||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||||
PLANETSCALE_SERVICE_TOKEN_NAME: ${{ secrets.PLANETSCALE_SERVICE_TOKEN_NAME }}
|
PLANETSCALE_SERVICE_TOKEN_NAME: ${{ secrets.PLANETSCALE_SERVICE_TOKEN_NAME }}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"db:generate": "drizzle-kit generate --config=drizzle.config.ts",
|
"db:generate": "drizzle-kit generate --config=drizzle.config.ts",
|
||||||
|
"db:ensure-unique-users": "bun src/ensure-unique-users.ts",
|
||||||
"db:migrate": "bun src/migrate.ts",
|
"db:migrate": "bun src/migrate.ts",
|
||||||
"db:push": "drizzle-kit push --config=drizzle.config.ts",
|
"db:push": "drizzle-kit push --config=drizzle.config.ts",
|
||||||
"db:studio": "drizzle-kit studio --config=drizzle.config.ts",
|
"db:studio": "drizzle-kit studio --config=drizzle.config.ts",
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ export type AthenaData = Record<string, string>
|
||||||
export class AthenaQueryError extends Schema.TaggedErrorClass<AthenaQueryError>()("AthenaQueryError", {
|
export class AthenaQueryError extends Schema.TaggedErrorClass<AthenaQueryError>()("AthenaQueryError", {
|
||||||
message: Schema.String,
|
message: Schema.String,
|
||||||
queryExecutionId: Schema.optional(Schema.String),
|
queryExecutionId: Schema.optional(Schema.String),
|
||||||
cause: Schema.optional(Schema.Defect()),
|
cause: Schema.optional(Schema.Defect),
|
||||||
}) {}
|
}) {}
|
||||||
|
|
||||||
export class AthenaQueryTimeoutError extends Schema.TaggedErrorClass<AthenaQueryTimeoutError>()(
|
export class AthenaQueryTimeoutError extends Schema.TaggedErrorClass<AthenaQueryTimeoutError>()(
|
||||||
|
|
|
||||||
|
|
@ -45,14 +45,14 @@ export class DrizzleClient extends Context.Service<DrizzleClient, Drizzle>()("@o
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DatabaseError extends Schema.TaggedErrorClass<DatabaseError>()("DatabaseError", {
|
export class DatabaseError extends Schema.TaggedErrorClass<DatabaseError>()("DatabaseError", {
|
||||||
cause: Schema.Defect(),
|
cause: Schema.Defect,
|
||||||
}) {}
|
}) {}
|
||||||
|
|
||||||
export const catchDbError = Effect.mapError((cause) => DatabaseError.make({ cause }))
|
export const catchDbError = Effect.mapError((cause) => DatabaseError.make({ cause }))
|
||||||
|
|
||||||
export class MigrationError extends Schema.TaggedErrorClass<MigrationError>()("MigrationError", {
|
export class MigrationError extends Schema.TaggedErrorClass<MigrationError>()("MigrationError", {
|
||||||
message: Schema.String,
|
message: Schema.String,
|
||||||
cause: Schema.optional(Schema.Defect()),
|
cause: Schema.optional(Schema.Defect),
|
||||||
}) {}
|
}) {}
|
||||||
|
|
||||||
export const migrate = Effect.fn("Database.migrate")(function* () {
|
export const migrate = Effect.fn("Database.migrate")(function* () {
|
||||||
|
|
|
||||||
26
packages/stats/core/src/ensure-unique-users.ts
Normal file
26
packages/stats/core/src/ensure-unique-users.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { Client } from "@planetscale/database"
|
||||||
|
import { Resource } from "sst/resource"
|
||||||
|
|
||||||
|
const tables = ["geo_stat", "model_stat", "provider_stat"] as const
|
||||||
|
|
||||||
|
const client = new Client({ url: Resource.StatsDatabase.url })
|
||||||
|
|
||||||
|
await tables.reduce(
|
||||||
|
(promise, table) => promise.then(() => ensureUniqueUsersColumn(table)),
|
||||||
|
Promise.resolve(),
|
||||||
|
)
|
||||||
|
|
||||||
|
async function ensureUniqueUsersColumn(table: (typeof tables)[number]) {
|
||||||
|
const result = await client.execute<{ column_name: string }>(
|
||||||
|
"SELECT column_name FROM information_schema.columns WHERE table_schema = database() AND table_name = ? AND column_name = 'unique_users'",
|
||||||
|
[table],
|
||||||
|
)
|
||||||
|
|
||||||
|
if (result.rows.length > 0) {
|
||||||
|
console.log(`unique_users column already exists on ${table}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await client.execute(`ALTER TABLE \`${table}\` ADD \`unique_users\` bigint NOT NULL DEFAULT 0`)
|
||||||
|
console.log(`added unique_users column to ${table}`)
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue