rado 1.0.0-preview.5 → 1.0.1

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.
package/README.md CHANGED
@@ -20,7 +20,7 @@ Conditions can be created by accessing the fields of the table:
20
20
 
21
21
  ```ts
22
22
  import {eq} from 'rado'
23
- eq(User.id.is, 1) // Compare with a value
23
+ eq(User.id, 1) // Compare with a value
24
24
  eq(User.id, Post.userId) // Compare to fields on other tables
25
25
  ```
26
26
 
@@ -1,4 +1,4 @@
1
- import { internalData, type HasQuery, type HasSql, type HasTable, type HasTarget } from './Internal.js';
1
+ import { type HasQuery, type HasSql, type HasTarget, internalData } from './Internal.js';
2
2
  import type { IsPostgres, QueryMeta } from './MetaData.js';
3
3
  import type { QueryData } from './Query.js';
4
4
  import { type SelectionInput } from './Selection.js';
@@ -18,7 +18,7 @@ declare class BuilderBase<Meta extends QueryMeta> {
18
18
  selectDistinctOn<Input extends SelectionInput>(this: Builder<IsPostgres>, columns: Array<HasSql>, selection: Input): WithSelection<Input, Meta>;
19
19
  update<Definition extends TableDefinition>(table: Table<Definition>): UpdateTable<Definition, Meta>;
20
20
  insert<Definition extends TableDefinition>(into: Table<Definition>): InsertInto<Definition, Meta>;
21
- delete(from: HasTable): DeleteFrom<Meta>;
21
+ delete<Definition extends TableDefinition>(from: Table<Definition>): DeleteFrom<Definition, Meta>;
22
22
  }
23
23
  export type CTE<Input = unknown> = Input & HasTarget & HasQuery;
