1import * as GCP from "@/GCP";
2import * as Effect from "effect/Effect";
3import { serveProbes } from "../../bindingHost.ts";
4
5export const ITEMS_DDL =
6 "CREATE TABLE Items (\n Id STRING(36) NOT NULL,\n) PRIMARY KEY(Id)";
7
8export const Db = GCP.Spanner.Instance("Db", {
9 config: "regional-us-central1",
10 processingUnits: 100,
11});
12
13/** Database `GetDdl` reads (roles/spanner.databaseReader). */
14export const Schema = Effect.gen(function* () {
15 const instance = yield* Db;
16 return yield* GCP.Spanner.Database("Schema", {
17 instance: instance.name,
18 extraStatements: [ITEMS_DDL],
19 });
20});
21
22/** Database `ExecuteSql` queries (roles/spanner.databaseUser). */
23export const App = Effect.gen(function* () {
24 const instance = yield* Db;
25 return yield* GCP.Spanner.Database("App", {
26 instance: instance.name,
27 extraStatements: [ITEMS_DDL],
28 });
29});
30
31/**
32 * Effect-native Cloud Run service exercising every Spanner binding as its
33 * own runtime service account. Deployed from {@link ../Bindings.test.ts}.
34 */
35export default class SpannerBindingsHost extends GCP.Function<SpannerBindingsHost>()(
36 "SpannerBindingsHost",
37 { main: import.meta.url, invokerIamDisabled: true },
38 Effect.gen(function* () {
39 const getInstance = yield* GCP.Spanner.GetInstance(Db);
40 const getDdl = yield* GCP.Spanner.GetDdl(Schema);
41 const executeSql = yield* GCP.Spanner.ExecuteSql(App);
42
43 return {
44 fetch: serveProbes({
45 getInstance: getInstance(),
46 getDdl: getDdl(),
47 executeSql: executeSql({
48 sql: "SELECT COUNT(*) AS n FROM Items WHERE Id != @id",
49 params: { id: "none" },
50 paramTypes: { id: { code: "STRING" } },
51 }),
52 }),
53 };
54 }).pipe(
55 Effect.provide(GCP.Spanner.GetInstanceHttp),
56 Effect.provide(GCP.Spanner.GetDdlHttp),
57 Effect.provide(GCP.Spanner.ExecuteSqlHttp),
58 ),
59) {}