1
+ import FluentKit
1
2
import FluentSQL
2
- import SQLiteKit
3
3
import NIOCore
4
- import SQLiteNIO
5
4
import SQLKit
6
- import FluentKit
5
+ import SQLiteKit
6
+ import SQLiteNIO
7
7
8
8
struct FluentSQLiteDatabase : Database , SQLDatabase , SQLiteDatabase {
9
9
let database : any SQLiteDatabase
@@ -12,28 +12,27 @@ struct FluentSQLiteDatabase: Database, SQLDatabase, SQLiteDatabase {
12
12
let dataDecoder : SQLiteDataDecoder
13
13
let queryLogLevel : Logger . Level ?
14
14
let inTransaction : Bool
15
-
15
+
16
16
private func adjustFluentQuery( _ original: DatabaseQuery , _ converted: any SQLExpression ) -> any SQLExpression {
17
17
/// For `.create` query actions, we want to return the generated IDs, unless the `customIDKey` is the
18
18
/// empty string, which we use as a very hacky signal for "we don't implement this for composite IDs yet".
19
- if case . create = original. action, original. customIDKey != . some( . string( " " ) ) {
20
- return SQLKit . SQLList ( [ converted, SQLReturning ( . init( ( original. customIDKey ?? . id) . description) ) ] , separator: SQLRaw ( " " ) )
21
- } else {
19
+ guard case . create = original. action, original. customIDKey != . some( . string( " " ) ) else {
22
20
return converted
23
21
}
22
+ return SQLKit . SQLList ( [ converted, SQLReturning ( . init( ( original. customIDKey ?? . id) . description) ) ] , separator: SQLRaw ( " " ) )
24
23
}
25
-
24
+
26
25
// Database
27
-
28
- func execute( query: DatabaseQuery , onOutput: @escaping @Sendable ( any DatabaseOutput ) -> ( ) ) -> EventLoopFuture < Void > {
26
+
27
+ func execute( query: DatabaseQuery , onOutput: @escaping @Sendable ( any DatabaseOutput ) -> Void ) -> EventLoopFuture < Void > {
29
28
/// SQLiteKit will handle applying the configured data decoder to each row when providing `SQLRow`s.
30
- return self . execute (
29
+ self . execute (
31
30
sql: self . adjustFluentQuery ( query, SQLQueryConverter ( delegate: SQLiteConverterDelegate ( ) ) . convert ( query) ) ,
32
31
{ onOutput ( $0. databaseOutput ( ) ) }
33
32
)
34
33
}
35
-
36
- func execute( query: DatabaseQuery , onOutput: @escaping @Sendable ( any DatabaseOutput ) -> ( ) ) async throws {
34
+
35
+ func execute( query: DatabaseQuery , onOutput: @escaping @Sendable ( any DatabaseOutput ) -> Void ) async throws {
37
36
try await self . execute (
38
37
sql: self . adjustFluentQuery ( query, SQLQueryConverter ( delegate: SQLiteConverterDelegate ( ) ) . convert ( query) ) ,
39
38
{ onOutput ( $0. databaseOutput ( ) ) }
@@ -42,20 +41,22 @@ struct FluentSQLiteDatabase: Database, SQLDatabase, SQLiteDatabase {
42
41
43
42
func execute( schema: DatabaseSchema ) -> EventLoopFuture < Void > {
44
43
var schema = schema
45
-
44
+
46
45
if schema. action == . update {
47
- schema. updateFields = schema. updateFields. filter { switch $0 { // Filter out enum updates.
48
- case . dataType( _, . enum( _) ) : return false
49
- default : return true
50
- } }
46
+ schema. updateFields = schema. updateFields. filter {
47
+ switch $0 { // Filter out enum updates.
48
+ case . dataType( _, . enum( _) ) : false
49
+ default : true
50
+ }
51
+ }
51
52
guard schema. createConstraints. isEmpty, schema. updateFields. isEmpty, schema. deleteConstraints. isEmpty else {
52
53
return self . eventLoop. makeFailedFuture ( FluentSQLiteUnsupportedAlter ( ) )
53
54
}
54
55
if schema. createFields. isEmpty, schema. deleteFields. isEmpty { // If there were only enum updates, bail out.
55
56
return self . eventLoop. makeSucceededFuture ( ( ) )
56
57
}
57
58
}
58
-
59
+
59
60
return self . execute (
60
61
sql: SQLSchemaConverter ( delegate: SQLiteConverterDelegate ( ) ) . convert ( schema) ,
61
62
{ self . logger. debug ( " Unexpected row returned from schema query: \( $0) " ) }
@@ -65,30 +66,29 @@ struct FluentSQLiteDatabase: Database, SQLDatabase, SQLiteDatabase {
65
66
func execute( enum: DatabaseEnum ) -> EventLoopFuture < Void > {
66
67
self . eventLoop. makeSucceededFuture ( ( ) )
67
68
}
68
-
69
+
69
70
func withConnection< T> ( _ closure: @escaping @Sendable ( any Database ) -> EventLoopFuture < T > ) -> EventLoopFuture < T > {
70
71
self . eventLoop. makeFutureWithTask { try await self . withConnection { try await closure ( $0) . get ( ) } }
71
72
}
72
-
73
+
73
74
func withConnection< T> ( _ closure: @escaping @Sendable ( any Database ) async throws -> T ) async throws -> T {
74
75
try await self . withConnection {
75
- try await closure ( FluentSQLiteDatabase (
76
- database: $0,
77
- context: self . context,
78
- dataEncoder: self . dataEncoder,
79
- dataDecoder: self . dataDecoder,
80
- queryLogLevel: self . queryLogLevel,
81
- inTransaction: self . inTransaction
82
- ) )
76
+ try await closure (
77
+ FluentSQLiteDatabase (
78
+ database: $0,
79
+ context: self . context,
80
+ dataEncoder: self . dataEncoder,
81
+ dataDecoder: self . dataDecoder,
82
+ queryLogLevel: self . queryLogLevel,
83
+ inTransaction: self . inTransaction
84
+ ) )
83
85
}
84
86
}
85
-
87
+
86
88
func transaction< T> ( _ closure: @escaping @Sendable ( any Database ) -> EventLoopFuture < T > ) -> EventLoopFuture < T > {
87
- self . inTransaction ?
88
- closure ( self ) :
89
- self . eventLoop. makeFutureWithTask { try await self . transaction { try await closure ( $0) . get ( ) } }
89
+ self . inTransaction ? closure ( self ) : self . eventLoop. makeFutureWithTask { try await self . transaction { try await closure ( $0) . get ( ) } }
90
90
}
91
-
91
+
92
92
func transaction< T> ( _ closure: @escaping @Sendable ( any Database ) async throws -> T ) async throws -> T {
93
93
guard !self . inTransaction else {
94
94
return try await closure ( self )
@@ -103,11 +103,11 @@ struct FluentSQLiteDatabase: Database, SQLDatabase, SQLiteDatabase {
103
103
queryLogLevel: self . queryLogLevel,
104
104
inTransaction: true
105
105
)
106
-
106
+
107
107
try await db. raw ( " BEGIN TRANSACTION " ) . run ( )
108
108
do {
109
109
let result = try await closure ( db)
110
-
110
+
111
111
try await db. raw ( " COMMIT TRANSACTION " ) . run ( )
112
112
return result
113
113
} catch {
@@ -116,31 +116,32 @@ struct FluentSQLiteDatabase: Database, SQLDatabase, SQLiteDatabase {
116
116
}
117
117
}
118
118
}
119
-
119
+
120
120
// SQLDatabase
121
121
122
122
var dialect : any SQLDialect {
123
123
self . database. sql ( encoder: self . dataEncoder, decoder: self . dataDecoder, queryLogLevel: self . queryLogLevel) . dialect
124
124
}
125
-
125
+
126
126
var version : ( any SQLDatabaseReportedVersion ) ? {
127
127
self . database. sql ( encoder: self . dataEncoder, decoder: self . dataDecoder, queryLogLevel: self . queryLogLevel) . version
128
128
}
129
-
130
- func execute( sql query: any SQLExpression , _ onRow: @escaping @Sendable ( any SQLRow ) -> ( ) ) -> EventLoopFuture < Void > {
129
+
130
+ func execute( sql query: any SQLExpression , _ onRow: @escaping @Sendable ( any SQLRow ) -> Void ) -> EventLoopFuture < Void > {
131
131
self . database. sql ( encoder: self . dataEncoder, decoder: self . dataDecoder, queryLogLevel: self . queryLogLevel) . execute ( sql: query, onRow)
132
132
}
133
-
134
- func execute( sql query: any SQLExpression , _ onRow: @escaping @Sendable ( any SQLRow ) -> ( ) ) async throws {
135
- try await self . database. sql ( encoder: self . dataEncoder, decoder: self . dataDecoder, queryLogLevel: self . queryLogLevel) . execute ( sql: query, onRow)
133
+
134
+ func execute( sql query: any SQLExpression , _ onRow: @escaping @Sendable ( any SQLRow ) -> Void ) async throws {
135
+ try await self . database. sql ( encoder: self . dataEncoder, decoder: self . dataDecoder, queryLogLevel: self . queryLogLevel) . execute (
136
+ sql: query, onRow)
136
137
}
137
-
138
+
138
139
func withSession< R> ( _ closure: @escaping @Sendable ( any SQLDatabase ) async throws -> R ) async throws -> R {
139
140
try await self . database. sql ( encoder: self . dataEncoder, decoder: self . dataDecoder, queryLogLevel: self . queryLogLevel) . withSession ( closure)
140
141
}
141
142
142
143
// SQLiteDatabase
143
-
144
+
144
145
func query( _ query: String , _ binds: [ SQLiteData ] , logger: Logger , _ onRow: @escaping @Sendable ( SQLiteRow ) -> Void ) -> EventLoopFuture < Void > {
145
146
self . withConnection { $0. query ( query, binds, logger: logger, onRow) }
146
147
}
0 commit comments