Skip to main content
DatabaseQueue provides a single database connection that serializes all database accesses. It’s the simplest way to access an SQLite database with GRDB.

Overview

DatabaseQueue opens a single connection to an SQLite database. All database operations are executed serially on a private dispatch queue.
let dbQueue = try DatabaseQueue(path: "/path/to/database.sqlite")
Use DatabaseQueue when you need:
  • Simple, serial database access
  • A single-connection database
  • Testing with in-memory databases
For concurrent read access with a pool of connections, use DatabasePool.

Initialization

Opening a Database File

path
String
required
The path to the database file
configuration
Configuration
default:"Configuration()"
Optional database configuration
let dbQueue = try DatabaseQueue(path: "/path/to/database.sqlite")

// With configuration
var config = Configuration()
config.readonly = true
let dbQueue = try DatabaseQueue(path: dbPath, configuration: config)

Creating an In-Memory Database

named
String?
default:"nil"
Optional name for a shared in-memory database
// Independent in-memory database
let dbQueue = try DatabaseQueue()

// Shared in-memory database
let dbQueue = try DatabaseQueue(named: "myDatabase")

Properties

configuration
Configuration
The database configuration
path
String
The path to the database file

Reading from the Database

read(_:)

Synchronously reads from the database.
value
(Database) throws -> T
required
A closure that accesses the database
let playerCount = try dbQueue.read { db in
    try Player.fetchCount(db)
}

asyncRead(_:)

Asynchronously reads from the database.
dbQueue.asyncRead { result in
    switch result {
    case .success(let db):
        let players = try Player.fetchAll(db)
        // Use players
    case .failure(let error):
        // Handle error
    }
}

unsafeRead(_:)

Reads from the database without wrapping in a transaction.
This method is unsafe because the database may be changed by concurrent writes. Use with caution.
let value = try dbQueue.unsafeRead { db in
    try Player.fetchOne(db, key: 1)
}

Writing to the Database

write(_:)

Synchronously writes to the database in an implicit transaction.
updates
(Database) throws -> T
required
A closure that updates the database
try dbQueue.write { db in
    try Player(name: "Arthur", score: 100).insert(db)
    try Player.filter(Column("score") < 50).deleteAll(db)
}
If the closure throws an error, the transaction is rolled back and the error is rethrown.

inTransaction(::)

Executes operations in an explicit transaction.
kind
Database.TransactionKind?
default:"nil"
The transaction type (DEFERRED, IMMEDIATE, or EXCLUSIVE)
updates
(Database) throws -> Database.TransactionCompletion
required
A closure that performs database operations
try dbQueue.inTransaction { db in
    try Player(name: "Arthur").insert(db)
    try Player(name: "Barbara").insert(db)
    return .commit // or .rollback
}

writeWithoutTransaction(_:)

Executes database operations without an implicit transaction.
Database operations can see changes from concurrent writes. Two identical requests may not return the same value.
try dbQueue.writeWithoutTransaction { db in
    try Player(name: "Arthur").insert(db)
    let count = try Player.fetchCount(db)
}

Async/Await Support

// Async read
let players = try await dbQueue.read { db in
    try Player.fetchAll(db)
}

// Async write
try await dbQueue.write { db in
    try Player(name: "Arthur").insert(db)
}

Memory Management

releaseMemory()

Frees as much memory as possible.
dbQueue.releaseMemory()
On iOS, GRDB automatically releases memory when receiving memory warnings or when the app enters the background.

Database Interruption

interrupt()

Cancels any running database statement.
dbQueue.interrupt()
The database connection is not closed. Interrupted operations throw a DatabaseError with code SQLITE_INTERRUPT.

Closing the Database

close()

Closes the database connection.
try dbQueue.close()
Once closed, the database queue cannot be reopened. Create a new instance instead.

Temporary Database Copies

inMemoryCopy(fromPath:configuration:)

Creates an in-memory copy of a database file.
let dbQueue = try DatabaseQueue.inMemoryCopy(
    fromPath: "/path/to/database.sqlite"
)

temporaryCopy(fromPath:configuration:)

Creates a temporary on-disk copy that is automatically deleted when closed.
let dbQueue = try DatabaseQueue.temporaryCopy(
    fromPath: "/path/to/database.sqlite"
)

See Also

Build docs developers (and LLMs) love