rado 1.0.15 → 1.2.0

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.
Files changed (81) hide show
  1. package/dist/compat.d.ts +3 -3
  2. package/dist/compat.js +2 -0
  3. package/dist/core/Builder.d.ts +14 -9
  4. package/dist/core/Builder.js +24 -32
  5. package/dist/core/Column.d.ts +13 -4
  6. package/dist/core/Column.js +43 -8
  7. package/dist/core/Constraint.d.ts +16 -5
  8. package/dist/core/Constraint.js +17 -6
  9. package/dist/core/Database.d.ts +11 -4
  10. package/dist/core/Database.js +20 -4
  11. package/dist/core/Dialect.js +2 -2
  12. package/dist/core/Driver.d.ts +3 -3
  13. package/dist/core/Emitter.d.ts +7 -29
  14. package/dist/core/Emitter.js +31 -139
  15. package/dist/core/Index.d.ts +1 -1
  16. package/dist/core/Internal.d.ts +5 -4
  17. package/dist/core/Queries.d.ts +46 -0
  18. package/dist/core/{Query.js → Queries.js} +10 -8
  19. package/dist/core/Resolver.d.ts +2 -2
  20. package/dist/core/Selection.d.ts +7 -10
  21. package/dist/core/Selection.js +15 -13
  22. package/dist/core/Sql.d.ts +8 -29
  23. package/dist/core/Sql.js +67 -118
  24. package/dist/core/Table.d.ts +7 -3
  25. package/dist/core/Table.js +24 -8
  26. package/dist/core/Virtual.d.ts +1 -1
  27. package/dist/core/Virtual.js +15 -14
  28. package/dist/core/expr/Conditions.d.ts +4 -4
  29. package/dist/core/expr/Conditions.js +18 -8
  30. package/dist/core/expr/Field.d.ts +8 -6
  31. package/dist/core/expr/Field.js +3 -3
  32. package/dist/core/expr/Include.d.ts +10 -7
  33. package/dist/core/expr/Include.js +29 -12
  34. package/dist/core/expr/Input.d.ts +3 -1
  35. package/dist/core/expr/Input.js +24 -7
  36. package/dist/core/expr/Json.js +2 -2
  37. package/dist/core/query/CTE.d.ts +8 -0
  38. package/dist/core/query/CTE.js +33 -0
  39. package/dist/core/query/Delete.d.ts +14 -13
  40. package/dist/core/query/Delete.js +32 -6
  41. package/dist/core/query/Insert.d.ts +17 -36
  42. package/dist/core/query/Insert.js +121 -72
  43. package/dist/core/query/Query.d.ts +124 -0
  44. package/dist/core/query/Select.d.ts +74 -33
  45. package/dist/core/query/Select.js +255 -57
  46. package/dist/core/query/Shared.d.ts +3 -0
  47. package/dist/core/query/Shared.js +23 -0
  48. package/dist/core/query/Update.d.ts +13 -13
  49. package/dist/core/query/Update.js +51 -22
  50. package/dist/driver/d1.d.ts +2 -2
  51. package/dist/driver/libsql.d.ts +2 -2
  52. package/dist/driver/mysql2.d.ts +2 -2
  53. package/dist/driver/pg.d.ts +2 -2
  54. package/dist/driver/pglite.d.ts +2 -2
  55. package/dist/index.d.ts +7 -7
  56. package/dist/index.js +7 -7
  57. package/dist/mysql/columns.d.ts +37 -37
  58. package/dist/mysql/columns.js +32 -15
  59. package/dist/mysql/dialect.js +6 -7
  60. package/dist/mysql/diff.js +2 -1
  61. package/dist/mysql.d.ts +3 -2
  62. package/dist/mysql.js +11 -2
  63. package/dist/postgres/columns.d.ts +13 -13
  64. package/dist/postgres/columns.js +15 -6
  65. package/dist/postgres/dialect.js +6 -7
  66. package/dist/postgres/diff.js +2 -1
  67. package/dist/postgres.d.ts +3 -2
  68. package/dist/postgres.js +11 -2
  69. package/dist/sqlite/columns.d.ts +16 -1
  70. package/dist/sqlite/columns.js +36 -3
  71. package/dist/sqlite/dialect.js +6 -6
  72. package/dist/sqlite/diff.js +3 -5
  73. package/dist/sqlite.d.ts +3 -2
  74. package/dist/sqlite.js +11 -2
  75. package/dist/universal/functions.js +4 -1
  76. package/package.json +4 -4
  77. package/dist/core/Join.d.ts +0 -1
  78. package/dist/core/Query.d.ts +0 -46
  79. package/dist/core/query/Union.d.ts +0 -35
  80. package/dist/core/query/Union.js +0 -107
  81. /package/dist/core/{Join.js → query/Query.js} +0 -0
