Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #11

Merged
merged 49 commits into from
Jan 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
a486a20
Move types pg types to prod dependencies
AndriiSherman Sep 11, 2021
660db57
Change version to 0.9.0
AndriiSherman Sep 11, 2021
3f2e457
Add type for every exception
AndriiSherman Sep 11, 2021
eba7b70
Update setters for update statement together with enum types hadnling…
AndriiSherman Sep 23, 2021
7f2c6bf
0.9.1
AndriiSherman Sep 25, 2021
a330bb6
Update README docs (#2)
AndriiSherman Nov 20, 2021
e503f5f
Merge branch 'develop' of https://github.com/lambda-direct/drizzle-or…
AndriiSherman Nov 20, 2021
b643d32
Feature/last updates (#3)
AndriiSherman Nov 30, 2021
d382c37
Merge branch 'develop' of https://github.com/lambda-direct/drizzle-or…
AndriiSherman Nov 30, 2021
ef1f164
0.9.2
AndriiSherman Nov 30, 2021
ef5c3c9
Add serial to serializer
AndriiSherman Dec 4, 2021
d985baf
0.9.3
AndriiSherman Dec 4, 2021
71679dd
Add onConstraint for serializer
AndriiSherman Dec 4, 2021
e253465
0.9.4
AndriiSherman Dec 4, 2021
635e709
Move ON DELETE and ON UPDATE to references
AndriiSherman Dec 4, 2021
189b3b5
0.9.5
AndriiSherman Dec 4, 2021
0857c7b
Add foreignKeyName to serializer
AndriiSherman Dec 4, 2021
3cd5db9
0.9.6
AndriiSherman Dec 4, 2021
fc8ea14
Improvements (#4)
AndriiSherman Dec 6, 2021
fc093a4
Merge branch 'develop' of https://github.com/lambda-direct/drizzle-or…
AndriiSherman Dec 6, 2021
ceb6d45
0.9.7
AndriiSherman Dec 7, 2021
efc81d1
onContrsaint as optional
AndriiSherman Dec 7, 2021
a015511
0.9.8
AndriiSherman Dec 7, 2021
388cd46
Fix serializer key
AndriiSherman Dec 13, 2021
4c99083
0.9.9
AndriiSherman Dec 13, 2021
3c8541c
0.9.10
AndriiSherman Dec 13, 2021
1e7a09f
Fix Nan exception on mapping
AndriiSherman Dec 16, 2021
a939b9e
Add smallInt type
AndriiSherman Dec 16, 2021
48c6590
0.9.11
AndriiSherman Dec 16, 2021
114e322
Export ExtractModel type
AndriiSherman Dec 17, 2021
c32d6a5
0.9.12
AndriiSherman Dec 17, 2021
5a2d566
Feature/knex (#6)
AndriiSherman Dec 23, 2021
b59d8c1
Merge branch 'develop' of https://github.com/lambda-direct/drizzle-or…
AndriiSherman Dec 23, 2021
ca232ac
0.9.13
AndriiSherman Dec 23, 2021
1da6b77
0.9.14
AndriiSherman Dec 23, 2021
b075651
Export ISession
AndriiSherman Dec 23, 2021
13d3c58
0.9.15
AndriiSherman Dec 23, 2021
daefc39
Release/0.9.16 (#7)
AndriiSherman Dec 27, 2021
7b53d13
Merge branch 'develop' of https://github.com/lambda-direct/drizzle-or…
AndriiSherman Dec 27, 2021
2ede3b5
Add serializer to introspect database to json snapshot (#8)
AndriiSherman Dec 27, 2021
efaa70a
Merge branch 'main' of https://github.com/lambda-direct/drizzle-orm i…
AndriiSherman Dec 27, 2021
2a2f987
Fix `any` type returning from `.notNull()` and `.primaryKey()` functions
AndriiSherman Dec 28, 2021
0a4b452
0.9.18
AndriiSherman Dec 28, 2021
591219f
Fix querying be Date
AndriiSherman Jan 24, 2022
e433f3c
0.9.19
AndriiSherman Jan 24, 2022
b63a205
Add Changelog for version 0.9.19
AndriiSherman Jan 24, 2022
31abd8a
Feature/partial select (#10)
AndriiSherman Jan 27, 2022
17c0e6c
Merge branch 'main' of https://github.com/lambda-direct/drizzle-orm i…
AndriiSherman Jan 27, 2022
97be648
Merge branch 'develop' of https://github.com/lambda-direct/drizzle-or…
AndriiSherman Jan 27, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,109 @@
# Changelog

### 0.10.0 (January 27, 2022)
### Breaking changes:
- Move limit offset to function calls
#### Previous limit/offset usage:
```typescript
await usersTable.select({limit: 20, offset: 20}).all();
```
#### Current limit/offset usage:
```typescript
await usersTable.select().limit(20).offset(20).all();
```
- Change join calls starting from second one

Starting from second join you need to provide table to join from. As long as PostgreSQL has a possibility to join on tables, that already were in previous joins, we need to have a possibility to clarify from which exact table we need to join
#### Previous join funcition call with parameters:
```typescript
await usersToUserGroupsTable.select()
.where(eq(userGroupsTable.id, 1))
.leftJoin(UsersTable,
(userToGroup) => userToGroup.userId,
(users) => users.id)
.leftJoin(UserGroupsTable,
(userToGroup) => userToGroup.groupId,
(userGroup) => userGroup.id)
.execute()
```
#### Current join funcition call with parameters:
```typescript
await usersToUserGroupsTable.select()
.where(eq(userGroupsTable.id, 1))
.leftJoin(UsersTable,
(userToGroup) => userToGroup.userId,
(users) => users.id)
.leftJoin(UsersToUserGroupsTable, UserGroupsTable,
(userToGroup) => userToGroup.groupId,
(userGroup) => userGroup.id)
.execute()
```
- Create partial select on simple select + on each join

If you want to select only specific fields from select request you could provide your own interface with columns to map to:
#### Example
```typescript
const partialSelect = await usersTable.select({
id: usersTable.id,
phone: usersTable.phone,
}).all();

// Usage
const { mappedId, mappedPhone } = partialSelect;
```

Same could be done with specific columns selecting on joined tables
#### Example
```typescript
const usersWithUserGroups = await usersToUserGroupsTable.select()
.where(eq(userGroupsTable.id, 1))
.leftJoin(UsersTable,
(userToGroup) => userToGroup.userId,
(users) => users.id,
// Partial fields to be selected from UsersTable
{
id: usersTable.id,
})
.leftJoin(UsersToUserGroupsTable, UserGroupsTable,
(userToGroup) => userToGroup.groupId,
(userGroup) => userGroup.id,
// Partial fields to be selected from UserGroupsTable
{
id: userGroupsTable.id,
})
.execute();
```

- Create possibility to have self FK and self joins

You could create FK on same table you are creating it from
#### Example
```typescript
public cityId = this.int('city_id').foreignKey(CitiesTable, (table) => table.id, { onUpdate: 'CASCADE' });
```
- Delete first() on execution and add findOne(), that will throw an error

Previously we had `.first()` function, that was just getting first element from rows returned from `pg` driver
Right now, invoking `.findOne()` function should check if response contains exactly 1 element in repsponse. If not, it will throw an error
### Example
```typescript
const firstSelect = await usersTable.select().findOne();
```
- Fix wrong types. Right now you won't get undefined from select query
---

### 0.9.19 (January 24, 2022)
### Fixes and Functionality:
- Fix all queries by `Date`

---

### 0.9.18 (December 28, 2021)
### Fixes and Functionality:
- Fix `any` type returning from `.notNull()` and `.primaryKey()` functions

---

### 0.9.17 (December 27, 2021)
### Fixes and Functionality:
- Add serializer `fromDb()` method to introspect selected database to drizzle-kit json shanpsot format
Expand Down
48 changes: 39 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ const usersTable = new UsersTable(db);
const allSelect = await usersTable.select().all();

// select first
const firstSelect = await usersTable.select().first();
const firstSelect = await usersTable.select().findOne();
```
#### **Sorting and Filtering**
---
Expand All @@ -178,7 +178,7 @@ const orSelect = await usersTable.select().where(
```
##### Select all records from `Users` using **LIMIT** and **OFFSET**
```typescript
const limitOffsetSelect = await usersTable.select({ limit: 10, offset: 10 }).all();
const limitOffsetSelect = await usersTable.select().limit(10).offset(10).all();
```
##### Select all records from `Users` where `phone` contains `"hello"`
```typescript
Expand Down Expand Up @@ -232,6 +232,17 @@ const notEqSelect = usersTable.select().where(
```typescript
const ordered = await usersTable.select().orderBy((table) => table.phone, Order.ASC).all();
```
#### **Partial Selecting**
```typescript
const partialSelect = await usersTable.select({
id: usersTable.id,
phone: usersTable.phone,
}).all();

// Usage
const { mappedId, mappedPhone } = partialSelect;
```


### **Update**
---
Expand All @@ -254,7 +265,7 @@ await usersTable.update()
await usersTable.update()
.where(eq(usersTable.phone, 'hello'))
.set({ fullName: 'newName' })
.first();
.findOne();
```

### **Delete**
Expand All @@ -274,7 +285,7 @@ await usersTable.delete()
```typescript
await usersTable.delete()
.where(eq(usersTable.phone, 'hello'))
.first();
.findOne();
```

### **Insert**
Expand All @@ -297,7 +308,7 @@ const user = await usersTable.insert({
const user = await usersTable.insert({
test: 1,
createdAt: new Date(),
}).first();
}).findOne();
```
##### Insert many `users` with required fields and get all inserted entities
```typescript
Expand Down Expand Up @@ -349,7 +360,7 @@ const citiesWithUserObject = userWithCities.map((city, user) => ({ ...city, user
.leftJoin(UsersTable,
(userToGroup) => userToGroup.userId,
(users) => users.id)
.leftJoin(UserGroupsTable,
.leftJoin(UsersToUserGroupsTable, UserGroupsTable,
(userToGroup) => userToGroup.groupId,
(users) => users.id)
.execute();
Expand All @@ -371,7 +382,7 @@ const citiesWithUserObject = userWithCities.map((city, user) => ({ ...city, user
.leftJoin(UsersTable,
(userToGroup) => userToGroup.userId,
(users) => users.id)
.leftJoin(UserGroupsTable,
.leftJoin(UsersToUserGroupsTable, UserGroupsTable,
(userToGroup) => userToGroup.groupId,
(users) => users.id)
.execute();
Expand All @@ -386,14 +397,33 @@ const citiesWithUserObject = userWithCities.map((city, user) => ({ ...city, user
users: userGroupWithUsers.many,
};
```
### Join using partial field select
##### Join Cities with Users getting only needed fields form request
```typescript
await citiesTable.select({
id: citiesTable.id,
userId: citiesTable.userId,
})
.where(eq(citiesTable.id, 1))
.leftJoin(UsersTable,
(city) => city.userId,
(users) => users.id,
{
id: usersTable.id,
})
.execute();

const citiesWithUserObject = userWithCities.map((city, user) => ({ ...city, user }));
```


## Migrations
#### To run migrations generated by drizzle-kit you could use `Migtator` class
#### To run migrations generated by drizzle-kit you could use `Migrator` class
##### Provide drizzle-kit config path
```typescript
await drizzle.migrator(db).migrate('src/drizzle.config.yaml');
```
##### Provide object with path to folder with migrations
##### Another possibility is to provide object with path to folder with migrations
```typescript
await drizzle.migrator(db).migrate({ migrationFolder: 'drizzle' });
```
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "drizzle-orm",
"version": "0.9.17",
"version": "0.9.19",
"description": "",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
17 changes: 12 additions & 5 deletions src/builders/aggregators/abstractAggregator.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
/* eslint-disable max-len */
import { AbstractColumn, Column } from '../../columns/column';
import ColumnType from '../../columns/types/columnType';
import { AbstractTable } from '../../tables';
import { ecranate } from '../../utils/ecranate';

// eslint-disable-next-line max-len
export default class Aggregator {
protected _fields: Array<string> = [];
protected _table: AbstractTable<any>;

public constructor(table: AbstractTable<any>) {
public constructor(table: AbstractTable<any>, partial?: {[name: string]: AbstractColumn<ColumnType<any>, boolean, boolean, AbstractTable<any>>}) {
this._table = table;
this._fields = this.generateSelectArray(this._table.tableName(),
Object.values(this._table.mapServiceToDb()));
if (!partial) {
this._fields = this.generateSelectArray(this._table.tableName(),
Object.values(this._table.mapServiceToDb()));
} else {
this._fields = this.generateSelectArray(this._table.tableName(),
Object.values(partial));
}
}

protected generateSelectArray = (table: string, columns: AbstractColumn<ColumnType>[]) => {
protected generateSelectArray = (table: string, columns: AbstractColumn<ColumnType>[], id?: number) => {
const selectFields: string[] = [];

columns.forEach((field: any) => {
Expand All @@ -23,7 +30,7 @@ export default class Aggregator {
selectFields.push('.');
selectFields.push(ecranate(field.getColumnName()));
selectFields.push(' AS ');
selectFields.push(ecranate(`${table.replace('.', '_')}_${field.getColumnName()}`));
selectFields.push(ecranate(`${field.getAlias()}${id ? `_${id}` : ''}`));
selectFields.push(',');
}
});
Expand Down
48 changes: 35 additions & 13 deletions src/builders/aggregators/selectAggregator.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable max-len */
import { AbstractColumn } from '../../columns/column';
import ColumnType from '../../columns/types/columnType';
import { AbstractTable } from '../../tables';
Expand All @@ -18,8 +19,10 @@ export default class SelectAggregator extends Aggregator {
// private _groupBy: Array<string> = [];
private _orderBy: Array<string> = [];

public constructor(table: AbstractTable<any>) {
super(table);
// public constructor(table: AbstractTable<any>);
// public constructor(table: AbstractTable<any>, partial: {[name: string]: AbstractColumn<ColumnType<any>, boolean, boolean, AbstractTable<any>>})
public constructor(table: AbstractTable<any>, partial?: {[name: string]: AbstractColumn<ColumnType<any>, boolean, boolean, AbstractTable<any>>}) {
super(table, partial);
}

public filters = (filters: Expr): SelectAggregator => {
Expand Down Expand Up @@ -70,29 +73,48 @@ export default class SelectAggregator extends Aggregator {
};

// Add select generator for second table also
public join = (joins: Array<Join<any> | undefined>): SelectAggregator => {
joins.forEach((join: Join<any> | undefined) => {
if (join) {
const tableFrom = join.fromColumn.getParentName();
const tableTo = join.toColumn.getParentName();
const { type } = join;
public join = (joins: Array<{
join: Join<any>, partial?: {[name: string]: AbstractColumn<ColumnType<any>, boolean, boolean, any>},
id?: number
}>): SelectAggregator => {
const cache: {[tableName: string]: string} = {};
joins.forEach((joinObject: {
join: Join<any>, partial?: {[name: string]: AbstractColumn<ColumnType<any>, boolean, boolean, any>},
id?: number
}) => {
if (joinObject) {
const tableFrom = joinObject.join.fromColumn.getParentName();
const tableTo = joinObject.join.toColumn.getParentName();
const { type } = joinObject.join;

const selectString = this.generateSelectArray(tableTo, Object.values(join.mappedServiceToDb)).join('');
let selectString;
if (joinObject.partial) {
selectString = this.generateSelectArray(`${tableTo}${joinObject.id ? `_${joinObject.id}` : ''}`, Object.values(joinObject.partial), joinObject.id).join('');
} else {
selectString = this.generateSelectArray(`${tableTo}${joinObject.id ? `_${joinObject.id}` : ''}`, Object.values(joinObject.join.mappedServiceToDb), joinObject.id).join('');
}
this._fields.push(', ');
this._fields.push(selectString);
this._join.push('\n');
this._join.push(type);
this._join.push(' ');
this._join.push(tableTo);
this._join.push(' ');
this._join.push(`AS ${tableTo}${joinObject.id ? `_${joinObject.id}` : ''}`);
this._join.push('\n');
this._join.push('ON ');
this._join.push(tableFrom);
if (cache[tableFrom]) {
this._join.push(cache[tableFrom]);
} else {
this._join.push(tableFrom);
cache[tableTo] = `${tableTo}${joinObject.id ? `_${joinObject.id}` : ''}`;
}
this._join.push('.');
this._join.push(join.fromColumn.getColumnName());
this._join.push(joinObject.join.fromColumn.getColumnName());
this._join.push(' = ');
this._join.push(tableTo);
this._join.push(`${tableTo}${joinObject.id ? `_${joinObject.id}` : ''}`);
this._join.push('.');
this._join.push(join.toColumn.getColumnName());
this._join.push(joinObject.join.toColumn.getColumnName());
}
});

Expand Down
Loading