Back to packages list

Vals using kysely

Description from the NPM package:
Type safe SQL query builder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import { Kysely, sql } from "npm:kysely";
export async function up(db: Kysely<any>): Promise<void> {
await db.schema
.createTable("person")
.addColumn("id", "integer", (col) => col.primaryKey())
.addColumn("first_name", "text", (col) => col.notNull())
.addColumn("last_name", "text")
.addColumn("gender", "text", (col) => col.notNull())
.addColumn("created_at", "text", (col) => col.defaultTo(sql`CURRENT_TIMESTAMP`).notNull())
.execute();
await db.schema
.createTable("pet")
.addColumn("id", "integer", (col) => col.primaryKey())
.addColumn("name", "text", (col) => col.notNull().unique())
.addColumn("owner_id", "integer", (col) => col.references("person.id").onDelete("cascade").notNull())
.addColumn("species", "text", (col) => col.notNull())
.execute();
await db.schema
.createIndex("pet_owner_id_index")
.on("pet")
.column("owner_id")
.execute();
}
export async function down(db: Kysely<any>): Promise<void> {
await db.schema.dropTable("pet").execute();
await db.schema.dropTable("person").execute();
}

Kysely on val.town

Uses @easrng/kyselyVtDialect as a Kysely Dialect and @easrng/kyselyVtTypes for type autogeneration.

1
2
3
4
5
6
7
8
9
10
11
import type { DB } from "https://easrng-kyselyvttypes.web.val.run/?tables=contacts";
import { VtDialect } from "https://esm.town/v/easrng/kyselyVtDialect";
import { Kysely } from "npm:kysely@0.27.3";
// ^ pinned version because val.town's editor doesn't
// load version ranges.
const db = new Kysely<DB>({
dialect: new VtDialect(),
});
const rows = await db.selectFrom("contacts").selectAll().execute();
// ^ { contact_id: number; email: string; first_name: string; ... }[]
console.log(rows);
1
2
3
4
5
6
7
8
9
10
11
import { VtDialect } from "https://esm.town/v/easrng/kyselyVtDialect";
import type { DB } from "https://nbbaier-kyselyVtTypes.web.val.run/?tables=users";
import { Kysely } from "npm:kysely@0.27.3";
// ^ pinned version because val.town's editor doesn't
// load version ranges.
const db = new Kysely<DB>({
dialect: new VtDialect(),
});
const rows = await db.selectFrom("users").selectAll().where("id", "=", "1").execute();
// ^ { contact_id: number; email: string; first_name: string; ... }[]
console.log(rows);

Kysely on val.town

Uses @easrng/kyselyVtDialect as a Kysely Dialect and @easrng/kyselyVtTypes for type autogeneration.

1
2
3
4
5
6
7
8
9
10
11
import type { DB } from "https://easrng-kyselyvttypes.web.val.run/?tables=contacts";
import { VtDialect } from "https://esm.town/v/easrng/kyselyVtDialect";
import { Kysely } from "npm:kysely@0.27.3";
// ^ pinned version because val.town's editor doesn't
// load version ranges.
const db = new Kysely<DB>({
dialect: new VtDialect(),
});
const rows = await db.selectFrom("contacts").selectAll().execute();
// ^ { contact_id: number; email: string; first_name: string; ... }[]
console.log(rows);

Kysely Dialect for @std/sqlite

Caveats

It doesn't support transactions, there's no real way to do them on top of @std/sqlite AFAICT.

Usage

Create valimport { VtDialect } from "https://esm.town/v/easrng/kyselyVtDialect"; import { Kysely } from "npm:kysely"; const db = new Kysely({ dialect: new VtDialect(), });

Demo

See @easrng/kyselyVtDemo, which uses this along with @easrng/kyselyVtTypes to generate schema types.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import { sqlite } from "https://esm.town/v/std/sqlite";
import * as kysely from "npm:kysely@^0.27.3";
export class VtDialect implements kysely.Dialect {
createAdapter(): kysely.DialectAdapter {
return new kysely.SqliteAdapter();
}
createDriver(): kysely.Driver {
return new VtDriver();
}
createIntrospector(db: kysely.Kysely<any>): kysely.DatabaseIntrospector {
return new kysely.SqliteIntrospector(db);
}
createQueryCompiler(): kysely.QueryCompiler {
return new kysely.SqliteQueryCompiler();
}
}
export class VtDriver implements kysely.Driver {
async init(): Promise<void> {
}
async acquireConnection(): Promise<VtConnection> {
return new VtConnection();
}
async beginTransaction(
connection: VtConnection,
_settings: kysely.TransactionSettings,
): Promise<void> {
throw new Error("val.town does not support transactions");
}
async commitTransaction(connection: VtConnection): Promise<void> {
throw new Error("val.town does not support transactions");
}
async rollbackTransaction(connection: VtConnection): Promise<void> {
throw new Error("val.town does not support transactions");
}
async releaseConnection(connection: VtConnection): Promise<void> {
}
async destroy(): Promise<void> {
}
}
export class VtConnection implements kysely.DatabaseConnection {
async executeQuery<R>(compiledQuery: kysely.CompiledQuery): Promise<kysely.QueryResult<R>> {
const result = await sqlite.execute({
sql: compiledQuery.sql,
args: compiledQuery.parameters as any,
});
return {
numAffectedRows: BigInt(result.rowsAffected),
rows: result.rows.map(row => Object.fromEntries(row.map((value, i) => [result.columns[i], value]))) as R[],
};
}
async *streamQuery<R>(
_compiledQuery: kysely.CompiledQuery,
_chunkSize: number,
): AsyncIterableIterator<kysely.QueryResult<R>> {
throw new Error("val.town does not support streaming yet");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
import { turso } from "https://esm.town/v/neverstew/turso";
export const kyselyToSql = <T>(
query:
| import("npm:kysely").Compilable<T>
| import("npm:kysely").CompiledQuery<T>,
): Parameters<ReturnType<typeof turso>["execute"]>[0] => {
let compiled = "compile" in query ? query.compile() : query;
return {
sql: query.sql,
args: query.parameters,
};
};
1
Next