Skip to content

Commit

Permalink
Merge pull request #1105 from stephencelis/userVersion
Browse files Browse the repository at this point in the history
Native user_version support in Connection
  • Loading branch information
nathanfallet committed Jan 25, 2022
2 parents 1c86a47 + 608684a commit 5680160
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 20 deletions.
14 changes: 2 additions & 12 deletions Documentation/Index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1457,21 +1457,11 @@ try db.run(users.drop(ifExists: true))

### Migrations and Schema Versioning

You can add a convenience property on `Connection` to query and set the
You can use the convenience property on `Connection` to query and set the
[`PRAGMA user_version`](https://sqlite.org/pragma.html#pragma_user_version).

This is a great way to manage your schema’s version over migrations.

```swift
extension Connection {
public var userVersion: Int32 {
get { return Int32(try! scalar("PRAGMA user_version") as! Int64)}
set { try! run("PRAGMA user_version = \(newValue)") }
}
}
```

Then you can conditionally run your migrations along the lines of:
You can conditionally run your migrations along the lines of:

```swift
if db.userVersion == 0 {
Expand Down
13 changes: 13 additions & 0 deletions Sources/SQLite/Core/Connection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,19 @@ public final class Connection {
Int(sqlite3_total_changes(handle))
}

/// The user version of the database.
/// See SQLite [PRAGMA user_version](https://sqlite.org/pragma.html#pragma_user_version)
public var userVersion: Int32? {
get {
(try? scalar("PRAGMA user_version") as? Int64).map(Int32.init)
}
set {
if let userVersion = newValue {
_ = try? run("PRAGMA user_version = \(userVersion)")
}
}
}

// MARK: - Execute

/// Executes a batch of SQL statements.
Expand Down
5 changes: 5 additions & 0 deletions Tests/SQLiteTests/ConnectionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ class ConnectionTests: SQLiteTestCase {
XCTAssertEqual(2, db.totalChanges)
}

func test_userVersion() {
db.userVersion = 2
XCTAssertEqual(2, db.userVersion!)
}

func test_prepare_preparesAndReturnsStatements() {
_ = try! db.prepare("SELECT * FROM users WHERE admin = 0")
_ = try! db.prepare("SELECT * FROM users WHERE admin = ?", 0)
Expand Down
26 changes: 19 additions & 7 deletions Tests/SQLiteTests/QueryTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -391,15 +391,27 @@ class QueryTests: XCTestCase {
let value = TestCodable(int: 1, string: "2", bool: true, float: 3, double: 4,
date: Date(timeIntervalSince1970: 0), optional: nil, sub: value1)
let update = try emails.update(value)
let encodedJSON = try JSONEncoder().encode(value1)
let encodedJSONString = String(data: encodedJSON, encoding: .utf8)!
assertSQL(

// NOTE: As Linux JSON decoding doesn't order keys the same way, we need to check prefix, suffix,
// and extract JSON to decode it and check the decoded object.

let expectedPrefix =
"""
UPDATE \"emails\" SET \"int\" = 1, \"string\" = '2', \"bool\" = 1, \"float\" = 3.0, \"double\" = 4.0,
\"date\" = '1970-01-01T00:00:00.000', \"sub\" = '\(encodedJSONString)'
""".replacingOccurrences(of: "\n", with: ""),
update
)
\"date\" = '1970-01-01T00:00:00.000', \"sub\" = '
""".replacingOccurrences(of: "\n", with: "")
let expectedSuffix = "'"

let sql = update.asSQL()
XCTAssert(sql.hasPrefix(expectedPrefix))
XCTAssert(sql.hasSuffix(expectedSuffix))

let extractedJSON = String(sql[
sql.index(sql.startIndex, offsetBy: expectedPrefix.count) ..<
sql.index(sql.endIndex, offsetBy: -expectedSuffix.count)
])
let decodedJSON = try JSONDecoder().decode(TestCodable.self, from: extractedJSON.data(using: .utf8)!)
XCTAssertEqual(decodedJSON, value1)
}

func test_delete_compilesDeleteExpression() {
Expand Down
13 changes: 12 additions & 1 deletion Tests/SQLiteTests/TestHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ let qualifiedTable = Table("table", database: "main")
let virtualTable = VirtualTable("virtual_table")
let _view = View("view") // avoid Mac XCTestCase collision

class TestCodable: Codable {
class TestCodable: Codable, Equatable {
let int: Int
let string: String
let bool: Bool
Expand All @@ -125,4 +125,15 @@ class TestCodable: Codable {
self.optional = optional
self.sub = sub
}

static func == (lhs: TestCodable, rhs: TestCodable) -> Bool {
lhs.int == rhs.int &&
lhs.string == rhs.string &&
lhs.bool == rhs.bool &&
lhs.float == rhs.float &&
lhs.double == rhs.double &&
lhs.date == rhs.date &&
lhs.optional == rhs.optional &&
lhs.sub == rhs.sub
}
}

0 comments on commit 5680160

Please sign in to comment.