rado 1.0.0-preview.2 → 1.0.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.
Files changed (118) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -144
  3. package/dist/core/Builder.d.ts +2 -8
  4. package/dist/core/Builder.js +10 -26
  5. package/dist/core/Column.d.ts +17 -10
  6. package/dist/core/Column.js +29 -21
  7. package/dist/core/Constraint.d.ts +6 -5
  8. package/dist/core/Database.d.ts +19 -9
  9. package/dist/core/Database.js +59 -23
  10. package/dist/core/Dialect.d.ts +6 -4
  11. package/dist/core/Dialect.js +16 -6
  12. package/dist/core/Diff.d.ts +6 -0
  13. package/dist/core/Driver.d.ts +20 -6
  14. package/dist/core/Emitter.d.ts +13 -8
  15. package/dist/core/Emitter.js +50 -42
  16. package/dist/core/Index.d.ts +19 -14
  17. package/dist/core/Index.js +29 -8
  18. package/dist/core/Internal.d.ts +8 -8
  19. package/dist/core/Internal.js +8 -6
  20. package/dist/core/MetaData.d.ts +1 -0
  21. package/dist/core/Query.d.ts +25 -26
  22. package/dist/core/Query.js +43 -26
  23. package/dist/core/Resolver.d.ts +16 -5
  24. package/dist/core/Resolver.js +71 -6
  25. package/dist/core/Schema.d.ts +1 -1
  26. package/dist/core/Selection.d.ts +15 -5
  27. package/dist/core/Selection.js +66 -34
  28. package/dist/core/Sql.d.ts +17 -13
  29. package/dist/core/Sql.js +17 -2
  30. package/dist/core/Table.d.ts +10 -3
  31. package/dist/core/Table.js +46 -14
  32. package/dist/core/expr/Conditions.d.ts +24 -34
  33. package/dist/core/expr/Conditions.js +47 -63
  34. package/dist/core/expr/Field.d.ts +2 -1
  35. package/dist/core/expr/Include.d.ts +19 -0
  36. package/dist/core/expr/Include.js +52 -0
  37. package/dist/core/expr/Input.d.ts +2 -1
  38. package/dist/core/expr/Json.d.ts +13 -0
  39. package/dist/core/expr/Json.js +16 -0
  40. package/dist/core/query/Delete.d.ts +4 -3
  41. package/dist/core/query/Delete.js +1 -7
  42. package/dist/core/query/Insert.d.ts +10 -7
  43. package/dist/core/query/Insert.js +10 -13
  44. package/dist/core/query/Select.d.ts +15 -27
  45. package/dist/core/query/Select.js +26 -85
  46. package/dist/core/query/Union.d.ts +24 -17
  47. package/dist/core/query/Union.js +37 -21
  48. package/dist/core/query/Update.d.ts +4 -4
  49. package/dist/core/query/Update.js +10 -11
  50. package/dist/driver/better-sqlite3.d.ts +1 -1
  51. package/dist/driver/better-sqlite3.js +25 -7
  52. package/dist/driver/bun-sqlite.d.ts +1 -2
  53. package/dist/driver/bun-sqlite.js +8 -1
  54. package/dist/driver/mysql2.d.ts +29 -0
  55. package/dist/driver/mysql2.js +87 -0
  56. package/dist/driver/pg.d.ts +11 -8
  57. package/dist/driver/pg.js +23 -11
  58. package/dist/driver/pglite.d.ts +7 -4
  59. package/dist/driver/pglite.js +27 -5
  60. package/dist/driver/sql.js.d.ts +1 -1
  61. package/dist/driver/sql.js.js +17 -8
  62. package/dist/index.d.ts +7 -5
  63. package/dist/index.js +7 -5
  64. package/dist/interop.d.ts +3 -0
  65. package/dist/interop.js +0 -0
  66. package/dist/mysql/MysqlBuilder.d.ts +3 -0
  67. package/dist/mysql/MysqlBuilder.js +6 -0
  68. package/dist/mysql/MysqlColumns.d.ts +68 -0
  69. package/dist/mysql/MysqlColumns.js +151 -0
  70. package/dist/mysql/MysqlDialect.d.ts +2 -0
  71. package/dist/mysql/MysqlDialect.js +57 -0
  72. package/dist/mysql/MysqlDiff.d.ts +2 -0
  73. package/dist/mysql/MysqlDiff.js +8 -0
  74. package/dist/mysql.d.ts +7 -0
  75. package/dist/mysql.js +28 -0
  76. package/dist/postgres/PostgresBuilder.d.ts +3 -0
  77. package/dist/postgres/PostgresBuilder.js +6 -0
  78. package/dist/postgres/PostgresColumns.d.ts +55 -4
  79. package/dist/postgres/PostgresColumns.js +146 -20
  80. package/dist/postgres/PostgresDialect.d.ts +2 -2
  81. package/dist/postgres/PostgresDialect.js +51 -45
  82. package/dist/postgres/PostgresDiff.d.ts +2 -0
  83. package/dist/postgres/PostgresDiff.js +193 -0
  84. package/dist/postgres.d.ts +5 -0
  85. package/dist/postgres.js +25 -0
  86. package/dist/sqlite/SqliteBuilder.d.ts +3 -0
  87. package/dist/sqlite/SqliteBuilder.js +6 -0
  88. package/dist/sqlite/SqliteColumns.d.ts +2 -1
  89. package/dist/sqlite/SqliteColumns.js +18 -17
  90. package/dist/sqlite/SqliteDialect.d.ts +2 -2
  91. package/dist/sqlite/SqliteDialect.js +49 -40
  92. package/dist/sqlite/SqliteDiff.d.ts +2 -0
  93. package/dist/sqlite/SqliteDiff.js +169 -0
  94. package/dist/sqlite/SqliteFunctions.d.ts +158 -1
  95. package/dist/sqlite/SqliteFunctions.js +77 -74
  96. package/dist/sqlite.d.ts +4 -1
  97. package/dist/sqlite.js +19 -1
  98. package/dist/universal/UniversalColumns.d.ts +2 -2
  99. package/dist/universal/UniversalColumns.js +11 -22
  100. package/dist/universal/UniversalFunctions.d.ts +4 -0
  101. package/dist/universal/UniversalFunctions.js +13 -0
  102. package/dist/universal/UniversalTransaction.d.ts +9 -2
  103. package/dist/universal/UniversalTransaction.js +24 -10
  104. package/dist/universal.d.ts +1 -0
  105. package/dist/universal.js +1 -0
  106. package/package.json +6 -4
  107. package/dist/core/query/CreateTable.d.ts +0 -13
  108. package/dist/core/query/CreateTable.js +0 -24
  109. package/dist/core/query/DropTable.d.ts +0 -13
  110. package/dist/core/query/DropTable.js +0 -24
  111. package/dist/migrate/Scan.d.ts +0 -1
  112. package/dist/postgres/PostgresSchema.d.ts +0 -1
  113. package/dist/postgres/PostgresSchema.js +0 -5
  114. package/dist/postgres/PostgresTable.d.ts +0 -1
  115. package/dist/postgres/PostgresTable.js +0 -5
  116. package/dist/sqlite/SqliteTable.d.ts +0 -1
  117. package/dist/sqlite/SqliteTable.js +0 -5
  118. /package/dist/{migrate/Scan.js → core/Diff.js} +0 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Ben Merckx
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -3,11 +3,9 @@
3
3
  # rado
