Skip to content

Commit 8717e4a

Browse files
authored
Merge pull request #201 from vapor/release
mysql 3.0 release
2 parents 0b926de + f806b71 commit 8717e4a

37 files changed

+323
-285
lines changed

Sources/MySQL/Codable/MySQLQueryEncoder.swift

Lines changed: 0 additions & 90 deletions
This file was deleted.

Sources/MySQL/Connection/MySQLColumn.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,3 @@ extension Dictionary where Key == MySQLColumn {
6868
return self[MySQLColumn(table: table, name: column)]
6969
}
7070
}
71-

Sources/MySQL/Connection/MySQLConnection+Connect.swift

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,34 @@ import Crypto
22

33
extension MySQLConnection {
44
/// Connects to a MySQL server using TCP.
5-
public static func connect(
6-
config: MySQLDatabaseConfig,
7-
on worker: Worker,
8-
onError: @escaping (Error) -> ()
9-
) -> Future<MySQLConnection> {
10-
let handler = MySQLConnectionHandler(config: config)
5+
///
6+
/// MySQLConnection.connect(config: .root(database: "vapor"), on: ...)
7+
///
8+
/// - parameters:
9+
/// - config: Connection configuration options.
10+
/// - worker: Event loop to run the connection on.
11+
public static func connect(config: MySQLDatabaseConfig, on worker: Worker) -> Future<MySQLConnection> {
12+
let ready = worker.eventLoop.newPromise(Void.self)
13+
let handler = MySQLConnectionHandler(config: config, ready: ready)
1114
let bootstrap = ClientBootstrap(group: worker.eventLoop)
12-
.channelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEADDR), value: 1)
13-
.channelInitializer { channel in
14-
return channel.pipeline.addMySQLClientHandlers().then {
15-
channel.pipeline.add(handler: handler)
15+
.channelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEADDR), value: 1)
16+
.channelInitializer { channel in
17+
return channel.pipeline.addMySQLClientHandlers().then {
18+
return channel.pipeline.add(handler: handler)
19+
}
1620
}
17-
}
18-
return bootstrap.connect(host: config.hostname, port: config.port).map { channel -> MySQLConnection in
19-
return .init(handler: handler, channel: channel)
20-
}.flatMap { conn in
21-
let rfq = worker.eventLoop.newPromise(Void.self)
22-
handler.readyForQuery = rfq
23-
return rfq.futureResult.map { conn }
21+
let channel = bootstrap.connect(host: config.hostname, port: config.port)
22+
channel.catch { ready.fail(error: $0) }
23+
return channel.flatMap { channel in
24+
let conn = MySQLConnection(handler: handler, channel: channel)
25+
return ready.futureResult.transform(to: conn)
2426
}
2527
}
2628
}
2729

