A simple, zero-configuration script to quickly boot FreeBSD ISO images using QEMU
1import { Data, Effect } from "effect";
2import type { DeleteResult, InsertResult } from "kysely";
3import { ctx } from "./context.ts";
4import type { Image } from "./db.ts";
5
6export class DbError extends Data.TaggedError("DatabaseError")<{
7 message?: string;
8}> {}
9
10export const listImages = (): Effect.Effect<Image[], DbError, never> =>
11 Effect.tryPromise({
12 try: () => ctx.db.selectFrom("images").selectAll().execute(),
13 catch: (error) =>
14 new DbError({
15 message: error instanceof Error ? error.message : String(error),
16 }),
17 });
18
19export const getImage = (
20 id: string,
21): Effect.Effect<Image | undefined, DbError, never> =>
22 Effect.tryPromise({
23 try: () =>
24 ctx.db
25 .selectFrom("images")
26 .selectAll()
27 .where((eb) =>
28 eb.or([
29 eb.and([
30 eb("repository", "=", id.split(":")[0]),
31 eb("tag", "=", id.split(":")[1] || "latest"),
32 ]),
33 eb("id", "=", id),
34 eb("digest", "=", id),
35 ])
36 )
37 .executeTakeFirst(),
38 catch: (error) =>
39 new DbError({
40 message: error instanceof Error ? error.message : String(error),
41 }),
42 });
43
44export const saveImage = (
45 image: Image,
46): Effect.Effect<InsertResult[], DbError, never> =>
47 Effect.tryPromise({
48 try: () =>
49 ctx.db.insertInto("images")
50 .values(image)
51 .onConflict((oc) =>
52 oc
53 .column("repository")
54 .column("tag")
55 .doUpdateSet({
56 size: image.size,
57 path: image.path,
58 format: image.format,
59 digest: image.digest,
60 })
61 )
62 .execute(),
63 catch: (error) =>
64 new DbError({
65 message: error instanceof Error ? error.message : String(error),
66 }),
67 });
68
69export const deleteImage = (
70 id: string,
71): Effect.Effect<DeleteResult[], DbError, never> =>
72 Effect.tryPromise({
73 try: () =>
74 ctx.db.deleteFrom("images").where((eb) =>
75 eb.or([
76 eb.and([
77 eb("repository", "=", id.split(":")[0]),
78 eb("tag", "=", id.split(":")[1] || "latest"),
79 ]),
80 eb("id", "=", id),
81 ])
82 ).execute(),
83 catch: (error) =>
84 new DbError({
85 message: error instanceof Error ? error.message : String(error),
86 }),
87 });