4
4
 
5
5
  Fully typed, lightweight TypeScript query builder.
6
- Currently focused on SQLite.
7
6
 
8
7
  - Definition via TypeScript types
9
8
  - Composable queries
10
- - Aggregate rows in selects
11
9
  - First class JSON columns
12
10
  - No code generation step
13
11
  - No dependencies
@@ -18,39 +16,21 @@ Currently focused on SQLite.
18
16
 
19
17
  #### Where
20
18
 
21
- Conditions can be created by accessing the fields of the table
22
- instances and using the operators of `Expr`:
19
+ Conditions can be created by accessing the fields of the table:
23
20
 
24
21
  ```ts
25
- User.id // This is an Expr<number> which has an `is` method to compare
26
- User.id.is(1) // Compare with a value, results in an Expr<boolean>
27
- User.id.is(Post.userId) // Compare to fields on other tables
22
+ import {eq} from 'rado'
23
+ eq(User.id.is, 1) // Compare with a value
24
+ eq(User.id, Post.userId) // Compare to fields on other tables
28
25
  ```
29
26
 
30
27
  Rows can be selected by passing the condition in the where method:
31
28
 
32
29
  ```ts
33
- // Call a table instance to start a query selecting from that table
34
- User().where(User.id.is(1))
30
+ import {eq, or, gt, lt} from 'rado'
31
+ db.select().from(User).where(eq(User.id, 1))
35
32
  // Conditions can be as complex as you want
36
- User().where(User.id.isGreater(1).and(User.id.isLess(5)))
37
- // `And` conditions can also be comma separated in `where` to improve readability
38
- User().where(User.id.isGreater(1), User.id.isLess(5))
39
- ```
40
-
41
- There's a shortcut for comparing columns of a table directly in its call.
42
- The first comparison above can be simplified to:
43
-
44
- ```ts
45
- User({id: 1}) // Is the same as User().where(User.id.is(1))
46
- ```
47
-
48
- This comes in handy when joining tables too:
49
-
50
- ```ts
51
- User({id: 1}).innerJoin(Post({userId: User.id}))
52
- // Is equal to:
53
- User().innerJoin(Post, Post.userId.is(User.id)).where(User.id.is(1))
33
+ db.select().from(User).where(or(gt(User.id, 1), lt(User.id, 5)))
54
34
  ```
