All skills

Use when writing raw SQL with GRDB, complex joins across 4+ tables, window functions, ValueObservation for reactive queries, or dropping down from SQLiteData for performance. Direct SQLite access for iOS/macOS with type-safe queries and migrations.

Use this Skill: https://skilld.dev/gh/johnrogers/claude-swift-engineering/grdb

This session only. Nothing lands on disk.

referencesvalue-observation.md

≈623 tokens on demand. Your agent reads this file only when SKILL.md points to it.

ValueObservation - Reactive Queries

ValueObservation automatically re-executes queries when database changes occur.

Basic Observation

import GRDB
import Combine

let observation = ValueObservation.tracking { db in
    try Track.fetchAll(db)
}

let cancellable = observation.publisher(in: dbQueue)
    .sink(
        receiveCompletion: { _ in },
        receiveValue: { tracks in
            print("Tracks updated: \(tracks.count)")
        }
    )

Filtered Observation

func observeGenre(_ genre: String) -> ValueObservation<[Track]> {
    ValueObservation.tracking { db in
        try Track.filter(Column("genre") == genre).fetchAll(db)
    }
}

SwiftUI Integration (GRDBQuery)

import GRDBQuery

struct TracksRequest: Queryable {
    static var defaultValue: [Track] { [] }

    func publisher(in dbQueue: DatabaseQueue) -> AnyPublisher<[Track], Error> {
        ValueObservation
            .tracking { db in try Track.fetchAll(db) }
            .publisher(in: dbQueue)
            .eraseToAnyPublisher()
    }
}

struct TrackListView: View {
    @Query(TracksRequest())
    var tracks: [Track]

    var body: some View {
        List(tracks) { track in Text(track.title) }
    }
}

Manual Observation (Non-Combine)

let observer = observation.start(
    in: dbQueue,
    onError: { error in print("Error: \(error)") },
    onChange: { tracks in print("Changed: \(tracks.count)") }
)

observer.cancel()  // When done

Performance Optimization

Problem: Re-evaluates on ANY write

ValueObservation.tracking { db in
    try Track.fetchAll(db)  // CPU spike on unrelated changes
}

Solution 1: Remove Duplicates

observation.removeDuplicates().publisher(in: dbQueue)

Solution 2: Debounce

observation.removeDuplicates()
    .publisher(in: dbQueue)
    .debounce(for: 0.5, scheduler: DispatchQueue.main)

Solution 3: Region Tracking

ValueObservation.tracking(region: Track.all()) { db in
    try Track.fetchAll(db)  // Only Track changes trigger
}

Decision Framework

Dataset Size Optimization
Small (<1k) Plain .tracking
Medium (1-10k) .removeDuplicates() + .debounce()
Large (10k+) Region tracking

Async/Await

for try await tracks in ValueObservation
    .tracking { db in try Track.fetchAll(db) }
    .values(in: dbQueue) {
    print("Updated: \(tracks.count)")
}

Source: SKILL.md on GitHub

No alerts16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill provides comprehensive documentation and code examples for using the GRDB.swift library for SQLite access in iOS/macOS applications. No security issues were detected. It follows best practices for database management, including parameterized queries to prevent SQL injection and clear performance guidelines.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    6 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at d62eb71. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Dormantupdated 9 months ago

README badge

README badge for johnrogers/claude-swift-engineering/grdb