1import * as AWS from "@/AWS";
2import { Keyspace, Table } from "@/AWS/Keyspaces";
3import * as Test from "@/Test/Alchemy";
4import * as keyspaces from "@distilled.cloud/aws/keyspaces";
5import { expect } from "alchemy-test";
6import * as Effect from "effect/Effect";
7
8const { test } = Test.make({ providers: AWS.providers() });
9
10const getTable = (keyspaceName: string, tableName: string) =>
11 keyspaces
12 .getTable({ keyspaceName, tableName })
13 .pipe(
14 Effect.catchTag("ResourceNotFoundException", () =>
15 Effect.succeed(undefined),
16 ),
17 );
18
19test.provider(
20 "create, add column, delete Keyspaces table",
21 (stack) =>
22 Effect.gen(function* () {
23 yield* stack.destroy();
24
25 const ksName = "alchemy_tbl_test_ks";
26
27 // create keyspace + table
28 const created = yield* stack.deploy(
29 Effect.gen(function* () {
30 const keyspace = yield* Keyspace("Ks", { keyspaceName: ksName });
31 const table = yield* Table("Events", {
32 keyspaceName: keyspace.keyspaceName,
33 tableName: "events",
34 columns: [
35 { name: "device", type: "text" },
36 { name: "ts", type: "timestamp" },
37 { name: "payload", type: "blob" },
38 ],
39 partitionKeys: ["device"],
40 clusteringKeys: [{ name: "ts", orderBy: "DESC" }],
41 pointInTimeRecovery: true,
42 });
43 return { table };
44 }),
45 );
46
47 expect(created.table.tableName).toEqual("events");
48 expect(created.table.status).toEqual("ACTIVE");
49
50 // out-of-band verification
51 const observed = yield* getTable(ksName, "events");
52 expect(observed?.status).toEqual("ACTIVE");
53 expect(observed?.pointInTimeRecovery?.status).toEqual("ENABLED");
54 const cols = new Set(
55 (observed?.schemaDefinition?.allColumns ?? []).map((c) => c.name),
56 );
57 expect(cols.has("device")).toBe(true);
58 expect(cols.has("payload")).toBe(true);
59
60 // update: add a column in place
61 yield* stack.deploy(
62 Effect.gen(function* () {
63 const keyspace = yield* Keyspace("Ks", { keyspaceName: ksName });
64 const table = yield* Table("Events", {
65 keyspaceName: keyspace.keyspaceName,
66 tableName: "events",
67 columns: [
68 { name: "device", type: "text" },
69 { name: "ts", type: "timestamp" },
70 { name: "payload", type: "blob" },
71 { name: "region", type: "text" },
72 ],
73 partitionKeys: ["device"],
74 clusteringKeys: [{ name: "ts", orderBy: "DESC" }],
75 pointInTimeRecovery: true,
76 });
77 return { table };
78 }),
79 );
80 const reobserved = yield* getTable(ksName, "events");
81 const reCols = new Set(
82 (reobserved?.schemaDefinition?.allColumns ?? []).map((c) => c.name),
83 );
84 expect(reCols.has("region")).toBe(true);
85
86 // delete
87 yield* stack.destroy();
88 const gone = yield* getTable(ksName, "events");
89 expect(gone).toBeUndefined();
90 }),
91 {
92 tags: ["provider:aws", "provider:aws:keyspaces", "live"],
93 timeout: 300_000,
94 },
95);