GRDB.swift v1.0.0 Release Notes
-
🚀 Released June 20, 2017 :tada:
GRDB 1.0 comes with enhancements, and API stability.
It comes with breaking changes, but the good news is that they are the last (until GRDB 2.0) :sweat_smile:!
Requirements have changed: Xcode 8.3+ / Swift 3.1
As a matter of fact, GRDB 1.0 still supports Xcode 8.1 and Swift 3.0. But future versions are free to use Swift 3.1 features, and will require Xcode 8.3+.
The targetted operating systems are unchanged: iOS 8.0+ / OSX 10.9+ / watchOS 2.0+
Record types have their
persistentDictionary
property replaced with theencode(to:)
method:struct Player : Persistable { let name: String let score: Int // Old // var persistentDictionary: [String: DatabaseValueConvertible?] { // return [ // "name": name, // "score": score, // ] // } // New func encode(to container: inout PersistenceContainer) { container["name"] = name container["score"] = score } }
This is good for applications that declare lists of columns:
struct Player : RowConvertible, Persistable { let name: String let score: Int static let databaseTableName = "players" // Declare Player columns enum Columns { static let name = Column("name") static let score = Column("score") } // Use columns in `init(row:)` init(row: Row) { name = row.value(Columns.name) score = row.value(Columns.score) } // Use columns in the new `encode(to:)` method: func encode(to container: inout PersistenceContainer) { container[Columns.name] = name container[Columns.score] = score } }
Database Observation has been enhanced:
Database.afterNextTransactionCommit(_:)
is the simplest way to handle successful transactions, and synchronize the database with other resources such as files, or system sensors (documentation).// Make sure the database is inside a transaction db.inSavepoint { // Perform some database job try ... // Register extra job that is only executed after database changes // have been committed and written to disk. db.afterNextTransactionCommit { ... } }
On the low-level side, applications can now specify the extent of database observation (documentation).
✅ DatabaseMigrator is easier to test, with its
DatabaseMigrator.migrate(_:upTo:)
method which partially migrates your databases (documentation).On the side of database schema introspection, the new
Database.foreignKeys(on:)
method lists the foreign keys defined on a table.
Full list of changes
class Database { - func add(transactionObserver: TransactionObserver) + func add(transactionObserver: TransactionObserver, extent: TransactionObservationExtent = .observerLifetime) + func afterNextTransactionCommit(_ closure: @escaping (Database) -> ()) + func foreignKeys(on tableName: String) throws -> [ForeignKeyInfo] } -struct DatabaseCoder: DatabaseValueConvertible struct DatabaseMigrator { + func migrate(_ writer: DatabaseWriter, upTo targetIdentifier: String) throws } protocol DatabaseWriter : DatabaseReader { - func add(transactionObserver: TransactionObserver) + func add(transactionObserver: TransactionObserver, extent: TransactionObservationExtent = .observerLifetime) } protocol MutablePersistable : TableMapping { - var persistentDictionary: [String: DatabaseValueConvertible?] { get } + func encode(to container: inout PersistenceContainer) } extension QueryInterfaceRequest { - func contains(_ value: SQLExpressible) -> SQLExpression - func exists() -> SQLExpression } extension Request { - func adapted(_ adapter: @escaping (Database) throws -> RowAdapter) -> AnyRequest + func adapted(_ adapter: @escaping (Database) throws -> RowAdapter) -> AdaptedRequest<Self> } protocol TypedRequest : Request { - associatedtype Fetched + associatedtype RowDecoder } extension TypedRequest { - func adapted(_ adapter: @escaping (Database) throws -> RowAdapter) -> AnyTypedRequest<Fetched> + func adapted(_ adapter: @escaping (Database) throws -> RowAdapter) -> AdaptedTypedRequest<Self> }