Skip to content
Source
Sign inSign up
Open History to see the last commit

SqliteRouting.ts

52 lines1.8 KB

1import * as NodeServices from "@effect/platform-node/NodeServices";
2import * as Effect from "effect/Effect";
3import * as FileSystem from "effect/FileSystem";
4import * as Layer from "effect/Layer";
5import * as Option from "effect/Option";
6import * as Path from "effect/Path";
7import * as Statement from "effect/sql/Statement";
8import * as Tracer from "effect/Tracer";
9​
10import * as Sqlite from "../Sqlite.ts";
11​
12export const layerReaderDatabase = Layer.unwrap(
13 Effect.gen(function* () {
14 const fs = yield* FileSystem.FileSystem;
15 const path = yield* Path.Path;
16 const directory = yield* fs.makeTempDirectoryScoped({ prefix: "t3-routing-" });
17 return Sqlite.layerFromPath(path.join(directory, "state.sqlite"));
18 }),
19).pipe(Layer.provide(NodeServices.layer));
20​
21export const traceSqlRouting = () => {
22 const queries: Array<{ query: string; connection: unknown }> = [];
23 const tracer = Tracer.make({
24 span(options) {
25 const span = new Tracer.NativeSpan(options);
26 const end = span.end.bind(span);
27 span.end = (endTime, exit) => {
28 end(endTime, exit);
29 const query = span.attributes.get("db.query.text");
30 if (typeof query === "string") {
31 let owner: Tracer.AnySpan | undefined = span;
32 let connection: unknown;
33 while (owner?._tag === "Span") {
34 connection = owner.attributes.get("db.connection");
35 if (connection !== undefined) break;
36 owner = Option.getOrUndefined(owner.parent);
37 }
38 queries.push({ query, connection });
39 }
40 };
41 return span;
42 },
43 });
44 return {
45 queries,
46 trace: <A, E, R>(effect: Effect.Effect<A, E, R>) =>
47 effect.pipe(
48 Effect.withTracer(tracer),
49 Effect.provideService(Statement.SpanPropagationEnabled, true),
50 ),
51 };
52};