Skip to content

Commit eba9397

Browse files
feat: add thenRef method in eb.case (#1531)
Co-authored-by: igalklebanov <igalklebanov@gmail.com>
1 parent 1d55e41 commit eba9397

3 files changed

Lines changed: 72 additions & 3 deletions

File tree

src/query-builder/case-builder.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,29 @@ export class CaseThenBuilder<DB, TB extends keyof DB, W, O> {
9393
),
9494
})
9595
}
96+
97+
/**
98+
* Adds a `then` clause to the `case` statement where the value is a reference to a column.
99+
*
100+
* A `thenRef` call can be followed by {@link Whenable.when}, {@link CaseWhenBuilder.else},
101+
* {@link CaseWhenBuilder.end} or {@link CaseWhenBuilder.endCase} call.
102+
*/
103+
thenRef<RE extends ReferenceExpression<DB, TB>>(
104+
expression: RE,
105+
): CaseWhenBuilder<
106+
DB,
107+
TB,
108+
W,
109+
O | ExtractTypeFromReferenceExpression<DB, TB, RE>
110+
> {
111+
return new CaseWhenBuilder({
112+
...this.#props,
113+
node: CaseNode.cloneWithThen(
114+
this.#props.node,
115+
parseReferenceExpression(expression),
116+
),
117+
})
118+
}
96119
}
97120

98121
export class CaseWhenBuilder<DB, TB extends keyof DB, W, O>
@@ -196,7 +219,7 @@ interface Whenable<DB, TB extends keyof DB, W, O> {
196219
/**
197220
* Adds a `when` clause to the case statement.
198221
*
199-
* A `when` call must be followed by a {@link CaseThenBuilder.then} call.
222+
* A `when` call must be followed by either a {@link CaseThenBuilder.then} or {@link CaseThenBuilder.thenRef} call.
200223
*/
201224
when<
202225
RE extends ReferenceExpression<DB, TB>,

test/node/src/case.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,40 @@ for (const dialect of DIALECTS) {
6060
await query.execute()
6161
})
6262

63+
it('should execute a query with a case...when...thenRef...end operator', async () => {
64+
const query = ctx.db
65+
.selectFrom('person')
66+
.select((eb) =>
67+
eb
68+
.case()
69+
.when('gender', '=', 'male')
70+
.thenRef('first_name')
71+
.end()
72+
.as('title'),
73+
)
74+
75+
testSql(query, dialect, {
76+
postgres: {
77+
sql: `select case when "gender" = $1 then "first_name" end as "title" from "person"`,
78+
parameters: ['male'],
79+
},
80+
mysql: {
81+
sql: 'select case when `gender` = ? then `first_name` end as `title` from `person`',
82+
parameters: ['male'],
83+
},
84+
mssql: {
85+
sql: `select case when "gender" = @1 then "first_name" end as "title" from "person"`,
86+
parameters: ['male'],
87+
},
88+
sqlite: {
89+
sql: `select case when "gender" = ? then "first_name" end as "title" from "person"`,
90+
parameters: ['male'],
91+
},
92+
})
93+
94+
await query.execute()
95+
})
96+
6397
it('should execute a query with a case...value...when...then...end operator', async () => {
6498
const query = ctx.db
6599
.selectFrom('person')

test/typings/test-d/case.test-d.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,28 @@ async function testCase(eb: ExpressionBuilder<Database, 'person'>) {
6969
.end(),
7070
)
7171

72-
// references
72+
// eb.refs
7373
expectType<ExpressionWrapper<Database, 'person', string | number>>(
7474
eb
7575
.case()
76-
.when('gender', '=', 'male')
76+
.when('first_name', '=', eb.ref('last_name'))
7777
.then(eb.ref('first_name'))
7878
.else(eb.ref('age'))
7979
.end(),
8080
)
8181

82+
// refs
83+
expectType<ExpressionWrapper<Database, 'person', string | number | null>>(
84+
eb
85+
.case()
86+
.when('first_name', '=', eb.ref('last_name')) // TODO: whenRef
87+
.thenRef('first_name')
88+
.when('deleted_at', 'is not', null)
89+
.thenRef('age')
90+
// .elseRef('age')
91+
.end(),
92+
)
93+
8294
// expressions
8395
expectType<ExpressionWrapper<Database, 'person', `Mr. ${string}` | null>>(
8496
eb

0 commit comments

Comments
 (0)