55
35
 
56
36
  #### Select
@@ -58,75 +38,40 @@ User().innerJoin(Post, Post.userId.is(User.id)).where(User.id.is(1))
58
38
  Retrieve a single field
59
39
 
60
40
  ```ts
61
- User().select(User.name)
41
+ db.select(User.name).from(User)
62
42
  ```
63
43
 
64
44
  Or an object of data
65
45
 
66
46
  ```ts
67
- User().select({
68
- ...User, // Get all user fields: id, username
69
- posts: Post({userId: User.id}) // Aggregate posts of this user
70
- })
71
- ```
72
-
73
- You can call the `posts` helper method defined in the example schema below
74
- to achieve the same:
75
-
76
- ```ts
77
- User().select({
47
+ import {eq, include} from 'rado'
48
+ db.select({
49
+ // Get all user fields: id, username
78
50
  ...User,
79
- posts: User.posts()
80
- })
81
- ```
82
-
83
- Retrieve all posts with their author and tags and count the tag usage in other
84
- posts:
85
-
86
- ```ts
87
- import {count} from 'rado/sqlite'
88
- // Alias tables using `as`
89
- const pt = PostTags().as('pt')
90
- Post().select({
91
- ...Post,
92
- author: Post.author().select(User.username),
93
- tags: Post.tags().select({
94
- count: pt({tagId: Tag.id}).select(count()).first(),
95
- name: Tag.name
96
- })
97
- })
51
+ // Aggregate posts of this user
52
+ posts: include(db.select().from(Post).where(eq(Post.userId, User.id)))
53
+ }).from(User)
98
54
  ```
99
55
 
100
56
  Join other tables and select fields from either table:
101
57
 
102
58
  ```ts
103
- User({id: 1}).innerJoin(Post({userId: User.id})).select({
104
- username: User.username
105
- post: Post
106
- })
107
- ```
108
-
109
- Create expressions to select complex values:
110
-
111
- ```ts
112
- import {iif} from 'rado/sqlite'
113
- Person().select({
114
- name: Person.firstName.concat(' ').concat(Person.lastName),
115
- isMario: Person.firstName.is('Mario'),
116
- isActor: Person.id.isIn(Actor().select(Actor.personId)),
117
- email: iif(Person.email.isNotNull(), Person.email, 'its.me@mario'),
118
- twitterHandle: Person.socialMedia
119
- .filter(media => media.type.is('twitter'))
120
- .map(media => media.handle)
121
- .maybeFirst()
122
- })
59
+ db
60
+ .select({
61
+ username: User.username
62
+ post: Post
63
+ })
64
+ .from(User)
65
+ .innerJoin(Post, eq(Post.userId, User.id))
66
+ .where(eq(User.id, 1))
123
67
  ```
124
68
 
125
69
  Order, group, limit queries:
126
70
 
127
71
  ```ts
128
- User()
129
- .orderBy(User.username.asc())
72
+ import {asc} from 'rado'
73
+ db.select().from(User)
74
+ .orderBy(asc(User.username))
130
75
  .groupBy(User.id, User.username)
131
76
  .skip(20)
132
77
  .take(10)
@@ -134,16 +79,16 @@ User()
134
79
 
135
80
  #### Insert
136
81
 
137
- Insert a single row and return the result:
82
+ Insert a single row:
138
83
 
139
84
  ```ts
