1
1
import type { Compilable , CompiledQuery , KyselyPlugin , LogEvent , QueryResult , RawBuilder , Sql , Transaction } from 'kysely'
2
2
import { Kysely , sql } from 'kysely'
3
3
import { SqliteSerializePlugin } from 'kysely-plugin-serialize'
4
- import type { SimplifySingleResult } from 'kysely/dist/cjs/util/type-utils'
5
- import { parseTableMap , preCompile , runCreateTable } from './utils'
6
- import type { AvailableBuilder , BuilderResult , Logger , QueryBuilderOutput , SqliteBuilderOption , Table } from './types'
4
+ import type { Simplify } from 'kysely/dist/cjs/util/type-utils'
5
+ import { parseTableMap , precompileQuery , runCreateTable } from './utils'
6
+ import type { AvailableBuilder , Logger , QueryBuilderOutput , QueryBuilderResult , SqliteBuilderOption , Table } from './types'
7
7
import { Stack } from './stack'
8
8
9
9
type DBStatus =
10
- | 'needDrop'
11
- | 'noNeedDrop'
12
- | 'ready'
10
+ | 'needDrop'
11
+ | 'noNeedDrop'
12
+ | 'ready'
13
+ | 'destroy'
13
14
14
15
export class SqliteBuilder < DB extends Record < string , any > > {
15
16
public kysely : Kysely < DB >
@@ -45,20 +46,27 @@ export class SqliteBuilder<DB extends Record<string, any>> {
45
46
return this
46
47
}
47
48
48
- private async isEmptyTable ( ) : Promise < boolean > {
49
+ private async isFailToInitDB ( ) : Promise < boolean > {
50
+ if ( this . status === 'destroy' ) {
51
+ this . logger ?. error ( 'DB have been destroyed' )
52
+ return true
53
+ }
49
54
this . status !== 'ready' && await this . init ( )
50
55
if ( this . status === 'ready' ) {
51
56
return false
52
57
}
53
- this . logger ?. error ( 'fail to init table ' )
58
+ this . logger ?. error ( 'fail to init DB ' )
54
59
return true
55
60
}
56
61
62
+ /**
63
+ * execute sql in transaction, support nest transactions
64
+ */
57
65
public async transaction < T > (
58
66
cb : ( trx : Transaction < DB > ) => Promise < T > ,
59
67
errorMsg ?: string ,
60
68
) : Promise < T | undefined > {
61
- if ( await this . isEmptyTable ( ) ) {
69
+ if ( await this . isFailToInitDB ( ) ) {
62
70
return undefined
63
71
}
64
72
return await this . kysely . transaction ( )
@@ -79,11 +87,14 @@ export class SqliteBuilder<DB extends Record<string, any>> {
79
87
return this . trxs . isEmpty ( ) ? this . kysely : this . trxs . peek ( )
80
88
}
81
89
90
+ /**
91
+ * execute query manually, auto detect transaction
92
+ */
82
93
public async exec < O > (
83
94
cb : ( db : Kysely < DB > | Transaction < DB > ) => Promise < O > ,
84
95
errorMsg ?: string ,
85
96
) : Promise < O | undefined > {
86
- if ( await this . isEmptyTable ( ) ) {
97
+ if ( await this . isFailToInitDB ( ) ) {
87
98
return undefined
88
99
}
89
100
return cb ( this . getDB ( ) )
@@ -93,48 +104,63 @@ export class SqliteBuilder<DB extends Record<string, any>> {
93
104
} )
94
105
}
95
106
107
+ /**
108
+ * execute query and auto return first result, auto detect transaction
109
+ */
96
110
public async execOne < O > (
97
111
cb : ( db : Kysely < DB > | Transaction < DB > ) => AvailableBuilder < DB , O > ,
98
112
errorMsg ?: string ,
99
- ) : Promise < SimplifySingleResult < O > | undefined > {
113
+ ) : Promise < Simplify < O > | undefined > {
100
114
const resultList = await this . execList ( cb , errorMsg )
101
115
return resultList ?. length ? resultList [ 0 ] : undefined
102
116
}
103
117
118
+ /**
119
+ * execute query and auto return results, auto detect transaction
120
+ */
104
121
public async execList < O > (
105
122
cb : ( db : Kysely < DB > | Transaction < DB > ) => AvailableBuilder < DB , O > ,
106
123
errorMsg ?: string ,
107
- ) : Promise < Exclude < SimplifySingleResult < O > , undefined > [ ] | undefined > {
108
- if ( await this . isEmptyTable ( ) ) {
124
+ ) : Promise < Simplify < O > [ ] | undefined > {
125
+ if ( await this . isFailToInitDB ( ) ) {
109
126
return undefined
110
127
}
111
128
return cb ( this . getDB ( ) )
112
129
. execute ( )
113
130
. catch ( ( err ) => {
114
131
errorMsg && this . logger ?. error ( errorMsg , err )
115
132
return undefined
116
- } ) as any
133
+ } )
117
134
}
118
135
119
- public preCompile < O > (
136
+ /**
137
+ * see {@link precompileQuery}
138
+ */
139
+ public precompile < O > (
120
140
queryBuilder : ( db : Kysely < DB > | Transaction < DB > ) => QueryBuilderOutput < Compilable < O > > ,
121
- ) : ReturnType < typeof preCompile < O > > {
122
- return preCompile ( queryBuilder ( this . kysely ) )
141
+ ) : ReturnType < typeof precompileQuery < O > > {
142
+ return precompileQuery ( queryBuilder ( this . kysely ) )
123
143
}
124
144
145
+ /**
146
+ * exec compiled query, and return rows in result, auto detect transaction, useful for select
147
+ */
125
148
public async execCompiledRows < O > (
126
149
query : CompiledQuery < O > ,
127
150
errorMsg ?: string ,
128
- ) : Promise < BuilderResult < O > [ 'rows' ] | undefined > {
151
+ ) : Promise < QueryBuilderResult < O > [ 'rows' ] | undefined > {
129
152
const result = await this . execCompiled ( query , errorMsg )
130
- return result ?. rows ?? undefined
153
+ return result ?. rows ?. length ? result . rows : undefined
131
154
}
132
155
156
+ /**
157
+ * exec compiled query, return result, auto detect transaction
158
+ */
133
159
public async execCompiled < O > (
134
160
query : CompiledQuery < O > ,
135
161
errorMsg ?: string ,
136
- ) : Promise < BuilderResult < O > | undefined > {
137
- if ( await this . isEmptyTable ( ) ) {
162
+ ) : Promise < QueryBuilderResult < O > | undefined > {
163
+ if ( await this . isFailToInitDB ( ) ) {
138
164
return undefined
139
165
}
140
166
return this . getDB ( ) . executeQuery ( query )
@@ -144,14 +170,31 @@ export class SqliteBuilder<DB extends Record<string, any>> {
144
170
} ) as any
145
171
}
146
172
173
+ /**
174
+ * compile query builder
175
+ */
147
176
public async toSQL < T extends Compilable > ( cb : ( db : Kysely < DB > ) => T ) : Promise < CompiledQuery < unknown > > {
148
- return cb ( this . getDB ( ) ) . compile ( )
177
+ return cb ( this . kysely ) . compile ( )
149
178
}
150
179
151
- public async raw < T = any > ( rawSql : ( s : Sql ) => RawBuilder < T > ) : Promise < QueryResult < T > | undefined > {
152
- if ( await this . isEmptyTable ( ) ) {
180
+ /**
181
+ * execute raw sql, auto detect transaction
182
+ * @see {@link Sql }
183
+ */
184
+ public async raw < O = any > ( rawSql : ( s : Sql ) => RawBuilder < O > ) : Promise < QueryResult < O > | undefined > {
185
+ if ( await this . isFailToInitDB ( ) ) {
153
186
return undefined
154
187
}
155
188
return rawSql ( sql ) . execute ( this . getDB ( ) )
156
189
}
190
+
191
+ /**
192
+ * destroy db connection
193
+ */
194
+ public async destroy ( ) {
195
+ await this . kysely . destroy ( )
196
+ this . status = 'destroy'
197
+ this . tableMap . clear ( )
198
+ this . trxs . clear ( )
199
+ }
157
200
}
0 commit comments