diff options
| author | Sebastien Castiel <sebastien@castiel.me> | 2023-12-08 14:56:51 -0500 |
|---|---|---|
| committer | Sebastien Castiel <sebastien@castiel.me> | 2023-12-08 14:56:51 -0500 |
| commit | 92a21ff4c5df6e9f771cfbd140835dce3b6d7b0d (patch) | |
| tree | 33f09b0069550f58e287a4e12a70f20ff1f50cea /src/scripts | |
| parent | 9cc819b0c900d82efb55b6bc8c9faa38d21c0197 (diff) | |
Migration script, improvements in expenses list
Diffstat (limited to 'src/scripts')
| -rw-r--r-- | src/scripts/migrate.ts | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/src/scripts/migrate.ts b/src/scripts/migrate.ts new file mode 100644 index 0000000..bf7d93c --- /dev/null +++ b/src/scripts/migrate.ts @@ -0,0 +1,130 @@ +// @ts-nocheck +import { randomId } from '@/lib/api' +import { getPrisma } from '@/lib/prisma' +import { Prisma } from '@prisma/client' +import { Client } from 'pg' + +process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0' + +async function main() { + withClient(async (client) => { + const prisma = await getPrisma() + + const { rows: groupRows } = await client.query<{ + id: string + name: string + currency: string + created_at: Date + }>('select id, name, currency, created_at from groups') + + for (const groupRow of groupRows) { + const participants: Prisma.ParticipantCreateManyInput[] = [] + const expenses: Prisma.ExpenseCreateManyInput[] = [] + const expenseParticipants: Prisma.ExpensePaidForCreateManyInput[] = [] + const participantIdsMapping: Record<number, string> = {} + const expenseIdsMapping: Record<number, string> = {} + + const existingGroup = await prisma.group.findUnique({ + where: { id: groupRow.id }, + }) + if (existingGroup) { + console.log(`Group ${groupRow.id} already exists, skipping.`) + continue + } + + const group: Prisma.GroupCreateInput = { + id: groupRow.id, + name: groupRow.name, + currency: groupRow.currency, + createdAt: groupRow.created_at, + } + + const { rows: participantRows } = await client.query<{ + id: number + created_at: Date + name: string + }>( + 'select id, created_at, name from participants where group_id = $1::text', + [groupRow.id], + ) + for (const participantRow of participantRows) { + const id = randomId() + participantIdsMapping[participantRow.id] = id + participants.push({ + id, + groupId: groupRow.id, + name: participantRow.name, + }) + } + + const { rows: expenseRows } = await client.query<{ + id: number + created_at: Date + description: string + amount: number + paid_by_participant_id: number + is_reimbursement: boolean + }>( + 'select id, created_at, description, amount, paid_by_participant_id, is_reimbursement from expenses where group_id = $1::text', + [groupRow.id], + ) + for (const expenseRow of expenseRows) { + const id = randomId() + expenseIdsMapping[expenseRow.id] = id + expenses.push({ + id, + amount: Math.round(expenseRow.amount * 100), + groupId: groupRow.id, + title: expenseRow.description, + createdAt: expenseRow.created_at, + isReimbursement: expenseRow.is_reimbursement === true, + paidById: participantIdsMapping[expenseRow.paid_by_participant_id], + }) + } + + if (expenseRows.length > 0) { + const { rows: expenseParticipantRows } = await client.query<{ + expense_id: number + participant_id: number + }>( + 'select expense_id, participant_id from expense_participants where expense_id = any($1::int[]);', + [expenseRows.map((row) => row.id)], + ) + for (const expenseParticipantRow of expenseParticipantRows) { + expenseParticipants.push({ + expenseId: expenseIdsMapping[expenseParticipantRow.expense_id], + participantId: + participantIdsMapping[expenseParticipantRow.participant_id], + }) + } + } + + console.log('Creating group:', group) + await prisma.group.create({ data: group }) + console.log('Creating participants:', participants) + await prisma.participant.createMany({ data: participants }) + console.log('Creating expenses:', expenses) + await prisma.expense.createMany({ data: expenses }) + console.log('Creating expenseParticipants:', expenseParticipants) + await prisma.expensePaidFor.createMany({ data: expenseParticipants }) + } + }) +} + +async function withClient(fn: (client: Client) => void | Promise<void>) { + const client = new Client({ + connectionString: process.env.OLD_POSTGRES_URL, + ssl: true, + }) + await client.connect() + console.log('Connected.') + + try { + await fn(client) + } finally { + await client.end() + console.log('Disconnected.') + } +} + +main().catch(console.error) |
