Skip to content

Commit 5e70376

Browse files
committed
increments() no longer changes the column type to serial on postgres
1 parent 4285b5c commit 5e70376

16 files changed

+272
-157
lines changed

README.md

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,34 +163,67 @@ changes completely. Migrations need to be "frozen in time".
163163
The migrations can use the [Kysely.schema](https://koskimas.github.io/kysely/classes/SchemaModule.html)
164164
module to modify the schema. Migrations can also run normal queries to modify the data.
165165

166+
### PostgreSQL migration example
167+
166168
```ts
167169
import { Kysely } from 'kysely'
168170

169171
export async function up(db: Kysely<any>): Promise<void> {
170172
await db.schema
171173
.createTable('person')
172-
.addColumn('id', 'integer', (col) => col.increments().primaryKey())
174+
.addColumn('id', 'serial', (col) => col.primaryKey())
173175
.addColumn('first_name', 'varchar')
174176
.addColumn('last_name', 'varchar')
175177
.addColumn('gender', 'varchar(50)')
176178
.execute()
177179

178180
await db.schema
179181
.createTable('pet')
180-
.addColumn('id', 'integer', (col) => col.increments().primaryKey())
182+
.addColumn('id', 'serial', (col) => col.primaryKey())
181183
.addColumn('name', 'varchar', (col) => col.notNull().unique())
182184
.addColumn('owner_id', 'integer', (col) =>
183185
col.references('person.id').onDelete('cascade')
184186
)
185187
.addColumn('species', 'varchar')
186-
// Older MySQL versions don't support column-level foreign key
187-
// constraint definitions and you need to add them using the table
188-
// builder by uncommenting the following:
189-
//
190-
// .addForeignKeyConstraint(
191-
// 'pet_owner_id_fk', ['owner_id'], 'person', ['id'],
192-
// (cb) => cb.onDelete('cascade')
193-
// )
188+
.execute()
189+
190+
await db.schema
191+
.createIndex('pet_owner_id_index')
192+
.on('pet')
193+
.column('owner_id')
194+
.execute()
195+
}
196+
197+
export async function down(db: Kysely<any>): Promise<void> {
198+
await db.schema.dropTable('pet').execute()
199+
await db.schema.dropTable('person').execute()
200+
}
201+
```
202+
203+
### MySQL migration example
204+
205+
```ts
206+
import { Kysely } from 'kysely'
207+
208+
export async function up(db: Kysely<any>): Promise<void> {
209+
await db.schema
210+
.createTable('person')
211+
.addColumn('id', 'integer', (col) => col.increments().primaryKey())
212+
.addColumn('first_name', 'varchar')
213+
.addColumn('last_name', 'varchar')
214+
.addColumn('gender', 'varchar(50)')
215+
.execute()
216+
217+
await db.schema
218+
.createTable('pet')
219+
.addColumn('id', 'integer', (col) => col.increments().primaryKey())
220+
.addColumn('name', 'varchar', (col) => col.notNull().unique())
221+
.addColumn('owner_id', 'integer')
222+
.addColumn('species', 'varchar')
223+
.addForeignKeyConstraint(
224+
'pet_owner_id_fk', ['owner_id'], 'person', ['id'],
225+
(cb) => cb.onDelete('cascade')
226+
)
194227
.execute()
195228

196229
await db.schema

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "kysely",
3-
"version": "0.8.1",
3+
"version": "0.9.0",
44
"description": "Type safe SQL query builder",
55
"repository": {
66
"type": "git",

src/dialect/mysql/mysql-query-compiler.ts

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,6 @@
1-
import { ColumnDefinitionNode } from '../../operation-node/column-definition-node.js'
21
import { DefaultQueryCompiler } from '../../query-compiler/default-query-compiler.js'
32

43
export class MysqlQueryCompiler extends DefaultQueryCompiler {
5-
protected override visitColumnDefinition(node: ColumnDefinitionNode): void {
6-
this.visitNode(node.column)
7-
this.append(' ')
8-
this.visitNode(node.dataType)
9-
10-
if (node.defaultTo) {
11-
this.append(' default ')
12-
this.visitNode(node.defaultTo)
13-
}
14-
15-
if (!node.isNullable || node.isAutoIncrementing) {
16-
this.append(' not null')
17-
}
18-
19-
if (node.isAutoIncrementing) {
20-
this.append(' auto_increment')
21-
}
22-
23-
if (node.isUnique) {
24-
this.append(' unique')
25-
}
26-
27-
if (node.isPrimaryKey) {
28-
this.append(' primary key')
29-
}
30-
31-
if (node.references) {
32-
this.append(' ')
33-
this.visitNode(node.references)
34-
}
35-
36-
if (node.check) {
37-
this.append(' ')
38-
this.visitNode(node.check)
39-
}
40-
}
41-
424
protected override visitReturning(): void {
435
// Do nothing.
446
}

src/operation-node/primitive-value-list-node.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const PrimitiveValueListNode = freeze({
2222
create(values: ReadonlyArray<PrimitiveValue>): PrimitiveValueListNode {
2323
return freeze({
2424
kind: 'PrimitiveValueListNode',
25-
values: freeze(values),
25+
values: freeze([...values]),
2626
})
2727
},
2828
})

src/query-builder/function-builder.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@ export class FunctionBuilder<DB, TB extends keyof DB> {
9797
* Calls the `sum` function for the column given as the argument.
9898
*
9999
* If this is used in a `select` statement the type of the selected expression
100-
* will be `number | string` by default. This is because Kysely can't know the
101-
* type the db driver outputs. Sometimes the output can be larger than the
102-
* largest javascript number and a string is returned instead. Most drivers
100+
* will be `number | string | BigInt` by default. This is because Kysely can't
101+
* know the type the db driver outputs. Sometimes the output can be larger than
102+
* the largest javascript number and a string is returned instead. Most drivers
103103
* allow you to configure the output type of large numbers and Kysely can't
104104
* know if you've done so.
105105
*
@@ -125,9 +125,9 @@ export class FunctionBuilder<DB, TB extends keyof DB> {
125125
* Calls the `count` function for the column given as the argument.
126126
*
127127
* If this is used in a `select` statement the type of the selected expression
128-
* will be `number | string` by default. This is because Kysely can't know the
129-
* type the db driver outputs. Sometimes the output can be larger than the
130-
* largest javascript number and a string is returned instead. Most drivers
128+
* will be `number | string | BigInt` by default. This is because Kysely can't
129+
* know the type the db driver outputs. Sometimes the output can be larger than
130+
* the largest javascript number and a string is returned instead. Most drivers
131131
* allow you to configure the output type of large numbers and Kysely can't
132132
* know if you've done so.
133133
*

src/query-compiler/default-query-compiler.ts

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,15 @@ export class DefaultQueryCompiler
7979
extends OperationNodeVisitor
8080
implements QueryCompiler
8181
{
82-
#sqlFragments: string[] = []
82+
#sql = ''
8383
#parameters: any[] = []
8484

8585
protected get numParameters(): number {
8686
return this.#parameters.length
8787
}
8888

8989
compileQuery(node: RootOperationNode): CompiledQuery {
90-
this.#sqlFragments = []
90+
this.#sql = ''
9191
this.#parameters = []
9292

9393
this.visitNode(node)
@@ -99,7 +99,7 @@ export class DefaultQueryCompiler
9999
}
100100

101101
protected getSql(): string {
102-
return this.#sqlFragments.join('')
102+
return this.#sql
103103
}
104104

105105
protected override visitSelectQuery(node: SelectQueryNode): void {
@@ -445,20 +445,7 @@ export class DefaultQueryCompiler
445445
protected override visitColumnDefinition(node: ColumnDefinitionNode): void {
446446
this.visitNode(node.column)
447447
this.append(' ')
448-
449-
if (node.isAutoIncrementing) {
450-
// Postgres overrides the data type for autoincrementing columns.
451-
if (
452-
DataTypeNode.is(node.dataType) &&
453-
node.dataType.dataType === 'bigint'
454-
) {
455-
this.append('bigserial')
456-
} else {
457-
this.append('serial')
458-
}
459-
} else {
460-
this.visitNode(node.dataType)
461-
}
448+
this.visitNode(node.dataType)
462449

463450
if (node.defaultTo) {
464451
this.append(' default ')
@@ -469,6 +456,11 @@ export class DefaultQueryCompiler
469456
this.append(' not null')
470457
}
471458

459+
if (node.isAutoIncrementing) {
460+
this.append(' ')
461+
this.append(this.getAutoIncrement())
462+
}
463+
472464
if (node.isUnique) {
473465
this.append(' unique')
474466
}
@@ -488,6 +480,10 @@ export class DefaultQueryCompiler
488480
}
489481
}
490482

483+
protected getAutoIncrement() {
484+
return 'auto_increment'
485+
}
486+
491487
protected override visitReferences(node: ReferencesNode): void {
492488
this.append('references ')
493489
this.visitNode(node.table)
@@ -888,7 +884,7 @@ export class DefaultQueryCompiler
888884
}
889885

890886
protected append(str: string): void {
891-
this.#sqlFragments.push(str)
887+
this.#sql += str
892888
}
893889

894890
protected appendValue(value: PrimitiveValue): void {

src/schema/alter-table-builder.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ import { CheckConstraintNode } from '../operation-node/check-constraint-node.js'
4242
import { ForeignKeyConstraintNode } from '../operation-node/foreign-key-constraint-node.js'
4343
import { ColumnNode } from '../operation-node/column-node.js'
4444

45+
/**
46+
* This builder can be used to create a `alter table` query.
47+
*/
4548
export class AlterTableBuilder {
4649
readonly #props: AlterTableBuilderProps
4750

src/schema/column-definition-builder.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,11 @@ import {
1818

1919
export interface ColumnDefinitionBuilderInterface<R> {
2020
/**
21-
* Makes the column automatically incrementing.
21+
* Adds `auto_increment` or `autoincrement` to the column definition
22+
* depending on the dialect.
2223
*
23-
* On some dialects this may change the column type as well. For example
24-
* on postgres this sets the column type to `serial` no matter what you
25-
* have specified before. This is one of the few cases where Kysely does
26-
* something "unexpected".
24+
* Some dialects like PostgreSQL don't support this. On PostgreSQL
25+
* you can use the `serial` or `bigserial` data type instead.
2726
*/
2827
increments(): R
2928

0 commit comments

Comments
 (0)