@@ -1,12 +1,29 @@
1
1
  // src/core/expr/Input.ts
2
- import { getSql, getTable, hasSql, hasTable } from "../Internal.js";
2
+ import {
3
+ getField,
4
+ getSql,
5
+ getTable,
6
+ hasField,
7
+ hasSql,
8
+ hasTable
9
+ } from "../Internal.js";
3
10
  import { sql } from "../Sql.js";
4
- function input(value) {
5
- if (typeof value !== "object" || value === null) return sql.value(value);
6
- if (hasTable(value)) return sql.identifier(getTable(value).name);
7
- if (hasSql(value)) return getSql(value);
8
- return sql.value(value);
11
+ function input(value, maybeField) {
12
+ const isObject = value && typeof value === "object";
13
+ if (isObject && hasTable(value))
14
+ return sql.identifier(getTable(value).aliased);
15
+ if (isObject && hasSql(value)) return getSql(value);
16
+ const fieldSource = maybeField && typeof maybeField === "object" && hasField(maybeField) && getField(maybeField).source;
17
+ return fieldSource && "mapToDriverValue" in fieldSource ? mapToColumn(fieldSource, value) : sql.value(value);
18
+ }
19
+ function mapToColumn({ mapToDriverValue }, expr) {
20
+ const isObject = expr && typeof expr === "object";
21
+ if (isObject && hasSql(expr)) return getSql(expr);
22
+ return input(
23
+ expr !== null && mapToDriverValue ? mapToDriverValue(expr) : expr
24
+ );
9
25
  }
10
26
  export {
11
- input
27
+ input,
28
+ mapToColumn
12
29
  };
@@ -11,8 +11,8 @@ function jsonExpr(e) {
11
11
  return jsonExpr(
12
12
  sql.jsonPath({
13
13
  target: getSql(target),
14
- asSql: true,
15
- segments: [isNumber ? Number(prop) : prop]
14
+ segments: [isNumber ? Number(prop) : prop],
15
+ asSql: true
16
16
  }).mapWith({
17
17
  mapFromDriverValue(value, specs) {
18
18
  return specs.parsesJson ? value : JSON.parse(value);
@@ -0,0 +1,8 @@
1
+ import { type HasQuery, type HasTarget } from '../Internal.js';
2
+ import type { SelectionInput } from '../Selection.js';
3
+ import { type Sql } from '../Sql.js';
4
+ import type { QueryBase } from './Query.js';
5
+ import type { UnionBase } from './Select.js';
6
+ export type CTE<Input = unknown> = Input & HasTarget & HasQuery;
7
+ export declare function createCTE<Input extends SelectionInput>(cteName: string, query: UnionBase<Input>): CTE<Input>;
8
+ export declare function formatCTE(query: QueryBase): Sql | undefined;
@@ -0,0 +1,33 @@
1
+ // src/core/query/CTE.ts
2
+ import {
3
+ getQuery,
4
+ getSelection,
5
+ getTarget,
6
+ internalQuery
7
+ } from "../Internal.js";
8
+ import { sql } from "../Sql.js";
9
+ function createCTE(cteName, query) {
10
+ const fields = getSelection(query).makeVirtual(cteName);
11
+ return Object.assign(fields, {
12
+ [internalQuery]: getQuery(query).nameSelf(cteName)
13
+ });
14
+ }
15
+ function formatCTE(query) {
16
+ const isRecursive = query.withRecursive;
17
+ const definitions = isRecursive ? query.withRecursive : query.with;
18
+ if (!definitions) return;
19
+ return sql.query({
20
+ [isRecursive ? "withRecursive" : "with"]: sql.join(
21
+ definitions.map((cte) => {
22
+ const query2 = getQuery(cte);
23
+ const target = getTarget(cte);
24
+ return sql`${target} as (${query2})`;
25
+ }),
26
+ sql`, `
27
+ )
28
+ });
29
+ }
30
+ export {
31
+ createCTE,
32
+ formatCTE
33
+ };
@@ -1,22 +1,23 @@
1
- import { type HasSql, type HasTable, internalData, internalQuery, internalSelection } from '../Internal.js';
1
+ import { type HasQuery, type HasSql, internalData, internalQuery, internalSelection } from '../Internal.js';
2
2
  import type { IsPostgres, IsSqlite, QueryMeta } from '../MetaData.js';
3
- import { Query, type QueryData } from '../Query.js';
3
+ import { type QueryData, SingleQuery } from '../Queries.js';
4
4
  import { type Selection, type SelectionInput, type SelectionRow } from '../Selection.js';
5
5
  import { type Sql } from '../Sql.js';
6
6
  import type { TableDefinition, TableRow } from '../Table.js';
7
- export interface DeleteData<Meta extends QueryMeta = QueryMeta> extends QueryData<Meta> {
8
- from: HasTable;
9
- where?: HasSql;
10
- returning?: Selection;
11
- }
12
- export declare class Delete<Result, Meta extends QueryMeta = QueryMeta> extends Query<Result, Meta> {
13
- readonly [internalData]: DeleteData<Meta>;
7
+ import type { Input } from '../expr/Input.js';
8
+ import type { DeleteQuery } from './Query.js';
9
+ export declare class Delete<Result, Meta extends QueryMeta = QueryMeta> extends SingleQuery<Result, Meta> implements HasQuery<Result> {
10
+ readonly [internalData]: QueryData<Meta> & DeleteQuery;
14
11
  readonly [internalSelection]?: Selection;
15
- constructor(data: DeleteData<Meta>);
16
- get [internalQuery](): Sql;
12
+ constructor(data: QueryData<Meta> & DeleteQuery);
13
+ get [internalQuery](): Sql<Result>;
14
+ limit(limit: Input<number>): Delete<Result, Meta>;
15
+ offset(offset: Input<number>): Delete<Result, Meta>;
16
+ orderBy(...orderBy: Array<HasSql>): Delete<Result, Meta>;
17
17
  }
18
18
  export declare class DeleteFrom<Definition extends TableDefinition, Meta extends QueryMeta> extends Delete<void, Meta> {
19
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
+ returning(this: DeleteFrom<Definition, IsPostgres | IsSqlite>): Delete<Array<TableRow<Definition>>, Meta>;
21
+ returning<Input extends SelectionInput>(this: DeleteFrom<Definition, IsPostgres | IsSqlite>, returning: Input): Delete<Array<SelectionRow<Input>>, Meta>;
22
22
  }
23
+ export declare function deleteQuery(query: DeleteQuery): Sql;
@@ -1,25 +1,37 @@
1
1
  // src/core/query/Delete.ts
2
2
  import {
3
3
  getData,
4
+ getTable,
4
5
  internalData,
5
6
  internalQuery,
6
7
  internalSelection
7
8
  } from "../Internal.js";
8
- import { Query } from "../Query.js";
9
+ import { SingleQuery } from "../Queries.js";
9
10
  import {
10
11
  selection
11
12
  } from "../Selection.js";
12
13
  import { sql } from "../Sql.js";
13
14
  import { and } from "../expr/Conditions.js";
14
- var Delete = class extends Query {
15
+ import { formatCTE } from "./CTE.js";
16
+ import { formatModifiers } from "./Shared.js";
17
+ var Delete = class _Delete extends SingleQuery {
15
18
  [internalData];
16
19
  constructor(data) {
17
20
  super(data);
18
21
  this[internalData] = data;
19
- if (data.returning) this[internalSelection] = data.returning;
22
+ if (data.returning) this[internalSelection] = selection(data.returning);
20
23
  }
21
24
  get [internalQuery]() {
22
- return sql.chunk("emitDelete", this);
25
+ return deleteQuery(getData(this));
26
+ }
27
+ limit(limit) {
28
+ return new _Delete({ ...getData(this), limit });
29
+ }
30
+ offset(offset) {
31
+ return new _Delete({ ...getData(this), offset });
32
+ }
33
+ orderBy(...orderBy) {
34
+ return new _Delete({ ...getData(this), orderBy });
23
35
  }
24
36
  };
25
37
  var DeleteFrom = class _DeleteFrom extends Delete {
@@ -30,11 +42,25 @@ var DeleteFrom = class _DeleteFrom extends Delete {
30
42
  const data = getData(this);
31
43
  return new Delete({
32
44
  ...data,
33
- returning: returning ? selection(returning) : selection.table(data.from)
45
+ returning: returning ?? data.delete
34
46
  });
35
47
  }
36
48
  };
49
+ function deleteQuery(query) {
50
+ const { delete: from, where, returning } = query;
51
+ const table = getTable(from);
52
+ return sql.query(
53
+ formatCTE(query),
54
+ {
55
+ deleteFrom: sql.identifier(table.name),
56
+ where,
57
+ returning: returning && selection(returning)
58
+ },
59
+ formatModifiers(query)
60
+ );
61
+ }
37
62
  export {
38
63
  Delete,
39
- DeleteFrom
64
+ DeleteFrom,
65
+ deleteQuery
40
66
  };
@@ -1,50 +1,31 @@
1
- import { type HasSql, type HasTable, internalData, internalQuery, internalSelection } from '../Internal.js';
1
+ import { type HasQuery, internalData, internalQuery, internalSelection } from '../Internal.js';
2
2
  import type { IsMysql, IsPostgres, IsSqlite, QueryMeta } from '../MetaData.js';
3
- import { Query, type QueryData } from '../Query.js';
3
+ import { type QueryData, SingleQuery } from '../Queries.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, TableInsert, TableRow, TableUpdate } from '../Table.js';
7
- interface InsertIntoData<Meta extends QueryMeta> extends QueryData<Meta> {
8
- into: HasTable;
9
- values?: HasSql;
10
- select?: HasSql;
11
- }
12
- export interface InsertData<Meta extends QueryMeta> extends InsertIntoData<Meta> {
13
- returning?: Selection;
14
- onConflict?: HasSql;
15
- onDuplicateKeyUpdate?: HasSql;
16
- }
17
- export declare class Insert<Result, Meta extends QueryMeta = QueryMeta> extends Query<Result, Meta> {
18
- readonly [internalData]: InsertData<Meta>;
6
+ import type { TableDefinition, TableInsert, TableRow } from '../Table.js';
7
+ import type { InsertQuery, OnConflict, OnConflictSet, OnConflictUpdate } from './Query.js';
8
+ export declare class Insert<Result, Meta extends QueryMeta = QueryMeta> extends SingleQuery<Result, Meta> implements HasQuery<Result> {
9
+ readonly [internalData]: QueryData<Meta> & InsertQuery;
19
10
  readonly [internalSelection]?: Selection;
20
- constructor(data: InsertData<Meta>);
21
- get [internalQuery](): Sql;
11
+ constructor(data: QueryData<Meta> & InsertQuery);
12
+ get [internalQuery](): Sql<Result>;
22
13
  }
23
14
  declare class InsertCanReturn<Definition extends TableDefinition, Meta extends QueryMeta> extends Insert<void, Meta> {
24
- returning(this: InsertCanReturn<Definition, IsPostgres | IsSqlite>): Insert<TableRow<Definition>, Meta>;
25
- returning<Input extends SelectionInput>(this: InsertCanReturn<Definition, IsPostgres | IsSqlite>, returning: Input): Insert<SelectionRow<Input>, Meta>;
26
- }
27
- export interface OnConflict {
28
- target: HasSql | Array<HasSql>;
29
- targetWhere?: HasSql<boolean>;
30
- }
31
- export interface OnConflictSet<Definition extends TableDefinition> {
32
- set: TableUpdate<Definition>;
33
- }
34
- export interface OnConflictUpdate<Definition extends TableDefinition> extends OnConflict, OnConflictSet<Definition> {
35
- setWhere?: HasSql<boolean>;
15
+ returning<Meta extends IsPostgres | IsSqlite>(this: InsertCanReturn<Definition, Meta>): Insert<Array<TableRow<Definition>>, Meta>;
16
+ returning<Input extends SelectionInput, Meta extends IsPostgres | IsSqlite>(this: InsertCanReturn<Definition, Meta>, returning: Input): Insert<Array<SelectionRow<Input>>, Meta>;
36
17
  }
37
18
  declare class InsertCanConflict<Definition extends TableDefinition, Meta extends QueryMeta> extends InsertCanReturn<Definition, Meta> {
38
- #private;
39
- onConflictDoNothing(this: InsertCanConflict<Definition, IsPostgres | IsSqlite>, onConflict?: OnConflict): InsertCanReturn<Definition, Meta>;
40
- onConflictDoUpdate(this: InsertCanConflict<Definition, IsPostgres | IsSqlite>, onConflict: OnConflictUpdate<Definition>): InsertCanReturn<Definition, Meta>;
41
- onDuplicateKeyUpdate(this: InsertCanConflict<Definition, IsMysql>, update: OnConflictSet<Definition>): InsertCanReturn<Definition, Meta>;
19
+ onConflictDoNothing<Meta extends IsPostgres | IsSqlite>(this: InsertCanConflict<Definition, Meta>, onConflictDoNothing?: OnConflict): InsertCanConflict<Definition, Meta>;
20
+ onConflictDoUpdate<Meta extends IsPostgres | IsSqlite>(this: InsertCanConflict<Definition, Meta>, onConflict: OnConflictUpdate<Definition>): InsertCanConflict<Definition, Meta>;
21
+ onDuplicateKeyUpdate<Meta extends IsMysql>(this: InsertCanConflict<Definition, Meta>, onDuplicateKeyUpdate: OnConflictSet<Definition>): InsertCanConflict<Definition, Meta>;
42
22
  }
43
23
  export declare class InsertInto<Definition extends TableDefinition, Meta extends QueryMeta> {
44
- [internalData]: InsertData<Meta>;
45
- constructor(data: InsertData<Meta>);
24
+ [internalData]: QueryData<Meta> & InsertQuery;
25
+ constructor(data: QueryData<Meta> & InsertQuery);
46
26
  values(value: TableInsert<Definition>): InsertCanConflict<Definition, Meta>;
47
27
  values(values: Array<TableInsert<Definition>>): InsertCanConflict<Definition, Meta>;
48
- select(query: Query<TableRow<Definition>, Meta>): InsertCanConflict<Definition, Meta>;
28
+ select(query: SingleQuery<Array<TableRow<Definition>>, Meta>): InsertCanConflict<Definition, Meta>;
49
29
  }
30
+ export declare function insertQuery(query: InsertQuery): Sql;
50
31
  export {};
@@ -1,28 +1,29 @@
1
1
  // src/core/query/Insert.ts
2
2
  import {
3
3
  getData,
4
- getQuery,
5
4
  getTable,
6
- hasSql,
7
5
  internalData,
8
6
  internalQuery,
9
7
  internalSelection
10
8
  } from "../Internal.js";
11
- import { Query } from "../Query.js";
9
+ import { SingleQuery } from "../Queries.js";
12
10
  import {
13
11
  selection
14
12
  } from "../Selection.js";
15
13
  import { sql } from "../Sql.js";
16
- import { input } from "../expr/Input.js";
17
- var Insert = class extends Query {
14
+ import { input, mapToColumn } from "../expr/Input.js";
15
+ import { formatCTE } from "./CTE.js";
16
+ import { selectQuery } from "./Select.js";
17
+ import { formatModifiers } from "./Shared.js";
18
+ var Insert = class extends SingleQuery {
18
19
  [internalData];
19
20
  constructor(data) {
20
21
  super(data);
21
22
  this[internalData] = data;
22
- if (data.returning) this[internalSelection] = data.returning;
23
+ if (data.returning) this[internalSelection] = selection(data.returning);
23
24
  }
24
25
  get [internalQuery]() {
25
- return sql.chunk("emitInsert", this);
26
+ return insertQuery(getData(this));
26
27
  }
27
28
  };
28
29
  var InsertCanReturn = class extends Insert {
@@ -30,93 +31,141 @@ var InsertCanReturn = class extends Insert {
30
31
  const data = getData(this);
31
32
  return new Insert({
32
33
  ...data,
33
- returning: returning ? selection(returning) : selection.table(data.into)
34
+ returning: returning ?? data.insert
34
35
  });
35
36
  }
36
37
  };
37
- var InsertCanConflict = class extends InsertCanReturn {
38
- onConflictDoNothing(onConflict) {
39
- return this.#onConflict(onConflict ?? {});
38
+ var InsertCanConflict = class _InsertCanConflict extends InsertCanReturn {
39
+ onConflictDoNothing(onConflictDoNothing) {
40
+ const { on = [], ...data } = getData(this);
41
+ return new _InsertCanConflict({
42
+ ...data,
43
+ on: [...on, { conflictDoNothing: onConflictDoNothing ?? true }]
44
+ });
40
45
  }
41
46
  onConflictDoUpdate(onConflict) {
42
- return this.#onConflict(onConflict);
43
- }
44
- onDuplicateKeyUpdate(update) {
45
- return new InsertCanReturn({
46
- ...getData(this),
47
- onDuplicateKeyUpdate: this.#updateFields(update.set)
47
+ const { on = [], ...data } = getData(this);
48
+ return new _InsertCanConflict({
49
+ ...data,
50
+ on: [...on, { conflictDoUpdate: onConflict }]
48
51
  });
49
52
  }
50
- #updateFields(update) {
51
- return sql.join(
52
- Object.entries(update).map(
53
- ([key, value]) => sql`${sql.identifier(key)} = ${input(value)}`
54
- ),
55
- sql`, `
56
- );
57
- }
58
- #onConflict({
59
- target,
60
- targetWhere,
61
- set,
62
- setWhere
63
- }) {
64
- const update = set && this.#updateFields(set);
65
- return new InsertCanReturn({
66
- ...getData(this),
67
- onConflict: sql.join([
68
- target && sql`(${Array.isArray(target) ? sql.join(target, sql`, `) : target})`,
69
- targetWhere && sql`where ${targetWhere}`,
70
- update ? sql.join([
71
- sql`do update set ${update}`,
72
- setWhere && sql`where ${setWhere}`
73
- ]) : sql`do nothing`
74
- ])
53
+ onDuplicateKeyUpdate(onDuplicateKeyUpdate) {
54
+ const { on = [], ...data } = getData(this);
55
+ return new _InsertCanConflict({
56
+ ...data,
57
+ on: [...on, { duplicateKeyUpdate: onDuplicateKeyUpdate }]
75
58
  });
76
59
  }
77
60
  };
78
- var defaultKeyword = sql.universal({
79
- sqlite: sql`null`,
80
- default: sql`default`
81
- });
82
61
  var InsertInto = class {
83
62
  [internalData];
84
63
  constructor(data) {
85
64
  this[internalData] = data;
86
65
  }
87
- values(insert) {
88
- const { into } = getData(this);
89
- const rows = Array.isArray(insert) ? insert : [insert];
90
- const table = getTable(into);
91
- const values = sql.join(
92
- rows.map((row) => {
93
- return sql`(${sql.join(
94
- Object.entries(table.columns).map(([key, column]) => {
95
- const value = row[key];
96
- const { $default, mapToDriverValue } = getData(column);
97
- if (value !== void 0) {
98
- if (value && typeof value === "object" && hasSql(value))
99
- return value;
100
- return input(mapToDriverValue?.(value) ?? value);
101
- }
102
- if ($default) return $default();
103
- return defaultKeyword;
104
- }),
105
- sql`, `
106
- )})`;
107
- }),
108
- sql`, `
109
- );
110
- return new InsertCanConflict({ ...getData(this), values });
66
+ values(values) {
67
+ return new InsertCanConflict({
68
+ ...getData(this),
69
+ values
70
+ });
111
71
  }
112
72
  select(query) {
113
73
  return new InsertCanConflict({
114
74
  ...getData(this),
115
- select: getQuery(query)
75
+ ...getData(query)
116
76
  });
117
77
  }
118
78
  };
79
+ function formatDefaultValue(value) {
80
+ return sql.universal({
81
+ sqlite: value,
82
+ default: sql`default`
83
+ });
84
+ }
85
+ var defaultKeyword = formatDefaultValue(sql`null`);
86
+ function formatValues(table, rows) {
87
+ return sql.join(
88
+ rows.map((row) => {
89
+ return sql`(${sql.join(
90
+ Object.entries(table.columns).map(([key, column]) => {
91
+ const expr = row[key];
92
+ const columnApi = getData(column);
93
+ const { $onUpdate, $default, defaultValue } = columnApi;
94
+ if (expr !== void 0) return mapToColumn(columnApi, expr);
95
+ if ($default) return $default();
96
+ if (defaultValue) return formatDefaultValue(defaultValue);
97
+ if ($onUpdate) return $onUpdate();
98
+ return defaultKeyword;
99
+ }),
100
+ sql`, `
101
+ )})`;
102
+ }),
103
+ sql`, `
104
+ );
105
+ }
106
+ function formatUpdates(update) {
107
+ return sql.join(
108
+ Object.entries(update).map(
109
+ ([key, value]) => sql`${sql.identifier(key)} = ${input(value)}`
110
+ ),
111
+ sql`, `
112
+ );
113
+ }
114
+ function formatConflict({
115
+ target,
116
+ targetWhere,
117
+ set,
118
+ where: setWhere
119
+ }) {
120
+ const update = set && formatUpdates(set);
121
+ return sql.query({
122
+ onConflict: sql.join([
123
+ target && sql`(${Array.isArray(target) ? sql.join(target, sql`, `) : target})`,
124
+ targetWhere && sql`where ${targetWhere}`,
125
+ update ? sql.join([
126
+ sql`do update set ${update}`,
127
+ setWhere && sql`where ${setWhere}`
128
+ ]) : sql`do nothing`
129
+ ])
130
+ });
131
+ }
132
+ function formatConflicts(on) {
133
+ return sql.join(
134
+ on.map((conflict) => {
135
+ if ("duplicateKeyUpdate" in conflict)
136
+ return sql.query({
137
+ onDuplicateKeyUpdate: formatUpdates(conflict.duplicateKeyUpdate.set)
138
+ });
139
+ if ("conflictDoUpdate" in conflict)
140
+ return formatConflict(conflict.conflictDoUpdate);
141
+ if ("conflictDoNothing" in conflict)
142
+ return formatConflict(
143
+ conflict.conflictDoNothing === true ? {} : conflict.conflictDoNothing
144
+ );
145
+ throw new Error("Unknown conflict type");
146
+ })
147
+ );
148
+ }
149
+ function insertQuery(query) {
150
+ const { insert, values, select, returning } = query;
151
+ if (!values && !select) throw new Error("No values defined");
152
+ const table = getTable(insert);
153
+ const tableName = sql.identifier(table.name);
154
+ const toInsert = values ? sql.query({
155
+ values: formatValues(table, Array.isArray(values) ? values : [values])
156
+ }) : selectQuery(query);
157
+ const conflicts = query.on ? formatConflicts(query.on) : void 0;
158
+ return sql.query(
159
+ formatCTE(query),
160
+ { insertInto: sql`${tableName} (${table.listColumns()})` },
161
+ toInsert,
162
+ conflicts,
163
+ returning && sql.query({ returning: selection(returning) }),
164
+ formatModifiers(query)
165
+ ).inlineFields(false);
166
+ }
119
167
  export {
120
168
  Insert,
121
- InsertInto
169
+ InsertInto,
170
+ insertQuery
122
171
  };
@@ -0,0 +1,124 @@
1
+ import type { HasSql, HasTarget } from '../Internal.js';
2
+ import type { MakeNullable, SelectionInput, SelectionRow } from '../Selection.js';
3
+ import type { Sql } from '../Sql.js';
4
+ import type { Table, TableDefinition, TableFields, TableInsert, TableUpdate } from '../Table.js';
5
+ import type { Expand } from '../Types.js';
6
+ import type { Input } from '../expr/Input.js';
7
+ import type { CTE } from './CTE.js';
8
+ export interface InnerJoin<Target> {
9
+ innerJoin: Target;
10
+ on: HasSql<boolean>;
11
+ }
12
+ export interface LeftJoin<Target> {
13
+ leftJoin: Target;
14
+ on: HasSql<boolean>;
15
+ }
16
+ export interface RightJoin<Target> {
17
+ rightJoin: Target;
18
+ on: HasSql<boolean>;
19
+ }
20
+ export interface FullJoin<Target> {
21
+ fullJoin: Target;
22
+ on: HasSql<boolean>;
23
+ }
24
+ export interface CrossJoin<Target> {
25
+ crossJoin: Target;
26
+ on: HasSql<boolean>;
27
+ }
28
+ export type Join<Target = HasTarget | Sql> = InnerJoin<Target> | LeftJoin<Target> | RightJoin<Target> | FullJoin<Target> | CrossJoin<Target>;
29
+ export type JoinOp = 'leftJoin' | 'rightJoin' | 'innerJoin' | 'fullJoin' | 'crossJoin';
30
+ export interface QueryBase {
31
+ with?: Array<CTE>;
32
+ withRecursive?: Array<CTE>;
33
+ }
34
+ interface SelectBase<Returning> {
35
+ where?: HasSql<boolean>;
36
+ distinct?: boolean;
37
+ distinctOn?: Array<HasSql>;
38
+ groupBy?: Array<HasSql>;
39
+ having?: HasSql<boolean> | ((input: Returning) => HasSql<boolean>);
40
+ }
41
+ export interface ResultModifiers {
42
+ orderBy?: Array<HasSql>;
43
+ limit?: Input<number>;
44
+ offset?: Input<number>;
45
+ }
46
+ export type FromGuard<Target = HasTarget | Sql> = Target | [Target, ...Array<Join<Target>>];
47
+ interface SelectionBase<Returning = SelectionInput> extends SelectBase<Returning> {
48
+ select: Returning;
49
+ from?: FromGuard;
50
+ }
51
+ export interface SelectionQuery<Returning = SelectionInput> extends SelectionBase<Returning>, QueryBase, ResultModifiers {
52
+ }
53
+ interface FromBase<Target = FromGuard> extends SelectBase<undefined> {
54
+ from: Target;
55
+ }
56
+ export interface FromQuery<Target> extends FromBase<Target>, QueryBase, ResultModifiers {
57
+ }
58
+ type FoldJoins<T extends Array<unknown>, Result> = T extends [
59
+ infer Join,
60
+ ...infer Joins
61
+ ] ? FoldJoins<Joins, Join extends LeftJoin<Table<infer Definition, infer Name>> ? Result & MakeNullable<Record<Name, TableFields<Definition>>> : Join extends RightJoin<Table<infer Definition, infer Name>> ? MakeNullable<Result> & Record<Name, TableFields<Definition>> : Join extends InnerJoin<Table<infer Definition, infer Name>> ? Result & Record<Name, TableFields<Definition>> : Join extends FullJoin<Table<infer Definition, infer Name>> ? MakeNullable<Result> & MakeNullable<Record<Name, TableFields<Definition>>> : Result> : Result;
62
+ export type FromRow<Target> = Target extends [
63
+ Table<infer Definition, infer Name>,
64
+ ...infer Joins
65
+ ] ? Joins['length'] extends 0 ? TableFields<Definition> : Expand<FoldJoins<Joins, Record<Name, TableFields<Definition>>>> : SelectionRow<Target>;
66
+ export type Union<Returning = SelectionInput> = {
67
+ union: SelectQuery<Returning>;
68
+ } | {
69
+ unionAll: SelectQuery<Returning>;
70
+ } | {
71
+ intersect: SelectQuery<Returning>;
72
+ } | {
73
+ intersectAll: SelectQuery<Returning>;
74
+ } | {
75
+ except: SelectQuery<Returning>;
76
+ } | {
77
+ exceptAll: SelectQuery<Returning>;
78
+ };
79
+ export type UnionOp = 'union' | 'unionAll' | 'intersect' | 'intersectAll' | 'except' | 'exceptAll';
80
+ export type CompoundSelect<Returning = SelectionInput> = [
81
+ SelectQuery<Returning>,
82
+ ...Array<Union<Returning>>
83
+ ];
84
+ export interface UnionQuery<Returning = SelectionInput> extends QueryBase, ResultModifiers {
85
+ select: CompoundSelect<Returning>;
86
+ }
87
+ export interface SelectQuery<Returning = SelectionInput> extends SelectionQuery<Returning> {
88
+ }
89
+ export interface OnConflict {
90
+ target: HasSql | Array<HasSql>;
91
+ targetWhere?: HasSql<boolean>;
92
+ }
93
+ export interface OnConflictSet<Definition extends TableDefinition> {
94
+ set: TableUpdate<Definition>;
95
+ }
96
+ export interface OnConflictUpdate<Definition extends TableDefinition> extends OnConflict, OnConflictSet<Definition> {
97
+ where?: HasSql<boolean>;
98
+ }
99
+ export type Conflict<Definition extends TableDefinition = TableDefinition> = {
100
+ conflictDoNothing: true | OnConflict;
101
+ } | {
102
+ conflictDoUpdate: OnConflictUpdate<Definition>;
103
+ } | {
104
+ duplicateKeyUpdate: OnConflictSet<Definition>;
105
+ };
106
+ export interface InsertQuery<Returning = SelectionInput, Definition extends TableDefinition = TableDefinition> extends Partial<SelectionQuery<Returning>>, QueryBase, ResultModifiers {
107
+ insert: Table<Definition>;
108
+ values?: TableInsert<Definition> | Array<TableInsert<Definition>>;
109
+ returning?: Returning;
110
+ on?: Array<Conflict<Definition>>;
111
+ }
112
+ export interface DeleteQuery<Returning = SelectionInput, Definition extends TableDefinition = TableDefinition> extends QueryBase, ResultModifiers {
113
+ delete: Table<Definition>;
114
+ where?: HasSql<boolean>;
115
+ returning?: Returning;
116
+ }
117
+ export interface UpdateQuery<Returning = SelectionInput, Definition extends TableDefinition = TableDefinition> extends QueryBase, ResultModifiers {
118
+ update: Table<Definition>;
119
+ set?: TableUpdate<Definition>;
120
+ where?: HasSql<boolean>;
121
+ returning?: Returning;
122
+ }
123
+ export type Query<Returning = SelectionInput> = SelectionQuery<Returning> | FromQuery<Returning> | InsertQuery<Returning> | DeleteQuery<Returning> | UpdateQuery<Returning>;
124
+ export {};