2830
extension ChannelPipeline {
2931
/// Adds MySQL packet encoder and decoder to the channel pipeline.
30-
func addMySQLClientHandlers(first: Bool = false) -> Future<Void> {
32+
public func addMySQLClientHandlers(first: Bool = false) -> Future<Void> {
3133
let session = MySQLPacketState()
3234
return addHandlers(MySQLPacketEncoder(session: session), MySQLPacketDecoder(session: session), first: first)
3335
}

Sources/MySQL/Connection/MySQLConnection+Metadata.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,30 @@
11
extension MySQLConnection {
2+
/// Query result metadata.
3+
///
4+
/// conn.lastMetadata?.affectedRows
5+
///
26
public struct Metadata {
7+
/// Root OK packet.
38
private let ok: MySQLPacket.OK
49

10+
/// Number of affected rows from the last query.
511
public var affectedRows: UInt64 {
612
return ok.affectedRows
713
}
814

15+
/// `AUTO_INCREMENT` insert ID from the last query (if exists).
916
public var lastInsertID: UInt64? {
1017
return ok.lastInsertID
1118
}
1219

20+
/// Casts the `lastInsertID` to a generic `FixedWidthInteger`.
1321
public func lastInsertID<I>(as type: I.Type = I.self) -> I?
1422
where I: FixedWidthInteger
1523
{
1624
return lastInsertID.flatMap(numericCast)
1725
}
1826

27+
/// Creates a new query result metadata.
1928
init(_ ok: MySQLPacket.OK) {
2029
self.ok = ok
2130
}

Sources/MySQL/Connection/MySQLConnection+SimpleQuery.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ extension MySQLConnection {
1111
var rows: [[MySQLColumn: MySQLData]] = []
1212
return simpleQuery(string) { row in
1313
rows.append(row)
14-
}.map(to: [[MySQLColumn: MySQLData]].self) {
14+
}.map {
1515
return rows
1616
}
1717
}

Sources/MySQL/Connection/MySQLConnection+TransportConfig.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import NIOOpenSSL
22

3+
/// Supported options for MySQL connection TLS.
34
public struct MySQLTransportConfig {
45
/// Does not attempt to enable TLS (this is the default).
56
public static var cleartext: MySQLTransportConfig {

Sources/MySQL/Connection/MySQLConnection.swift

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@ public final class MySQLConnection: BasicWorker, DatabaseConnection, DatabaseQue
3030

3131
/// The channel
3232
private let channel: Channel
33-
34-
/// Currently running `send(...)`.
35-
private var currentSend: Promise<Void>?
3633

3734
/// Close has been requested.
3835
private var isClosing: Bool
@@ -49,18 +46,19 @@ public final class MySQLConnection: BasicWorker, DatabaseConnection, DatabaseQue
4946
// currently running calls to `send(...)`.
5047
channel.closeFuture.always {
5148
self.isClosed = true
52-
if let current = self.currentSend {
49+
switch handler.state {
50+
// connection is closing, the handler is not going to be ready for query
51+
case .nascent(let ready): ready.fail(error: closeError)
52+
case .callback(let currentSend, _):
5353
if self.isClosing {
5454
// if we're closing, this is the close's current send
5555
// so complete it!
56-
current.succeed()
56+
currentSend.succeed()
5757
} else {
5858
// if currently sending, fail it
59-
current.fail(error: closeError)
59+
currentSend.fail(error: closeError)
6060
}
61-
} else if let rfq = handler.readyForQuery {
62-
// connection is closing, the handler is not going to be ready for query
63-
rfq.fail(error: closeError)
61+
case .waiting: break
6462
}
6563
}
6664
}
@@ -78,16 +76,13 @@ public final class MySQLConnection: BasicWorker, DatabaseConnection, DatabaseQue
7876
return eventLoop.newFailedFuture(error: closeError)
7977
}
8078

81-
// if currentSend is not nil, previous send has not completed
82-
assert(currentSend == nil, "Attempting to call `send(...)` again before previous invocation has completed.")
8379
switch handler.state {
8480
case .waiting: break
8581
default: assertionFailure("Attempting to call `send(...)` while handler is still: \(handler.state).")
8682
}
8783

8884
// create a new promise and store it
8985
let promise = eventLoop.newPromise(Void.self)
90-
currentSend = promise
9186

9287
handler.state = .callback(promise) { packet in
9388
switch packet {
@@ -108,8 +103,7 @@ public final class MySQLConnection: BasicWorker, DatabaseConnection, DatabaseQue
108103
channel.flush()
109104

110105
// FIXME: parse metadata from ok packet
111-
112-
promise.futureResult.always { self.currentSend = nil }
106+
113107
return promise.futureResult
114108
}
115109

@@ -120,7 +114,11 @@ public final class MySQLConnection: BasicWorker, DatabaseConnection, DatabaseQue
120114

121115
/// Closes this client.
122116
public func close(done promise: Promise<Void>?) {
123-
assert(currentSend == nil, "Cannot close while sending.")
117+
switch handler.state {
118+
case .waiting: break
119+
case .nascent: fatalError("Cannot close while still connecting.")
120+
case .callback: fatalError("Cannot close during a query.")
121+
}
124122
self.isClosing = true
125123
let done = send([.quit]) { packet in
126124
return true

0 commit comments

Comments
 (0)