140
- User().insertOne({username: 'Mario'})
85
+ db.insert(User).values({username: 'Mario'})
141
86
  ```
142
87
 
143
88
  Insert multiple rows:
144
89
 
145
90
  ```ts
146
- User().insertAll([{username: 'Mario'}, {username: 'Luigi'}])
91
+ db.insert(User).values([{username: 'Mario'}, {username: 'Luigi'}])
147
92
  ```
148
93
 
149
94
  #### Update
@@ -151,14 +96,17 @@ User().insertAll([{username: 'Mario'}, {username: 'Luigi'}])
151
96
  Set values
152
97
 
153
98
  ```ts
154
- User({id: 1}).set({username: 'Bowser'})
99
+ db.update(User)
100
+ .set({username: 'Bowser'})
101
+ .where(eq(User.id, 1))
155
102
  ```
156
103
 
157
104
  Use expressions to update complex values:
158
105
 
159
106
  ```ts
160
- User()
161
- .set({username: User.username.concat(' [removed]')})
107
+ import {concat} from 'rado/sqlite'
108
+ db.update(User)
109
+ .set({username: concat(User.username, ' [removed]')})
162
110
  .where(User.deleted)
163
111
  ```
164
112
 
@@ -167,62 +115,49 @@ User()
167
115
  Delete rows
168
116
 
169
117
  ```ts
170
- User({id: 1}).delete()
118
+ db.delete(User).where(eq(User.id, 1))
171
119
  ```
172
120
 
173
121
  ## Schema definition
174
122
 
175
123
  ```ts
176
- import {table, column} from 'rado'
124
+ import * as sqlite from 'rado/sqlite'
125
+ import {sqliteTable as table} from 'rado/sqlite'
177
126
 
178
127
  const User = table({
179
- // Pass a definition under a key with the actual name of the table in database
180
- user: class {
181
- id = column.integer.primaryKey()
182
- username = column.string
183
-
184
- // Define helper methods directly on the model
185
- posts() {
186
- return Post({userId: this.id})
187
- }
188
- }
128
+ id: sqlite.integer().primaryKey(),
129
+ userName: sqlite.text('user') // Column names are optional
189
130
  })
190
131
 
191
132
  const Post = table({
192
- post: class {
193
- id = column.integer.primaryKey()
194
- userId = column.integer.references(() => User.id)
195
- content = column.string
196
-
197
- author() {
198
- return User({id: this.userId}).first()
199
- }
200
-
201
- tags() {
202
- return Tag({id: PostTags.tagId}).innerJoin(PostTags({postId: this.id}))
203
- }
204
- }
133
+ id: sqlite.integer().primaryKey(),
134
+ userId: sqlite.integer().references(() => User.id),
135
+ content: sqlite.text()
205
136
  })
206
137
 
207
138
  const Tag = table({
208
- tag: class {
209
- id = column.integer.primaryKey()
210
- name = column.string
211
- }
139
+ id: sqlite.integer().primaryKey(),
140
+ name: sqlite.text()
212
141
  })
213
142
 
214
143
  const PostTags = table({
215
- post_tag: class {
216
- postId = column.integer.references(() => Post.id)
217
- tagId = column.integer.references(() => Tag.id)
218
- }
144
+ postId: sqlite.integer().references(() => Post.id),
145
+ tagId: sqlite.integer().references(() => Tag.id)
219
146
  })
220
147
  ```
221
148
 
222
149
  ## Connections
223
150
 
224
- Currently supported SQLite drivers:
225
- `better-sqlite3`, `sql.js`, `sqlite3`, `bun:sqlite`, `@sqlite.org/sqlite-wasm`
151
+ Currently supported drivers:
152
+
153
+ | Driver | import |
154
+ | ---------------- | ------------------------------ |
155
+ | `better-sqlite3` | `'rado/driver/better-sqlite3'` |
156
+ | `bun-sqlite` | `'rado/driver/bun-sqlite'` |
157
+ | `mysql2` | `'rado/driver/mysql2'` |
158
+ | `pg` | `'rado/driver/pg'` |
159
+ | `pglite` | `'rado/driver/pglite'` |
160
+ | `sql.js` | `'rado/driver/sql.js'` |
226
161
 
227
162
  Pass an instance of the database to the `connect` function to get started:
228
163
 
@@ -233,32 +168,16 @@ import {connect} from 'rado/driver/better-sqlite3'
233
168
  const db = connect(new Database('foobar.db'))
234
169
  ```
