Skip to content

Commit

Permalink
fix: disallow chaining AlterColumnBuilder operations (kysely-org#467)
Browse files Browse the repository at this point in the history
  • Loading branch information
soanvig committed May 12, 2023
1 parent 9ecf9bf commit aaddf04
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 37 deletions.
16 changes: 3 additions & 13 deletions src/operation-node/alter-column-node.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { OperationNode } from './operation-node.js'
import { freeze } from '../util/object-utils.js'
import { ColumnNode } from './column-node.js'
import { DataTypeNode } from './data-type-node.js'
import { ValueNode } from './value-node.js'
import { RawNode } from './raw-node.js'
import { DataTypeNode } from './data-type-node.js'

export type AlterColumnNodeProps = Omit<AlterColumnNode, 'kind' | 'column'>

Expand All @@ -26,20 +25,11 @@ export const AlterColumnNode = freeze({
return node.kind === 'AlterColumnNode'
},

create(column: string): AlterColumnNode {
create<T extends keyof AlterColumnNode>(column: string, prop: T, value: Required<AlterColumnNode>[T]): AlterColumnNode {
return freeze({
kind: 'AlterColumnNode',
column: ColumnNode.create(column),
})
},

cloneWith(
node: AlterColumnNode,
props: AlterColumnNodeProps
): AlterColumnNode {
return freeze({
...node,
...props,
[prop]: value
})
},
})
44 changes: 22 additions & 22 deletions src/schema/alter-column-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,49 +10,39 @@ import {
} from '../parser/default-value-parser.js'

export class AlterColumnBuilder {
protected readonly alterColumnNode: AlterColumnNode
protected column: string

constructor(alterColumnNode: AlterColumnNode) {
this.alterColumnNode = alterColumnNode
constructor(column: string) {
this.column = column
}

setDataType(dataType: ColumnDataType): AlteredColumnBuilder {
return new AlteredColumnBuilder(
AlterColumnNode.cloneWith(this.alterColumnNode, {
dataType: DataTypeNode.create(dataType),
})
AlterColumnNode.create(this.column, 'dataType', DataTypeNode.create(dataType))
)
}

setDefault(value: DefaultValueExpression): AlteredColumnBuilder {
return new AlteredColumnBuilder(
AlterColumnNode.cloneWith(this.alterColumnNode, {
setDefault: parseDefaultValueExpression(value),
})
AlterColumnNode.create(this.column, 'setDefault', parseDefaultValueExpression(value))
)
}

dropDefault(): AlteredColumnBuilder {
return new AlteredColumnBuilder(
AlterColumnNode.cloneWith(this.alterColumnNode, {
dropDefault: true,
})
AlterColumnNode.create(this.column, 'dropDefault', true)
)
}

setNotNull(): AlteredColumnBuilder {
return new AlteredColumnBuilder(
AlterColumnNode.cloneWith(this.alterColumnNode, {
setNotNull: true,
})
AlterColumnNode.create(this.column, 'setNotNull', true)
)
}

dropNotNull(): AlteredColumnBuilder {
return new AlteredColumnBuilder(
AlterColumnNode.cloneWith(this.alterColumnNode, {
dropNotNull: true,
})
AlterColumnNode.create(this.column, 'dropNotNull', true)
)
}

Expand All @@ -66,20 +56,30 @@ export class AlterColumnBuilder {
}

/**
* Allows us to force consumers to do something, anything, when altering a column.
* Allows us to force consumers to do something, anything, when altering a column,
* and also disallows chaining more methods on AlterColumnBuilder, because
* SQL syntax for chaining ALTER COLUMN operations would be not WYSIWYG
*
* Basically, deny the following:
*
* ```ts
* db.schema.alterTable('person').alterColumn('age', (ac) => ac)
* ```
*
* ```ts
* db.schema.alterTable('person').alterColumn('age', (ac) => ac.dropNotNull().setNotNull())
* ```
*
* Which would now throw a compilation error, instead of a runtime error.
*/
export class AlteredColumnBuilder
extends AlterColumnBuilder
implements OperationNodeSource
export class AlteredColumnBuilder implements OperationNodeSource
{
protected readonly alterColumnNode: AlterColumnNode

constructor(alterColumnNode: AlterColumnNode) {
this.alterColumnNode = alterColumnNode
}

toOperationNode(): AlterColumnNode {
return this.alterColumnNode
}
Expand Down
4 changes: 2 additions & 2 deletions src/schema/alter-table-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export class AlterTableBuilder implements ColumnAlteringInterface {
alteration: AlterColumnBuilderCallback
): AlterTableColumnAlteringBuilder {
const builder = alteration(
new AlterColumnBuilder(AlterColumnNode.create(column))
new AlterColumnBuilder(column)
)

return new AlterTableColumnAlteringBuilder({
Expand Down Expand Up @@ -292,7 +292,7 @@ export class AlterTableColumnAlteringBuilder
alteration: AlterColumnBuilderCallback
): AlterTableColumnAlteringBuilder {
const builder = alteration(
new AlterColumnBuilder(AlterColumnNode.create(column))
new AlterColumnBuilder(column)
)

return new AlterTableColumnAlteringBuilder({
Expand Down

0 comments on commit aaddf04

Please sign in to comment.