Skip to content

Commit b5c605a

Browse files
authored
Merge branch 'master' into json-recipe
2 parents 2c1bb3e + 57ca6e5 commit b5c605a

37 files changed

+4266
-90
lines changed

.github/workflows/test.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,6 @@ jobs:
5757

5858
- name: Run esbuild test
5959
run: npm run test:esbuild
60+
61+
- name: Run cloudflare workers test
62+
run: npm run test:cloudflare-workers

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"test:browser:build": "rm -rf test/browser/bundle.js && esbuild test/browser/main.ts --bundle --outfile=test/browser/bundle.js",
4141
"test:browser": "npm run build && npm run test:browser:build && node test/browser/test.js",
4242
"test:bun": "npm run build && cd test/bun && bun install && bun run test",
43+
"test:cloudflare-workers": "npm run build && cd test/cloudflare-workers && npm ci && npm test",
4344
"test:deno": "npm run build && deno run --allow-env --allow-read --allow-net test/deno/local.test.ts && deno run --allow-env --allow-read --allow-net test/deno/cdn.test.ts",
4445
"test:typings": "tsd test/typings",
4546
"test:esmimports": "node scripts/check-esm-imports.js",

site/docs/examples/WHERE/0030-or-where.mdx renamed to site/docs/examples/WHERE/0040-or-where.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515

1616
import {
1717
orWhere
18-
} from './0030-or-where'
18+
} from './0040-or-where'
1919

2020
<div style={{ marginBottom: '1em' }}>
2121
<Playground code={orWhere} setupCode={exampleSetup} />

site/docs/examples/WHERE/0040-conditional-where-calls.mdx renamed to site/docs/examples/WHERE/0050-conditional-where-calls.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313

1414
import {
1515
conditionalWhereCalls
16-
} from './0040-conditional-where-calls'
16+
} from './0050-conditional-where-calls'
1717

1818
<div style={{ marginBottom: '1em' }}>
1919
<Playground code={conditionalWhereCalls} setupCode={exampleSetup} />

site/docs/examples/WHERE/0050-complex-where-clause.mdx renamed to site/docs/examples/WHERE/0060-complex-where-clause.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414

1515
import {
1616
complexWhereClause
17-
} from './0050-complex-where-clause'
17+
} from './0060-complex-where-clause'
1818

1919
<div style={{ marginBottom: '1em' }}>
2020
<Playground code={complexWhereClause} setupCode={exampleSetup} />