235
170
 
236
- Currently all drivers are synchronous except for the `sqlite3` driver which is
237
- async.
238
171
 
239
172
  #### Run queries
240
173
 
241
174
  Call the connection with a query to retrieve its results:
242
175
 
243
176
  ```ts
244
- const posts = db(Post())
177
+ // For sync drivers this will be an array:
178
+ const posts = db.select().from(Post).all()
245
179
  // For async drivers this will be a Promise:
246
- const posts = await db(Post())
247
- ```
248
-
249
- #### Iterate results
250
-
251
- Iterate over query results:
252
-
253
- ```ts
254
- const allPosts = Post()
255
- for (const row of db.iterate(allPosts)) {
256
- console.log(row)
257
- }
258
- // For async drivers:
259
- for await (const row of db.iterate(allPosts)) {
260
- console.log(row)
261
- }
180
+ const posts = await db.select().from(Post)
262
181
  ```
263
182
 
264
183
  #### Transactions
@@ -268,10 +187,9 @@ and can optionally return a result:
268
187
 
269
188
  ```ts
270
189
  const firstUserId = db.transaction(tx => {
271
- const createTable = User().create()
190
+ const createTable = db.create(User)
272
191
  tx(createTable)
273
- const insertUser = User().insertOne({username: 'Mario'})
274
- tx(insertUser)
275
- return insertUser.id
192
+ const insertUser = db.insert(User).values({username: 'Mario'}).returning(User.id)
193
+ return tx(insertUser)
276
194
  })
277
195
  ```
@@ -1,19 +1,15 @@
1
1
  import { internalData, type HasQuery, type HasSql, type HasTable, type HasTarget } from './Internal.js';
2
2
  import type { IsPostgres, QueryMeta } from './MetaData.js';
3
3
  import type { QueryData } from './Query.js';
4
- import type { SelectionInput } from './Selection.js';
4
+ import { type SelectionInput } from './Selection.js';
5
5
  import type { Table, TableDefinition } from './Table.js';
6
- import { Create } from './query/CreateTable.js';
7
6
  import { DeleteFrom } from './query/Delete.js';
8
- import { Drop } from './query/DropTable.js';
9
7
  import { InsertInto } from './query/Insert.js';
10
8
  import type { SelectBase, WithSelection, WithoutSelection } from './query/Select.js';
11
9
  import { UpdateTable } from './query/Update.js';
12
10
  declare class BuilderBase<Meta extends QueryMeta> {
13
11
  readonly [internalData]: QueryData<Meta>;
14
- constructor(data: QueryData<Meta>);
15
- createTable<Definition extends TableDefinition>(table: Table<Definition>): Create<Meta>;
16
- dropTable(table: HasTable): Drop<Meta>;
12
+ constructor(data?: QueryData<Meta>);
17
13
  select(): WithoutSelection<Meta>;
18
14
  select<Input extends SelectionInput>(selection: Input): WithSelection<Input, Meta>;
19
15
  selectDistinct(): WithoutSelection<Meta>;
@@ -30,7 +26,5 @@ export declare class Builder<Meta extends QueryMeta> extends BuilderBase<Meta> {
30
26
  as<Input extends SelectionInput>(query: SelectBase<Input, Meta>): CTE<Input>;
31
27
  };
32
28
  with(...cte: Array<CTE>): BuilderBase<Meta>;
33
- createTable<Definition extends TableDefinition>(table: Table<Definition>): Create<Meta>;
34
- dropTable(table: HasTable): Drop<Meta>;
35
29
  }
36
30
  export {};
@@ -7,32 +7,24 @@ import {
7
7
  internalQuery,
8
8
  internalTarget
9
9
  } from "./Internal.js";
10
+ import { selection } from "./Selection.js";
10
11
  import { sql } from "./Sql.js";
11
- import { Create } from "./query/CreateTable.js";
12
12
  import { DeleteFrom } from "./query/Delete.js";
13
- import { Drop } from "./query/DropTable.js";
14
13
  import { InsertInto } from "./query/Insert.js";
15
14
  import { Select } from "./query/Select.js";
16
15
  import { UpdateTable } from "./query/Update.js";
