11import type { Dialect , Generated } from 'kysely'
2- import { CompiledQuery , Kysely } from 'kysely'
2+ import { CompiledQuery , Kysely , sql } from 'kysely'
33
44interface DB {
5+ audit : AuditTable
56 test : TestTable
67}
8+ interface AuditTable {
9+ id : Generated < number >
10+ test_id : number
11+ note : string
12+ }
713interface TestTable {
814 id : Generated < number >
915 name : string
1016 age : number
11- int8 : Uint8Array
17+ int8 : Uint8Array | null
1218}
19+
1320export async function testCase ( dialect : Dialect , expect : any , supportStream = true ) : Promise < void > {
1421 const db = new Kysely < DB > ( { dialect } )
22+
23+ try {
24+ await createSchema ( db )
25+ await assertInsertSelectAndBlobRoundTrip ( db , dialect , expect )
26+ await assertFilteringOrderingAndAggregates ( db , expect )
27+ await assertUpdateDeleteAndJoins ( db , expect )
28+ await assertTransactionsRollbackAndCommit ( db , expect )
29+ await assertRawReturningQuery ( db , expect )
30+
31+ if ( supportStream ) {
32+ await assertStreaming ( db , dialect , expect )
33+ }
34+ } finally {
35+ await db . destroy ( )
36+ }
37+ }
38+
39+ async function createSchema ( db : Kysely < DB > ) : Promise < void > {
1540 await db . schema
1641 . createTable ( 'test' )
1742 . addColumn ( 'id' , 'integer' , ( builder ) => builder . autoIncrement ( ) . primaryKey ( ) )
1843 . addColumn ( 'name' , 'text' )
1944 . addColumn ( 'age' , 'integer' )
2045 . addColumn ( 'int8' , 'blob' )
2146 . execute ( )
47+
48+ await db . schema
49+ . createTable ( 'audit' )
50+ . addColumn ( 'id' , 'integer' , ( builder ) => builder . autoIncrement ( ) . primaryKey ( ) )
51+ . addColumn ( 'test_id' , 'integer' )
52+ . addColumn ( 'note' , 'text' )
53+ . execute ( )
54+ }
55+
56+ async function assertInsertSelectAndBlobRoundTrip (
57+ db : Kysely < DB > ,
58+ dialect : Dialect ,
59+ expect : any ,
60+ ) : Promise < void > {
2261 await db
2362 . insertInto ( 'test' )
24- . values ( {
25- age : 18 ,
26- name : `test ${ dialect . toString ( ) } ` ,
27- int8 : new Uint8Array ( [ 1 , 2 , 3 ] ) ,
28- } )
63+ . values ( [
64+ {
65+ age : 18 ,
66+ name : `test ${ dialect . toString ( ) } ` ,
67+ int8 : new Uint8Array ( [ 1 , 2 , 3 ] ) ,
68+ } ,
69+ {
70+ age : 42 ,
71+ name : 'second row' ,
72+ int8 : new Uint8Array ( [ 4 , 5 , 6 ] ) ,
73+ } ,
74+ ] )
2975 . execute ( )
76+
3077 const { age, name, int8 } = await db
3178 . selectFrom ( 'test' )
3279 . selectAll ( )
33- . limit ( 1 )
80+ . where ( 'id' , '=' , 1 )
3481 . executeTakeFirstOrThrow ( )
82+
3583 expect ( age ) . toStrictEqual ( 18 )
3684 expect ( name ) . toStrictEqual ( `test ${ dialect . toString ( ) } ` )
37- expect ( Array . from ( int8 ) ) . toStrictEqual ( [ 1 , 2 , 3 ] )
38- if ( supportStream ) {
39- const rows = db . selectFrom ( 'test' ) . selectAll ( ) . stream ( )
40- let count = 0
41- for await ( const row of rows ) {
42- count ++
43- expect ( row . age ) . toStrictEqual ( 18 )
44- expect ( row . name ) . toStrictEqual ( `test ${ dialect . toString ( ) } ` )
45- expect ( Array . from ( row . int8 ) ) . toStrictEqual ( [ 1 , 2 , 3 ] )
46- }
47- expect ( count ) . toStrictEqual ( 1 )
48- }
85+ expect ( Array . from ( int8 ?? [ ] ) ) . toStrictEqual ( [ 1 , 2 , 3 ] )
86+ }
87+
88+ async function assertFilteringOrderingAndAggregates ( db : Kysely < DB > , expect : any ) : Promise < void > {
89+ const rows = await db
90+ . selectFrom ( 'test' )
91+ . select ( [ 'id' , 'name' ] )
92+ . where ( 'age' , '>=' , 18 )
93+ . orderBy ( 'age' , 'desc' )
94+ . execute ( )
95+
96+ expect ( rows ) . toStrictEqual ( [
97+ { id : 2 , name : 'second row' } ,
98+ { id : 1 , name : expect . stringContaining ( 'test ' ) } ,
99+ ] )
100+
101+ const aggregate = await db
102+ . selectFrom ( 'test' )
103+ . select ( ( { fn } ) => [
104+ fn . count < number > ( 'id' ) . as ( 'total' ) ,
105+ fn . avg < number > ( 'age' ) . as ( 'averageAge' ) ,
106+ ] )
107+ . executeTakeFirstOrThrow ( )
49108
109+ expect ( aggregate ) . toStrictEqual ( { total : 2 , averageAge : 30 } )
110+ }
111+
112+ async function assertUpdateDeleteAndJoins ( db : Kysely < DB > , expect : any ) : Promise < void > {
113+ await db . updateTable ( 'test' ) . set ( { age : 19 } ) . where ( 'id' , '=' , 1 ) . execute ( )
114+ await db . deleteFrom ( 'test' ) . where ( 'id' , '=' , 2 ) . execute ( )
115+ await db . insertInto ( 'audit' ) . values ( { test_id : 1 , note : 'updated age' } ) . execute ( )
116+
117+ const joined = await db
118+ . selectFrom ( 'test' )
119+ . innerJoin ( 'audit' , 'audit.test_id' , 'test.id' )
120+ . select ( [ 'test.id' , 'test.age' , 'audit.note' ] )
121+ . executeTakeFirstOrThrow ( )
122+
123+ expect ( joined ) . toStrictEqual ( { id : 1 , age : 19 , note : 'updated age' } )
124+
125+ const remaining = await db . selectFrom ( 'test' ) . select ( 'id' ) . orderBy ( 'id' ) . execute ( )
126+ expect ( remaining ) . toStrictEqual ( [ { id : 1 } ] )
127+ }
128+
129+ async function assertTransactionsRollbackAndCommit ( db : Kysely < DB > , expect : any ) : Promise < void > {
130+ await expect (
131+ db . transaction ( ) . execute ( async ( trx ) => {
132+ await trx
133+ . insertInto ( 'test' )
134+ . values ( { age : 99 , name : 'rolled back' , int8 : new Uint8Array ( [ 9 ] ) } )
135+ . execute ( )
136+ throw new Error ( 'rollback transaction' )
137+ } ) ,
138+ ) . rejects . toThrow ( 'rollback transaction' )
139+
140+ const rolledBack = await db
141+ . selectFrom ( 'test' )
142+ . select ( 'id' )
143+ . where ( 'name' , '=' , 'rolled back' )
144+ . execute ( )
145+ expect ( rolledBack ) . toStrictEqual ( [ ] )
146+
147+ await db . transaction ( ) . execute ( async ( trx ) => {
148+ await trx
149+ . insertInto ( 'test' )
150+ . values ( { age : 21 , name : 'committed' , int8 : new Uint8Array ( [ 7 , 8 ] ) } )
151+ . execute ( )
152+ } )
153+
154+ const committed = await db
155+ . selectFrom ( 'test' )
156+ . select ( [ 'age' , 'name' , 'int8' ] )
157+ . where ( 'name' , '=' , 'committed' )
158+ . executeTakeFirstOrThrow ( )
159+ expect ( committed . age ) . toStrictEqual ( 21 )
160+ expect ( committed . name ) . toStrictEqual ( 'committed' )
161+ expect ( Array . from ( committed . int8 ?? [ ] ) ) . toStrictEqual ( [ 7 , 8 ] )
162+ }
163+
164+ async function assertRawReturningQuery ( db : Kysely < DB > , expect : any ) : Promise < void > {
50165 const result = await db . executeQuery (
51166 CompiledQuery . raw ( 'insert into test("age", "name") values (?, ?) returning *' , [
52167 20 ,
@@ -55,10 +170,40 @@ export async function testCase(dialect: Dialect, expect: any, supportStream = tr
55170 )
56171 expect ( result . rows [ 0 ] ) . toStrictEqual ( {
57172 age : 20 ,
58- id : 2 ,
173+ id : 4 ,
59174 int8 : null ,
60175 name : 'test name' ,
61176 } )
62177
63- await db . destroy ( )
178+ const rawSelection = await db
179+ . selectFrom ( 'test' )
180+ . select ( sql < number > `age + 1` . as ( 'nextAge' ) )
181+ . where ( 'name' , '=' , 'test name' )
182+ . executeTakeFirstOrThrow ( )
183+ expect ( rawSelection ) . toStrictEqual ( { nextAge : 21 } )
184+ }
185+
186+ async function assertStreaming ( db : Kysely < DB > , dialect : Dialect , expect : any ) : Promise < void > {
187+ const rows = db . selectFrom ( 'test' ) . selectAll ( ) . orderBy ( 'id' ) . stream ( )
188+ const streamed : unknown [ ] = [ ]
189+
190+ for await ( const row of rows ) {
191+ streamed . push ( {
192+ age : row . age ,
193+ id : row . id ,
194+ int8 : row . int8 === null ? null : Array . from ( row . int8 ) ,
195+ name : row . name ,
196+ } )
197+ }
198+
199+ expect ( streamed ) . toStrictEqual ( [
200+ {
201+ age : 19 ,
202+ id : 1 ,
203+ int8 : [ 1 , 2 , 3 ] ,
204+ name : `test ${ dialect . toString ( ) } ` ,
205+ } ,
206+ { age : 21 , id : 3 , int8 : [ 7 , 8 ] , name : 'committed' } ,
207+ { age : 20 , id : 4 , int8 : null , name : 'test name' } ,
208+ ] )
64209}
0 commit comments