rado 1.3.0-preview.3 → 1.3.0-preview.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,14 +13,25 @@ var IndexData = class {
13
13
  };
14
14
  var IndexApi = class extends IndexData {
15
15
  toSql(tableName, indexName, ifNotExists) {
16
+ const fields = this.fields.map(
17
+ (field) => sql.join([
18
+ field,
19
+ this.order && sql.unsafe(this.order),
20
+ this.nulls && sql`nulls ${sql.unsafe(this.nulls)}`
21
+ ])
22
+ );
16
23
  return sql.join([
17
24
  sql`create`,
18
25
  this.unique && sql`unique`,
19
26
  sql`index`,
27
+ this.concurrently && sql`concurrently`,
20
28
  ifNotExists && sql`if not exists`,
21
29
  sql.identifier(indexName),
22
30
  sql`on`,
23
- sql`${sql.identifier(tableName)}(${sql.join(this.fields, sql`, `)})`,
31
+ this.only && sql`only`,
32
+ sql.identifier(tableName),
33
+ this.using && sql`using ${this.using}`,
34
+ sql`(${sql.join(fields, sql`, `)})`,
24
35
  this.where && sql`where ${this.where}`
25
36
  ]).inlineFields(false);
26
37
  }
@@ -1,7 +1,7 @@
1
1
  export type QueryMode = 'sync' | 'async' | undefined;
2
2
  export type Runtime = 'sqlite' | 'mysql' | 'postgres';
3
3
  export type QueryDialect = 'universal' | Runtime;
4
- export type Deliver<Meta extends QueryMeta, Result> = Meta extends Either ? Result | Promise<Result> : Meta extends Sync ? Result : Promise<Result>;
4
+ export type Deliver<Meta extends QueryMeta, Result> = Meta extends Sync ? Result : Meta extends Async ? Promise<Result> : Result | Promise<Result>;
5
5
  export interface QueryMeta {
6
6
  mode: QueryMode;
7
7
  dialect: QueryDialect;
@@ -83,13 +83,13 @@ export interface SelectBase<Input, Meta extends QueryMeta = QueryMeta> extends U
83
83
  }
84
84
  export interface WithoutSelection<Meta extends QueryMeta> {
85
85
  from<Definition extends TableDefinition, Name extends string>(from: Table<Definition, Name>): AllFrom<TableFields<Definition>, Meta, Record<Name, TableFields<Definition>>>;
86
- from<Input>(from: SubQuery<Input>): SelectionFrom<Input, Meta>;
87
- from<Input>(from: VirtualTarget<Input>): SelectionFrom<Input, Meta>;
86
+ from<Input, Name extends string>(from: SubQuery<Input, Name>): SelectionFromTargets<Input, Meta, Name>;
87
+ from<Input>(from: VirtualTarget<Input>): SelectionFromTargets<Input, Meta, string>;
88
88
  }
89
89
  export interface WithSelection<Input, Meta extends QueryMeta> extends SelectBase<Input, Meta>, HasSql<SelectionRow<Input>> {
90
- from<Definition extends TableDefinition, Name extends string>(from: Table<Definition, Name>): SelectionFrom<Input, Meta>;
91
- from(from: HasTarget): SelectionFrom<Input, Meta>;
92
- from(from: SubQuery<unknown>): SelectionFrom<Input, Meta>;
90
+ from<Definition extends TableDefinition, Name extends string>(from: Table<Definition, Name>): SelectionFromTargets<Input, Meta, Name>;
91
+ from<SubInput, Name extends string>(from: SubQuery<SubInput, Name>): SelectionFromTargets<Input, Meta, Name>;
92
+ from<Name extends string>(from: HasTarget<Name>): SelectionFromTargets<Input, Meta, Name>;
93
93
  from(from: HasSql): Select<Input, Meta>;
94
94
  }
95
95
  export interface AllFrom<Input, Meta extends QueryMeta, Tables = Input> extends SelectBase<Input, Meta> {
@@ -110,28 +110,30 @@ export interface AllFrom<Input, Meta extends QueryMeta, Tables = Input> extends
110
110
  fullJoin<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): AllFrom<Expand<MakeNullable<Tables> & MakeNullable<Record<Name, TableFields<Definition>>>>, Meta>;
111
111
  fullJoin<Input, Name extends string>(right: SubQuery<Input, Name>, on: HasSql<boolean>): AllFrom<Expand<MakeNullable<Tables> & MakeNullable<Record<Name, Input>>>, Meta>;
112
112
  }