17
16
  var BuilderBase = class {
18
17
  [internalData];
19
- constructor(data) {
18
+ constructor(data = {}) {
20
19
  this[internalData] = data;
21
20
  }
22
- createTable(table) {
23
- return new Create({ ...getData(this), table });
24
- }
25
- dropTable(table) {
26
- return new Drop({ ...getData(this), table });
27
- }
28
21
  select(input) {
29
22
  return new Select({
30
23
  ...getData(this),
31
24
  select: {
32
25
  type: input ? "selection" : "allFrom",
33
- input,
34
- tables: [],
35
- nullable: []
26
+ selection: input && selection(input),
27
+ tables: []
36
28
  }
37
29
  });
38
30
  }
@@ -41,21 +33,19 @@ var BuilderBase = class {
41
33
  ...getData(this),
42
34
  select: {
43
35
  type: input ? "selection" : "allFrom",
44
- input,
45
- tables: [],
46
- nullable: []
36
+ selection: input && selection(input),
37
+ tables: []
47
38
  },
48
39
  distinct: true
49
40
  });
50
41
  }
51
- selectDistinctOn(columns, selection) {
42
+ selectDistinctOn(columns, input) {
52
43
  return new Select({
53
44
  ...getData(this),
54
45
  select: {
55
- type: selection ? "selection" : "allFrom",
56
- input: selection,
57
- tables: [],
58
- nullable: []
46
+ type: input ? "selection" : "allFrom",
47
+ selection: input && selection(input),
48
+ tables: []
59
49
  },
60
50
  distinctOn: columns
61
51
  });
@@ -88,12 +78,6 @@ var Builder = class extends BuilderBase {
88
78
  cte
89
79
  });
90
80
  }
91
- createTable(table) {
92
- return new Create({ ...getData(this), table });
93
- }
94
- dropTable(table) {
95
- return new Drop({ ...getData(this), table });
96
- }
97
81
  };
