From 1058b3a517ab7ac5202a9159365bb3de806fbfa1 Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Sat, 14 Sep 2024 07:29:59 -0400 Subject: [PATCH 01/33] run custom db reset in cleanupDb --- tests/db-utils.ts | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index b9bed247..ffd772fe 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -120,15 +120,42 @@ export async function cleanupDb(prisma: PrismaClient) { { name: string }[] >`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '_prisma_migrations';` + const migrationPaths = fs + .readdirSync('prisma/migrations') + .filter((dir) => dir !== 'migration_lock.toml') + .map((dir) => `prisma/migrations/${dir}/migration.sql`) + + const migrations = migrationPaths.map((path) => { + // Parse the sql into individual statements + const sql = fs + .readFileSync(path) + .toString() + .split(';') + .map((statement) => (statement += ';')) + + // Remove empty last line + sql.pop() + + return sql + }) + try { // Disable FK constraints to avoid relation conflicts during deletion await prisma.$executeRawUnsafe(`PRAGMA foreign_keys = OFF`) await prisma.$transaction([ - // Delete all rows from each table, preserving table structures + // Delete all tables except the ones that are excluded above ...tables.map(({ name }) => - prisma.$executeRawUnsafe(`DELETE from "${name}"`), + prisma.$executeRawUnsafe(`DROP TABLE "${name}"`), ), ]) + + // Run the migrations sequentially + for (const migration of migrations) { + await prisma.$transaction([ + // Run each sql statement in the migration + ...migration.map((sql) => prisma.$executeRawUnsafe(sql)), + ]) + } } catch (error) { console.error('Error cleaning up database:', error) } finally { From 0fa8a200c7a78b7276b2362debfdf95135834f43 Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Fri, 30 Aug 2024 14:33:56 +0200 Subject: [PATCH 02/33] reset test db with prisma reset reset test db with prisma reset reset test db with prisma reset use custom db reset in `cleanupDb` use ; instead of ); for end of sql splitting reset test db with prisma reset use custom db reset in `cleanupDb` use ; instead of ); for end of sql splitting run prisma reset between tests reset test db with prisma reset use custom db reset in `cleanupDb` use ; instead of ); for end of sql splitting run prisma reset between tests use prisma reset for seeding add instructions for customising Role and Permission seeds --- .../20230914194400_init/migration.sql | 49 ++++++++++++++- prisma/seed.ts | 45 +------------- tests/db-utils.ts | 60 +++++-------------- tests/setup/db-setup.ts | 8 +-- tests/setup/global-setup.ts | 13 +--- 5 files changed, 68 insertions(+), 107 deletions(-) diff --git a/prisma/migrations/20230914194400_init/migration.sql b/prisma/migrations/20230914194400_init/migration.sql index 6349954e..5ee0147e 100644 --- a/prisma/migrations/20230914194400_init/migration.sql +++ b/prisma/migrations/20230914194400_init/migration.sql @@ -173,6 +173,53 @@ CREATE INDEX "_RoleToUser_B_index" ON "_RoleToUser"("B"); -- Hey there, Kent here! This is how you can reliably seed your database with -- some data. You edit the migration.sql file and that will handle it for you. +-- The user Roles and Permissions are seeded here. +-- If you'd like to customise roles and permissions, you can edit and add the code below to your `prisma/seed.ts` file. +-- Seed your development database with `npx prisma db seed` +-- Create a sql dump of your database with `sqlite3 prisma/data.db .dump > seed.sql` +-- Replace the SQL below with your new Roles & Permissions related SQL from `seed.sql` + +-- console.time('๐Ÿ”‘ Created permissions...') +-- const entities = ['user', 'note'] +-- const actions = ['create', 'read', 'update', 'delete'] +-- const accesses = ['own', 'any'] as const + +-- let permissionsToCreate = [] +-- for (const entity of entities) { +-- for (const action of actions) { +-- for (const access of accesses) { +-- permissionsToCreate.push({ entity, action, access }) +-- } +-- } +-- } +-- await prisma.permission.createMany({ data: permissionsToCreate }) +-- console.timeEnd('๐Ÿ”‘ Created permissions...') + +-- console.time('๐Ÿ‘‘ Created roles...') +-- await prisma.role.create({ +-- data: { +-- name: 'admin', +-- permissions: { +-- connect: await prisma.permission.findMany({ +-- select: { id: true }, +-- where: { access: 'any' }, +-- }), +-- }, +-- }, +-- }) +-- await prisma.role.create({ +-- data: { +-- name: 'user', +-- permissions: { +-- connect: await prisma.permission.findMany({ +-- select: { id: true }, +-- where: { access: 'own' }, +-- }), +-- }, +-- }, +-- }) +-- console.timeEnd('๐Ÿ‘‘ Created roles...') + INSERT INTO Permission VALUES('clnf2zvli0000pcou3zzzzome','create','user','own','',1696625465526,1696625465526); INSERT INTO Permission VALUES('clnf2zvll0001pcouly1310ku','create','user','any','',1696625465529,1696625465529); INSERT INTO Permission VALUES('clnf2zvll0002pcouka7348re','read','user','own','',1696625465530,1696625465530); @@ -208,4 +255,4 @@ INSERT INTO _PermissionToRole VALUES('clnf2zvlo0006pcouyoptc5jp','clnf2zvlx000hp INSERT INTO _PermissionToRole VALUES('clnf2zvlp0008pcou9r0fhbm8','clnf2zvlx000hpcou5dfrbegs'); INSERT INTO _PermissionToRole VALUES('clnf2zvlq000apcouxnspejs9','clnf2zvlx000hpcou5dfrbegs'); INSERT INTO _PermissionToRole VALUES('clnf2zvlr000cpcouy1vp6oeg','clnf2zvlx000hpcou5dfrbegs'); -INSERT INTO _PermissionToRole VALUES('clnf2zvls000epcou4ts5ui8f','clnf2zvlx000hpcou5dfrbegs'); \ No newline at end of file +INSERT INTO _PermissionToRole VALUES('clnf2zvls000epcou4ts5ui8f','clnf2zvlx000hpcou5dfrbegs'); diff --git a/prisma/seed.ts b/prisma/seed.ts index 9f29df1f..5c59bd63 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -3,12 +3,12 @@ import { promiseHash } from 'remix-utils/promise' import { prisma } from '#app/utils/db.server.ts' import { MOCK_CODE_GITHUB } from '#app/utils/providers/constants' import { - cleanupDb, createPassword, createUser, getNoteImages, getUserImages, img, + resetDb, } from '#tests/db-utils.ts' import { insertGitHubUser } from '#tests/mocks/github.ts' @@ -17,50 +17,9 @@ async function seed() { console.time(`๐ŸŒฑ Database has been seeded`) console.time('๐Ÿงน Cleaned up the database...') - await cleanupDb(prisma) + await resetDb() console.timeEnd('๐Ÿงน Cleaned up the database...') - console.time('๐Ÿ”‘ Created permissions...') - const entities = ['user', 'note'] - const actions = ['create', 'read', 'update', 'delete'] - const accesses = ['own', 'any'] as const - - let permissionsToCreate = [] - for (const entity of entities) { - for (const action of actions) { - for (const access of accesses) { - permissionsToCreate.push({ entity, action, access }) - } - } - } - await prisma.permission.createMany({ data: permissionsToCreate }) - console.timeEnd('๐Ÿ”‘ Created permissions...') - - console.time('๐Ÿ‘‘ Created roles...') - await prisma.role.create({ - data: { - name: 'admin', - permissions: { - connect: await prisma.permission.findMany({ - select: { id: true }, - where: { access: 'any' }, - }), - }, - }, - }) - await prisma.role.create({ - data: { - name: 'user', - permissions: { - connect: await prisma.permission.findMany({ - select: { id: true }, - where: { access: 'own' }, - }), - }, - }, - }) - console.timeEnd('๐Ÿ‘‘ Created roles...') - const totalUsers = 5 console.time(`๐Ÿ‘ค Created ${totalUsers} users...`) const noteImages = await getNoteImages() diff --git a/tests/db-utils.ts b/tests/db-utils.ts index ffd772fe..0841c9cb 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -3,6 +3,7 @@ import { faker } from '@faker-js/faker' import { type PrismaClient } from '@prisma/client' import bcrypt from 'bcryptjs' import { UniqueEnforcer } from 'enforce-unique' +import { execaCommand } from 'execa' const uniqueUsernameEnforcer = new UniqueEnforcer() @@ -115,50 +116,17 @@ export async function img({ } } -export async function cleanupDb(prisma: PrismaClient) { - const tables = await prisma.$queryRaw< - { name: string }[] - >`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '_prisma_migrations';` - - const migrationPaths = fs - .readdirSync('prisma/migrations') - .filter((dir) => dir !== 'migration_lock.toml') - .map((dir) => `prisma/migrations/${dir}/migration.sql`) - - const migrations = migrationPaths.map((path) => { - // Parse the sql into individual statements - const sql = fs - .readFileSync(path) - .toString() - .split(';') - .map((statement) => (statement += ';')) - - // Remove empty last line - sql.pop() - - return sql - }) - - try { - // Disable FK constraints to avoid relation conflicts during deletion - await prisma.$executeRawUnsafe(`PRAGMA foreign_keys = OFF`) - await prisma.$transaction([ - // Delete all tables except the ones that are excluded above - ...tables.map(({ name }) => - prisma.$executeRawUnsafe(`DROP TABLE "${name}"`), - ), - ]) - - // Run the migrations sequentially - for (const migration of migrations) { - await prisma.$transaction([ - // Run each sql statement in the migration - ...migration.map((sql) => prisma.$executeRawUnsafe(sql)), - ]) - } - } catch (error) { - console.error('Error cleaning up database:', error) - } finally { - await prisma.$executeRawUnsafe(`PRAGMA foreign_keys = ON`) - } +export async function resetDb(dbPath?: string) { + const databaseUrl = dbPath ? { DATABASE_URL: `file:${dbPath}` } : {} + + await execaCommand( + 'npx prisma migrate reset --force --skip-seed --skip-generate', + { + stdio: 'inherit', + env: { + ...process.env, + ...databaseUrl, + }, + }, + ) } diff --git a/tests/setup/db-setup.ts b/tests/setup/db-setup.ts index ea66e14b..9e71d20c 100644 --- a/tests/setup/db-setup.ts +++ b/tests/setup/db-setup.ts @@ -1,8 +1,7 @@ import path from 'node:path' import fsExtra from 'fs-extra' import { afterAll, afterEach, beforeAll } from 'vitest' -import { cleanupDb } from '#tests/db-utils.ts' -import { BASE_DATABASE_PATH } from './global-setup.ts' +import { BASE_DATABASE_PATH, setup } from './global-setup.ts' const databaseFile = `./tests/prisma/data.${process.env.VITEST_POOL_ID || 0}.db` const databasePath = path.join(process.cwd(), databaseFile) @@ -12,11 +11,8 @@ beforeAll(async () => { await fsExtra.copyFile(BASE_DATABASE_PATH, databasePath) }) -// we *must* use dynamic imports here so the process.env.DATABASE_URL is set -// before prisma is imported and initialized afterEach(async () => { - const { prisma } = await import('#app/utils/db.server.ts') - await cleanupDb(prisma) + await setup() }) afterAll(async () => { diff --git a/tests/setup/global-setup.ts b/tests/setup/global-setup.ts index af7fe31e..6ec2745e 100644 --- a/tests/setup/global-setup.ts +++ b/tests/setup/global-setup.ts @@ -1,6 +1,6 @@ import path from 'node:path' -import { execaCommand } from 'execa' import fsExtra from 'fs-extra' +import { resetDb } from '#tests/db-utils.js' export const BASE_DATABASE_PATH = path.join( process.cwd(), @@ -22,14 +22,5 @@ export async function setup() { } } - await execaCommand( - 'npx prisma migrate reset --force --skip-seed --skip-generate', - { - stdio: 'inherit', - env: { - ...process.env, - DATABASE_URL: `file:${BASE_DATABASE_PATH}`, - }, - }, - ) + await resetDb(BASE_DATABASE_PATH) } From ee9ec4ea6e09dbd5b8ca6feb36dde04ddcda1bf8 Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Mon, 23 Sep 2024 12:50:01 +0200 Subject: [PATCH 03/33] run prisma reset via spawn --- tests/db-utils.ts | 9 ++++----- tests/setup/db-setup.ts | 5 +++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index 0841c9cb..12967031 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -1,9 +1,8 @@ +import { spawnSync } from 'node:child_process' import fs from 'node:fs' import { faker } from '@faker-js/faker' -import { type PrismaClient } from '@prisma/client' import bcrypt from 'bcryptjs' import { UniqueEnforcer } from 'enforce-unique' -import { execaCommand } from 'execa' const uniqueUsernameEnforcer = new UniqueEnforcer() @@ -119,10 +118,10 @@ export async function img({ export async function resetDb(dbPath?: string) { const databaseUrl = dbPath ? { DATABASE_URL: `file:${dbPath}` } : {} - await execaCommand( - 'npx prisma migrate reset --force --skip-seed --skip-generate', + spawnSync( + 'npx', + ['prisma', 'migrate', 'reset', '--force', '--skip-seed', '--skip-generate'], { - stdio: 'inherit', env: { ...process.env, ...databaseUrl, diff --git a/tests/setup/db-setup.ts b/tests/setup/db-setup.ts index 9e71d20c..f44bc7cc 100644 --- a/tests/setup/db-setup.ts +++ b/tests/setup/db-setup.ts @@ -1,7 +1,8 @@ import path from 'node:path' import fsExtra from 'fs-extra' import { afterAll, afterEach, beforeAll } from 'vitest' -import { BASE_DATABASE_PATH, setup } from './global-setup.ts' +import { resetDb } from '#tests/db-utils.js' +import { BASE_DATABASE_PATH } from './global-setup.ts' const databaseFile = `./tests/prisma/data.${process.env.VITEST_POOL_ID || 0}.db` const databasePath = path.join(process.cwd(), databaseFile) @@ -12,7 +13,7 @@ beforeAll(async () => { }) afterEach(async () => { - await setup() + await resetDb() }) afterAll(async () => { From d5afca72713e54d6959ce2538824c6c861252463 Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Tue, 24 Sep 2024 09:57:42 +0200 Subject: [PATCH 04/33] use custom db reset --- prisma/seed.ts | 4 +-- tests/db-utils.ts | 61 ++++++++++++++++++++++++++++--------- tests/setup/db-setup.ts | 7 +++-- tests/setup/global-setup.ts | 13 ++++++-- 4 files changed, 65 insertions(+), 20 deletions(-) diff --git a/prisma/seed.ts b/prisma/seed.ts index 5c59bd63..d86f25b7 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -3,12 +3,12 @@ import { promiseHash } from 'remix-utils/promise' import { prisma } from '#app/utils/db.server.ts' import { MOCK_CODE_GITHUB } from '#app/utils/providers/constants' import { + cleanupDb, createPassword, createUser, getNoteImages, getUserImages, img, - resetDb, } from '#tests/db-utils.ts' import { insertGitHubUser } from '#tests/mocks/github.ts' @@ -17,7 +17,7 @@ async function seed() { console.time(`๐ŸŒฑ Database has been seeded`) console.time('๐Ÿงน Cleaned up the database...') - await resetDb() + await cleanupDb(prisma) console.timeEnd('๐Ÿงน Cleaned up the database...') const totalUsers = 5 diff --git a/tests/db-utils.ts b/tests/db-utils.ts index 12967031..ffd772fe 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -1,6 +1,6 @@ -import { spawnSync } from 'node:child_process' import fs from 'node:fs' import { faker } from '@faker-js/faker' +import { type PrismaClient } from '@prisma/client' import bcrypt from 'bcryptjs' import { UniqueEnforcer } from 'enforce-unique' @@ -115,17 +115,50 @@ export async function img({ } } -export async function resetDb(dbPath?: string) { - const databaseUrl = dbPath ? { DATABASE_URL: `file:${dbPath}` } : {} - - spawnSync( - 'npx', - ['prisma', 'migrate', 'reset', '--force', '--skip-seed', '--skip-generate'], - { - env: { - ...process.env, - ...databaseUrl, - }, - }, - ) +export async function cleanupDb(prisma: PrismaClient) { + const tables = await prisma.$queryRaw< + { name: string }[] + >`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '_prisma_migrations';` + + const migrationPaths = fs + .readdirSync('prisma/migrations') + .filter((dir) => dir !== 'migration_lock.toml') + .map((dir) => `prisma/migrations/${dir}/migration.sql`) + + const migrations = migrationPaths.map((path) => { + // Parse the sql into individual statements + const sql = fs + .readFileSync(path) + .toString() + .split(';') + .map((statement) => (statement += ';')) + + // Remove empty last line + sql.pop() + + return sql + }) + + try { + // Disable FK constraints to avoid relation conflicts during deletion + await prisma.$executeRawUnsafe(`PRAGMA foreign_keys = OFF`) + await prisma.$transaction([ + // Delete all tables except the ones that are excluded above + ...tables.map(({ name }) => + prisma.$executeRawUnsafe(`DROP TABLE "${name}"`), + ), + ]) + + // Run the migrations sequentially + for (const migration of migrations) { + await prisma.$transaction([ + // Run each sql statement in the migration + ...migration.map((sql) => prisma.$executeRawUnsafe(sql)), + ]) + } + } catch (error) { + console.error('Error cleaning up database:', error) + } finally { + await prisma.$executeRawUnsafe(`PRAGMA foreign_keys = ON`) + } } diff --git a/tests/setup/db-setup.ts b/tests/setup/db-setup.ts index f44bc7cc..ea66e14b 100644 --- a/tests/setup/db-setup.ts +++ b/tests/setup/db-setup.ts @@ -1,7 +1,7 @@ import path from 'node:path' import fsExtra from 'fs-extra' import { afterAll, afterEach, beforeAll } from 'vitest' -import { resetDb } from '#tests/db-utils.js' +import { cleanupDb } from '#tests/db-utils.ts' import { BASE_DATABASE_PATH } from './global-setup.ts' const databaseFile = `./tests/prisma/data.${process.env.VITEST_POOL_ID || 0}.db` @@ -12,8 +12,11 @@ beforeAll(async () => { await fsExtra.copyFile(BASE_DATABASE_PATH, databasePath) }) +// we *must* use dynamic imports here so the process.env.DATABASE_URL is set +// before prisma is imported and initialized afterEach(async () => { - await resetDb() + const { prisma } = await import('#app/utils/db.server.ts') + await cleanupDb(prisma) }) afterAll(async () => { diff --git a/tests/setup/global-setup.ts b/tests/setup/global-setup.ts index 6ec2745e..af7fe31e 100644 --- a/tests/setup/global-setup.ts +++ b/tests/setup/global-setup.ts @@ -1,6 +1,6 @@ import path from 'node:path' +import { execaCommand } from 'execa' import fsExtra from 'fs-extra' -import { resetDb } from '#tests/db-utils.js' export const BASE_DATABASE_PATH = path.join( process.cwd(), @@ -22,5 +22,14 @@ export async function setup() { } } - await resetDb(BASE_DATABASE_PATH) + await execaCommand( + 'npx prisma migrate reset --force --skip-seed --skip-generate', + { + stdio: 'inherit', + env: { + ...process.env, + DATABASE_URL: `file:${BASE_DATABASE_PATH}`, + }, + }, + ) } From 6bf0771525271fc21a93897ef4ab6605e9c27fb2 Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Tue, 24 Sep 2024 17:53:58 -0600 Subject: [PATCH 05/33] Update tests/db-utils.ts --- tests/db-utils.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index ffd772fe..738dab15 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -131,10 +131,9 @@ export async function cleanupDb(prisma: PrismaClient) { .readFileSync(path) .toString() .split(';') - .map((statement) => (statement += ';')) - - // Remove empty last line - sql.pop() + .map(statement => statement.trim()) + .filter(Boolean) + .map((statement) => `${statement};`)) return sql }) From 7cc50fd8966d5e4721a2dd2d4796780ac93f6596 Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Tue, 24 Sep 2024 17:54:38 -0600 Subject: [PATCH 06/33] Update prisma/migrations/20230914194400_init/migration.sql --- prisma/migrations/20230914194400_init/migration.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/prisma/migrations/20230914194400_init/migration.sql b/prisma/migrations/20230914194400_init/migration.sql index 5ee0147e..c9845c52 100644 --- a/prisma/migrations/20230914194400_init/migration.sql +++ b/prisma/migrations/20230914194400_init/migration.sql @@ -256,3 +256,4 @@ INSERT INTO _PermissionToRole VALUES('clnf2zvlp0008pcou9r0fhbm8','clnf2zvlx000hp INSERT INTO _PermissionToRole VALUES('clnf2zvlq000apcouxnspejs9','clnf2zvlx000hpcou5dfrbegs'); INSERT INTO _PermissionToRole VALUES('clnf2zvlr000cpcouy1vp6oeg','clnf2zvlx000hpcou5dfrbegs'); INSERT INTO _PermissionToRole VALUES('clnf2zvls000epcou4ts5ui8f','clnf2zvlx000hpcou5dfrbegs'); + From ac110c09413b118ed5ed73ddf5f6372636670528 Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Tue, 24 Sep 2024 17:55:22 -0600 Subject: [PATCH 07/33] remove extra line (whoops) --- prisma/migrations/20230914194400_init/migration.sql | 1 - 1 file changed, 1 deletion(-) diff --git a/prisma/migrations/20230914194400_init/migration.sql b/prisma/migrations/20230914194400_init/migration.sql index c9845c52..5ee0147e 100644 --- a/prisma/migrations/20230914194400_init/migration.sql +++ b/prisma/migrations/20230914194400_init/migration.sql @@ -256,4 +256,3 @@ INSERT INTO _PermissionToRole VALUES('clnf2zvlp0008pcou9r0fhbm8','clnf2zvlx000hp INSERT INTO _PermissionToRole VALUES('clnf2zvlq000apcouxnspejs9','clnf2zvlx000hpcou5dfrbegs'); INSERT INTO _PermissionToRole VALUES('clnf2zvlr000cpcouy1vp6oeg','clnf2zvlx000hpcou5dfrbegs'); INSERT INTO _PermissionToRole VALUES('clnf2zvls000epcou4ts5ui8f','clnf2zvlx000hpcou5dfrbegs'); - From 99af7cd365292a72778f0ba60b672754111e40cb Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Tue, 24 Sep 2024 17:56:17 -0600 Subject: [PATCH 08/33] whoops --- tests/db-utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index 738dab15..4ae5fd46 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -131,9 +131,9 @@ export async function cleanupDb(prisma: PrismaClient) { .readFileSync(path) .toString() .split(';') - .map(statement => statement.trim()) + .map((statement) => statement.trim()) .filter(Boolean) - .map((statement) => `${statement};`)) + .map((statement) => `${statement};`) return sql }) From 8d2be4c25c1fba36d6828b6a505067bc4cdee908 Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Wed, 25 Sep 2024 14:28:02 +0200 Subject: [PATCH 09/33] improve error logging --- tests/db-utils.ts | 59 ++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index 4ae5fd46..e1e2fd37 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -120,40 +120,37 @@ export async function cleanupDb(prisma: PrismaClient) { { name: string }[] >`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '_prisma_migrations';` - const migrationPaths = fs - .readdirSync('prisma/migrations') - .filter((dir) => dir !== 'migration_lock.toml') - .map((dir) => `prisma/migrations/${dir}/migration.sql`) - - const migrations = migrationPaths.map((path) => { - // Parse the sql into individual statements - const sql = fs - .readFileSync(path) - .toString() - .split(';') - .map((statement) => statement.trim()) - .filter(Boolean) - .map((statement) => `${statement};`) - - return sql - }) - try { // Disable FK constraints to avoid relation conflicts during deletion await prisma.$executeRawUnsafe(`PRAGMA foreign_keys = OFF`) - await prisma.$transaction([ - // Delete all tables except the ones that are excluded above - ...tables.map(({ name }) => - prisma.$executeRawUnsafe(`DROP TABLE "${name}"`), - ), - ]) - - // Run the migrations sequentially - for (const migration of migrations) { - await prisma.$transaction([ - // Run each sql statement in the migration - ...migration.map((sql) => prisma.$executeRawUnsafe(sql)), - ]) + + // Delete tables except the ones that are excluded above + for (const { name } of tables) { + await prisma.$executeRawUnsafe(`DROP TABLE IF EXISTS "${name}"`) + } + + const migrationPaths = fs + .readdirSync('prisma/migrations') + .filter((dir) => dir !== 'migration_lock.toml') + .map((dir) => `prisma/migrations/${dir}/migration.sql`) + + // Run each migration + for (const path of migrationPaths) { + const sql = fs.readFileSync(path, 'utf8') + const statements = sql + .split(';') + .map((statement) => statement.trim()) + .filter(Boolean) + + // Run each sql statement in the migration + for (const statement of statements) { + try { + await prisma.$executeRawUnsafe(`${statement};`) + } catch (error) { + console.warn(`Failed to execute statement: ${statement}`, error) + // Continue with the next statement + } + } } } catch (error) { console.error('Error cleaning up database:', error) From c142a92e27056ac20b86e2cbab31cb778cd804e6 Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Wed, 25 Sep 2024 14:35:04 -0600 Subject: [PATCH 10/33] Update tests/db-utils.ts --- tests/db-utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index e1e2fd37..fbeef4ef 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -147,8 +147,8 @@ export async function cleanupDb(prisma: PrismaClient) { try { await prisma.$executeRawUnsafe(`${statement};`) } catch (error) { - console.warn(`Failed to execute statement: ${statement}`, error) - // Continue with the next statement + console.warn(`Failed to execute statement: ${statement}`) + throw error } } } From 17686c90902e321f6669885e8b1157098a06d4f0 Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Thu, 26 Sep 2024 18:15:40 +0200 Subject: [PATCH 11/33] log failed statement as error --- tests/db-utils.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index fbeef4ef..bb7818f9 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -147,8 +147,7 @@ export async function cleanupDb(prisma: PrismaClient) { try { await prisma.$executeRawUnsafe(`${statement};`) } catch (error) { - console.warn(`Failed to execute statement: ${statement}`) - throw error + console.error(`Failed to execute statement: ${statement}`, error) } } } From 9fae58594222b99f338a14af1513836f7a3ef1a7 Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Thu, 26 Sep 2024 18:19:35 +0200 Subject: [PATCH 12/33] trigger CI rerun --- tests/db-utils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index bb7818f9..aed4804a 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -147,6 +147,7 @@ export async function cleanupDb(prisma: PrismaClient) { try { await prisma.$executeRawUnsafe(`${statement};`) } catch (error) { + //trigger CI rerun console.error(`Failed to execute statement: ${statement}`, error) } } From 63c021a91ea90ee7e2057930ce88dd00b2ce44be Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Thu, 26 Sep 2024 18:21:46 +0200 Subject: [PATCH 13/33] throw error again --- tests/db-utils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index aed4804a..991bad27 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -149,6 +149,7 @@ export async function cleanupDb(prisma: PrismaClient) { } catch (error) { //trigger CI rerun console.error(`Failed to execute statement: ${statement}`, error) + throw error } } } From c117336200febaac69f483f0f41bf255e95a5951 Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Thu, 26 Sep 2024 19:25:15 +0200 Subject: [PATCH 14/33] trigger rerun again --- tests/db-utils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index 991bad27..8063ed39 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -147,7 +147,6 @@ export async function cleanupDb(prisma: PrismaClient) { try { await prisma.$executeRawUnsafe(`${statement};`) } catch (error) { - //trigger CI rerun console.error(`Failed to execute statement: ${statement}`, error) throw error } From 2db09180c8ba7af6c04f11d8fab24d573bf68a0b Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Thu, 26 Sep 2024 19:34:14 +0200 Subject: [PATCH 15/33] one more time --- tests/db-utils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index 8063ed39..991bad27 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -147,6 +147,7 @@ export async function cleanupDb(prisma: PrismaClient) { try { await prisma.$executeRawUnsafe(`${statement};`) } catch (error) { + //trigger CI rerun console.error(`Failed to execute statement: ${statement}`, error) throw error } From 03edf6cf807646d7f7d4810fa0a152c177464ba9 Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Thu, 26 Sep 2024 19:36:13 +0200 Subject: [PATCH 16/33] and again --- tests/db-utils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index 991bad27..8063ed39 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -147,7 +147,6 @@ export async function cleanupDb(prisma: PrismaClient) { try { await prisma.$executeRawUnsafe(`${statement};`) } catch (error) { - //trigger CI rerun console.error(`Failed to execute statement: ${statement}`, error) throw error } From 55b795025c7e278502d2ceddf0956f688607b23a Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Thu, 26 Sep 2024 19:45:16 +0200 Subject: [PATCH 17/33] use console.warn again --- tests/db-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index 8063ed39..fbeef4ef 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -147,7 +147,7 @@ export async function cleanupDb(prisma: PrismaClient) { try { await prisma.$executeRawUnsafe(`${statement};`) } catch (error) { - console.error(`Failed to execute statement: ${statement}`, error) + console.warn(`Failed to execute statement: ${statement}`) throw error } } From 50490e43466b573e592f85839309ef358afdb863 Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Thu, 26 Sep 2024 19:53:51 +0200 Subject: [PATCH 18/33] retrigger --- tests/db-utils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index fbeef4ef..6dee2f82 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -145,6 +145,7 @@ export async function cleanupDb(prisma: PrismaClient) { // Run each sql statement in the migration for (const statement of statements) { try { + //trigger CI await prisma.$executeRawUnsafe(`${statement};`) } catch (error) { console.warn(`Failed to execute statement: ${statement}`) From 07444708ddbc7dd96057baa7a26d29e9d969a4cb Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Thu, 26 Sep 2024 19:55:25 +0200 Subject: [PATCH 19/33] retrigger --- tests/db-utils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index 6dee2f82..fbeef4ef 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -145,7 +145,6 @@ export async function cleanupDb(prisma: PrismaClient) { // Run each sql statement in the migration for (const statement of statements) { try { - //trigger CI await prisma.$executeRawUnsafe(`${statement};`) } catch (error) { console.warn(`Failed to execute statement: ${statement}`) From 112bd0df9376e555e3214cb6938c84ff191801ef Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Thu, 26 Sep 2024 19:57:44 +0200 Subject: [PATCH 20/33] retrigger --- tests/db-utils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index fbeef4ef..6dee2f82 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -145,6 +145,7 @@ export async function cleanupDb(prisma: PrismaClient) { // Run each sql statement in the migration for (const statement of statements) { try { + //trigger CI await prisma.$executeRawUnsafe(`${statement};`) } catch (error) { console.warn(`Failed to execute statement: ${statement}`) From 3fbaa7810ecdf61863bbbb930bf5af493a1f4eb7 Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Thu, 26 Sep 2024 20:07:02 +0200 Subject: [PATCH 21/33] remove trigger line --- tests/db-utils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index 6dee2f82..fbeef4ef 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -145,7 +145,6 @@ export async function cleanupDb(prisma: PrismaClient) { // Run each sql statement in the migration for (const statement of statements) { try { - //trigger CI await prisma.$executeRawUnsafe(`${statement};`) } catch (error) { console.warn(`Failed to execute statement: ${statement}`) From a411a4adf92be2490a8d7880885634ac8035650f Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Sat, 28 Sep 2024 09:53:56 +0200 Subject: [PATCH 22/33] Wrap statement execution in a transaction --- tests/db-utils.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index fbeef4ef..adc98025 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -143,14 +143,16 @@ export async function cleanupDb(prisma: PrismaClient) { .filter(Boolean) // Run each sql statement in the migration - for (const statement of statements) { - try { - await prisma.$executeRawUnsafe(`${statement};`) - } catch (error) { - console.warn(`Failed to execute statement: ${statement}`) - throw error + await prisma.$transaction(async (tx) => { + for (const statement of statements) { + try { + await tx.$executeRawUnsafe(`${statement}`) + } catch (error) { + console.warn(`Failed to execute statement: ${statement}`) + throw error + } } - } + }) } } catch (error) { console.error('Error cleaning up database:', error) From e27922752110cf7a5569f3b85b5b9d8f1f3081e6 Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Sat, 28 Sep 2024 10:06:45 +0200 Subject: [PATCH 23/33] Try map --- tests/db-utils.ts | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index adc98025..ea2a2417 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -125,9 +125,11 @@ export async function cleanupDb(prisma: PrismaClient) { await prisma.$executeRawUnsafe(`PRAGMA foreign_keys = OFF`) // Delete tables except the ones that are excluded above - for (const { name } of tables) { - await prisma.$executeRawUnsafe(`DROP TABLE IF EXISTS "${name}"`) - } + await prisma.$transaction([ + ...tables.map(({ name }) => + prisma.$executeRawUnsafe(`DROP TABLE IF EXISTS "${name}"`), + ), + ]) const migrationPaths = fs .readdirSync('prisma/migrations') @@ -143,16 +145,11 @@ export async function cleanupDb(prisma: PrismaClient) { .filter(Boolean) // Run each sql statement in the migration - await prisma.$transaction(async (tx) => { - for (const statement of statements) { - try { - await tx.$executeRawUnsafe(`${statement}`) - } catch (error) { - console.warn(`Failed to execute statement: ${statement}`) - throw error - } - } - }) + await prisma.$transaction([ + ...statements.map((statement) => + prisma.$executeRawUnsafe(`${statement}`), + ), + ]) } } catch (error) { console.error('Error cleaning up database:', error) From bdfb389965f1c975dc6c02f1a276e8b59fd2da1d Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Sat, 28 Sep 2024 10:42:10 +0200 Subject: [PATCH 24/33] explicitly set isolation level --- tests/db-utils.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index ea2a2417..c2b49493 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -1,6 +1,6 @@ import fs from 'node:fs' import { faker } from '@faker-js/faker' -import { type PrismaClient } from '@prisma/client' +import { Prisma, type PrismaClient } from '@prisma/client' import bcrypt from 'bcryptjs' import { UniqueEnforcer } from 'enforce-unique' @@ -145,11 +145,16 @@ export async function cleanupDb(prisma: PrismaClient) { .filter(Boolean) // Run each sql statement in the migration - await prisma.$transaction([ - ...statements.map((statement) => - prisma.$executeRawUnsafe(`${statement}`), - ), - ]) + await prisma.$transaction( + [ + ...statements.map((statement) => + prisma.$executeRawUnsafe(`${statement}`), + ), + ], + { + isolationLevel: Prisma.TransactionIsolationLevel.Serializable, + }, + ) } } catch (error) { console.error('Error cleaning up database:', error) From 8de38de81805f6d9de0f66e503226ed7ec642af7 Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Sat, 28 Sep 2024 10:45:01 +0200 Subject: [PATCH 25/33] retrigger --- tests/db-utils.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index c2b49493..cc297640 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -144,6 +144,8 @@ export async function cleanupDb(prisma: PrismaClient) { .map((statement) => statement.trim()) .filter(Boolean) + //trigger CI + // Run each sql statement in the migration await prisma.$transaction( [ From b3e5377ae45d710798da79cf9a524f1133e01067 Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Sat, 28 Sep 2024 10:48:41 +0200 Subject: [PATCH 26/33] retrigger --- tests/db-utils.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index cc297640..c2b49493 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -144,8 +144,6 @@ export async function cleanupDb(prisma: PrismaClient) { .map((statement) => statement.trim()) .filter(Boolean) - //trigger CI - // Run each sql statement in the migration await prisma.$transaction( [ From bfa6b99c77b680c9b775c53e9f4c3378c3665043 Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Sat, 28 Sep 2024 10:50:10 +0200 Subject: [PATCH 27/33] retrigger --- tests/db-utils.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index c2b49493..cc297640 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -144,6 +144,8 @@ export async function cleanupDb(prisma: PrismaClient) { .map((statement) => statement.trim()) .filter(Boolean) + //trigger CI + // Run each sql statement in the migration await prisma.$transaction( [ From eb2dd6016e87a6c4d22f4b480b95d3ff0132fcc1 Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Sat, 28 Sep 2024 10:52:16 +0200 Subject: [PATCH 28/33] retrigger --- tests/db-utils.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index cc297640..c2b49493 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -144,8 +144,6 @@ export async function cleanupDb(prisma: PrismaClient) { .map((statement) => statement.trim()) .filter(Boolean) - //trigger CI - // Run each sql statement in the migration await prisma.$transaction( [ From 1b0be2bffbecaa1f801987564ecb493ce5eed70f Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Sat, 28 Sep 2024 10:56:34 +0200 Subject: [PATCH 29/33] retrigger --- tests/db-utils.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index c2b49493..30506b7a 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -144,6 +144,8 @@ export async function cleanupDb(prisma: PrismaClient) { .map((statement) => statement.trim()) .filter(Boolean) + //trigger + // Run each sql statement in the migration await prisma.$transaction( [ From ccebfbf3848ac78aa85e2ec163b176f629789297 Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Sun, 29 Sep 2024 09:44:38 +0200 Subject: [PATCH 30/33] remove explicit isolation level config --- tests/db-utils.ts | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index 30506b7a..2dbe2eae 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -147,16 +147,11 @@ export async function cleanupDb(prisma: PrismaClient) { //trigger // Run each sql statement in the migration - await prisma.$transaction( - [ - ...statements.map((statement) => - prisma.$executeRawUnsafe(`${statement}`), - ), - ], - { - isolationLevel: Prisma.TransactionIsolationLevel.Serializable, - }, - ) + await prisma.$transaction([ + ...statements.map((statement) => + prisma.$executeRawUnsafe(`${statement}`), + ), + ]) } } catch (error) { console.error('Error cleaning up database:', error) From 39c270204a0b2217e6819b72317649d06f5812ba Mon Sep 17 00:00:00 2001 From: Devon Neill <35456245+devneill@users.noreply.github.com> Date: Mon, 30 Sep 2024 16:01:44 +0200 Subject: [PATCH 31/33] Remove unused import --- tests/db-utils.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index 2dbe2eae..ea2a2417 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -1,6 +1,6 @@ import fs from 'node:fs' import { faker } from '@faker-js/faker' -import { Prisma, type PrismaClient } from '@prisma/client' +import { type PrismaClient } from '@prisma/client' import bcrypt from 'bcryptjs' import { UniqueEnforcer } from 'enforce-unique' @@ -144,8 +144,6 @@ export async function cleanupDb(prisma: PrismaClient) { .map((statement) => statement.trim()) .filter(Boolean) - //trigger - // Run each sql statement in the migration await prisma.$transaction([ ...statements.map((statement) => From 3c975b99f4184c7548ee0c7e13ada89479051266 Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Mon, 30 Sep 2024 18:35:03 -0600 Subject: [PATCH 32/33] try switching to better-sqlite3 --- prisma/seed.ts | 2 +- tests/db-utils.ts | 81 +++++++++++++++++++++++++---------------- tests/setup/db-setup.ts | 3 +- 3 files changed, 52 insertions(+), 34 deletions(-) diff --git a/prisma/seed.ts b/prisma/seed.ts index d86f25b7..f38edef3 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -17,7 +17,7 @@ async function seed() { console.time(`๐ŸŒฑ Database has been seeded`) console.time('๐Ÿงน Cleaned up the database...') - await cleanupDb(prisma) + await cleanupDb() console.timeEnd('๐Ÿงน Cleaned up the database...') const totalUsers = 5 diff --git a/tests/db-utils.ts b/tests/db-utils.ts index ea2a2417..c261d327 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -2,6 +2,7 @@ import fs from 'node:fs' import { faker } from '@faker-js/faker' import { type PrismaClient } from '@prisma/client' import bcrypt from 'bcryptjs' +import Database from 'better-sqlite3' import { UniqueEnforcer } from 'enforce-unique' const uniqueUsernameEnforcer = new UniqueEnforcer() @@ -115,45 +116,63 @@ export async function img({ } } -export async function cleanupDb(prisma: PrismaClient) { - const tables = await prisma.$queryRaw< - { name: string }[] - >`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '_prisma_migrations';` +let _migrationSqls: Array> | undefined +async function getMigrationSqls() { + if (_migrationSqls) return _migrationSqls + + const migrationSqls: Array> = [] + const migrationPaths = (await fs.promises.readdir('prisma/migrations')) + .filter((dir) => dir !== 'migration_lock.toml') + .map((dir) => `prisma/migrations/${dir}/migration.sql`) + + for (const path of migrationPaths) { + const sql = await fs.promises.readFile(path, 'utf8') + const statements = sql + .split(';') + .map((statement) => statement.trim()) + .filter(Boolean) + migrationSqls.push(statements) + } + + _migrationSqls = migrationSqls + + return migrationSqls +} + +export async function cleanupDb() { + const db = new Database(process.env.DATABASE_URL!.replace('file:', '')) try { // Disable FK constraints to avoid relation conflicts during deletion - await prisma.$executeRawUnsafe(`PRAGMA foreign_keys = OFF`) + db.exec('PRAGMA foreign_keys = OFF') + + // Get all table names + const tables = db + .prepare( + ` + SELECT name FROM sqlite_master + WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '_prisma_migrations' + `, + ) + .all() as { name: string }[] // Delete tables except the ones that are excluded above - await prisma.$transaction([ - ...tables.map(({ name }) => - prisma.$executeRawUnsafe(`DROP TABLE IF EXISTS "${name}"`), - ), - ]) - - const migrationPaths = fs - .readdirSync('prisma/migrations') - .filter((dir) => dir !== 'migration_lock.toml') - .map((dir) => `prisma/migrations/${dir}/migration.sql`) - - // Run each migration - for (const path of migrationPaths) { - const sql = fs.readFileSync(path, 'utf8') - const statements = sql - .split(';') - .map((statement) => statement.trim()) - .filter(Boolean) + for (const { name } of tables) { + db.exec(`DROP TABLE IF EXISTS "${name}"`) + } + // Get migration SQLs and run each migration + const migrationSqls = await getMigrationSqls() + for (const statements of migrationSqls) { // Run each sql statement in the migration - await prisma.$transaction([ - ...statements.map((statement) => - prisma.$executeRawUnsafe(`${statement}`), - ), - ]) + db.transaction(() => { + for (const statement of statements) { + db.exec(statement) + } + })() } - } catch (error) { - console.error('Error cleaning up database:', error) } finally { - await prisma.$executeRawUnsafe(`PRAGMA foreign_keys = ON`) + db.exec('PRAGMA foreign_keys = ON') + db.close() } } diff --git a/tests/setup/db-setup.ts b/tests/setup/db-setup.ts index ea66e14b..4ddaa591 100644 --- a/tests/setup/db-setup.ts +++ b/tests/setup/db-setup.ts @@ -15,8 +15,7 @@ beforeAll(async () => { // we *must* use dynamic imports here so the process.env.DATABASE_URL is set // before prisma is imported and initialized afterEach(async () => { - const { prisma } = await import('#app/utils/db.server.ts') - await cleanupDb(prisma) + await cleanupDb() }) afterAll(async () => { From 4d9537b0eaec2e926abed1d3f52e5c83e3cdd471 Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Mon, 30 Sep 2024 18:35:17 -0600 Subject: [PATCH 33/33] lint issue --- tests/db-utils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/db-utils.ts b/tests/db-utils.ts index c261d327..5264125e 100644 --- a/tests/db-utils.ts +++ b/tests/db-utils.ts @@ -1,6 +1,5 @@ import fs from 'node:fs' import { faker } from '@faker-js/faker' -import { type PrismaClient } from '@prisma/client' import bcrypt from 'bcryptjs' import Database from 'better-sqlite3' import { UniqueEnforcer } from 'enforce-unique'