site/docs/getting-started/Instantiation.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ const dialect = new MysqlDialect({
4747
sqlite: (packageManager) =>
4848
isDialectSupported('sqlite', packageManager)
4949
? `import * as SQLite from '${DRIVER_NPM_PACKAGE_NAMES.sqlite}'
50-
import { Kysely, SQLiteDialect } from 'kysely'
50+
import { Kysely, SqliteDialect } from 'kysely'
5151
52-
const dialect = new SQLiteDialect({
52+
const dialect = new SqliteDialect({
5353
database: new SQLite(':memory:'),
5454
})`
5555
: `/* Kysely doesn't support SQLite + ${
@@ -67,7 +67,7 @@ const dialectClassNames: Record<
6767
postgresql: () => 'PostgresDialect',
6868
mysql: () => 'MysqlDialect',
6969
sqlite: (packageManager) =>
70-
isDialectSupported('sqlite', packageManager) ? 'SQLiteDialect' : null,
70+
isDialectSupported('sqlite', packageManager) ? 'SqliteDialect' : null,
7171
}
7272

7373
export function Instantiation(

src/expression/expression-builder.ts

Lines changed: 73 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@ import { QueryExecutor } from '../query-executor/query-executor.js'
2929
import {
3030
BinaryOperatorExpression,
3131
ComparisonOperatorExpression,
32+
FilterObject,
3233
OperandValueExpression,
3334
OperandValueExpressionOrList,
35+
parseFilterList,
36+
parseFilterObject,
3437
parseValueBinaryOperation,
3538
parseValueBinaryOperationOrExpression,
3639
} from '../parser/binary-operation-parser.js'
3740
import { Expression } from './expression.js'
38-
import { AndNode } from '../operation-node/and-node.js'
39-
import { OrNode } from '../operation-node/or-node.js'
4041
import { ParensNode } from '../operation-node/parens-node.js'
4142
import { ExpressionWrapper } from './expression-wrapper.js'
4243
import {
@@ -51,10 +52,9 @@ import {
5152
parseValueExpressionOrList,
5253
} from '../parser/value-parser.js'
5354
import { NOOP_QUERY_EXECUTOR } from '../query-executor/noop-query-executor.js'
54-
import { ValueNode } from '../operation-node/value-node.js'
5555
import { CaseBuilder } from '../query-builder/case-builder.js'
5656
import { CaseNode } from '../operation-node/case-node.js'
57-
import { isUndefined } from '../util/object-utils.js'
57+
import { isReadonlyArray, isUndefined } from '../util/object-utils.js'
5858
import { JSONPathBuilder } from '../query-builder/json-path-builder.js'
5959

6060
export interface ExpressionBuilder<DB, TB extends keyof DB> {
@@ -577,15 +577,42 @@ export interface ExpressionBuilder<DB, TB extends keyof DB> {
577577
* ```sql
578578
* select "person".*
579579
* from "person"
580-
* where "first_name" = $1
581-
* and "first_name" = $2
582-
* and "first_name" = $3
580+
* where (
581+
* "first_name" = $1
582+
* and "first_name" = $2
583+
* and "first_name" = $3
584+
* )
585+
* ```
586+
*
587+
* Optionally you can use the simpler object notation if you only need
588+
* equality comparisons:
589+
*
590+
* ```ts
591+
* db.selectFrom('person')
592+
* .selectAll('person')
593+
* .where((eb) => eb.and({
594+
* first_name: 'Jennifer',
595+
* last_name: 'Aniston'
596+
* }))
597+
* ```
598+
*
599+
* The generated SQL (PostgreSQL):
600+
*
601+
* ```sql
602+
* select "person".*
603+
* from "person"
604+
* where (
605+
* "first_name" = $1
606+
* and "last_name" = $2
607+
* )
583608
* ```
584609
*/
585610
and(
586611
exprs: ReadonlyArray<Expression<SqlBool>>
587612
): ExpressionWrapper<DB, TB, SqlBool>
588613

614+
and(exprs: Readonly<FilterObject<DB, TB>>): ExpressionWrapper<DB, TB, SqlBool>
615+
589616
/**
590617
* Combines two or more expressions using the logical `or` operator.
591618
*
@@ -600,7 +627,7 @@ export interface ExpressionBuilder<DB, TB extends keyof DB> {
600627
* ```ts
601628
* db.selectFrom('person')
602629
* .selectAll('person')
603-
* .where((eb) => or([
630+
* .where((eb) => eb.or([
604631
* eb('first_name', '=', 'Jennifer'),
605632
* eb('fist_name', '=', 'Arnold'),
606633
* eb('fist_name', '=', 'Sylvester')
@@ -612,15 +639,42 @@ export interface ExpressionBuilder<DB, TB extends keyof DB> {
612639
* ```sql
613640
* select "person".*
614641
* from "person"
615-
* where "first_name" = $1
616-
* or "first_name" = $2
617-
* or "first_name" = $3
642+
* where (
643+
* "first_name" = $1
644+
* or "first_name" = $2
645+
* or "first_name" = $3
646+
* )
647+
* ```
648+
*
649+
* Optionally you can use the simpler object notation if you only need
650+
* equality comparisons:
651+
*
652+
* ```ts
653+
* db.selectFrom('person')
654+
* .selectAll('person')
655+
* .where((eb) => eb.or({
656+
* first_name: 'Jennifer',
657+
* last_name: 'Aniston'
658+
* }))
659+
* ```
660+
*
661+
* The generated SQL (PostgreSQL):
662+
*
663+
* ```sql
664+
* select "person".*
665+
* from "person"
666+
* where (
667+
* "first_name" = $1
668+
* or "last_name" = $2
669+
* )
618670
* ```
619671
*/
620672
or(
621673
exprs: ReadonlyArray<Expression<SqlBool>>
622674
): ExpressionWrapper<DB, TB, SqlBool>
623675

676+
or(exprs: Readonly<FilterObject<DB, TB>>): ExpressionWrapper<DB, TB, SqlBool>
677+
624678
/**
625679
* Wraps the expression in parentheses.
626680
*
@@ -812,45 +866,23 @@ export function createExpressionBuilder<DB, TB extends keyof DB>(
812866
},
813867

814868
and(
815-
exprs: ReadonlyArray<Expression<SqlBool>>
869+
exprs: ReadonlyArray<Expression<SqlBool>> | Readonly<FilterObject<DB, TB>>
816870
): ExpressionWrapper<DB, TB, SqlBool> {
817-
if (exprs.length === 0) {
818-
return new ExpressionWrapper(ValueNode.createImmediate(true))
819-
} else if (exprs.length === 1) {
820-
return new ExpressionWrapper(exprs[0].toOperationNode())
821-
}
822-
823-
let node = AndNode.create(
824-
exprs[0].toOperationNode(),
825-
exprs[1].toOperationNode()
826-
)
827-
828-
for (let i = 2; i < exprs.length; ++i) {
829-
node = AndNode.create(node, exprs[i].toOperationNode())
871+
if (isReadonlyArray(exprs)) {
872+
return new ExpressionWrapper(parseFilterList(exprs, 'and'))
830873
}
831874

832-
return new ExpressionWrapper(ParensNode.create(node))
875+
return new ExpressionWrapper(parseFilterObject(exprs, 'and'))
833876
},
834877

835878
or(
836-
exprs: ReadonlyArray<Expression<SqlBool>>
879+
exprs: ReadonlyArray<Expression<SqlBool>> | Readonly<FilterObject<DB, TB>>
837880
): ExpressionWrapper<DB, TB, SqlBool> {
838-
if (exprs.length === 0) {
839-
return new ExpressionWrapper(ValueNode.createImmediate(false))
840-
} else if (exprs.length === 1) {
841-
return new ExpressionWrapper(exprs[0].toOperationNode())
842-
}
843-
844-
let node = OrNode.create(
845-
exprs[0].toOperationNode(),
846-
exprs[1].toOperationNode()
847-
)
848-
849-
for (let i = 2; i < exprs.length; ++i) {
850-
node = OrNode.create(node, exprs[i].toOperationNode())
881+
if (isReadonlyArray(exprs)) {
882+
return new ExpressionWrapper(parseFilterList(exprs, 'or'))
851883
}
852884

853-
return new ExpressionWrapper(ParensNode.create(node))
885+
return new ExpressionWrapper(parseFilterObject(exprs, 'or'))
854886
},
855887

856888
parens(...args: any[]) {

0 commit comments

Comments
 (0)