98
82
  export {
99
83
  Builder
@@ -1,9 +1,10 @@
1
- import type { HasColumn, HasSql } from './Internal.js';
2
- import { internalColumn } from './Internal.js';
3
- import type { Sql } from './Sql.js';
1
+ import type { DriverSpecs } from './Driver.js';
2
+ import type { HasSql } from './Internal.js';
3
+ import { internalData } from './Internal.js';
4
+ import { type Sql } from './Sql.js';
4
5
  import type { Field, FieldData } from './expr/Field.js';
5
6
  import { type Input } from './expr/Input.js';
6
- export declare class ColumnData {
7
+ export interface ColumnData {
7
8
  type: Sql;
8
9
  name?: string;
9
10
  json?: boolean;
@@ -15,15 +16,16 @@ export declare class ColumnData {
15
16
  references?(): FieldData;
16
17
  onUpdate?: HasSql;
17
18
  onDelete?: HasSql;
18
- mapFromDriverValue?(value: unknown): unknown;
19
+ mapFromDriverValue?(value: unknown, specs: DriverSpecs): unknown;
19
20
  mapToDriverValue?(value: unknown): unknown;
20
21
  }
21
- export declare class Column<Value = unknown> implements HasColumn {
22
- readonly [internalColumn]: ColumnData;
22
+ type WithoutNull<Value> = Exclude<Value, null>;
23
+ export declare class Column<Value = unknown> {
24
+ readonly [internalData]: ColumnData;
23
25
  constructor(data: ColumnData);
24
- notNull(): RequiredColumn<NonNullable<Value>>;
25
- default(value: Input<NonNullable<Value>> | (() => Input<NonNullable<Value>>)): Column<NonNullable<Value>>;
26
- primaryKey(): Column<NonNullable<Value>>;
26
+ notNull(): RequiredColumn<WithoutNull<Value>>;
27
+ default(value: Input<WithoutNull<Value>> | (() => Input<WithoutNull<Value>>)): Column<WithoutNull<Value>>;
28
+ primaryKey(): Column<WithoutNull<Value>>;
27
29
  unique(name?: string): Column<Value>;
28
30
  references(foreignField: Field | (() => Field)): Column<Value>;
29
31
  }
@@ -35,4 +37,9 @@ declare const required: unique symbol;
35
37
  export interface RequiredColumn<Value = unknown> extends Column<Value> {
36
38
  [required]: true;
37
39
  }
40
+ export interface Columns {
41
+ <T>(data: ColumnData): Column<T>;
42
+ [key: string]: (...args: Array<Input<any>>) => Sql<any>;
43
+ }
44
+ export declare const column: Columns;
38
45
  export {};
@@ -1,45 +1,35 @@
1
1
  // src/core/Column.ts
2
- import { getField, internalColumn } from "./Internal.js";
2
+ import { getData, getField, internalData } from "./Internal.js";
3
+ import { sql } from "./Sql.js";
3
4
  import { input } from "./expr/Input.js";
4
- var ColumnData = class {
5
- type;
6
- name;
7
- json;
8
- primary;
9
- notNull;
10
- isUnique;
11
- autoIncrement;
12
- onUpdate;
13
- onDelete;
14
- };
15
5
  var Column = class _Column {
16
- [internalColumn];
6
+ [internalData];
17
7
  constructor(data) {
18
- this[internalColumn] = data;
8
+ this[internalData] = data;
19
9
  }
20
10
  notNull() {
21
11
  return new _Column({
22
- ...this[internalColumn],
12
+ ...getData(this),
23
13
  notNull: true
24
14
  });
25
15
  }
26
16
  default(value) {
27
17
  return new _Column({
28
- ...this[internalColumn],
18
+ ...getData(this),
29
19
  defaultValue() {
30
20
  return input(value instanceof Function ? value() : value);
31
21
  }
32
22
  });
33
23
  }
34
24
  primaryKey() {
35
- return new _Column({ ...this[internalColumn], primary: true });
25
+ return new _Column({ ...getData(this), primary: true });
36
26
  }
37
27
  unique(name) {
38
- return new _Column({ ...this[internalColumn], isUnique: true });
28
+ return new _Column({ ...getData(this), isUnique: true });
39
29
  }
40
30
  references(foreignField) {
41
31
  return new _Column({
42
- ...this[internalColumn],
32
+ ...getData(this),
43
33
  references() {
44
34
  return getField(
45
35
  typeof foreignField === "function" ? foreignField() : foreignField
@@ -53,8 +43,26 @@ var JsonColumn = class extends Column {
53
43
  super({ ...data, json: true });
54
44
  }
55
45
  };
46
+ function createColumn(data) {
47
+ return new Column(data);
48
+ }
49
+ var column = new Proxy(createColumn, {
50
+ get(target, method) {
51
+ return target[method] ??= (...args) => {
52
+ while (args.length > 0)
53
+ if (args.at(-1) === void 0)
54
+ args.pop();
55
+ if (args.length === 0)
56
+ return sql.unsafe(method);
57
+ return sql`${sql.unsafe(method)}(${sql.join(
58
+ args.map(sql.inline),
59
+ sql`, `
60
+ )})`;
61
+ };
62
+ }
63
+ });
56
64
  export {
57
65
  Column,
58
- ColumnData,
59
- JsonColumn
66
+ JsonColumn,
67
+ column
60
68
  };
@@ -1,4 +1,5 @@
1
1
  import { internalConstraint, internalData, type HasConstraint, type HasData } from './Internal.js';
2
+ import { type Sql } from './Sql.js';
2
3
  import type { Field, FieldData } from './expr/Field.js';
3
4
  export interface UniqueConstraintData {
4
5
  fields: Array<FieldData>;
@@ -9,10 +10,10 @@ export declare class UniqueConstraint<TableName extends string = string> impleme
9
10
  [internalData]: UniqueConstraintData;
10
11
  constructor(data: UniqueConstraintData);
11
12
  on<TableName extends string>(...columns: Array<Field<unknown, TableName>>): UniqueConstraint<TableName>;
12
- nullsNotDistinct(): UniqueConstraint<string>;
13
- get [internalConstraint](): import("./Sql.ts").Sql<unknown>;
13
+ nullsNotDistinct(): UniqueConstraint<TableName>;
14
+ get [internalConstraint](): Sql;
14
15
  }
15
- export declare function unique(): UniqueConstraint<string>;
16
+ export declare function unique(): UniqueConstraint;
16
17
  export interface PrimaryKeyConstraintData {
17
18
  fields: Array<FieldData>;
18
19
  }
@@ -21,7 +22,7 @@ export declare class PrimaryKeyConstraint<TableName extends string = string> imp
21
22
  private brand;
22
23
  [internalData]: PrimaryKeyConstraintData;
23
24
  constructor(data: PrimaryKeyConstraintData);
24
- get [internalConstraint](): import("./Sql.ts").Sql<unknown>;
25
+ get [internalConstraint](): Sql;
25
26
  }
26
27
  export declare function primaryKey<TableName extends string = string>(...fields: Array<Field<unknown, TableName>>): PrimaryKeyConstraint<TableName>;
27
28
  export interface ForeignKeyConstraintData {
@@ -33,7 +34,7 @@ export declare class ForeignKeyConstraint<TableName extends string = string> imp
33
34
  [internalData]: ForeignKeyConstraintData;
34
35
  constructor(data: ForeignKeyConstraintData);
35
36
  references<ForeignTable extends string>(...fields: Array<Field<unknown, ForeignTable>>): ForeignKeyConstraint<TableName>;
36
- get [internalConstraint](): import("./Sql.ts").Sql<unknown>;
37
+ get [internalConstraint](): Sql;
37
38
  }
38
39
  export declare function foreignKey<TableName extends string = string>(...fields: Array<Field<unknown, TableName>>): ForeignKeyConstraint<TableName>;
39
40
  export type Constraint = UniqueConstraint | PrimaryKeyConstraint | ForeignKeyConstraint;
@@ -1,20 +1,28 @@
1
1
  import { Builder } from './Builder.js';
2
2
  import type { Dialect } from './Dialect.js';
3
+ import type { Diff } from './Diff.js';
3
4
  import type { Driver } from './Driver.js';
4
- import { internalResolver, type HasResolver } from './Internal.js';
5
- import type { Async, Either, QueryDialect, QueryMeta, Sync } from './MetaData.js';
5
+ import { type HasQuery, type HasResolver, type HasSql, type HasTable, internalResolver } from './Internal.js';
6
+ import type { Async, Deliver, Either, QueryDialect, QueryMeta, Sync } from './MetaData.js';
7
+ import { QueryBatch } from './Query.js';
6
8
  import { Resolver } from './Resolver.js';
9
+ import type { Table } from './Table.js';
7
10
  export declare class Database<Meta extends QueryMeta = Either> extends Builder<Meta> implements HasResolver<Meta> {
8
- #private;
11
+ driver: Driver;
12
+ dialect: Dialect;
13
+ diff: Diff;
9
14
  readonly [internalResolver]: Resolver<Meta>;
10
- constructor(driver: Driver, dialect: Dialect, transactionDepth?: number);
15
+ constructor(driver: Driver, dialect: Dialect, diff: Diff);
11
16
  close(this: Database<Async>): Promise<void>;
12
17
  close(this: Database<Sync>): void;
13
18
  [Symbol.dispose](this: Database<Sync>): void;
14
19
  [Symbol.asyncDispose](this: Database<Async>): Promise<void>;
15
- transaction<T>(this: Database<Sync>, run: (tx: Transaction<Meta>) => T, options?: TransactionOptions[Meta['dialect']]): T;
16
- transaction<T>(this: Database<Async>, run: (tx: Transaction<Meta>) => Promise<T>, options?: TransactionOptions[Meta['dialect']]): Promise<T>;
17
- transaction<T>(run: (tx: Transaction<Meta>) => T | Promise<T>, options?: TransactionOptions[Meta['dialect']]): T | Promise<T>;
20
+ create(...tables: Array<HasTable>): QueryBatch<unknown, Meta>;
21
+ drop(...tables: Array<HasTable>): QueryBatch<unknown, Meta>;
22
+ migrate(...tables: Array<Table>): Deliver<Meta, void>;
23
+ batch<Queries extends Array<HasSql | HasQuery>>(queries: Queries): QueryBatch<unknown, Meta>;
24
+ execute(input: HasSql): Deliver<Meta, void>;
25
+ transaction<T>(run: (tx: Transaction<Meta>) => T, options?: TransactionOptions[Meta['dialect']]): Deliver<Meta, T>;
18
26
  }
19
27
  export interface TransactionOptions {
20
28
  universal: never;
@@ -32,10 +40,12 @@ export interface TransactionOptions {
32
40
  withConsistentSnapshot?: boolean;
33
41
  };
34
42
  }
35
- export declare class Rollback extends Error {
43
+ export declare class Rollback<Data = never> extends Error {
44
+ data: Data;
45
+ constructor(data: Data);
36
46
  }
37
47
  export declare class Transaction<Meta extends QueryMeta> extends Database<Meta> {
38
- rollback(): never;
48
+ rollback<Data>(data?: Data): never;
39
49
  }
40
50
  export declare class SyncDatabase<Dialect extends QueryDialect> extends Database<Sync<Dialect>> {
41
51
  }