diff --git a/apps/web/lib/folder.ts b/apps/web/lib/folder.ts index ed3273154..35ec3fcc2 100644 --- a/apps/web/lib/folder.ts +++ b/apps/web/lib/folder.ts @@ -22,7 +22,7 @@ export const getFolderById = Effect.fn(function* (folderId: string) { if (!folderId) throw new Error("Folder ID is required"); const db = yield* Database; - const [folder] = yield* db.execute((db) => + const [folder] = yield* db.use((db) => db .select() .from(folders) @@ -69,7 +69,7 @@ const getSharedSpacesForVideos = Effect.fn(function* ( const db = yield* Database; // Fetch space-level sharing - const spaceSharing = yield* db.execute((db) => + const spaceSharing = yield* db.use((db) => db .select({ videoId: spaceVideos.videoId, @@ -90,7 +90,7 @@ const getSharedSpacesForVideos = Effect.fn(function* ( ); // Fetch organization-level sharing - const orgSharing = yield* db.execute((db) => + const orgSharing = yield* db.use((db) => db .select({ videoId: sharedVideos.videoId, @@ -164,7 +164,7 @@ export const getVideosByFolderId = Effect.fn(function* ( if (!folderId) throw new Error("Folder ID is required"); const db = yield* Database; - const videoData = yield* db.execute((db) => + const videoData = yield* db.use((db) => db .select({ id: videos.id, @@ -287,7 +287,7 @@ export const getChildFolders = Effect.fn(function* ( const user = yield* CurrentUser; if (!user.activeOrganizationId) throw new Error("No active organization"); - const childFolders = yield* db.execute((db) => + const childFolders = yield* db.use((db) => db .select({ id: folders.id, diff --git a/packages/web-backend/src/Auth.ts b/packages/web-backend/src/Auth.ts index 5cdcb8b21..df27be4a3 100644 --- a/packages/web-backend/src/Auth.ts +++ b/packages/web-backend/src/Auth.ts @@ -19,7 +19,7 @@ export const getCurrentUser = Effect.gen(function* () { ).pipe( Option.map((session) => Effect.gen(function* () { - const [currentUser] = yield* db.execute((db) => + const [currentUser] = yield* db.use((db) => db .select() .from(Db.users) @@ -50,7 +50,7 @@ export const HttpAuthMiddlewareLive = Layer.effect( if (authHeader?.length === 36) { user = yield* database - .execute((db) => + .use((db) => db .select() .from(Db.users) diff --git a/packages/web-backend/src/Database.ts b/packages/web-backend/src/Database.ts index 736be511b..a6293a91f 100644 --- a/packages/web-backend/src/Database.ts +++ b/packages/web-backend/src/Database.ts @@ -1,15 +1,22 @@ import { db } from "@cap/database"; import { DatabaseError } from "@cap/web-domain"; +import type { Query } from "drizzle-orm"; import { Effect } from "effect"; export class Database extends Effect.Service()("Database", { effect: Effect.gen(function* () { return { - execute: (cb: (_: ReturnType) => Promise) => - Effect.tryPromise({ - try: () => cb(db()), + use: ( + cb: (_: ReturnType) => Promise & { toSQL?(): Query }, + ) => { + const promise = cb(db()); + const sql = promise.toSQL?.().sql ?? "Transaction"; + + return Effect.tryPromise({ + try: () => promise, catch: (cause) => new DatabaseError({ cause }), - }), + }).pipe(Effect.withSpan("Database.execute", { attributes: { sql } })); + }, }; }), }) {} diff --git a/packages/web-backend/src/Folders/FoldersRepo.ts b/packages/web-backend/src/Folders/FoldersRepo.ts index d94000680..359c83c8e 100644 --- a/packages/web-backend/src/Folders/FoldersRepo.ts +++ b/packages/web-backend/src/Folders/FoldersRepo.ts @@ -26,7 +26,7 @@ export class FoldersRepo extends Effect.Service()("FoldersRepo", { filters?: { organizationId?: Organisation.OrganisationId }, ) => db - .execute((db) => + .use((db) => db .select() .from(Db.folders) @@ -41,13 +41,13 @@ export class FoldersRepo extends Effect.Service()("FoldersRepo", { .pipe(Effect.map(Array.get(0))); const delete_ = (id: Folder.FolderId) => - db.execute((db) => db.delete(Db.folders).where(Dz.eq(Db.folders.id, id))); + db.use((db) => db.delete(Db.folders).where(Dz.eq(Db.folders.id, id))); const create = (data: CreateFolderInput) => Effect.gen(function* () { const id = Folder.FolderId.make(nanoId()); - yield* db.execute((db) => + yield* db.use((db) => db.insert(Db.folders).values([ { ...data, @@ -63,7 +63,7 @@ export class FoldersRepo extends Effect.Service()("FoldersRepo", { const update = (id: Folder.FolderId, data: Partial) => Effect.gen(function* () { - yield* db.execute((db) => + yield* db.use((db) => db .update(Db.folders) .set({ diff --git a/packages/web-backend/src/Folders/index.ts b/packages/web-backend/src/Folders/index.ts index 24fa514b5..5c3933890 100644 --- a/packages/web-backend/src/Folders/index.ts +++ b/packages/web-backend/src/Folders/index.ts @@ -28,7 +28,7 @@ export class Folders extends Effect.Service()("Folders", { spaceId: Space.SpaceIdOrOrganisationId | null; }): Effect.Effect => Effect.gen(function* () { - const children = yield* db.execute((db) => + const children = yield* db.use((db) => db .select({ id: Db.folders.id, @@ -46,7 +46,7 @@ export class Folders extends Effect.Service()("Folders", { // Folders can't be both in the root and in a space if (folder.spaceId) { const { spaceId } = folder; - yield* db.execute((db) => + yield* db.use((db) => db .update(Db.spaceVideos) .set({ folderId: folder.parentId }) @@ -58,7 +58,7 @@ export class Folders extends Effect.Service()("Folders", { ), ); } else { - yield* db.execute((db) => + yield* db.use((db) => db .update(Db.videos) .set({ folderId: folder.parentId }) @@ -66,7 +66,7 @@ export class Folders extends Effect.Service()("Folders", { ); } - yield* db.execute((db) => + yield* db.use((db) => db.delete(Db.folders).where(Dz.eq(Db.folders.id, folder.id)), ); }); @@ -118,7 +118,7 @@ export class Folders extends Effect.Service()("Folders", { */ delete: Effect.fn("Folders.delete")(function* (id: Folder.FolderId) { const [folder] = yield* db - .execute((db) => + .use((db) => db.select().from(Db.folders).where(Dz.eq(Db.folders.id, id)), ) .pipe(Policy.withPolicy(policy.canEdit(id))); @@ -182,7 +182,7 @@ export class Folders extends Effect.Service()("Folders", { } } - yield* db.execute((db) => + yield* db.use((db) => db .update(Db.folders) .set({ diff --git a/packages/web-backend/src/Organisations/OrganisationsRepo.ts b/packages/web-backend/src/Organisations/OrganisationsRepo.ts index 0c0b3736c..332eb753b 100644 --- a/packages/web-backend/src/Organisations/OrganisationsRepo.ts +++ b/packages/web-backend/src/Organisations/OrganisationsRepo.ts @@ -13,7 +13,7 @@ export class OrganisationsRepo extends Effect.Service()( return { membershipForVideo: (userId: User.UserId, videoId: Video.VideoId) => - db.execute((db) => + db.use((db) => db .select({ membershipId: Db.organizationMembers.id }) .from(Db.organizationMembers) @@ -33,7 +33,7 @@ export class OrganisationsRepo extends Effect.Service()( ), membership: (userId: User.UserId, orgId: Organisation.OrganisationId) => db - .execute((db) => + .use((db) => db .select({ membershipId: Db.organizationMembers.id, diff --git a/packages/web-backend/src/S3Buckets/S3BucketsRepo.ts b/packages/web-backend/src/S3Buckets/S3BucketsRepo.ts index 677c7e369..1b06f9a46 100644 --- a/packages/web-backend/src/S3Buckets/S3BucketsRepo.ts +++ b/packages/web-backend/src/S3Buckets/S3BucketsRepo.ts @@ -14,7 +14,7 @@ export class S3BucketsRepo extends Effect.Service()( const getForVideo = Effect.fn("S3BucketsRepo.getForVideo")( (videoId: Video.VideoId) => Effect.gen(function* () { - const [res] = yield* db.execute((db) => + const [res] = yield* db.use((db) => db .select({ bucket: Db.s3Buckets }) .from(Db.s3Buckets) @@ -33,7 +33,7 @@ export class S3BucketsRepo extends Effect.Service()( const getById = Effect.fn("S3BucketsRepo.getById")( (id: S3Bucket.S3BucketId) => Effect.gen(function* () { - const [res] = yield* db.execute((db) => + const [res] = yield* db.use((db) => db .select({ bucket: Db.s3Buckets }) .from(Db.s3Buckets) @@ -51,7 +51,7 @@ export class S3BucketsRepo extends Effect.Service()( const getForUser = Effect.fn("S3BucketsRepo.getForUser")( (userId: User.UserId) => Effect.gen(function* () { - const [res] = yield* db.execute((db) => + const [res] = yield* db.use((db) => db .select({ bucket: Db.s3Buckets }) .from(Db.s3Buckets) diff --git a/packages/web-backend/src/Spaces/SpacesRepo.ts b/packages/web-backend/src/Spaces/SpacesRepo.ts index 1406e61bd..bf2a8d000 100644 --- a/packages/web-backend/src/Spaces/SpacesRepo.ts +++ b/packages/web-backend/src/Spaces/SpacesRepo.ts @@ -12,7 +12,7 @@ export class SpacesRepo extends Effect.Service()("SpacesRepo", { return { membershipForVideo: (userId: User.UserId, videoId: Video.VideoId) => db - .execute((db) => + .use((db) => db .select({ membershipId: Db.spaceMembers.id }) .from(Db.spaceMembers) @@ -34,7 +34,7 @@ export class SpacesRepo extends Effect.Service()("SpacesRepo", { spaceId: Space.SpaceIdOrOrganisationId, ) => db - .execute((db) => + .use((db) => db .select({ membershipId: Db.spaceMembers.id, @@ -52,7 +52,7 @@ export class SpacesRepo extends Effect.Service()("SpacesRepo", { getById: (spaceId: Space.SpaceIdOrOrganisationId) => db - .execute((db) => + .use((db) => db.select().from(Db.spaces).where(Dz.eq(Db.spaces.id, spaceId)), ) .pipe(Effect.map(Array.get(0))), diff --git a/packages/web-backend/src/Spaces/index.ts b/packages/web-backend/src/Spaces/index.ts index 65cf02c19..854da82ce 100644 --- a/packages/web-backend/src/Spaces/index.ts +++ b/packages/web-backend/src/Spaces/index.ts @@ -19,7 +19,7 @@ export class Spaces extends Effect.Service()("Spaces", { spaceOrOrgId: Space.SpaceIdOrOrganisationId, ) { const [[space], [org]] = yield* Effect.all([ - db.execute((db) => + db.use((db) => db .select({ id: Db.spaces.id, @@ -31,7 +31,7 @@ export class Spaces extends Effect.Service()("Spaces", { .where(Dz.eq(Db.spaces.id, spaceOrOrgId)) .limit(1), ), - db.execute((db) => + db.use((db) => db .select({ id: Db.organizations.id, diff --git a/packages/web-backend/src/Videos/VideosRepo.ts b/packages/web-backend/src/Videos/VideosRepo.ts index a1de8cca2..d17c105fa 100644 --- a/packages/web-backend/src/Videos/VideosRepo.ts +++ b/packages/web-backend/src/Videos/VideosRepo.ts @@ -23,7 +23,7 @@ export class VideosRepo extends Effect.Service()("VideosRepo", { */ const getById = (id: Video.VideoId) => Effect.gen(function* () { - const [video] = yield* db.execute((db) => + const [video] = yield* db.use((db) => db.select().from(Db.videos).where(Dz.eq(Db.videos.id, id)), ); @@ -45,7 +45,7 @@ export class VideosRepo extends Effect.Service()("VideosRepo", { }); const delete_ = (id: Video.VideoId) => - db.execute(async (db) => + db.use(async (db) => db.transaction((db) => Promise.all([ db.delete(Db.videos).where(Dz.eq(Db.videos.id, id)), @@ -60,7 +60,7 @@ export class VideosRepo extends Effect.Service()("VideosRepo", { Effect.gen(function* () { const id = Video.VideoId.make(nanoId()); - yield* db.execute((db) => + yield* db.use((db) => db.transaction(async (db) => { const promises: MySqlInsertBase[] = [ db.insert(Db.videos).values([ diff --git a/packages/web-backend/src/Videos/index.ts b/packages/web-backend/src/Videos/index.ts index e2986c0cb..85767cfff 100644 --- a/packages/web-backend/src/Videos/index.ts +++ b/packages/web-backend/src/Videos/index.ts @@ -108,7 +108,7 @@ export class Videos extends Effect.Service()("Videos", { videoId: Video.VideoId, ) { const [result] = yield* db - .execute((db) => + .use((db) => db .select({ uploaded: Db.videoUploads.uploaded,