| 1 | import * as AWS from "@/AWS"; |
| 2 | import { Keyspace, Table } from "@/AWS/Keyspaces"; |
| 3 | import * as Test from "@/Test/Alchemy"; |
| 4 | import * as keyspaces from "@distilled.cloud/aws/keyspaces"; |
| 5 | import { expect } from "alchemy-test"; |
| 6 | import * as Effect from "effect/Effect"; |
| 7 | |
| 8 | const { test } = Test.make({ providers: AWS.providers() }); |
| 9 | |
| 10 | const getTable = (keyspaceName: string, tableName: string) => |
| 11 | keyspaces |
| 12 | .getTable({ keyspaceName, tableName }) |
| 13 | .pipe( |
| 14 | Effect.catchTag("ResourceNotFoundException", () => |
| 15 | Effect.succeed(undefined), |
| 16 | ), |
| 17 | ); |
| 18 | |
| 19 | test.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 | ); |