1
1
2
2
// --- stubs ---
3
3
4
+ struct URL
5
+ {
6
+ init ? ( string: String ) { }
7
+ init ? ( string: String , relativeTo: URL ? ) { }
8
+ }
9
+
10
+ extension String {
11
+ init ( contentsOf: URL ) throws {
12
+ var data = " "
13
+
14
+ // ...
15
+
16
+ self . init ( data)
17
+ }
18
+ }
19
+
4
20
public protocol Binding { }
5
21
6
22
extension String : Binding { }
7
23
8
24
class Statement {
9
- init ( _ connection: Connection , _ SQL : String ) throws { }
25
+ fileprivate let connection : Connection
10
26
11
- public func bind( _ values: Binding ? ... ) -> Statement { return Statement ( ) }
12
- public func bind( _ values: [ Binding ? ] ) -> Statement { return Statement ( ) }
13
- public func bind( _ values: [ String : Binding ? ] ) -> Statement { return Statement ( ) }
27
+ init ( _ connection: Connection , _ SQL: String ) throws { self . connection = connection}
14
28
15
- @ discardableResult public func run ( _ bindings : Binding ? ... ) throws -> Statement { return Statement ( ) }
16
- @ discardableResult public func run ( _ bindings : [ Binding ? ] ) throws -> Statement { return Statement ( ) }
17
- @ discardableResult public func run ( _ bindings : [ String : Binding ? ] ) throws -> Statement { return Statement ( ) }
29
+ public func bind ( _ values : Binding ? ... ) -> Statement { return Statement ( connection , " " ) }
30
+ public func bind ( _ values : [ Binding ? ] ) -> Statement { return Statement ( connection , " " ) }
31
+ public func bind ( _ values : [ String : Binding ? ] ) -> Statement { return Statement ( connection , " " ) }
18
32
19
- public func scalar( _ bindings: Binding ? ... ) throws -> Binding ? { return Binding ( ) }
20
- public func scalar( _ bindings: [ Binding ? ] ) throws -> Binding ? { return Binding ( ) }
21
- public func scalar( _ bindings: [ String : Binding ? ] ) throws -> Binding ? { return Binding ( ) }
33
+ @discardableResult public func run( _ bindings: Binding ? ... ) throws -> Statement { return Statement ( connection, " " ) }
34
+ @discardableResult public func run( _ bindings: [ Binding ? ] ) throws -> Statement { return Statement ( connection, " " ) }
35
+ @discardableResult public func run( _ bindings: [ String : Binding ? ] ) throws -> Statement { return Statement ( connection, " " ) }
36
+
37
+ public func scalar( _ bindings: Binding ? ... ) throws -> Binding ? { return nil }
38
+ public func scalar( _ bindings: [ Binding ? ] ) throws -> Binding ? { return nil }
39
+ public func scalar( _ bindings: [ String : Binding ? ] ) throws -> Binding ? { return nil }
22
40
}
23
41
24
42
class Connection {
25
43
public func execute( _ SQL: String ) throws { }
26
44
27
- public func prepare( _ statement: String , _ bindings: Binding ? ... ) throws -> Statement { return Statement ( ) }
28
- public func prepare( _ statement: String , _ bindings: [ Binding ? ] ) throws -> Statement { return Statement ( ) }
29
- public func prepare( _ statement: String , _ bindings: [ String : Binding ? ] ) throws -> Statement { return Statement ( ) }
45
+ public func prepare( _ statement: String , _ bindings: Binding ? ... ) throws -> Statement { return Statement ( self , " " ) }
46
+ public func prepare( _ statement: String , _ bindings: [ Binding ? ] ) throws -> Statement { return Statement ( self , " " ) }
47
+ public func prepare( _ statement: String , _ bindings: [ String : Binding ? ] ) throws -> Statement { return Statement ( self , " " ) }
30
48
31
- @discardableResult public func run( _ statement: String , _ bindings: Binding ? ... ) throws -> Statement { return Statement ( ) }
32
- @discardableResult public func run( _ statement: String , _ bindings: [ Binding ? ] ) throws -> Statement { return Statement ( ) }
33
- @discardableResult public func run( _ statement: String , _ bindings: [ String : Binding ? ] ) throws -> Statement { return Statement ( ) }
49
+ @discardableResult public func run( _ statement: String , _ bindings: Binding ? ... ) throws -> Statement { return Statement ( self , " " ) }
50
+ @discardableResult public func run( _ statement: String , _ bindings: [ Binding ? ] ) throws -> Statement { return Statement ( self , " " ) }
51
+ @discardableResult public func run( _ statement: String , _ bindings: [ String : Binding ? ] ) throws -> Statement { return Statement ( self , " " ) }
34
52
35
- public func scalar( _ statement: String , _ bindings: Binding ? ... ) throws -> Binding ? { return Binding ( ) }
36
- public func scalar( _ statement: String , _ bindings: [ Binding ? ] ) throws -> Binding ? { return Binding ( ) }
37
- public func scalar( _ statement: String , _ bindings: [ String : Binding ? ] ) throws -> Binding ? { return Binding ( ) }
53
+ public func scalar( _ statement: String , _ bindings: Binding ? ... ) throws -> Binding ? { return nil }
54
+ public func scalar( _ statement: String , _ bindings: [ Binding ? ] ) throws -> Binding ? { return nil }
55
+ public func scalar( _ statement: String , _ bindings: [ String : Binding ? ] ) throws -> Binding ? { return nil }
38
56
}
39
57
40
58
// --- tests ---
@@ -49,7 +67,6 @@ func test_sqlite_swift_api(db: Connection) {
49
67
let unsafeQuery3 = " SELECT * FROM users WHERE username=' \( remoteString) ' "
50
68
let safeQuery1 = " SELECT * FROM users WHERE username=' \( localString) ' "
51
69
let safeQuery2 = " SELECT * FROM users WHERE username=' \( remoteNumber) ' "
52
- let varQuery = " SELECT * FROM users WHERE username=? "
53
70
54
71
// --- execute ---
55
72
@@ -61,6 +78,8 @@ func test_sqlite_swift_api(db: Connection) {
61
78
62
79
// --- prepared statements ---
63
80
81
+ let varQuery = " SELECT * FROM users WHERE username=? "
82
+
64
83
let stmt1 = try db. prepare ( unsafeQuery3) // BAD
65
84
try stmt1. run ( )
66
85
@@ -70,5 +89,45 @@ func test_sqlite_swift_api(db: Connection) {
70
89
let stmt3 = try db. prepare ( varQuery, remoteString) // GOOD
71
90
try stmt3. run ( )
72
91
73
- // TODO: test all versions of prepare, run, scalar on Connection and Statement
92
+ let stmt4 = Statement ( db, localString) // GOOD
93
+ stmt4. run ( )
94
+
95
+ let stmt5 = Statement ( db, remoteString) // BAD
96
+ stmt5. run ( )
97
+
98
+ // --- more variants ---
99
+
100
+ let stmt6 = try db. prepare ( unsafeQuery1, " " ) // BAD
101
+ try stmt6. run ( )
102
+
103
+ let stmt7 = try db. prepare ( unsafeQuery1, [ " " ] ) // BAD
104
+ try stmt7. run ( )
105
+
106
+ let stmt8 = try db. prepare ( unsafeQuery1, [ " username " : " " ] ) // BAD
107
+ try stmt8. run ( )
108
+
109
+ db. run ( unsafeQuery1, " " ) // BAD
110
+
111
+ db. run ( unsafeQuery1, [ " " ] ) // BAD
112
+
113
+ db. run ( unsafeQuery1, [ " username " : " " ] ) // BAD
114
+
115
+ db. scalar ( unsafeQuery1, " " ) // BAD
116
+
117
+ db. scalar ( unsafeQuery1, [ " " ] ) // BAD
118
+
119
+ db. scalar ( unsafeQuery1, [ " username " : " " ] ) // BAD
120
+
121
+ let stmt9 = try db. prepare ( varQuery) // GOOD
122
+ stmt9. bind ( remoteString)
123
+ stmt9. bind ( [ remoteString] )
124
+ stmt9. bind ( [ " username " : remoteString] )
125
+ try stmt9. run ( remoteString)
126
+ try stmt9. run ( [ remoteString] )
127
+ try stmt9. run ( [ " username " : remoteString] )
128
+ try stmt9. scalar ( remoteString)
129
+ try stmt9. scalar ( [ remoteString] )
130
+ try stmt9. scalar ( [ " username " : remoteString] )
131
+
132
+ Statement ( db, remoteString) . run ( ) // BAD
74
133
}
0 commit comments