drizzle-orm 0.11.2 → 0.11.3
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 +211 -291
- package/index.d.ts +1 -1
- package/index.js +4 -2
- package/index.js.map +1 -1
- package/package.json +2 -2
- package/tables/abstractTable.d.ts +2 -0
- package/tables/abstractTable.js +5 -0
- package/tables/abstractTable.js.map +1 -1
- package/tables/inferTypes.d.ts +5 -0
- package/test.d.ts +0 -0
- package/test.js +0 -178
- package/test.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,294 +1,198 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* PostgreSQL
|
|
15
|
-
|
|
16
|
-
## Links
|
|
17
|
-
|
|
18
|
-
In Progress
|
|
19
|
-
|
|
20
|
-
## Installing
|
|
21
|
-
|
|
1
|
+
## DrizzleORM
|
|
2
|
+
DrizzleORM is a TypeScript ORM library with a [drizzle-kit](https://github.com/lambda-direct/drizzle-orm/tree/develop/kit) CLI companion for automatic SQL migrations generation. It's meant to be a library, not a framework, stay as an opt-in solution all the time at any levels. We try to follow SQL-like syntax whenever possible, be strongly typed ground top and fail in compile time, not in runtime. We implemented best in class `joins` and second to none `migrations generation`. Library has almost zero dependencies and being battle tested on production projects by multiple teams 🚀
|
|
3
|
+
|
|
4
|
+
| database | support |
|
|
5
|
+
|:-- | :---: |
|
|
6
|
+
| PostgreSQL | ✅ |
|
|
7
|
+
| MySQL | ⏳ |
|
|
8
|
+
| DynamoDB | ⏳ |
|
|
9
|
+
| SQLite | ⏳ |
|
|
10
|
+
| MS SQL | ⏳ |
|
|
11
|
+
| CockroachDB | ⏳ |
|
|
12
|
+
|
|
13
|
+
### Installation
|
|
22
14
|
```bash
|
|
23
15
|
npm install drizzle-orm drizzle-kit
|
|
24
16
|
```
|
|
25
|
-
#### **In Progress**
|
|
26
|
-
```bash
|
|
27
|
-
yarn add drizzle-orm drizzle-kit
|
|
28
|
-
bower install drizzle-orm drizzle-kit
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Connecting to database
|
|
32
|
-
|
|
33
|
-
```tsx
|
|
34
|
-
import { DbConnector } from "drizzle-orm";
|
|
35
|
-
|
|
36
|
-
// connect via postgresql connection url
|
|
37
|
-
const db = await new DbConnector()
|
|
38
|
-
.connectionString("postgres://user:password@host:port/db")
|
|
39
|
-
.connect();
|
|
40
|
-
|
|
41
|
-
// or by params
|
|
42
|
-
const db = await new DbConnector()
|
|
43
|
-
.params({
|
|
44
|
-
host: '0.0.0.0',
|
|
45
|
-
port: 5432,
|
|
46
|
-
user: 'user',
|
|
47
|
-
password: 'password',
|
|
48
|
-
db: 'optional_db_name'
|
|
49
|
-
}).connect();
|
|
50
|
-
```
|
|
51
|
-
## Project structure
|
|
52
|
-
- tables folder
|
|
53
|
-
- migrations folder
|
|
54
17
|
|
|
55
|
-
|
|
56
|
-
### Users Table
|
|
57
|
-
---
|
|
18
|
+
### Quick start
|
|
58
19
|
```typescript
|
|
20
|
+
import { drizzle, PgTable } from 'drizzle-orm'
|
|
59
21
|
|
|
60
|
-
export
|
|
61
|
-
|
|
62
|
-
export default class UsersTable extends AbstractTable<UsersTable> {
|
|
22
|
+
export class UsersTable extends PgTable<UsersTable> {
|
|
63
23
|
public id = this.serial('id').primaryKey();
|
|
64
24
|
public fullName = this.text('full_name');
|
|
65
|
-
|
|
66
25
|
public phone = this.varchar('phone', { size: 256 });
|
|
67
|
-
public media = this.jsonb<string[]>('media');
|
|
68
|
-
public decimalField = this.decimal('test', { precision: 100, scale: 2 }).notNull();
|
|
69
|
-
public bigIntField = this.bigint('test1', 'max_bytes_53');
|
|
70
|
-
public role = this.type(rolesEnum, 'name_in_table').notNull();
|
|
71
|
-
|
|
72
|
-
public createdAt = this.timestamp('created_at').notNull();
|
|
73
|
-
|
|
74
|
-
public createdAtWithTimezone = this.timestamptz('created_at_time_zone');
|
|
75
|
-
|
|
76
|
-
public updatedAt = this.timestamp('updated_at').defaultValue(Defaults.CURRENT_TIMESTAMP);
|
|
77
|
-
public isArchived = this.bool('is_archived').defaultValue(false);
|
|
78
|
-
|
|
79
|
-
public phoneFullNameIndex = this.index([this.phone, this.fullName]);
|
|
80
|
-
public phoneIndex = this.uniqueIndex(this.phone);
|
|
81
26
|
|
|
82
27
|
public tableName(): string {
|
|
83
28
|
return 'users';
|
|
84
29
|
}
|
|
85
30
|
}
|
|
86
|
-
|
|
87
|
-
### Cities Table
|
|
88
|
-
---
|
|
89
|
-
```typescript
|
|
90
|
-
interface CityMeta {
|
|
91
|
-
population: number,
|
|
92
|
-
connection: string,
|
|
93
|
-
}
|
|
31
|
+
export type User = InferType<UsersTable>
|
|
94
32
|
|
|
95
|
-
|
|
96
|
-
|
|
33
|
+
const db = await drizzle.connect("postgres://user:password@host:port/db");
|
|
34
|
+
const usersTable = new UsersTable(db);
|
|
97
35
|
|
|
98
|
-
|
|
99
|
-
|
|
36
|
+
const users: User[] = await usersTable.select().execute();
|
|
37
|
+
```
|
|
100
38
|
|
|
101
|
-
|
|
39
|
+
### Connecting to database
|
|
40
|
+
```typescript
|
|
102
41
|
|
|
103
|
-
|
|
42
|
+
const db = await drizzle.connect("postgres://user:password@host:port/db");
|
|
43
|
+
const db = await drizzle.connect({
|
|
44
|
+
host: "127.0.0.1",
|
|
45
|
+
port: 5432,
|
|
46
|
+
user: "postgres",
|
|
47
|
+
password: "postgres",
|
|
48
|
+
db: "db_name",
|
|
49
|
+
});
|
|
50
|
+
```
|
|
104
51
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
52
|
+
### SQL schema declaration
|
|
53
|
+
With `drizzle-orm` you declare SQL schema in typescritp. You can have either one `schema.ts` file with all declarations or you can group them logically in multiple files. We prefer to use single file schema.
|
|
54
|
+
```
|
|
55
|
+
📦project
|
|
56
|
+
├ 📂src
|
|
57
|
+
│ ├ 📂data
|
|
58
|
+
│ │ └ 📜schema.ts
|
|
59
|
+
│ └ ...
|
|
60
|
+
├ ...
|
|
61
|
+
└ 📜package.json
|
|
62
|
+
|
|
63
|
+
## or multiple schema files
|
|
64
|
+
├ 📂data
|
|
65
|
+
├ 📜users.ts
|
|
66
|
+
├ 📜countries.ts
|
|
67
|
+
├ 📜cities.ts
|
|
68
|
+
├ 📜products.ts
|
|
69
|
+
├ 📜clients.ts
|
|
70
|
+
├ 📜enums.ts
|
|
71
|
+
└ 📜etc.ts
|
|
109
72
|
```
|
|
110
|
-
|
|
111
|
-
---
|
|
73
|
+
This is how you declare SQL schema in `schema.ts`. You can declare tables, indexes and constraints, foreign keys and enums. Please pay attention to `export` keyword, they are mandatory if you'll be using drizzle-kit SQL migrations generator.
|
|
112
74
|
```typescript
|
|
113
|
-
|
|
114
|
-
|
|
75
|
+
// declaring enum in database
|
|
76
|
+
export const popularityEnum = createEnum({ alias: 'popularity', values: ['unknown', 'known', 'popular'] });
|
|
115
77
|
|
|
116
|
-
|
|
117
|
-
|
|
78
|
+
export class CountriesTable extends PgTable<CountriesTable> {
|
|
79
|
+
id = this.serial("id").primaryKey();
|
|
80
|
+
name = this.varchar("name", { size: 256 })
|
|
81
|
+
|
|
82
|
+
// declaring index
|
|
83
|
+
nameIndex = this.uniqueIndex(this.name)
|
|
118
84
|
|
|
119
85
|
public tableName(): string {
|
|
120
|
-
return '
|
|
86
|
+
return 'countries';
|
|
121
87
|
}
|
|
122
88
|
}
|
|
123
|
-
```
|
|
124
|
-
### User to User Groups Table
|
|
125
|
-
---
|
|
126
|
-
#### Many to many connection between Users and User Groups
|
|
127
|
-
```typescript
|
|
128
|
-
export default class UsersToUserGroupsTable extends AbstractTable<UsersToUserGroupsTable> {
|
|
129
|
-
public groupId = this.int('city_id').foreignKey(UserGroupsTable, (table) => table.id, { onDelete: 'CASCADE' });
|
|
130
|
-
public userId = this.int('user_id').foreignKey(UsersTable, (table) => table.id, { onDelete: 'CASCADE' });
|
|
131
89
|
|
|
132
|
-
|
|
90
|
+
export class CitiesTable extends PgTable<CitiesTable> {
|
|
91
|
+
id = this.serial("id").primaryKey();
|
|
92
|
+
name = this.varchar("name", { size: 256 })
|
|
93
|
+
countryId = this.int("country_id").foreignKey(CountriesTable, (country) => country.id)
|
|
94
|
+
|
|
95
|
+
// declaring enum column in table
|
|
96
|
+
popularity = this.type(popularityEnum, "popularity")
|
|
133
97
|
|
|
134
98
|
public tableName(): string {
|
|
135
|
-
return '
|
|
99
|
+
return 'cities';
|
|
136
100
|
}
|
|
137
101
|
}
|
|
138
102
|
```
|
|
139
|
-
|
|
140
|
-
## CRUD
|
|
141
|
-
### **SELECT**
|
|
142
|
-
---
|
|
103
|
+
The list of all possible types. You can also create custom types - !!see here!!.
|
|
143
104
|
```typescript
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
.connect();
|
|
105
|
+
export const enum = createEnum({ alias: "database-name", values: ["value1", "value2", "value3"] });
|
|
106
|
+
type(enum, "...")
|
|
147
107
|
|
|
148
|
-
|
|
108
|
+
smallint("...")
|
|
109
|
+
int("...")
|
|
110
|
+
bigint("...", maxBytes: "max_bytes_53")
|
|
111
|
+
bigint("...", maxBytes: "max_bytes_64")
|
|
149
112
|
|
|
150
|
-
|
|
151
|
-
|
|
113
|
+
bool("...")
|
|
114
|
+
text("...");
|
|
115
|
+
varchar("...");
|
|
116
|
+
varchar("...", { size: 256 });
|
|
152
117
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
#### **Sorting and Filtering**
|
|
157
|
-
---
|
|
158
|
-
##### Select all records from `Users` where phone is `"hello"`
|
|
159
|
-
```typescript
|
|
160
|
-
const eqSelect = await usersTable.select().where(
|
|
161
|
-
eq(usersTable.phone, 'hello')
|
|
162
|
-
).all();
|
|
163
|
-
```
|
|
164
|
-
##### Select all records from `Users` where **both** phone is `"hello"` **and** phone is `"hello"`
|
|
165
|
-
```typescript
|
|
166
|
-
const andSelect = await usersTable.select().where(
|
|
167
|
-
and([
|
|
168
|
-
eq(usersTable.phone, 'hello'),
|
|
169
|
-
eq(usersTable.phone, 'hello')
|
|
170
|
-
]),
|
|
171
|
-
).all();
|
|
172
|
-
```
|
|
173
|
-
##### Select all records from `Users` where **either** phone is `"hello"` **or** phone is `"hello"`
|
|
174
|
-
```typescript
|
|
175
|
-
const orSelect = await usersTable.select().where(
|
|
176
|
-
or([eq(usersTable.phone, 'hello')]),
|
|
177
|
-
).all();
|
|
178
|
-
```
|
|
179
|
-
##### Select all records from `Users` using **LIMIT** and **OFFSET**
|
|
180
|
-
```typescript
|
|
181
|
-
const limitOffsetSelect = await usersTable.select().limit(10).offset(10).all();
|
|
182
|
-
```
|
|
183
|
-
##### Select all records from `Users` where `phone` contains `"hello"`
|
|
184
|
-
```typescript
|
|
185
|
-
const likeSelect = await usersTable.select().where(
|
|
186
|
-
like(usersTable.phone, '%hello%')
|
|
187
|
-
).all();
|
|
188
|
-
```
|
|
189
|
-
##### Select all records from `Users` where `phone` equals to some of values from array
|
|
190
|
-
```typescript
|
|
191
|
-
const inArraySelect = usersTable.select().where(
|
|
192
|
-
inArray(usersTable.phone, ['hello'])
|
|
193
|
-
).all();
|
|
194
|
-
```
|
|
195
|
-
##### Select all records from `Users` where `phone` greater(**>**) than `"hello"`
|
|
196
|
-
```typescript
|
|
197
|
-
const greaterSelect = usersTable.select().where(
|
|
198
|
-
greater(usersTable.phone, 'hello')
|
|
199
|
-
).all();
|
|
200
|
-
```
|
|
201
|
-
##### Select all records from `Users` where `phone` less(**<**) than `"hello"`
|
|
202
|
-
```typescript
|
|
203
|
-
const lessSelect = usersTable.select().where(
|
|
204
|
-
less(usersTable.phone, 'hello')
|
|
205
|
-
).all();
|
|
206
|
-
```
|
|
207
|
-
##### Select all records from `Users` where `phone` greater or equals(**>=**) than `"hello"`
|
|
208
|
-
```typescript
|
|
209
|
-
const greaterEqSelect = usersTable.select().where(
|
|
210
|
-
greaterEq(usersTable.phone, 'hello')
|
|
211
|
-
).all();
|
|
212
|
-
```
|
|
213
|
-
##### Select all records from `Users` where `phone` less or equals(**<=**)
|
|
214
|
-
```typescript
|
|
215
|
-
const lessEqSelect = usersTable.select().where(
|
|
216
|
-
lessEq(usersTable.phone, 'hello')
|
|
217
|
-
).all();
|
|
218
|
-
```
|
|
219
|
-
##### Select all records from `Users` where `phone` is **NULL**
|
|
220
|
-
```typescript
|
|
221
|
-
const isNullSelect = usersTable.select().where(
|
|
222
|
-
isNull(usersTable.phone)
|
|
223
|
-
).all();
|
|
224
|
-
```
|
|
225
|
-
##### Select all records from `Users` where `phone` not equals to `"hello"`
|
|
226
|
-
```typescript
|
|
227
|
-
const notEqSelect = usersTable.select().where(
|
|
228
|
-
notEq(usersTable.phone, 'hello')
|
|
229
|
-
).all();
|
|
230
|
-
```
|
|
231
|
-
##### Select all records from `Users` ordered by `phone` in ascending order
|
|
232
|
-
```typescript
|
|
233
|
-
const ordered = await usersTable.select().orderBy((table) => table.phone, Order.ASC).all();
|
|
234
|
-
```
|
|
235
|
-
#### **Partial Selecting**
|
|
236
|
-
```typescript
|
|
237
|
-
const partialSelect = await usersTable.select({
|
|
238
|
-
mappedId: usersTable.id,
|
|
239
|
-
mappedPhone: usersTable.phone,
|
|
240
|
-
}).all();
|
|
118
|
+
serial("...");
|
|
119
|
+
bigserial("...", maxBytes: "max_bytes_53");
|
|
120
|
+
bigserial("...", maxBytes: "max_bytes_64");
|
|
241
121
|
|
|
242
|
-
|
|
243
|
-
const { mappedId, mappedPhone } = partialSelect;
|
|
244
|
-
```
|
|
122
|
+
decimal("...", { precision: 100, scale: 2 });
|
|
245
123
|
|
|
124
|
+
jsonb<...>("...");
|
|
125
|
+
jsonb<string[]>("...");
|
|
246
126
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
await usersTable.update()
|
|
252
|
-
.where(eq(usersTable.phone, 'hello'))
|
|
253
|
-
.set({ fullName: 'newName' })
|
|
254
|
-
.execute();
|
|
255
|
-
```
|
|
256
|
-
##### Update `fullName` to `newName` in `Users` where phone is `"hello"` returning updated `User` model
|
|
257
|
-
```typescript
|
|
258
|
-
await usersTable.update()
|
|
259
|
-
.where(eq(usersTable.phone, 'hello'))
|
|
260
|
-
.set({ fullName: 'newName' })
|
|
261
|
-
.all();
|
|
262
|
-
```
|
|
263
|
-
##### Update `fullName` to `newName` in `Users` where phone is `"hello"` returning updated `User` model
|
|
264
|
-
```typescript
|
|
265
|
-
await usersTable.update()
|
|
266
|
-
.where(eq(usersTable.phone, 'hello'))
|
|
267
|
-
.set({ fullName: 'newName' })
|
|
268
|
-
.findOne();
|
|
269
|
-
```
|
|
127
|
+
time("...")
|
|
128
|
+
timestamp("...") // with timezone
|
|
129
|
+
timestamptz("..."); // without timezone
|
|
130
|
+
timestamp("...").defaultValue(Defaults.CURRENT_TIMESTAMP)
|
|
270
131
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
132
|
+
index(column);
|
|
133
|
+
index([column1, column2, ...]);
|
|
134
|
+
uniqueIndex(column);
|
|
135
|
+
uniqueIndex([column1, column2, ...]);
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
column.primaryKey()
|
|
139
|
+
column.notNull()
|
|
140
|
+
column.defaultValue(...)
|
|
141
|
+
|
|
142
|
+
// 'CASCADE' | 'RESTRICT' | 'SET NULL' | 'SET DEFAULT'
|
|
143
|
+
column.foreignKey(Table, (table) => table.column, { onDelete: "CASCADE", onUpdate: "CASCADE" });
|
|
283
144
|
```
|
|
284
|
-
|
|
145
|
+
|
|
146
|
+
### Create Read Update Delete
|
|
147
|
+
Querying, sorting and filtering. We also support partial select.
|
|
285
148
|
```typescript
|
|
286
|
-
await
|
|
287
|
-
|
|
288
|
-
.findOne();
|
|
289
|
-
```
|
|
149
|
+
const db = await drizzle.connect("...")
|
|
150
|
+
const table = new UsersTable(db);
|
|
290
151
|
|
|
291
|
-
|
|
152
|
+
const result: User[] = await table.select().execute();
|
|
153
|
+
await table.select().where(
|
|
154
|
+
eq(table.id, 42)
|
|
155
|
+
).execute();
|
|
156
|
+
|
|
157
|
+
// you can combine filters with eq(...) or or(...)
|
|
158
|
+
await table.select().where(
|
|
159
|
+
and([eq(table.id, 42), eq(table.name, "Dan")])
|
|
160
|
+
).execute();
|
|
161
|
+
|
|
162
|
+
await table.select().where(
|
|
163
|
+
or([eq(table.id, 42), eq(table.id, 1)])
|
|
164
|
+
).execute();
|
|
165
|
+
|
|
166
|
+
// partial select
|
|
167
|
+
const result = await table.select({
|
|
168
|
+
mapped1: table.id,
|
|
169
|
+
mapped2: table.name,
|
|
170
|
+
}).execute();
|
|
171
|
+
const { mapped1, mapped2 } = result[0];
|
|
172
|
+
|
|
173
|
+
// limit offset & order by
|
|
174
|
+
await table.select().limit(10).offset(10).execute()
|
|
175
|
+
await table.select().orderBy((table) => table.name, Order.ASC)
|
|
176
|
+
await table.select().orderBy((table) => table.name, Order.DESC)
|
|
177
|
+
|
|
178
|
+
// list of all filter operators
|
|
179
|
+
eq(table.column, value)
|
|
180
|
+
notEq(table.column, value)
|
|
181
|
+
less(table.column, value)
|
|
182
|
+
lessEq(table.column, value)
|
|
183
|
+
greater(table.column, value)
|
|
184
|
+
greaterEq(table.column, value)
|
|
185
|
+
isNull(table.column)
|
|
186
|
+
isNotNull(table.column)
|
|
187
|
+
|
|
188
|
+
inArray(table.column, [...values])
|
|
189
|
+
like(table.column, value)
|
|
190
|
+
raw("raw sql filter")
|
|
191
|
+
|
|
192
|
+
and(exressions: Expr[])
|
|
193
|
+
or(exressions: Expr[])
|
|
194
|
+
```
|
|
195
|
+
Inserting
|
|
292
196
|
##### Insert `user` with required fields
|
|
293
197
|
```typescript
|
|
294
198
|
await usersTable.insert({
|
|
@@ -298,67 +202,83 @@ await usersTable.insert({
|
|
|
298
202
|
```
|
|
299
203
|
##### Insert `user` with required fields and get all rows as array
|
|
300
204
|
```typescript
|
|
301
|
-
const
|
|
302
|
-
|
|
205
|
+
const result = await usersTable.insert({
|
|
206
|
+
name: "Andrew",
|
|
303
207
|
createdAt: new Date(),
|
|
304
|
-
}).
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
const user = await usersTable.insert({
|
|
309
|
-
test: 1,
|
|
208
|
+
}).execute();
|
|
209
|
+
|
|
210
|
+
const result = await usersTable.insertMany([{
|
|
211
|
+
name: "Andrew",
|
|
310
212
|
createdAt: new Date(),
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
213
|
+
}, {
|
|
214
|
+
name: "Dan",
|
|
215
|
+
createdAt: new Date(),
|
|
216
|
+
}]).execute();
|
|
217
|
+
|
|
218
|
+
//await usersTable.insert({
|
|
219
|
+
// name: "Dan"
|
|
220
|
+
//})
|
|
221
|
+
//.onConflict(
|
|
222
|
+
// (table) => table.name,
|
|
223
|
+
// { name: 'name value to be upserted' }
|
|
224
|
+
//).execute();
|
|
322
225
|
```
|
|
323
|
-
|
|
226
|
+
|
|
227
|
+
Update and Delete
|
|
324
228
|
```typescript
|
|
325
|
-
await usersTable.
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
(table) => table.phoneIndex,
|
|
334
|
-
{ phone: 'confilctUpdate' },
|
|
335
|
-
).all();
|
|
229
|
+
await usersTable.update()
|
|
230
|
+
.where(eq(usersTable.name, 'Dan'))
|
|
231
|
+
.set({ name: 'Mr. Dan' })
|
|
232
|
+
.execute();
|
|
233
|
+
|
|
234
|
+
await usersTable.delete()
|
|
235
|
+
.where(eq(usersTable.name, 'Dan'))
|
|
236
|
+
.execute();
|
|
336
237
|
```
|
|
337
238
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
239
|
+
### Joins
|
|
240
|
+
Last but not least. Probably the most powerful feature in the library🚀
|
|
241
|
+
Many-to-one
|
|
341
242
|
```typescript
|
|
342
243
|
const usersTable = new UsersTable(db);
|
|
343
244
|
const citiesTable = new CitiesTable(db);
|
|
344
245
|
|
|
345
|
-
const
|
|
246
|
+
const result = await citiesTable.select()
|
|
346
247
|
.leftJoin(usersTable, (cities, users) => eq(cities.userId, users.id))
|
|
347
248
|
.where((cities, users) => eq(cities.id, 1))
|
|
348
249
|
.execute();
|
|
349
250
|
|
|
350
|
-
const
|
|
251
|
+
const citiesWithUsers: { city: City, user: User }[] = result.map((city, user) => ({ city, user }));
|
|
351
252
|
```
|
|
352
|
-
|
|
353
|
-
### Join Many-To-Many Tables
|
|
354
|
-
##### Join User Groups with Users, using many-to-many table
|
|
253
|
+
Many-to-many
|
|
355
254
|
```typescript
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
255
|
+
export class UsersTable extends PgTable<UsersTable> {
|
|
256
|
+
id = this.serial("id").primaryKey();
|
|
257
|
+
name = this.varchar("name");
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export class ChatGroupsTable extends PgTable<ChatGroupsTable> {
|
|
261
|
+
id = this.serial("id").primaryKey();
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export class ManyToManyTable extends PgTable<ManyToManyTable> {
|
|
265
|
+
userId = this.int('user_id').foreignKey(UsersTable, (table) => table.id, { onDelete: 'CASCADE' });
|
|
266
|
+
groupId = this.int('group_id').foreignKey(ChatGroupsTable, (table) => table.id, { onDelete: 'CASCADE' });
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
...
|
|
270
|
+
const usersTable = new UsersTable(db);
|
|
271
|
+
const chatGroupsTable = new ChatGroupsTable(db);
|
|
272
|
+
const manyToManyTable = new ManyToManyTable(db);
|
|
273
|
+
|
|
274
|
+
// querying user group with id 1 and all the participants(users)
|
|
275
|
+
const usersWithUserGroups = await manyToManyTable.select()
|
|
276
|
+
.leftJoin(usersTable, (manyToMany, users) => eq(manyToManyTable.userId, users.id))
|
|
277
|
+
.leftJoin(chatGroupsTable, (manyToMany, _users, chatGroups) => eq(manyToManyTable.groupId, chatGroups.id))
|
|
278
|
+
.where((manyToMany, _users, userGroups) => eq(userGroups.id, 1))
|
|
360
279
|
.execute();
|
|
361
280
|
```
|
|
281
|
+
|
|
362
282
|
### Join using partial field select
|
|
363
283
|
##### Join Cities with Users getting only needed fields form request
|
|
364
284
|
```typescript
|
package/index.d.ts
CHANGED
|
@@ -8,6 +8,6 @@ export * from './tables';
|
|
|
8
8
|
export * from './logger/consoleLogger';
|
|
9
9
|
export * from './logger/abstractLogger';
|
|
10
10
|
export declare const drizzle: {
|
|
11
|
-
connect(config: ClientConfig): Promise<DB>;
|
|
11
|
+
connect(config: ClientConfig | string): Promise<DB>;
|
|
12
12
|
migrator(db: DB): Migrator;
|
|
13
13
|
};
|
package/index.js
CHANGED
|
@@ -24,8 +24,10 @@ __exportStar(require("./logger/consoleLogger"), exports);
|
|
|
24
24
|
__exportStar(require("./logger/abstractLogger"), exports);
|
|
25
25
|
exports.drizzle = {
|
|
26
26
|
async connect(config) {
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
if (typeof config === 'string') {
|
|
28
|
+
return new db_1.DbConnector().connectionString(config).connect();
|
|
29
|
+
}
|
|
30
|
+
return new db_1.DbConnector().params(config).connect();
|
|
29
31
|
},
|
|
30
32
|
migrator(db) {
|
|
31
33
|
return new migrator_1.default(db);
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAEA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAEA,6BAA0D;AAC1D,mEAA2C;AAE3C,uCAAqB;AACrB,6CAA2B;AAC3B,4CAA0B;AAC1B,2CAAyB;AACzB,yDAAuC;AACvC,0DAAwC;AAE3B,QAAA,OAAO,GAAG;IACrB,KAAK,CAAC,OAAO,CAAC,MAA6B;QACzC,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;YAC9B,OAAO,IAAI,gBAAW,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;SAC7D;QACD,OAAO,IAAI,gBAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;IACpD,CAAC;IAED,QAAQ,CAAC,EAAM;QACb,OAAO,IAAI,kBAAQ,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;CACF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "drizzle-orm",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"lint": "eslint ./src --ext .ts",
|
|
41
41
|
"run": "ts-node src/docs/cases/simple_update.ts"
|
|
42
42
|
},
|
|
43
|
-
"readme": "# DrizzleORM\n\n**DrizzleORM** is an ORM framework for \n[TypeScript](https://www.typescriptlang.org/).\nIt offers you several levels of Database communication:\n* Typesafe Table View approach \n* Typesafe Query Builder\n* Simple SQL query execution\n\nDrizzle ORM is highly influenced by [Exposed](https://github.com/JetBrains/Exposed) and Jetbrains development methodology\n\n## Supported Databases\n\n* PostgreSQL\n\n## Links\n\nIn Progress\n\n## Installing\n\n```bash\nnpm install drizzle-orm drizzle-kit\n```\n#### **In Progress**\n```bash\nyarn add drizzle-orm drizzle-kit\nbower install drizzle-orm drizzle-kit\n```\n\n## Connecting to database\n\n```tsx\nimport { DbConnector } from \"drizzle-orm\";\n\n// connect via postgresql connection url\nconst db = await new DbConnector()\n\t.connectionString(\"postgres://user:password@host:port/db\")\n\t.connect();\n\n// or by params\nconst db = await new DbConnector()\n\t.params({\n\t\thost: '0.0.0.0',\n\t\tport: 5432,\n\t\tuser: 'user',\n\t\tpassword: 'password',\n\t\tdb: 'optional_db_name'\n\t}).connect();\n```\n## Project structure\n- tables folder\n- migrations folder\n\n## Create tables\n### Users Table\n---\n```typescript\n\nexport const rolesEnum = createEnum({ alias: 'test-enum', values: ['user', 'guest', 'admin'] });\n\nexport default class UsersTable extends AbstractTable<UsersTable> {\n public id = this.serial('id').primaryKey();\n public fullName = this.text('full_name');\n\n public phone = this.varchar('phone', { size: 256 });\n public media = this.jsonb<string[]>('media');\n public decimalField = this.decimal('test', { precision: 100, scale: 2 }).notNull();\n public bigIntField = this.bigint('test1', 'max_bytes_53');\n public role = this.type(rolesEnum, 'name_in_table').notNull();\n\n public createdAt = this.timestamp('created_at').notNull();\n\n public createdAtWithTimezone = this.timestamptz('created_at_time_zone');\n\n public updatedAt = this.timestamp('updated_at').defaultValue(Defaults.CURRENT_TIMESTAMP);\n public isArchived = this.bool('is_archived').defaultValue(false);\n\n public phoneFullNameIndex = this.index([this.phone, this.fullName]);\n public phoneIndex = this.uniqueIndex(this.phone);\n\n public tableName(): string {\n return 'users';\n }\n}\n```\n### Cities Table\n---\n```typescript\ninterface CityMeta {\n population: number,\n connection: string,\n}\n\nexport default class CitiesTable extends AbstractTable<CitiesTable> {\n public id = this.serial('id').primaryKey();\n\n public foundationDate = this.timestamp('name').notNull();\n public location = this.varchar('page', { size: 256 });\n\n public userId = this.int('user_id').foreignKey(UsersTable, (table) => table.id, { onUpdate: 'CASCADE' });\n\n public metadata = this.jsonb<CityMeta>('metadata');\n\n public tableName(): string {\n return 'cities';\n }\n}\n```\n### User Groups Table\n---\n```typescript\nexport default class UserGroupsTable extends AbstractTable<UserGroupsTable> {\n public id = this.serial('id').primaryKey();\n\n public name = this.varchar('name');\n public description = this.varchar('description');\n\n public tableName(): string {\n return 'user_groups';\n }\n}\n```\n### User to User Groups Table\n---\n#### Many to many connection between Users and User Groups\n```typescript\nexport default class UsersToUserGroupsTable extends AbstractTable<UsersToUserGroupsTable> {\n public groupId = this.int('city_id').foreignKey(UserGroupsTable, (table) => table.id, { onDelete: 'CASCADE' });\n public userId = this.int('user_id').foreignKey(UsersTable, (table) => table.id, { onDelete: 'CASCADE' });\n\n public manyToManyIndex = this.index([this.groupId, this.userId]);\n\n public tableName(): string {\n return 'users_to_user_groups';\n }\n}\n```\n\n## CRUD\n### **SELECT**\n---\n```typescript\nconst db = await new DbConnector()\n .connectionString('postgresql://postgres@127.0.0.1/drizzle')\n .connect();\n\nconst usersTable = new UsersTable(db);\n\n// select all\nconst allSelect = await usersTable.select().all();\n\n// select first\nconst firstSelect = await usersTable.select().findOne();\n```\n#### **Sorting and Filtering**\n---\n##### Select all records from `Users` where phone is `\"hello\"`\n```typescript\nconst eqSelect = await usersTable.select().where(\n eq(usersTable.phone, 'hello')\n).all();\n```\n##### Select all records from `Users` where **both** phone is `\"hello\"` **and** phone is `\"hello\"`\n```typescript\nconst andSelect = await usersTable.select().where(\n and([\n eq(usersTable.phone, 'hello'),\n eq(usersTable.phone, 'hello')\n ]),\n).all();\n```\n##### Select all records from `Users` where **either** phone is `\"hello\"` **or** phone is `\"hello\"`\n```typescript\nconst orSelect = await usersTable.select().where(\n or([eq(usersTable.phone, 'hello')]),\n).all();\n```\n##### Select all records from `Users` using **LIMIT** and **OFFSET**\n```typescript\nconst limitOffsetSelect = await usersTable.select().limit(10).offset(10).all();\n```\n##### Select all records from `Users` where `phone` contains `\"hello\"`\n```typescript\nconst likeSelect = await usersTable.select().where(\n like(usersTable.phone, '%hello%')\n).all();\n```\n##### Select all records from `Users` where `phone` equals to some of values from array\n```typescript\nconst inArraySelect = usersTable.select().where(\n inArray(usersTable.phone, ['hello'])\n).all();\n```\n##### Select all records from `Users` where `phone` greater(**>**) than `\"hello\"`\n```typescript\nconst greaterSelect = usersTable.select().where(\n greater(usersTable.phone, 'hello')\n).all();\n```\n##### Select all records from `Users` where `phone` less(**<**) than `\"hello\"`\n```typescript\nconst lessSelect = usersTable.select().where(\n less(usersTable.phone, 'hello')\n).all();\n```\n##### Select all records from `Users` where `phone` greater or equals(**>=**) than `\"hello\"`\n```typescript\nconst greaterEqSelect = usersTable.select().where(\n greaterEq(usersTable.phone, 'hello')\n).all();\n```\n##### Select all records from `Users` where `phone` less or equals(**<=**) \n```typescript\nconst lessEqSelect = usersTable.select().where(\n lessEq(usersTable.phone, 'hello')\n).all();\n```\n##### Select all records from `Users` where `phone` is **NULL**\n```typescript\nconst isNullSelect = usersTable.select().where(\n isNull(usersTable.phone)\n).all();\n```\n##### Select all records from `Users` where `phone` not equals to `\"hello\"`\n```typescript\nconst notEqSelect = usersTable.select().where(\n notEq(usersTable.phone, 'hello')\n).all();\n```\n##### Select all records from `Users` ordered by `phone` in ascending order\n```typescript\nconst ordered = await usersTable.select().orderBy((table) => table.phone, Order.ASC).all();\n```\n#### **Partial Selecting**\n ```typescript\n const partialSelect = await usersTable.select({\n mappedId: usersTable.id,\n mappedPhone: usersTable.phone,\n }).all();\n\n // Usage\n const { mappedId, mappedPhone } = partialSelect;\n ```\n\n\n### **Update**\n---\n##### Update `fullName` to `newName` in `Users` where phone is `\"hello\"`\n```typescript\nawait usersTable.update()\n .where(eq(usersTable.phone, 'hello'))\n .set({ fullName: 'newName' })\n .execute();\n```\n##### Update `fullName` to `newName` in `Users` where phone is `\"hello\"` returning updated `User` model\n```typescript\nawait usersTable.update()\n .where(eq(usersTable.phone, 'hello'))\n .set({ fullName: 'newName' })\n .all();\n```\n##### Update `fullName` to `newName` in `Users` where phone is `\"hello\"` returning updated `User` model\n```typescript\nawait usersTable.update()\n .where(eq(usersTable.phone, 'hello'))\n .set({ fullName: 'newName' })\n .findOne();\n```\n\n### **Delete**\n##### Delete `user` where phone is `\"hello\"`\n```typescript\nawait usersTable.delete()\n .where(eq(usersTable.phone, 'hello'))\n .execute();\n```\n##### Delete `user` where phone is `\"hello\"` returning updated `User` model\n```typescript\nawait usersTable.delete()\n .where(eq(usersTable.phone, 'hello'))\n .all();\n```\n##### Delete `user` where phone is `\"hello\"` returning updated `User` model\n```typescript\nawait usersTable.delete()\n .where(eq(usersTable.phone, 'hello'))\n .findOne();\n```\n\n### **Insert**\n##### Insert `user` with required fields\n```typescript\nawait usersTable.insert({\n test: 1,\n createdAt: new Date(),\n}).execute();\n```\n##### Insert `user` with required fields and get all rows as array\n```typescript\nconst user = await usersTable.insert({\n test: 1,\n createdAt: new Date(),\n}).all();\n```\n##### Insert `user` with required fields and get inserted entity\n```typescript\nconst user = await usersTable.insert({\n test: 1,\n createdAt: new Date(),\n}).findOne();\n```\n##### Insert many `users` with required fields and get all inserted entities\n```typescript\nconst users = await usersTable.insertMany([{\n test: 1,\n createdAt: new Date(),\n }, {\n test: 2,\n createdAt: new Date(),\n }]).all();\n```\n##### Insert many `users` with required fields and get all inserted entities. If such user already exists - update `phone` field\n```typescript\nawait usersTable.insertMany([{\n test: 1,\n createdAt: new Date(),\n }, {\n test: 2,\n createdAt: new Date(),\n }])\n .onConflict(\n (table) => table.phoneIndex,\n { phone: 'confilctUpdate' },\n ).all();\n```\n\n## Joins\n### Join One-To-Many Tables\n##### Join Cities with Users and map to city object with full user\n```typescript\nconst usersTable = new UsersTable(db);\nconst citiesTable = new CitiesTable(db);\n\nconst userWithCities = await citiesTable.select()\n .leftJoin(usersTable, (cities, users) => eq(cities.userId, users.id))\n .where((cities, users) => eq(cities.id, 1))\n .execute();\n\nconst citiesWithUserObject = userWithCities.map((city, user) => ({ ...city, user }));\n```\n\n### Join Many-To-Many Tables\n##### Join User Groups with Users, using many-to-many table\n```typescript\nconst usersWithUserGroups = await usersToUserGroupsTable.select()\n .leftJoin(usersTable, (usersToUserGroups, users) => eq(usersToUserGroups.userId, users.id))\n .leftJoin(userGroupsTable, (usersToUserGroups, _users, userGroups) => eq(usersToUserGroups.groupId, userGroups.id))\n .where((usersToUserGroups, _users, userGroups) => eq(userGroups.id, 1))\n .execute();\n```\n### Join using partial field select\n##### Join Cities with Users getting only needed fields form request\n```typescript\n await citiesTable.select({\n id: citiesTable.id,\n userId: citiesTable.userId,\n })\n .leftJoin(usersTable, (cities, users) => eq(cities.userId, users.id))\n .where((cities, users) => eq(cities.id, 1))\n .execute();\n\nconst citiesWithUserObject = userWithCities.map((city, user) => ({ ...city, user }));\n```\n### Another join examples with different callback ON statements\n```typescript\nawait citiesTable.select()\n .leftJoin(usersTable, (cities, _users) => eq(cities.id, 13))\n .where((cities, _users) => eq(cities.location, 'q'))\n .execute();\n// Join statement generated from query\n// LEFT JOIN users AS users_1\n// ON cities.\"id\"=$1\n// WHERE cities.\"page\"=$2\n//\n// Values: [13, 'q']\n\nawait citiesTable.select()\n .leftJoin(usersTable, (cities, _users) => and([\n eq(cities.id, 13), notEq(cities.id, 14),\n ]))\n .execute();\n// Join statement generated from query\n// LEFT JOIN users AS users_1\n// ON (cities.\"id\"=$1 and cities.\"id\"!=$2)\n//\n// Values: [13, 14]\n\nawait citiesTable.select()\n .leftJoin(usersTable, (_cities, _users) => raw('<custom expression after ON statement>'))\n .where((cities, _users) => eq(cities.location, 'location'))\n .execute();\n// Join statement generated from query\n// LEFT JOIN users AS users_1\n// ON <custom expression after ON statement>\n// WHERE cities.\"page\"=$1\n// \n// Values: ['location']\n```\n\n\n## Migrations\n#### To run migrations generated by drizzle-kit you could use `Migrator` class\n##### Provide drizzle-kit config path\n```typescript\nawait drizzle.migrator(db).migrate('src/drizzle.config.yaml');\n```\n##### Another possibility is to provide object with path to folder with migrations\n```typescript\nawait drizzle.migrator(db).migrate({ migrationFolder: 'drizzle' });\n```\n\n\n## Raw query usage\n#### If you have some complex queries to execute and drizzle-orm can't handle them yet, then you could use `rawQuery` execution\n\n\n##### Execute custom raw query\n```typescript\nconst res: QueryResult<any> = await db.session().execute('SELECT * FROM users WHERE user.id = $1', [1]);\n```"
|
|
43
|
+
"readme": "## DrizzleORM\nDrizzleORM is a TypeScript ORM library with a [drizzle-kit](https://github.com/lambda-direct/drizzle-orm/tree/develop/kit) CLI companion for automatic SQL migrations generation. It's meant to be a library, not a framework, stay as an opt-in solution all the time at any levels. We try to follow SQL-like syntax whenever possible, be strongly typed ground top and fail in compile time, not in runtime. We implemented best in class `joins` and second to none `migrations generation`. Library has almost zero dependencies and being battle tested on production projects by multiple teams 🚀\n\n| database | support |\n|:-- | :---: |\n| PostgreSQL | ✅ |\n| MySQL | ⏳ |\n| DynamoDB | ⏳ |\n| SQLite | ⏳ |\n| MS SQL | ⏳ |\n| CockroachDB | ⏳ |\n\n### Installation\n```bash\nnpm install drizzle-orm drizzle-kit\n```\n\n### Quick start\n```typescript\nimport { drizzle, PgTable } from 'drizzle-orm'\n\nexport class UsersTable extends PgTable<UsersTable> {\n public id = this.serial('id').primaryKey();\n public fullName = this.text('full_name');\n public phone = this.varchar('phone', { size: 256 });\n\n public tableName(): string {\n return 'users';\n }\n}\nexport type User = InferType<UsersTable>\n\nconst db = await drizzle.connect(\"postgres://user:password@host:port/db\");\nconst usersTable = new UsersTable(db);\n\nconst users: User[] = await usersTable.select().execute();\n```\n\n### Connecting to database\n```typescript\n\nconst db = await drizzle.connect(\"postgres://user:password@host:port/db\");\nconst db = await drizzle.connect({\n host: \"127.0.0.1\",\n port: 5432,\n user: \"postgres\",\n password: \"postgres\",\n db: \"db_name\",\n});\n```\n\n### SQL schema declaration\nWith `drizzle-orm` you declare SQL schema in typescritp. You can have either one `schema.ts` file with all declarations or you can group them logically in multiple files. We prefer to use single file schema.\n```\n📦project\n ├ 📂src\n │ ├ 📂data\n │ │ └ 📜schema.ts\n │ └ ...\n ├ ...\n └ 📜package.json\n \n## or multiple schema files\n├ 📂data\n ├ 📜users.ts\n ├ 📜countries.ts\n ├ 📜cities.ts\n ├ 📜products.ts\n ├ 📜clients.ts\n ├ 📜enums.ts\n └ 📜etc.ts\n```\nThis is how you declare SQL schema in `schema.ts`. You can declare tables, indexes and constraints, foreign keys and enums. Please pay attention to `export` keyword, they are mandatory if you'll be using drizzle-kit SQL migrations generator.\n```typescript\n// declaring enum in database\nexport const popularityEnum = createEnum({ alias: 'popularity', values: ['unknown', 'known', 'popular'] });\n\nexport class CountriesTable extends PgTable<CountriesTable> {\n id = this.serial(\"id\").primaryKey();\n name = this.varchar(\"name\", { size: 256 })\n\t\n // declaring index\n nameIndex = this.uniqueIndex(this.name)\n\n public tableName(): string {\n return 'countries';\n }\n}\n\nexport class CitiesTable extends PgTable<CitiesTable> {\n id = this.serial(\"id\").primaryKey();\n name = this.varchar(\"name\", { size: 256 })\n countryId = this.int(\"country_id\").foreignKey(CountriesTable, (country) => country.id)\n\n // declaring enum column in table\n popularity = this.type(popularityEnum, \"popularity\")\n\n public tableName(): string {\n return 'cities';\n }\n}\n```\nThe list of all possible types. You can also create custom types - !!see here!!.\n```typescript\nexport const enum = createEnum({ alias: \"database-name\", values: [\"value1\", \"value2\", \"value3\"] });\ntype(enum, \"...\")\n\nsmallint(\"...\")\nint(\"...\")\nbigint(\"...\", maxBytes: \"max_bytes_53\")\nbigint(\"...\", maxBytes: \"max_bytes_64\")\n\nbool(\"...\")\ntext(\"...\");\nvarchar(\"...\");\nvarchar(\"...\", { size: 256 });\n\nserial(\"...\");\nbigserial(\"...\", maxBytes: \"max_bytes_53\");\nbigserial(\"...\", maxBytes: \"max_bytes_64\");\n\ndecimal(\"...\", { precision: 100, scale: 2 });\n\njsonb<...>(\"...\");\njsonb<string[]>(\"...\");\n\ntime(\"...\")\ntimestamp(\"...\") // with timezone\ntimestamptz(\"...\"); // without timezone\ntimestamp(\"...\").defaultValue(Defaults.CURRENT_TIMESTAMP)\n\nindex(column);\nindex([column1, column2, ...]);\nuniqueIndex(column);\nuniqueIndex([column1, column2, ...]);\n\n\ncolumn.primaryKey()\ncolumn.notNull()\ncolumn.defaultValue(...)\n\n// 'CASCADE' | 'RESTRICT' | 'SET NULL' | 'SET DEFAULT'\ncolumn.foreignKey(Table, (table) => table.column, { onDelete: \"CASCADE\", onUpdate: \"CASCADE\" });\n```\n\n### Create Read Update Delete\nQuerying, sorting and filtering. We also support partial select.\n```typescript\nconst db = await drizzle.connect(\"...\")\nconst table = new UsersTable(db);\n\nconst result: User[] = await table.select().execute();\nawait table.select().where(\n eq(table.id, 42)\n).execute();\n\n// you can combine filters with eq(...) or or(...)\nawait table.select().where(\n and([eq(table.id, 42), eq(table.name, \"Dan\")])\n).execute();\n\nawait table.select().where(\n or([eq(table.id, 42), eq(table.id, 1)])\n).execute();\n\n// partial select\nconst result = await table.select({\n mapped1: table.id,\n mapped2: table.name,\n}).execute();\nconst { mapped1, mapped2 } = result[0];\n\n// limit offset & order by\nawait table.select().limit(10).offset(10).execute()\nawait table.select().orderBy((table) => table.name, Order.ASC)\nawait table.select().orderBy((table) => table.name, Order.DESC)\n\n// list of all filter operators\neq(table.column, value)\nnotEq(table.column, value)\nless(table.column, value)\nlessEq(table.column, value)\ngreater(table.column, value)\ngreaterEq(table.column, value)\nisNull(table.column)\nisNotNull(table.column)\n\ninArray(table.column, [...values])\nlike(table.column, value)\nraw(\"raw sql filter\")\n\nand(exressions: Expr[])\nor(exressions: Expr[])\n```\nInserting\n##### Insert `user` with required fields\n```typescript\nawait usersTable.insert({\n test: 1,\n createdAt: new Date(),\n}).execute();\n```\n##### Insert `user` with required fields and get all rows as array\n```typescript\nconst result = await usersTable.insert({\n name: \"Andrew\",\n createdAt: new Date(),\n}).execute();\n\nconst result = await usersTable.insertMany([{\n name: \"Andrew\",\n createdAt: new Date(),\n}, {\n name: \"Dan\",\n createdAt: new Date(),\n}]).execute();\n\n//await usersTable.insert({\n// name: \"Dan\"\n//})\n//.onConflict(\n//\t(table) => table.name,\n//\t{ name: 'name value to be upserted' }\n//).execute();\n```\n\nUpdate and Delete\n```typescript\nawait usersTable.update()\n .where(eq(usersTable.name, 'Dan'))\n .set({ name: 'Mr. Dan' })\n .execute();\n\t\nawait usersTable.delete()\n .where(eq(usersTable.name, 'Dan'))\n .execute();\n```\n\n### Joins\nLast but not least. Probably the most powerful feature in the library🚀\nMany-to-one\n```typescript\nconst usersTable = new UsersTable(db);\nconst citiesTable = new CitiesTable(db);\n\nconst result = await citiesTable.select()\n .leftJoin(usersTable, (cities, users) => eq(cities.userId, users.id))\n .where((cities, users) => eq(cities.id, 1))\n .execute();\n\nconst citiesWithUsers: { city: City, user: User }[] = result.map((city, user) => ({ city, user }));\n```\nMany-to-many\n```typescript\nexport class UsersTable extends PgTable<UsersTable> {\n id = this.serial(\"id\").primaryKey();\n\tname = this.varchar(\"name\");\n}\n\nexport class ChatGroupsTable extends PgTable<ChatGroupsTable> {\n id = this.serial(\"id\").primaryKey();\n}\n\nexport class ManyToManyTable extends PgTable<ManyToManyTable> {\n userId = this.int('user_id').foreignKey(UsersTable, (table) => table.id, { onDelete: 'CASCADE' });\n groupId = this.int('group_id').foreignKey(ChatGroupsTable, (table) => table.id, { onDelete: 'CASCADE' });\n}\n\n...\nconst usersTable = new UsersTable(db);\nconst chatGroupsTable = new ChatGroupsTable(db);\nconst manyToManyTable = new ManyToManyTable(db);\n\n// querying user group with id 1 and all the participants(users)\nconst usersWithUserGroups = await manyToManyTable.select()\n .leftJoin(usersTable, (manyToMany, users) => eq(manyToManyTable.userId, users.id))\n .leftJoin(chatGroupsTable, (manyToMany, _users, chatGroups) => eq(manyToManyTable.groupId, chatGroups.id))\n .where((manyToMany, _users, userGroups) => eq(userGroups.id, 1))\n .execute();\n```\n\n### Join using partial field select\n##### Join Cities with Users getting only needed fields form request\n```typescript\n await citiesTable.select({\n id: citiesTable.id,\n userId: citiesTable.userId,\n })\n .leftJoin(usersTable, (cities, users) => eq(cities.userId, users.id))\n .where((cities, users) => eq(cities.id, 1))\n .execute();\n\nconst citiesWithUserObject = userWithCities.map((city, user) => ({ ...city, user }));\n```\n### Another join examples with different callback ON statements\n```typescript\nawait citiesTable.select()\n .leftJoin(usersTable, (cities, _users) => eq(cities.id, 13))\n .where((cities, _users) => eq(cities.location, 'q'))\n .execute();\n// Join statement generated from query\n// LEFT JOIN users AS users_1\n// ON cities.\"id\"=$1\n// WHERE cities.\"page\"=$2\n//\n// Values: [13, 'q']\n\nawait citiesTable.select()\n .leftJoin(usersTable, (cities, _users) => and([\n eq(cities.id, 13), notEq(cities.id, 14),\n ]))\n .execute();\n// Join statement generated from query\n// LEFT JOIN users AS users_1\n// ON (cities.\"id\"=$1 and cities.\"id\"!=$2)\n//\n// Values: [13, 14]\n\nawait citiesTable.select()\n .leftJoin(usersTable, (_cities, _users) => raw('<custom expression after ON statement>'))\n .where((cities, _users) => eq(cities.location, 'location'))\n .execute();\n// Join statement generated from query\n// LEFT JOIN users AS users_1\n// ON <custom expression after ON statement>\n// WHERE cities.\"page\"=$1\n// \n// Values: ['location']\n```\n\n\n## Migrations\n#### To run migrations generated by drizzle-kit you could use `Migrator` class\n##### Provide drizzle-kit config path\n```typescript\nawait drizzle.migrator(db).migrate('src/drizzle.config.yaml');\n```\n##### Another possibility is to provide object with path to folder with migrations\n```typescript\nawait drizzle.migrator(db).migrate({ migrationFolder: 'drizzle' });\n```\n\n\n## Raw query usage\n#### If you have some complex queries to execute and drizzle-orm can't handle them yet, then you could use `rawQuery` execution\n\n\n##### Execute custom raw query\n```typescript\nconst res: QueryResult<any> = await db.session().execute('SELECT * FROM users WHERE user.id = $1', [1]);\n```"
|
|
44
44
|
}
|
|
@@ -65,3 +65,5 @@ export default abstract class AbstractTable<TTable extends AbstractTable<TTable>
|
|
|
65
65
|
protected text(name: string): Column<PgText, true, false, this>;
|
|
66
66
|
protected jsonb<TSubType>(name: string): Column<PgJsonb<TSubType>, true, false, this>;
|
|
67
67
|
}
|
|
68
|
+
export declare abstract class PgTable<TTable extends PgTable<TTable>> extends AbstractTable<TTable> {
|
|
69
|
+
}
|
package/tables/abstractTable.js
CHANGED
|
@@ -22,6 +22,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
22
22
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
23
|
};
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.PgTable = void 0;
|
|
26
|
+
/* eslint-disable max-classes-per-file */
|
|
25
27
|
/* eslint-disable import/no-cycle */
|
|
26
28
|
const pgVarChar_1 = __importDefault(require("../columns/types/pgVarChar"));
|
|
27
29
|
const pgTimestamp_1 = __importDefault(require("../columns/types/pgTimestamp"));
|
|
@@ -150,4 +152,7 @@ class AbstractTable {
|
|
|
150
152
|
}
|
|
151
153
|
}
|
|
152
154
|
exports.default = AbstractTable;
|
|
155
|
+
class PgTable extends AbstractTable {
|
|
156
|
+
}
|
|
157
|
+
exports.PgTable = PgTable;
|
|
153
158
|
//# sourceMappingURL=abstractTable.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstractTable.js","sourceRoot":"","sources":["../../../src/tables/abstractTable.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"abstractTable.js","sourceRoot":"","sources":["../../../src/tables/abstractTable.ts"],"names":[],"mappings":"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"}
|
package/tables/inferTypes.d.ts
CHANGED
|
@@ -21,6 +21,11 @@ export declare type ExtractModel<TTable> = {
|
|
|
21
21
|
} & {
|
|
22
22
|
[Key in ExtractOptionalFieldNames<TTable>]?: ExtractCodeType<TTable[Key]>;
|
|
23
23
|
};
|
|
24
|
+
export declare type InferType<TTable> = {
|
|
25
|
+
[Key in ExtractFieldNames<TTable>]: ExtractCodeType<TTable[Key]>;
|
|
26
|
+
} & {
|
|
27
|
+
[Key in ExtractOptionalFieldNames<TTable>]?: ExtractCodeType<TTable[Key]>;
|
|
28
|
+
};
|
|
24
29
|
export declare type ExtractUpdateModel<TTable> = {
|
|
25
30
|
[Key in ExtractFieldNames<TTable>]: ExtractCodeType<TTable[Key]> | UpdateCustomExpr<TTable[Key]>;
|
|
26
31
|
} & {
|
package/test.d.ts
DELETED
|
File without changes
|
package/test.js
DELETED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// /* eslint-disable max-len */
|
|
3
|
-
// import DbConnector from './db/dbConnector';
|
|
4
|
-
// import UsersTable from './docs/tables/usersTable';
|
|
5
|
-
// import ConsoleLogger from './logger/consoleLogger';
|
|
6
|
-
// import CitiesTable from './docs/tables/citiesTable';
|
|
7
|
-
// import UserGroupsTable from './docs/tables/userGroupsTable';
|
|
8
|
-
// import {
|
|
9
|
-
// and, eq, like, notEq, onEq, raw,
|
|
10
|
-
// } from './builders/requestBuilders/where/static';
|
|
11
|
-
// import UsersToUserGroupsTable from './docs/tables/usersToUserGroups';
|
|
12
|
-
// import Order from './builders/highLvlBuilders/order';
|
|
13
|
-
// (async () => {
|
|
14
|
-
// try {
|
|
15
|
-
// console.log('dd');
|
|
16
|
-
// const db = await new DbConnector()
|
|
17
|
-
// .connectionString('postgresql://postgres@127.0.0.1/migrator')
|
|
18
|
-
// .connect();
|
|
19
|
-
// db.useLogger(new ConsoleLogger());
|
|
20
|
-
// const citiesTable = new CitiesTable(db);
|
|
21
|
-
// const usersTable = new UsersTable(db);
|
|
22
|
-
// const userGroupsTable = new UserGroupsTable(db);
|
|
23
|
-
// const usersToUserGroupsTable = new UsersToUserGroupsTable(db);
|
|
24
|
-
// // // group case
|
|
25
|
-
// // const usersWithUserGroups = await usersToUserGroupsTable.select()
|
|
26
|
-
// // .where(eq(userGroupsTable.id, 1))
|
|
27
|
-
// // .leftJoinV1(UsersTable,
|
|
28
|
-
// // (userToGroup) => userToGroup.userId,
|
|
29
|
-
// // (users) => users.id,
|
|
30
|
-
// // {
|
|
31
|
-
// // id: usersTable.id,
|
|
32
|
-
// // })
|
|
33
|
-
// // .leftJoin(UsersToUserGroupsTable, UserGroupsTable,
|
|
34
|
-
// // (userToGroup) => userToGroup.groupId,
|
|
35
|
-
// // (userGroup) => userGroup.id,
|
|
36
|
-
// // {
|
|
37
|
-
// // id: userGroupsTable.id,
|
|
38
|
-
// // })
|
|
39
|
-
// // .execute();
|
|
40
|
-
// await citiesTable.select({
|
|
41
|
-
// id: citiesTable.id,
|
|
42
|
-
// userId: citiesTable.userId,
|
|
43
|
-
// })
|
|
44
|
-
// .leftJoin(usersTable, (cities, users) => eq(cities.userId, users.id))
|
|
45
|
-
// .where((cities, users) => eq(cities.id, 1))
|
|
46
|
-
// .execute();
|
|
47
|
-
// await citiesTable.select({
|
|
48
|
-
// id: citiesTable.id,
|
|
49
|
-
// userId: citiesTable.userId,
|
|
50
|
-
// })
|
|
51
|
-
// .leftJoin(usersTable, (cities, users) => onEq(cities.userId, users.id))
|
|
52
|
-
// .where((cities, _users) => eq(cities.id, 1))
|
|
53
|
-
// .execute();
|
|
54
|
-
// const usersWithUserGroups = await usersToUserGroupsTable.select()
|
|
55
|
-
// .leftJoin(usersTable, (usersToUserGroups, users) => onEq(usersToUserGroups.userId, users.id))
|
|
56
|
-
// .leftJoin(userGroupsTable, (usersToUserGroups, _users, userGroups) => onEq(usersToUserGroups.groupId, userGroups.id))
|
|
57
|
-
// .where((usersToUserGroups, _users, userGroups) => eq(userGroups.id, 2))
|
|
58
|
-
// .execute();
|
|
59
|
-
// const usersWithUserGroups1 = await usersToUserGroupsTable.select()
|
|
60
|
-
// .where(eq(userGroupsTable.id, 2))
|
|
61
|
-
// .leftJoin(usersTable, (usersToUserGroups, users) => onEq(usersToUserGroups.userId, users.id))
|
|
62
|
-
// .leftJoin(userGroupsTable, (usersToUserGroups, _users, userGroups) => onEq(usersToUserGroups.groupId, userGroups.id))
|
|
63
|
-
// .execute();
|
|
64
|
-
// const userWithCities = await citiesTable.select()
|
|
65
|
-
// .leftJoin(usersTable,
|
|
66
|
-
// (cities, users) => onEq(cities.userId, users.id))
|
|
67
|
-
// .where((cities, _users) => eq(cities.id, 1))
|
|
68
|
-
// .execute();
|
|
69
|
-
// await citiesTable.select()
|
|
70
|
-
// .leftJoin(usersTable, (cities, _users) => eq(cities.id, 13))
|
|
71
|
-
// .where((cities, _users) => eq(cities.location, 'q'))
|
|
72
|
-
// .execute();
|
|
73
|
-
// await citiesTable.select()
|
|
74
|
-
// .leftJoin(usersTable, (cities, _users) => and([
|
|
75
|
-
// eq(cities.id, 13), notEq(cities.id, 14),
|
|
76
|
-
// ]))
|
|
77
|
-
// .execute();
|
|
78
|
-
// await citiesTable.select()
|
|
79
|
-
// .leftJoin(usersTable, (_cities, _users) => raw('<custom expression after ON statement>'))
|
|
80
|
-
// .where((cities, _users) => eq(cities.location, 'location'))
|
|
81
|
-
// .execute();
|
|
82
|
-
// // const res1 = newJoinRes1.map((args, arg2, arg3) => ({ city: args, user: arg2 }));
|
|
83
|
-
// // console.log(res1);
|
|
84
|
-
// // const newJoinRes1 = await citiesTable.select()
|
|
85
|
-
// // .leftJoin(usersTable, (cities, firstJoinUsers) => onEq(cities.userId, firstJoinUsers.id))
|
|
86
|
-
// // .execute();
|
|
87
|
-
// // const res1 = newJoinRes1.map((args, arg2) => ({ city: args, user: arg2 }));
|
|
88
|
-
// // console.log(res1);
|
|
89
|
-
// // const newJoinRes2 = await citiesTable.select({ customId: citiesTable.userId })
|
|
90
|
-
// // .leftJoin(usersTable, (cities, firstJoinUsers) => onEq(cities.customId, firstJoinUsers.id))
|
|
91
|
-
// // .execute();
|
|
92
|
-
// // const res2 = newJoinRes2.map((args, arg2) => ({ city: args, user: arg2 }));
|
|
93
|
-
// // console.log(res2);
|
|
94
|
-
// // const joinsWithPartialObjectResponse = await citiesTable.select({ customUserId: citiesTable.userId })
|
|
95
|
-
// // .leftJoin(usersTable,
|
|
96
|
-
// // (cities, partialUsers) => onEq(cities.customUserId, partialUsers.customId),
|
|
97
|
-
// // { customId: usersTable.id })
|
|
98
|
-
// // .leftJoin(usersTable,
|
|
99
|
-
// // (_cities, partialUsers, anotherUsersJoin) => onEq(partialUsers.customId, anotherUsersJoin.anotherId),
|
|
100
|
-
// // { anotherId: usersTable.id })
|
|
101
|
-
// // .execute();
|
|
102
|
-
// // const newJoinRes3 = await citiesTable.select()
|
|
103
|
-
// // .leftJoin(usersTable, (cities, firstJoinUsers) => onEq(cities.userId, firstJoinUsers.customUserId), { customUserId: usersTable.id })
|
|
104
|
-
// // .execute();
|
|
105
|
-
// // const res3 = newJoinRes3.map((args, arg2) => ({ city: args, user: arg2 }));
|
|
106
|
-
// // console.log(res3);
|
|
107
|
-
// // const newJoinRes4 = await citiesTable.select({ customId: citiesTable.userId })
|
|
108
|
-
// // .leftJoin(usersTable, (cities, firstJoinUsers) => onEq(cities.customId, firstJoinUsers.customUserId), { customUserId: usersTable.id })
|
|
109
|
-
// // .execute();
|
|
110
|
-
// // const res4 = newJoinRes4.map((args, arg2) => ({ city: args, user: arg2 }));
|
|
111
|
-
// // console.log(res4);
|
|
112
|
-
// // const newJoinRes5 = await usersToUserGroupsTable.select()
|
|
113
|
-
// // .leftJoin(usersTable, (usersToUserGroup, users) => onEq(usersToUserGroup.userId, users.id))
|
|
114
|
-
// // .leftJoin(userGroupsTable, (usersToUserGroup, user, userGroup) => onEq(usersToUserGroup.groupId, userGroup.id))
|
|
115
|
-
// // .execute();
|
|
116
|
-
// // const res5 = newJoinRes5.map((_u, user, group) => ({
|
|
117
|
-
// // user,
|
|
118
|
-
// // group,
|
|
119
|
-
// // }));
|
|
120
|
-
// // console.log(res5);
|
|
121
|
-
// // const newJoinRes6 = await usersToUserGroupsTable.select()
|
|
122
|
-
// // .leftJoin(usersTable, (usersToUserGroup, users) => onEq(usersToUserGroup.userId, users.id))
|
|
123
|
-
// // .leftJoin(userGroupsTable, (usersToUserGroup, userGroup) => onEq(usersToUserGroup.groupId, userGroup.id))
|
|
124
|
-
// // .leftJoin(usersTable, (usersToUserGroup, users, usersToUserGroup1, users1) => onEq(usersToUserGroup.userId, users.id))
|
|
125
|
-
// // .leftJoin(userGroupsTable, (usersToUserGroup, user, usersToUserGroup1, users1, userGroupsTable2) => onEq(usersToUserGroup.groupId, usersToUserGroup1.id))
|
|
126
|
-
// // .leftJoin(usersTable, (usersToUserGroup, user, usersToUserGroup1, users1, userGroupsTable2, users2) => onEq(usersToUserGroup.userId, users1.id))
|
|
127
|
-
// // .leftJoin(userGroupsTable, (usersToUserGroup, user, usersToUserGroup1, users1, userGroupsTable2, users2, userGroupsTable3) => onEq(users1.id, userGroupsTable3.id))
|
|
128
|
-
// // .execute();
|
|
129
|
-
// // const res6 = newJoinRes5.map((_u, user, group) => ({
|
|
130
|
-
// // user,
|
|
131
|
-
// // group,
|
|
132
|
-
// // }));
|
|
133
|
-
// // console.log(res6);
|
|
134
|
-
// // const res = await citiesTable.update()
|
|
135
|
-
// // // .groupBy((table, join1, join2, join3) => [table.id, join1.id, join1.phone])
|
|
136
|
-
// // .where(eq(citiesTable.location, 'YR'))
|
|
137
|
-
// // .set({
|
|
138
|
-
// // metadata: [{
|
|
139
|
-
// // fallback_image: true,
|
|
140
|
-
// // team_image: 'https://files.slack.com/files-pri/T016CCC3FE3-F03461UR9M5/clinic_team_photo_1.jpg?pub_secret=560c098bfb',
|
|
141
|
-
// // image_alt_text: 'Generic Physiotherapy Clinic image 1',
|
|
142
|
-
// // logo: '',
|
|
143
|
-
// // logo_alt_text: ''
|
|
144
|
-
// // }],
|
|
145
|
-
// // })
|
|
146
|
-
// // // .leftJoin(CitiesTable, UsersTable, (table) => table.userId, (table) => table.id)
|
|
147
|
-
// // // .leftJoin(UsersTable, UsersTable, (table) => table.id, (table) => table.id)
|
|
148
|
-
// // .execute();
|
|
149
|
-
// // console.log(res);
|
|
150
|
-
// // const ser = new MigrationSerializer();
|
|
151
|
-
// // const res = ser.generate([usersTable as AbstractTable<UsersTable>], []);
|
|
152
|
-
// // console.log(JSON.stringify(res, null, 2));
|
|
153
|
-
// // const f = {
|
|
154
|
-
// // id: count(usersTable.id),
|
|
155
|
-
// // };
|
|
156
|
-
// // type d = ExtractModel<typeof f>;
|
|
157
|
-
// // const res = await usersTable.select()
|
|
158
|
-
// // .leftJoin(UsersTable, (table) => table.id, (table) => table.id)
|
|
159
|
-
// // .leftJoin(UsersTable, CitiesTable, (table) => table.id, (table) => table.id)
|
|
160
|
-
// // .execute();
|
|
161
|
-
// // const res = await usersTable.select()
|
|
162
|
-
// // // .groupBy((table, join1, join2, join3) => [table.id, join1.id, join1.phone])
|
|
163
|
-
// // .leftJoin(UsersTable, (table) => table.foundationDate, (table) => table.id)
|
|
164
|
-
// // .leftJoin(UsersTable, UsersTable, (table) => table.role, (table) => table.id)
|
|
165
|
-
// // .leftJoin(UsersTable, UsersTable, (table) => table.role, (table) => table.id)
|
|
166
|
-
// // // .groupBy({
|
|
167
|
-
// // // usersTable: usersTable.id,
|
|
168
|
-
// // // firstJoin: [usersTable.id],
|
|
169
|
-
// // // secondJoin: usersTable.id,
|
|
170
|
-
// // // thirdJoin: usersTable.id,
|
|
171
|
-
// // // })
|
|
172
|
-
// // .execute();
|
|
173
|
-
// // console.log(res);
|
|
174
|
-
// } catch (e) {
|
|
175
|
-
// console.log(e);
|
|
176
|
-
// }
|
|
177
|
-
// })();
|
|
178
|
-
//# sourceMappingURL=test.js.map
|
package/test.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/test.ts"],"names":[],"mappings":"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"}
|