113
- type MarkFieldsAsNullable<Input, TableName extends string> = Expand<{
113
+ type MarkFieldsAsNullable<Input, TableName extends string> = Input extends Table<infer Definition, TableName> ? TableFields<Definition> & IsNullable : Input extends Table ? Input : Expand<{
114
114
  [K in keyof Input]: Input[K] extends Field<infer T, TableName> ? HasSql<T | null> : Input[K] extends Table<infer Definition, TableName> ? TableFields<Definition> & IsNullable : Input[K] extends Record<string, Field<unknown, TableName> | HasSql<unknown>> ? Input[K] & IsNullable : Input[K] extends SelectionRecord ? MarkFieldsAsNullable<Input[K], TableName> : Input[K];
115
115
  }>;
116
- export interface SelectionFrom<Input, Meta extends QueryMeta> extends SelectBase<Input, Meta> {
117
- leftJoin<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFrom<MarkFieldsAsNullable<Input, Name>, Meta>;
118
- leftJoin<Name extends string>(right: HasTarget<Name>, on: HasSql<boolean>): SelectionFrom<MarkFieldsAsNullable<Input, Name>, Meta>;
119
- leftJoin(right: HasTarget, on: HasSql<boolean>): SelectionFrom<Input, Meta>;
120
- leftJoinLateral<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFrom<MarkFieldsAsNullable<Input, Name>, Meta>;
121
- leftJoinLateral<Name extends string>(right: HasTarget<Name>, on: HasSql<boolean>): SelectionFrom<MarkFieldsAsNullable<Input, Name>, Meta>;
122
- rightJoin<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFrom<Input, Meta>;
123
- rightJoin(right: HasTarget, on: HasSql<boolean>): SelectionFrom<Input, Meta>;
124
- innerJoin<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFrom<Input, Meta>;
125
- innerJoin(right: HasTarget, on: HasSql<boolean>): SelectionFrom<Input, Meta>;
126
- innerJoinLateral<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFrom<Input, Meta>;
127
- innerJoinLateral(right: HasTarget, on: HasSql<boolean>): SelectionFrom<Input, Meta>;
128
- crossJoin<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>): SelectionFrom<Input, Meta>;
129
- crossJoin(right: HasTarget): SelectionFrom<Input, Meta>;
130
- crossJoinLateral<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>): SelectionFrom<Input, Meta>;
131
- crossJoinLateral(right: HasTarget): SelectionFrom<Input, Meta>;
132
- fullJoin<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFrom<Input, Meta>;
133
- fullJoin<Name extends string>(right: HasTarget<Name>, on: HasSql<boolean>): SelectionFrom<MarkFieldsAsNullable<Input, Name>, Meta>;
134
- fullJoin(right: HasTarget, on: HasSql<boolean>): SelectionFrom<Input, Meta>;
116
+ export interface SelectionFrom<Input, Meta extends QueryMeta> extends SelectionFromTargets<Input, Meta, never> {
117
+ }
118
+ interface SelectionFromTargets<Input, Meta extends QueryMeta, FromNames extends string = never> extends SelectBase<Input, Meta> {
119
+ leftJoin<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<Input, Name>, Meta, FromNames | Name>;
120
+ leftJoin<Name extends string>(right: HasTarget<Name>, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<Input, Name>, Meta, FromNames | Name>;
121
+ leftJoin(right: HasTarget, on: HasSql<boolean>): SelectionFromTargets<Input, Meta, FromNames>;
122
+ leftJoinLateral<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<Input, Name>, Meta, FromNames | Name>;
123
+ leftJoinLateral<Name extends string>(right: HasTarget<Name>, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<Input, Name>, Meta, FromNames | Name>;
124
+ rightJoin<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<Input, FromNames>, Meta, FromNames | Name>;
125
+ rightJoin(right: HasTarget, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<Input, FromNames>, Meta, FromNames>;
126
+ innerJoin<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFromTargets<Input, Meta, FromNames | Name>;
127
+ innerJoin(right: HasTarget, on: HasSql<boolean>): SelectionFromTargets<Input, Meta, FromNames>;
128
+ innerJoinLateral<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFromTargets<Input, Meta, FromNames | Name>;
129
+ innerJoinLateral(right: HasTarget, on: HasSql<boolean>): SelectionFromTargets<Input, Meta, FromNames>;
130
+ crossJoin<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>): SelectionFromTargets<Input, Meta, FromNames | Name>;
131
+ crossJoin(right: HasTarget): SelectionFromTargets<Input, Meta, FromNames>;
132
+ crossJoinLateral<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>): SelectionFromTargets<Input, Meta, FromNames | Name>;
133
+ crossJoinLateral(right: HasTarget): SelectionFromTargets<Input, Meta, FromNames>;
134
+ fullJoin<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<MarkFieldsAsNullable<Input, FromNames>, Name>, Meta, FromNames | Name>;
135
+ fullJoin<Name extends string>(right: HasTarget<Name>, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<MarkFieldsAsNullable<Input, FromNames>, Name>, Meta, FromNames | Name>;
136
+ fullJoin(right: HasTarget, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<Input, FromNames>, Meta, FromNames>;
135
137
  }
136
138
  export declare function querySelection({ select, from }: SelectQuery): Selection;
137
139
  export declare function selectQuery(query: SelectQuery): Sql;
@@ -44,7 +44,10 @@ var BetterSqlite3Driver = class _BetterSqlite3Driver {
44
44
  this.client.close();
45
45
  }
46
46
  prepare(sql, options) {
47
- return new PreparedStatement(this.client.prepare(sql), options.isSelection);
47
+ return new PreparedStatement(
48
+ this.client.prepare(sql),
49
+ options?.isSelection ?? false
50
+ );
48
51
  }
49
52
  batch(queries) {
50
53
  return this.transaction(
@@ -4,10 +4,12 @@ import { sqliteDialect } from "../sqlite.js";
4
4
  import { sqliteDiff } from "../sqlite/diff.js";
5
5
  import { execTransaction } from "../sqlite/transactions.js";
6
6
  var PreparedStatement = class {
7
- constructor(stmt) {
7
+ constructor(stmt, isSelection) {
8
8
  this.stmt = stmt;
9
+ this.isSelection = isSelection;
9
10
  }
10
11
  stmt;
12
+ isSelection;
11
13
  all(params) {
12
14
  return this.stmt.all(...params);
13
15
  }
@@ -18,6 +20,10 @@ var PreparedStatement = class {
18
20
  return this.stmt.get(...params);
19
21
  }
20
22
  values(params) {
23
+ if (!this.isSelection) {
24
+ this.stmt.run(...params);
25
+ return [];
26
+ }
21
27
  return this.stmt.values(...params);
22
28
  }
23
29
  free() {
@@ -39,12 +45,17 @@ var BunSqliteDriver = class _BunSqliteDriver {
39
45
  close() {
40
46
  this.client.close();
41
47
  }
42
- prepare(sql) {
43
- return new PreparedStatement(this.client.prepare(sql));
48
+ prepare(sql, options) {
49
+ return new PreparedStatement(
50
+ this.client.prepare(sql),
51
+ options?.isSelection ?? false
52
+ );
44
53
  }
45
54
  batch(queries) {
46
55
  return this.transaction((tx) => {
47
- return queries.map(({ sql, params }) => tx.prepare(sql).values(params));
56
+ return queries.map(
57
+ ({ sql, params, isSelection }) => tx.prepare(sql, { isSelection }).values(params)
58
+ );
48
59
  }, {});
49
60
  }
50
61
  transaction(run, options) {
@@ -17,7 +17,7 @@ export declare class D1Driver implements AsyncDriver {
17
17
  supportsTransactions: boolean;
18
18
  constructor(client: Client);
19
19
  exec(query: string): Promise<void>;
20
- prepare(sql: string, options: PrepareOptions): PreparedStatement;
20
+ prepare(sql: string, options?: PrepareOptions): PreparedStatement;
21
21
  close(): Promise<void>;
22
22
  batch(queries: Array<BatchedQuery>): Promise<Array<Array<unknown>>>;
23
23
  transaction<T>(): Promise<T>;
package/dist/driver/d1.js CHANGED
@@ -37,7 +37,10 @@ var D1Driver = class {
37
37
  await this.client.exec(query);
38
38
  }
39
39
  prepare(sql, options) {
40
- return new PreparedStatement(this.client.prepare(sql), options.isSelection);
40
+ return new PreparedStatement(
41
+ this.client.prepare(sql),
42
+ options?.isSelection ?? false
43
+ );
41
44
  }
42
45
  async close() {
43
46
  }
@@ -46,7 +49,11 @@ var D1Driver = class {
46
49
  ({ sql, params }) => this.client.prepare(sql).bind(...params)
47
50
  );
48
51
  const rows = await this.client.batch(stmts);
49
- return rows.map((row) => row.results);
52
+ return rows.map((row, index) => {
53
+ const isSelection = queries[index]?.isSelection;
54
+ if (!isSelection) return [];
55
+ return row.results.map(Object.values);
56
+ });
50
57
  }
51
58
  async transaction() {
52
59
  throw new Error("Transactions are not supported in D1");
@@ -19,7 +19,7 @@ export declare class LibSQLClient implements AsyncDriver {
19
19
  supportsTransactions: boolean;
20
20
  constructor(client: Queryable, depth?: number);
21
21
  exec(query: string): Promise<void>;
22
- prepare(sql: string, options: PrepareOptions): PreparedStatement;
22
+ prepare(sql: string, options?: PrepareOptions): PreparedStatement;
23
23
  close(): Promise<void>;
24
24
  batch(queries: Array<BatchedQuery>): Promise<Array<Array<unknown>>>;
25
25
  transaction<T>(run: (inner: AsyncDriver) => Promise<T>, options: TransactionOptions['sqlite']): Promise<T>;
@@ -7,8 +7,9 @@ declare class PreparedStatement implements AsyncStatement {
7
7
  #private;
8
8
  private client;
9
9
  private sql;
10
+ private isSelection;
10
11
  private name?;
11
- constructor(client: Queryable, sql: string, name?: string | undefined);
12
+ constructor(client: Queryable, sql: string, isSelection: boolean, name?: string | undefined);
12
13
  all(params: Array<unknown>): Promise<Array<object>>;
13
14
  run(params: Array<unknown>): Promise<void>;
14
15
  get(params: Array<unknown>): Promise<object>;
@@ -4,13 +4,15 @@ import { mysqlDialect } from "../mysql/dialect.js";
4
4
  import { mysqlDiff } from "../mysql/diff.js";
5
5
  import { setTransaction, startTransaction } from "../mysql/transactions.js";
6
6
  var PreparedStatement = class {
7
- constructor(client, sql, name) {
7
+ constructor(client, sql, isSelection, name) {
8
8
  this.client = client;
9
9
  this.sql = sql;
10
+ this.isSelection = isSelection;
10
11
  this.name = name;
11
12
  }
12
13
  client;
13
14
  sql;
15
+ isSelection;
14
16
  name;
15
17
  #transformParam = (param) => {
16
18
  if (param instanceof Uint8Array) return Buffer.from(param);
@@ -26,6 +28,7 @@ var PreparedStatement = class {
26
28
  return this.all(params).then((rows) => rows[0] ?? null);
27
29
  }
28
30
  values(params) {
31
+ if (!this.isSelection) return this.run(params).then(() => []);
29
32
  return this.client.query({
30
33
  sql: this.sql,
31
34
  values: params.map(this.#transformParam),
@@ -48,7 +51,12 @@ var Mysql2Driver = class _Mysql2Driver {
48
51
  await this.client.query(query);
49
52
  }
50
53
  prepare(sql, options) {
51
- return new PreparedStatement(this.client, sql, options?.name);
54
+ return new PreparedStatement(
55
+ this.client,
56
+ sql,
57
+ options?.isSelection ?? false,
58
+ options?.name
59
+ );
52
60
  }
53
61
  async close() {
54
62
  if ("end" in this.client) return this.client.end();
@@ -56,8 +64,8 @@ var Mysql2Driver = class _Mysql2Driver {
56
64
  async batch(queries) {
57
65
  const transact = async (tx) => {
58
66
  const results = [];
59
- for (const { sql, params } of queries)
60
- results.push(await tx.prepare(sql).values(params));
67
+ for (const { sql, params, isSelection } of queries)
68
+ results.push(await tx.prepare(sql, { isSelection }).values(params));
61
69
  return results;
62
70
  };
63
71
  if (this.depth > 0) return transact(this);
@@ -50,7 +50,10 @@ var NodeSqliteDriver = class _NodeSqliteDriver {
50
50
  this.client.close();
51
51
  }
52
52
  prepare(sql, options) {
53
- return new PreparedStatement(this.client.prepare(sql), options.isSelection);
53
+ return new PreparedStatement(
54
+ this.client.prepare(sql),
55
+ options?.isSelection ?? false
56
+ );
54
57
  }
55
58
  batch(queries) {
56
59
  return this.transaction(
package/dist/driver/pg.js CHANGED
@@ -71,7 +71,8 @@ var PgDriver = class _PgDriver {
71
71
  }, {});
72
72
  }
73
73
  async transaction(run, options) {
74
- const client = "totalCount" in this.client ? await this.client.connect() : this.client;
74
+ const acquiredClient = this.depth === 0 && "totalCount" in this.client ? await this.client.connect() : void 0;
75
+ const client = acquiredClient ?? this.client;
75
76
  try {
76
77
  await client.query(this.depth > 0 ? `savepoint d${this.depth}` : "begin");
77
78
  if (this.depth === 0) await client.query(setTransaction(options));
@@ -86,7 +87,7 @@ var PgDriver = class _PgDriver {
86
87
  );
87
88
  throw error;
88
89
  } finally {
89
- if ("release" in client) client.release();
90
+ acquiredClient?.release();
90
91
  }
91
92
  }
92
93
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rado",
3
- "version": "1.3.0-preview.3",
3
+ "version": "1.3.0-preview.4",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,6 +36,9 @@
36
36
  "format:check": "oxfmt --check .",
37
37
  "lint": "oxlint .",
38
38
  "check": "bun run format:check && bun run lint",
39
+ "test:mysql": "bun test --test-filter mysql",
40
+ "test:postgres": "bun test --test-filter postgres pg",
41
+ "test:sqlite": "bun test --test-filter sqlite",
39
42
  "test:bun": "bun test",
40
43
  "test:node": "node --disable-warning=ExperimentalWarning --test-force-exit --test-concurrency=1 --test-reporter=spec --experimental-transform-types --test \"**/*.test.ts\"",
41
44
  "test:deno": "deno test --node-modules-dir=false --no-check -A --unstable-ffi",