24
24
  export declare class Builder<Meta extends QueryMeta> extends BuilderBase<Meta> {
@@ -1,6 +1,8 @@
1
1
  import type { ColumnData } from './Column.js';
2
2
  import { type HasQuery, type HasTarget } from './Internal.js';
3
+ import type { Runtime } from './MetaData.js';
3
4
  import { type Param } from './Param.js';
5
+ import { type Sql } from './Sql.js';
4
6
  import type { TableApi } from './Table.js';
5
7
  import type { FieldData } from './expr/Field.js';
6
8
  import type { IncludeData } from './expr/Include.js';
@@ -15,16 +17,12 @@ export declare abstract class Emitter {
15
17
  get hasParams(): boolean;
16
18
  bind(inputs?: Record<string, unknown>): Array<unknown>;
17
19
  processValue(value: unknown): unknown;
18
- abstract jsonArrayFn: string;
19
- abstract jsonGroupFn: string;
20
+ abstract runtime: Runtime;
20
21
  abstract emitIdentifier(value: string): void;
21
22
  abstract emitValue(value: unknown): void;
22
23
  abstract emitInline(value: unknown): void;
23
24
  abstract emitJsonPath(value: Array<number | string>): void;
24
25
  abstract emitPlaceholder(value: string): void;
25
- abstract emitDefaultValue(): void;
26
- abstract emitLastInsertId(): void;
27
- abstract emitIdColumn(): void;
28
26
  emitUnsafe(value: string): void;
29
27
  emitField(field: FieldData): void;
30
28
  emitCreateTable(tableApi: TableApi): void;
@@ -37,4 +35,5 @@ export declare abstract class Emitter {
37
35
  emitUpdate(update: Update<unknown>): void;
38
36
  emitWith(cte: Array<HasQuery & HasTarget>): void;
39
37
  emitInclude(data: IncludeData): void;
38
+ emitUniversal(runtimes: Partial<Record<Runtime | 'default', Sql>>): void;
40
39
  }
@@ -7,6 +7,8 @@ import {
7
7
  } from "./Internal.js";
8
8
  import { ValueParam } from "./Param.js";
9
9
  import { sql } from "./Sql.js";
10
+ import { callFunction } from "./expr/Functions.js";
11
+ import { jsonAggregateArray, jsonArray } from "./expr/Json.js";
10
12
  var Emitter = class {
11
13
  sql = "";
12
14
  params = [];
@@ -54,13 +56,10 @@ var Emitter = class {
54
56
  ]).emitTo(this);
55
57
  }
56
58
  emitReferences(fields) {
57
- sql.join([
59
+ callFunction(
58
60
  sql.identifier(fields[0].targetName),
59
- sql`(${sql.join(
60
- fields.map((field) => sql.identifier(field.fieldName)),
61
- sql`, `
62
- )})`
63
- ]).emitTo(this);
61
+ fields.map((field) => sql.identifier(field.fieldName))
62
+ ).emitTo(this);
64
63
  }
65
64
  emitDelete(deleteOp) {
66
65
  const { cte, from, where, returning } = getData(deleteOp);
@@ -148,13 +147,16 @@ var Emitter = class {
148
147
  if (!data.select.selection)
149
148
  throw new Error("No selection defined");
150
149
  const fields = data.select.selection.fieldNames();
151
- let subject = sql`${sql.unsafe(this.jsonArrayFn)}(${sql.join(
152
- fields.map((name) => sql`_.${sql.identifier(name)}`),
153
- sql`, `
154
- )})`;
155
- if (!data.first)
156
- subject = sql`${sql.unsafe(this.jsonGroupFn)}(${subject})`;
157
- sql`(select ${subject} from (${inner}) as _)`.emitTo(this);
150
+ const subject = jsonArray(
151
+ ...fields.map((name) => sql`_.${sql.identifier(name)}`)
152
+ );
153
+ sql`(select ${data.first ? subject : jsonAggregateArray(subject)} from (${inner}) as _)`.emitTo(this);
154
+ }
155
+ emitUniversal(runtimes) {
156
+ const sql2 = runtimes[this.runtime] ?? runtimes.default;
157
+ if (!sql2)
158
+ throw new Error("Unsupported runtime");
159
+ sql2.emitTo(this);
158
160
  }
159
161
  };
160
162
  export {
@@ -1,5 +1,6 @@
1
1
  export type QueryMode = 'sync' | 'async' | undefined;
2
- export type QueryDialect = 'universal' | 'sqlite' | 'mysql' | 'postgres';
2
+ export type Runtime = 'sqlite' | 'mysql' | 'postgres';
3
+ export type QueryDialect = 'universal' | Runtime;
3
4
  export type Deliver<Meta extends QueryMeta, Result> = Meta extends Either ? Result | Promise<Result> : Meta extends Sync ? Result : Promise<Result>;
4
5
  export interface QueryMeta {
5
6
  mode: QueryMode;
@@ -1,4 +1,4 @@
1
- import { type HasQuery, type HasResolver, type HasSql, type HasTarget, internalData, internalQuery } from './Internal.js';
1
+ import { internalData, internalQuery, type HasQuery, type HasResolver, type HasSql, type HasTarget } from './Internal.js';
2
2
  import type { Deliver, QueryMeta } from './MetaData.js';
3
3
  import type { PreparedStatement, Resolver } from './Resolver.js';
4
4
  import type { Sql } from './Sql.js';
@@ -26,7 +26,7 @@ export declare abstract class Query<Result, Meta extends QueryMeta> extends Exec
26
26
  abstract [internalQuery]: Sql;
27
27
  constructor(data: QueryData<Meta>);
28
28
  all(db?: HasResolver): Deliver<Meta, Array<Result>>;
29
- get(db?: HasResolver): Deliver<Meta, Result>;
29
+ get(db?: HasResolver): Deliver<Meta, Result | null>;
30
30
  run(db?: HasResolver): Deliver<Meta, void>;
31
31
  prepare<Inputs extends Record<string, unknown>>(name?: string): PreparedQuery<Result, Inputs, Meta>;
32
32
  toSQL(): {
@@ -60,9 +60,9 @@ var Query = class extends Executable {
60
60
  try {
61
61
  const result = prepared[resultType]();
62
62
  if (result instanceof Promise)
63
- return result.finally(prepared.free.bind(prepared));
63
+ return result.then((res) => res ?? null).finally(prepared.free.bind(prepared));
64
64
  prepared.free();
65
- return result;
65
+ return result ?? null;
66
66
  } catch (error) {
67
67
  prepared.free();
68
68
  throw error;
@@ -1,6 +1,7 @@
1
1
  import type { DriverSpecs } from './Driver.js';
2
2
  import type { Emitter } from './Emitter.js';
3
- import { internalSql, type HasSql } from './Internal.js';
3
+ import { type HasSql, internalSql } from './Internal.js';
4
+ import type { Runtime } from './MetaData.js';
4
5
  import type { FieldData } from './expr/Field.js';
5
6
  type EmitMethods = {
6
7
  [K in keyof Emitter as K extends `emit${string}` ? K : never]: Emitter[K];
@@ -45,6 +46,7 @@ export declare namespace sql {
45
46
  export function identifier<T>(identifier: string): Sql<T>;
46
47
  export function field<T>(field: FieldData): Sql<T>;
47
48
  export function chunk<Type extends keyof EmitMethods>(type: Type, inner: Parameters<EmitMethods[Type]>[0]): Sql;
49
+ export function universal(runtimes: Partial<Record<Runtime | 'default', Sql>>): Sql;
48
50
  type QueryChunk = HasSql | undefined;
49
51
  export function query(ast: Record<string, boolean | QueryChunk | Array<QueryChunk>>): Sql;
50
52
  export function join<T>(items: Array<Sql | HasSql | undefined | false>, separator?: Sql): Sql<T>;
package/dist/core/Sql.js CHANGED
@@ -136,6 +136,10 @@ function sql(strings, ...inner) {
136
136
  return empty().chunk(type, inner);
137
137
  }
138
138
  sql2.chunk = chunk;
139
+ function universal(runtimes) {
140
+ return chunk("emitUniversal", runtimes);
141
+ }
142
+ sql2.universal = universal;
139
143
  function query(ast) {
140
144
  return join(
141
145
  Object.entries(ast).map(([key, value2]) => {
@@ -1,6 +1,6 @@
1
1
  import { type HasSql } from '../Internal.js';
2
2
  import { type Sql } from '../Sql.js';
3
- import type { SelectBase } from '../query/Select.js';
3
+ import type { Select } from '../query/Select.js';
4
4
  import { type Input } from './Input.js';
5
5
  export declare const eq: <T>(left: Input<T>, right: Input<T>) => Sql<boolean>;
6
6
  export declare const ne: <T>(left: Input<T>, right: Input<T>) => Sql<boolean>;
@@ -29,4 +29,4 @@ export declare function desc<T>(input: HasSql<T>): Sql;
29
29
  export declare function distinct<T>(input: HasSql<T>): Sql;
30
30
  export declare function when<In, Out>(compare: Input<In>, ...cases: Array<[condition: Input<In>, result: Input<Out>] | Input<Out>>): Sql<Out>;
31
31
  export declare function when<Out>(...cases: Array<[condition: Input<boolean>, result: Input<Out>] | Input<Out>>): Sql<Out>;
32
- export declare function exists<T>(query: SelectBase<T>): Sql<boolean>;
32
+ export declare function exists<T>(query: Select<T>): Sql<boolean>;
@@ -1,5 +1,6 @@
1
1
  import { type Sql } from '../Sql.js';
2
2
  import { type Input } from './Input.js';
3
+ export declare function callFunction<Result>(name: Sql, args: Array<Input<unknown>>): Sql<Result>;
3
4
  export declare const Functions: Functions;
4
5
  export type Functions = {
5
6
  [key: string]: (...args: Array<Input<any>>) => Sql<any>;
@@ -1,12 +1,16 @@
1
1
  // src/core/expr/Functions.ts
2
2
  import { sql } from "../Sql.js";
3
3
  import { input } from "./Input.js";
4
+ function callFunction(name, args) {
5
+ return sql`${name}(${sql.join(args.map(input), sql`, `)})`;
6
+ }
4
7
  function get(target, method) {
5
8
  return target[method] ??= (...args) => {
6
- return sql`${sql.identifier(method)}(${sql.join(args.map(input), sql`, `)})`;
9
+ return callFunction(sql.identifier(method), args);
7
10
  };
8
11
  }
9
12
  var Functions = new Proxy(/* @__PURE__ */ Object.create(null), { get });
10
13
  export {
11
- Functions
14
+ Functions,
15
+ callFunction
12
16
  };
@@ -1,4 +1,5 @@
1
1
  import type { HasSql } from '../Internal.js';
2
+ import type { Input } from './Input.js';
2
3
  export interface JsonArrayHasSql<Value> extends HasSql<Array<Value>> {
3
4
  [index: number]: JsonExpr<Value>;
4
5
  }
@@ -10,4 +11,6 @@ type NullableEach<T> = {
10
11
  };
11
12
  export type JsonExpr<Value> = [NonNullable<Value>] extends [Array<infer V>] ? JsonArrayHasSql<null extends Value ? V | null : V> : [NonNullable<Value>] extends [object] ? JsonRecordHasSql<null extends Value ? NullableEach<Value> : Value> : HasSql<Value>;
12
13
  export declare function jsonExpr<Value>(e: HasSql<Value>): JsonExpr<Value>;
14
+ export declare function jsonAggregateArray(...args: Array<Input<unknown>>): import("../Sql.ts").Sql<unknown>;
15
+ export declare function jsonArray(...args: Array<Input<unknown>>): import("../Sql.ts").Sql<unknown>;
13
16
  export {};
@@ -1,5 +1,6 @@
1
1
  // src/core/expr/Json.ts
2
2
  import { sql } from "../Sql.js";
3
+ import { callFunction } from "./Functions.js";
3
4
  var INDEX_PROPERTY = /^\d+$/;
4
5
  function jsonExpr(e) {
5
6
  return new Proxy(e, {
@@ -11,6 +12,27 @@ function jsonExpr(e) {
11
12
  }
12
13
  });
13
14
  }
15
+ function jsonAggregateArray(...args) {
16
+ return callFunction(
17
+ sql.universal({
18
+ sqlite: sql`json_group_array`,
19
+ postgres: sql`json_agg`,
20
+ mysql: sql`json_arrayagg`
21
+ }),
22
+ args
23
+ );
24
+ }
25
+ function jsonArray(...args) {
26
+ return callFunction(
27
+ sql.universal({
28
+ postgres: sql`json_build_array`,
29
+ default: sql`json_array`
30
+ }),
31
+ args
32
+ );
33
+ }
14
34
  export {
35
+ jsonAggregateArray,
36
+ jsonArray,
15
37
  jsonExpr
16
38
  };
@@ -1,8 +1,9 @@
1
- import { internalData, internalQuery, internalSelection, type HasSql, type HasTable } from '../Internal.js';
2
- import type { QueryMeta } from '../MetaData.js';
1
+ import { type HasSql, type HasTable, internalData, internalQuery, internalSelection } from '../Internal.js';
2
+ import type { IsPostgres, IsSqlite, QueryMeta } from '../MetaData.js';
3
3
  import { Query, type QueryData } from '../Query.js';
4
4
  import { type Selection, type SelectionInput, type SelectionRow } from '../Selection.js';
5
5
  import { type Sql } from '../Sql.js';
6
+ import type { TableDefinition, TableRow } from '../Table.js';
6
7
  export interface DeleteData<Meta extends QueryMeta = QueryMeta> extends QueryData<Meta> {
7
8
  from: HasTable;
8
9
  where?: HasSql;
@@ -14,7 +15,8 @@ export declare class Delete<Result, Meta extends QueryMeta = QueryMeta> extends
14
15
  constructor(data: DeleteData<Meta>);
15
16
  get [internalQuery](): Sql;
16
17
  }
17
- export declare class DeleteFrom<Meta extends QueryMeta> extends Delete<void, Meta> {
18
- where(condition: HasSql<boolean>): DeleteFrom<Meta>;
19
- returning<Input extends SelectionInput>(returning: Input): Delete<SelectionRow<Input>, Meta>;
18
+ export declare class DeleteFrom<Definition extends TableDefinition, Meta extends QueryMeta> extends Delete<void, Meta> {
19
+ where(...where: Array<HasSql<boolean> | undefined>): DeleteFrom<Definition, Meta>;
20
+ returning(this: DeleteFrom<Definition, IsPostgres | IsSqlite>): Delete<TableRow<Definition>, Meta>;
21
+ returning<Input extends SelectionInput>(this: DeleteFrom<Definition, IsPostgres | IsSqlite>, returning: Input): Delete<SelectionRow<Input>, Meta>;
20
22
  }
@@ -10,6 +10,7 @@ import {
10
10
  selection
11
11
  } from "../Selection.js";
12
12
  import { sql } from "../Sql.js";
13
+ import { and } from "../expr/Conditions.js";
13
14
  var Delete = class extends Query {
14
15
  [internalData];
15
16
  constructor(data) {
@@ -23,13 +24,14 @@ var Delete = class extends Query {
23
24
  }
24
25
  };
25
26
  var DeleteFrom = class _DeleteFrom extends Delete {
26
- where(condition) {
27
- return new _DeleteFrom({ ...getData(this), where: condition });
27
+ where(...where) {
28
+ return new _DeleteFrom({ ...getData(this), where: and(...where) });
28
29
  }
29
30
  returning(returning) {
31
+ const data = getData(this);
30
32
  return new Delete({
31
- ...getData(this),
32
- returning: selection(returning)
33
+ ...data,
34
+ returning: selection(returning ?? data.from)
33
35
  });
34
36
  }
35
37
  };
@@ -66,6 +66,10 @@ var InsertCanConflict = class extends InsertCanReturn {
66
66
  });
67
67
  }
68
68
  };
69
+ var defaultKeyword = sql.universal({
70
+ sqlite: sql`null`,
71
+ default: sql`default`
72
+ });
69
73
  var InsertInto = class {
70
74
  [internalData];
71
75
  constructor(data) {
@@ -85,7 +89,7 @@ var InsertInto = class {
85
89
  return input(mapToDriverValue?.(value) ?? value);
86
90
  if (defaultValue)
87
91
  return defaultValue();
88
- return sql.chunk("emitDefaultValue", void 0);
92
+ return defaultKeyword;
89
93
  }),
90
94
  sql`, `
91
95
  )})`;
@@ -1,4 +1,4 @@
1
- import { internalData, internalQuery, internalSelection, type HasSelection, type HasSql, type HasTable, type HasTarget } from '../Internal.js';
1
+ import { type HasSelection, type HasSql, type HasTable, type HasTarget, internalData, internalQuery, internalSelection } from '../Internal.js';
2
2
  import type { QueryMeta } from '../MetaData.js';
3
3
  import type { Query } from '../Query.js';
4
4
  import { type IsNullable, type MakeNullable, type Selection, type SelectionRecord, type SelectionRow } from '../Selection.js';
@@ -35,7 +35,7 @@ export declare class Select<Input, Meta extends QueryMeta = QueryMeta> extends U
35
35
  rightJoin(right: HasTable, on: HasSql<boolean>): Select<Input, Meta>;
36
36
  innerJoin(right: HasTable, on: HasSql<boolean>): Select<Input, Meta>;
37
37
  fullJoin(right: HasTable, on: HasSql<boolean>): Select<Input, Meta>;
38
- where(...where: Array<HasSql<boolean>>): Select<Input, Meta>;
38
+ where(...where: Array<HasSql<boolean> | undefined>): Select<Input, Meta>;
39
39
  groupBy(...exprs: Array<HasSql>): Select<Input, Meta>;
40
40
  having(having: HasSql<boolean>): Select<Input, Meta>;
41
41
  orderBy(...exprs: Array<HasSql>): Select<Input, Meta>;
@@ -18,7 +18,7 @@ export declare class Update<Result, Meta extends QueryMeta = QueryMeta> extends
18
18
  }
19
19
  export declare class UpdateTable<Definition extends TableDefinition, Meta extends QueryMeta> extends Update<void, Meta> {
20
20
  set(values: TableUpdate<Definition>): UpdateTable<Definition, Meta>;
21
- where(where: HasSql<boolean>): UpdateTable<Definition, Meta>;
21
+ where(...where: Array<HasSql<boolean> | undefined>): UpdateTable<Definition, Meta>;
22
22
  returning(this: UpdateTable<Definition, IsPostgres | IsSqlite>): Update<TableRow<Definition>, Meta>;
23
23
  returning<Input extends SelectionInput>(this: UpdateTable<Definition, IsPostgres | IsSqlite>, returning?: Input): Update<SelectionRow<Input>, Meta>;
24
24
  }
@@ -11,6 +11,7 @@ import {
11
11
  selection
12
12
  } from "../Selection.js";
13
13
  import { sql } from "../Sql.js";
14
+ import { and } from "../expr/Conditions.js";
14
15
  import { input } from "../expr/Input.js";
15
16
  var Update = class extends Query {
16
17
  [internalData];
@@ -39,8 +40,11 @@ var UpdateTable = class _UpdateTable extends Update {
39
40
  );
40
41
  return new _UpdateTable({ ...getData(this), set });
41
42
  }
42
- where(where) {
43
- return new _UpdateTable({ ...getData(this), where });
43
+ where(...where) {
44
+ return new _UpdateTable({
45
+ ...getData(this),
46
+ where: and(...where)
47
+ });
44
48
  }
45
49
  returning(returning) {
46
50
  const data = getData(this);
@@ -2,6 +2,7 @@
2
2
  import { AsyncDatabase } from "../core/Database.js";
3
3
  import { mysqlDialect } from "../mysql/dialect.js";
4
4
  import { mysqlDiff } from "../mysql/diff.js";
5
+ import { setTransaction, startTransaction } from "../mysql/transactions.js";
5
6
  var PreparedStatement = class {
6
7
  constructor(client, sql, name) {
7
8
  this.client = client;
@@ -54,7 +55,14 @@ var Mysql2Driver = class _Mysql2Driver {
54
55
  const client = isPool(this.client) ? await this.client.getConnection() : this.client;
55
56
  const driver = new _Mysql2Driver(client, this.depth + 1);
56
57
  try {
57
- await client.query(this.depth > 0 ? `savepoint d${this.depth}` : "begin");
58
+ await client.query(
59
+ this.depth > 0 ? `savepoint d${this.depth}` : startTransaction(options)
60
+ );
61
+ if (this.depth === 0) {
62
+ const setOptions = setTransaction(options);
63
+ if (setOptions)
64
+ await client.query(setOptions);
65
+ }
58
66
  const result = await run(driver);
59
67
  await client.query(
60
68
  this.depth > 0 ? `release savepoint d${this.depth}` : "commit"
package/dist/driver/pg.js CHANGED
@@ -2,6 +2,7 @@
2
2
  import { AsyncDatabase } from "../core/Database.js";
3
3
  import { postgresDialect } from "../postgres/dialect.js";
4
4
  import { postgresDiff } from "../postgres/diff.js";
5
+ import { setTransaction } from "../postgres/transactions.js";
5
6
  var PreparedStatement = class {
6
7
  constructor(client, sql, name) {
7
8
  this.client = client;
@@ -69,6 +70,8 @@ var PgDriver = class _PgDriver {
69
70
  const client = "totalCount" in this.client ? await this.client.connect() : this.client;
70
71
  try {
71
72
  await client.query(this.depth > 0 ? `savepoint d${this.depth}` : "begin");
73
+ if (this.depth === 0)
74
+ await client.query(setTransaction(options));
72
75
  const result = await run(new _PgDriver(client, this.depth + 1));
73
76
  await client.query(
74
77
  this.depth > 0 ? `release savepoint d${this.depth}` : "commit"
@@ -2,6 +2,7 @@
2
2
  import { AsyncDatabase } from "../index.js";
3
3
  import { postgresDialect } from "../postgres/dialect.js";
4
4
  import { postgresDiff } from "../postgres/diff.js";
5
+ import { setTransaction } from "../postgres/transactions.js";
5
6
  var PreparedStatement = class {
6
7
  constructor(client, sql) {
7
8
  this.client = client;
@@ -59,7 +60,8 @@ var PGliteDriver = class _PGliteDriver {
59
60
  }
60
61
  async transaction(run, options) {
61
62
  if (this.depth === 0 && "transaction" in this.client)
62
- return this.client.transaction((tx) => {
63
+ return this.client.transaction(async (tx) => {
64
+ await tx.query(setTransaction(options));
63
65
  return run(new _PGliteDriver(tx, this.depth + 1));
64
66
  });
65
67
  await this.exec(`savepoint d${this.depth}`);
@@ -10,9 +10,8 @@ var ESCAPE_SINGLE_QUOTE = "''";
10
10
  var MATCH_SINGLE_QUOTE = /'/g;
11
11
  var mysqlDialect = new Dialect(
12
12
  class extends Emitter {
13
+ runtime = "mysql";
13
14
  paramIndex = 0;
14
- jsonArrayFn = "json_array";
15
- jsonGroupFn = "json_arrayagg";
16
15
  emitValue(value) {
17
16
  this.sql += "?";
18
17
  this.params.push(new ValueParam(value));
@@ -41,15 +40,6 @@ var mysqlDialect = new Dialect(
41
40
  emitIdentifier(identifier) {
42
41
  this.sql += BACKTICK + identifier.replace(MATCH_BACKTICK, ESCAPE_BACKTICK) + BACKTICK;
43
42
  }
44
- emitDefaultValue() {
45
- this.sql += "default";
46
- }
47
- emitIdColumn() {
48
- this.sql += "int not null auto_increment";
49
- }
50
- emitLastInsertId() {
51
- this.sql += "last_insert_id()";
52
- }
53
43
  }
54
44
  );
55
45
  export {
@@ -0,0 +1,3 @@
1
+ import type { TransactionOptions } from '../core/Database.js';
2
+ export declare function startTransaction(options: TransactionOptions['mysql']): string;
3
+ export declare function setTransaction(options: TransactionOptions['mysql']): string | undefined;
@@ -0,0 +1,20 @@
1
+ // src/mysql/transactions.ts
2
+ function startTransaction(options) {
3
+ return [
4
+ "start transaction",
5
+ options.withConsistentSnapshot && "with consistent snapshot",
6
+ options.accessMode
7
+ ].filter(Boolean).join(" ");
8
+ }
9
+ function setTransaction(options) {
10
+ if (!options.isolationLevel)
11
+ return;
12
+ return [
13
+ "set transaction",
14
+ options.isolationLevel && `isolation level ${options.isolationLevel}`
15
+ ].filter(Boolean).join(" ");
16
+ }
17
+ export {
18
+ setTransaction,
19
+ startTransaction
20
+ };
@@ -10,9 +10,8 @@ var ESCAPE_SINGLE_QUOTE = "''";
10
10
  var MATCH_SINGLE_QUOTE = /'/g;
11
11
  var postgresDialect = new Dialect(
12
12
  class extends Emitter {
13
+ runtime = "postgres";
13
14
  paramIndex = 0;
14
- jsonArrayFn = "json_build_array";
15
- jsonGroupFn = "json_agg";
16
15
  emitValue(value) {
17
16
  this.sql += `$${++this.paramIndex}`;
18
17
  this.params.push(new ValueParam(value));
@@ -49,15 +48,6 @@ var postgresDialect = new Dialect(
49
48
  emitIdentifier(identifier) {
50
49
  this.sql += DOUBLE_QUOTE + identifier.replace(MATCH_DOUBLE_QUOTE, ESCAPE_DOUBLE_QUOTE) + DOUBLE_QUOTE;
51
50
  }
52
- emitDefaultValue() {
53
- this.sql += "default";
54
- }
55
- emitIdColumn() {
56
- this.sql += "integer generated always as identity";
57
- }
58
- emitLastInsertId() {
59
- this.sql += "lastval()";
60
- }
61
51
  }
62
52
  );
63
53
  export {
@@ -0,0 +1,2 @@
1
+ import type { TransactionOptions } from '../core/Database.js';
2
+ export declare function setTransaction(options: TransactionOptions['postgres']): string;
@@ -0,0 +1,12 @@
1
+ // src/postgres/transactions.ts
2
+ function setTransaction(options) {
3
+ return [
4
+ "set transaction",
5
+ options.isolationLevel && `isolation level ${options.isolationLevel}`,
6
+ options.accessMode,
7
+ options.deferrable ? "deferrable" : "not deferrable"
8
+ ].filter(Boolean).join(" ");
9
+ }
10
+ export {
11
+ setTransaction
12
+ };
@@ -10,8 +10,7 @@ var ESCAPE_SINGLE_QUOTE = "''";
10
10
  var MATCH_SINGLE_QUOTE = /'/g;
11
11
  var sqliteDialect = new Dialect(
12
12
  class extends Emitter {
13
- jsonArrayFn = "json_array";
14
- jsonGroupFn = "json_group_array";
13
+ runtime = "sqlite";
15
14
  processValue(value) {
16
15
  return typeof value === "boolean" ? value ? 1 : 0 : value;
17
16
  }
@@ -42,18 +41,9 @@ var sqliteDialect = new Dialect(
42
41
  emitIdentifier(identifier) {
43
42
  this.sql += DOUBLE_QUOTE + identifier.replace(MATCH_DOUBLE_QUOTE, ESCAPE_DOUBLE_QUOTE) + DOUBLE_QUOTE;
44
43
  }
45
- emitDefaultValue() {
46
- this.sql += "null";
47
- }
48
44
  quoteString(input) {
49
45
  return SINGLE_QUOTE + input.replace(MATCH_SINGLE_QUOTE, ESCAPE_SINGLE_QUOTE) + SINGLE_QUOTE;
50
46
  }
51
- emitIdColumn() {
52
- this.sql += "integer";
53
- }
54
- emitLastInsertId() {
55
- this.sql += "last_insert_rowid()";
56
- }
57
47
  }
58
48
  );
59
49
  export {
@@ -142,7 +142,7 @@ var sqliteDiff = (hasTable) => {
142
142
  );
143
143
  const selection = { ...hasTable };
144
144
  for (const name of missingColumns) {
145
- selection[name] = getData(tableApi.columns[name]).defaultValue?.() ?? sql.chunk("emitDefaultValue", void 0);
145
+ selection[name] = getData(tableApi.columns[name]).defaultValue?.() ?? sql`null`;
146
146
  }
147
147
  return [
148
148
  // Create a new temporary table with the new definition
@@ -1,4 +1,4 @@
1
- import { JsonColumn, type Column } from '../core/Column.js';
1
+ import { type Column, JsonColumn } from '../core/Column.js';
2
2
  export declare function id(name?: string): Column<number>;
3
3
  export declare function text(name?: string): Column<string | null>;
4
4
  export declare function integer(name?: string): Column<number | null>;
@@ -1,10 +1,15 @@
1
1
  // src/universal/columns.ts
2
2
  import { JsonColumn, column } from "../core/Column.js";
3
3
  import { sql } from "../core/Sql.js";
4
+ var idType = sql.universal({
5
+ sqlite: sql`integer`,
6
+ postgres: sql`integer generated always as identity`,
7
+ mysql: sql`int not null auto_increment`
8
+ });
4
9
  function id(name) {
5
10
  return column({
6
11
  name,
7
- type: sql.chunk("emitIdColumn", void 0),
12
+ type: idType,
8
13
  primary: true
9
14
  });
10
15
  }
@@ -1,4 +1,4 @@
1
1
  import { type Sql } from '../core/Sql.js';
2
- import { type Input } from '../core/expr/Input.js';
2
+ import type { Input } from '../core/expr/Input.js';
3
3
  export declare function lastInsertId(): Sql<number>;
4
4
  export declare function concat(...slices: Array<Input<string | null>>): Sql<string>;
@@ -1,11 +1,16 @@
1
1
  // src/universal/functions.ts
2
2
  import { sql } from "../core/Sql.js";
3
- import { input } from "../core/expr/Input.js";
3
+ import { callFunction } from "../core/expr/Functions.js";
4
+ var insertId = sql.universal({
5
+ sqlite: sql`last_insert_rowid()`,
6
+ postgres: sql`lastval()`,
7
+ mysql: sql`last_insert_id()`
8
+ }).mapWith(Number);
4
9
  function lastInsertId() {
5
- return sql.chunk("emitLastInsertId", void 0).mapWith(Number);
10
+ return insertId;
6
11
  }
7
12
  function concat(...slices) {
8
- return sql`concat(${sql.join(slices.map(input), sql`, `)})`;
13
+ return callFunction(sql`concat`, slices);
9
14
  }
10
15
  export {
11
16
  concat,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rado",
3
- "version": "1.0.0-preview.5",
3
+ "version": "1.0.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -39,7 +39,7 @@
39
39
  "better-sqlite3": "^11.0.0",
40
40
  "esbuild": "^0.18.11",
41
41
  "glob": "^8.0.3",
42
- "madge": "^6.1.0",
42
+ "madge": "^8.0.0",
43
43
  "mysql2": "^3.9.7",
44
44
  "pg": "^8.11.5",
45
45
  "rimraf": "^4.1.2",