Skip to content

Commit

Permalink
Merge pull request #78 from vapor/transactions
Browse files Browse the repository at this point in the history
Added Transaction to connection
  • Loading branch information
BrettRToomey authored Jan 19, 2017
2 parents be6cfa6 + df385a5 commit 50945aa
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 3 deletions.
26 changes: 25 additions & 1 deletion Sources/MySQL/Connection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,31 @@ public final class Connection {

mysql_set_character_set(cConnection, encoding)
}


public func transaction(_ closure: () throws -> Void) throws {
// required by transactions, but I don't want to open the old
// MySQL query API to the public as it would be a burden to maintain.
func oldQuery(_ query: String) throws {
try lock.locked {
guard mysql_query(cConnection, query) == 0 else {
throw Error.execute(error)
}
}
}

try oldQuery("START TRANSACTION")

do {
try closure()
} catch {
// rollback changes and then rethrow the error
try oldQuery("ROLLBACK")
throw error
}

try oldQuery("COMMIT")
}

@discardableResult
public func execute(_ query: String, _ values: [NodeRepresentable] = []) throws -> [[String: Node]] {
var returnable: [[String: Node]] = []
Expand Down
5 changes: 3 additions & 2 deletions Tests/LinuxMain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import XCTest
@testable import MySQLTests

XCTMain([
testCase(MySQLTests.allTests)
testCase(DateTests.allTests),
testCase(MySQLTests.allTests),
])

#endif
#endif
57 changes: 57 additions & 0 deletions Tests/MySQLTests/MySQLTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class MySQLTests: XCTestCase {
("testTimestamps", testTimestamps),
("testSpam", testSpam),
("testError", testError),
("testTransaction", testTransaction),
("testTransactionFailed", testTransactionFailed),
]

var mysql: MySQL.Database!
Expand Down Expand Up @@ -201,4 +203,59 @@ class MySQLTests: XCTestCase {
XCTFail("Wrong error: \(error)")
}
}

func testTransaction() {
do {
let c = try mysql.makeConnection()
try c.execute("DROP TABLE IF EXISTS transaction")
try c.execute("CREATE TABLE transaction (name VARCHAR(64))")
try c.execute("INSERT INTO transaction VALUES (?)", [
"james"
])

try c.transaction {
try c.execute("UPDATE transaction SET name = 'James' where name = 'james'")
}

if let james = try c.execute("SELECT * FROM transaction").first {
XCTAssertEqual(james["name"]?.string, "James")
} else {
XCTFail("There should be one entry.")
}
} catch {
XCTFail("Testing transaction failed: \(error)")
}
}

func testTransactionFailed() {
do {
let c = try mysql.makeConnection()
try c.execute("DROP TABLE IF EXISTS transaction")
try c.execute("CREATE TABLE transaction (name VARCHAR(64))")
try c.execute("INSERT INTO transaction VALUES (?)", [
"tommy"
])

do {
try c.transaction {
// will succeed, but will be rolled back
try c.execute("UPDATE transaction SET name = 'Timmy'")

// malformed query, will throw
try c.execute("💉")
}

XCTFail("Transaction should have rethrown error.")

} catch {
if let tommy = try c.execute("SELECT * FROM transaction").first {
XCTAssertEqual(tommy["name"]?.string, "tommy", "Should have ROLLBACK")
} else {
XCTFail("There should be one entry.")
}
}
} catch {
XCTFail("Testing transaction failed: \(error)")
}
}
}

0 comments on commit 50945aa

Please sign in to comment.