agentsclimarketplace

Sqd ref

Skill sitapix/sqlitedata-swift-skills/skills/sqd-ref

Agent Skills for SQLiteData (Point-Free's GRDB-based SwiftData replacement with CloudKit sync). Covers @Table, fetch wrappers, queries, migrations, and SyncEngine.

Install
npx -y skills add sitapix/sqlitedata-swift-skills --skill sqd-ref

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use when looking up exact API signatures, init parameters, type details, or advanced patterns (FTS5, custom functions, seeding) — covers all public types, property wrappers, SyncEngine methods, and re-exported types. NOT for usage patterns (use core) or troubleshooting (use diag)

SKILL.md

11.3 KB, ~2.7k tokens by cl100k_base, as published. Nobody here has run it

SQLiteData API Reference

Complete API reference for all public types and methods in SQLiteData.

Contents

  • Re-exported Types
  • Property Wrappers (FetchAll, FetchOne, Fetch)
  • Protocols (FetchKeyRequest)
  • FetchSubscription
  • Database Setup (defaultDatabase, DependencyValues)
  • SyncEngine — init, state, control, sharing, database integration
  • SyncEngineDelegate
  • SyncMetadata
  • SharedRecord
  • IdentifierStringConvertible
  • Test Support (assertQuery)
  • Advanced Patterns — see advanced-patterns.md
  • Platform Availability & Package Dependencies

Re-exported Types

From GRDB: Configuration, Database, DatabaseError, DatabaseMigrator, DatabasePool, DatabaseQueue, DatabaseReader, DatabaseWriter, ValueObservationScheduler

From StructuredQueriesSQLite: @Table, @Column, @Selection, @ForeignKey, #sql, #bind

From Dependencies: @Dependency, prepareDependencies, DependencyValues

For usage patterns of these types, see /skill sqd-core.


Property Wrappers

FetchAll<Element: Sendable>

Fetches a collection of rows from SQLite with reactive observation.

@dynamicMemberLookup
@propertyWrapper
public struct FetchAll<Element: Sendable>: Sendable, DynamicProperty

Initializers:

// Fetch all rows from table (default order)
init(wrappedValue: [Element] = [], database: (any DatabaseReader)? = nil)
  where Element: Table, Element.QueryOutput == Element

// From a SelectStatement (query builder)
init<S: SelectStatement>(wrappedValue: [Element] = [], _ statement: S,
  database: (any DatabaseReader)? = nil)

// From any Statement<V>
init<V: QueryRepresentable>(wrappedValue: [Element] = [],
  _ statement: some Statement<V>, database: (any DatabaseReader)? = nil)

// With animation (iOS 17+)
init(..., animation: Animation)

// With custom scheduler
init(..., scheduler: some ValueObservationScheduler & Hashable)

Properties:

var wrappedValue: [Element]           // The fetched data
var projectedValue: Self              // Access to wrapper state ($items)
var loadError: (any Error)?           // Last error
var isLoading: Bool                   // Loading state
var publisher: some Publisher<[Element], Never>  // Combine publisher
var sharedReader: SharedReader<[Element]>        // Underlying reader

Methods:

func load() async throws                              // Reload current query
func load<S>(_ statement: S, database:) async throws -> FetchSubscription  // Load new query

FetchOne<Value: Sendable>

Fetches a single value (aggregate, first row, etc.) with reactive observation.

@dynamicMemberLookup
@propertyWrapper
public struct FetchOne<Value: Sendable>: Sendable, DynamicProperty

Same initializer patterns as FetchAll but for single values. Always requires a default wrappedValue.


Fetch<Value: Sendable>

Fetches custom data via FetchKeyRequest for multi-query transactions.

@dynamicMemberLookup
@propertyWrapper
public struct Fetch<Value: Sendable>: Sendable, DynamicProperty

Initializers:

// From FetchKeyRequest
init(wrappedValue: Value, _ request: some FetchKeyRequest<Value>,
  database: (any DatabaseReader)? = nil)

// With animation (iOS 17+)
init(wrappedValue: Value, _ request: some FetchKeyRequest<Value>,
  database: (any DatabaseReader)? = nil, animation: Animation)

// With custom scheduler
init(wrappedValue: Value, _ request: some FetchKeyRequest<Value>,
  database: (any DatabaseReader)? = nil, scheduler: some ValueObservationScheduler & Hashable)

Methods:

func load(_ request: some FetchKeyRequest<Value>, database:) async throws -> FetchSubscription

Protocols

FetchKeyRequest

public protocol FetchKeyRequest<Value>: Hashable, Sendable {
  associatedtype Value
  func fetch(_ db: Database) throws -> Value
}

FetchSubscription

public struct FetchSubscription: Sendable {
  public var task: Void { get async throws }
  public func cancel()
}

Database Setup

defaultDatabase

public func defaultDatabase(
  path: String? = nil,
  configuration: Configuration = Configuration()
) throws -> any DatabaseWriter

Context-aware:

  • Live: DatabasePool in Application Support
  • Preview/Test: DatabasePool at temporary path

DependencyValues Extensions

extension DependencyValues {
  public var defaultDatabase: any DatabaseWriter { get set }
  // CloudKit only:
  public var defaultSyncEngine: SyncEngine { get set }
}

SyncEngine (iOS 17+)

Wraps Apple's CKSyncEngine. For the underlying CloudKit sharing model and CKRecord.ID mapping, see /skill sqd-sharing.

@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *)
public final class SyncEngine: Observable, Sendable

Initialization

public convenience init<each T1: PrimaryKeyedTable, each T2: PrimaryKeyedTable>(
  for database: any DatabaseWriter,
  tables: repeat (each T1).Type,              // Shareable tables
  privateTables: repeat (each T2).Type,       // Private-only tables
  containerIdentifier: String? = nil,          // CloudKit container
  defaultZone: CKRecordZone = .defaultZone,
  startImmediately: Bool? = nil,               // Default: true
  delegate: (any SyncEngineDelegate)? = nil,
  logger: Logger = .disabled
) throws

State (all @Observable)

public var isRunning: Bool { get }
public var isSendingChanges: Bool { get }
public var isFetchingChanges: Bool { get }
public var isSynchronizing: Bool { get }  // isSending || isFetching

Control Methods

public func start() async throws
public func stop()
public func fetchChanges(_ options: CKSyncEngine.FetchChangesOptions) async throws
public func sendChanges(_ options: CKSyncEngine.SendChangesOptions) async throws
public func syncChanges(
  fetchOptions: CKSyncEngine.FetchChangesOptions,
  sendOptions: CKSyncEngine.SendChangesOptions
) async throws
public func syncChanges() async throws  // Convenience (default options)
public func deleteLocalData() async throws

Sharing

For CloudKit's sharing model (CKShare, participants, permissions, UICloudSharingController): /skill sqd-sharing

public func share<T: PrimaryKeyedTable>(
  record: T,
  configure: @Sendable (CKShare) -> Void
) async throws -> SharedRecord

public func unshare<T: PrimaryKeyedTable>(record: T) async throws
public func acceptShare(metadata: CKShare.Metadata) async throws

Database Integration

public func attachMetadatabase(containerIdentifier: String? = nil) throws
// Called on Database instance in prepareDatabase

public static func migratePrimaryKeys<each T: PrimaryKeyedTable>(
  _ db: Database,
  tables: repeat (each T).Type,
  dropUniqueConstraints: Bool = false,
  uuid: (any ScalarDatabaseFunction<(), UUID>)? = nil
) throws

Static Properties

public static let writePermissionError: String
  // "co.pointfree.SQLiteData.CloudKit.write-permission-error"
public static let invalidRecordNameError: String
  // "co.pointfree.SQLiteData.CloudKit.invalid-record-name-error"

// SQL expression (for triggers):
public static var isSynchronizing: Bool  // Swift property
public static var $isSynchronizing       // SQL expression for use in #sql / triggers

SyncEngineDelegate

public protocol SyncEngineDelegate: AnyObject, Sendable {
  func syncEngine(
    _ syncEngine: SyncEngine,
    accountChanged changeType: CKSyncEngine.Event.AccountChange.ChangeType
  ) async
}

SyncMetadata

Full struct definition and joining patterns: see /skill sqd-cloudkit §6.

Key lookup types:

SyncMetadata.ID          // Composite key: recordPrimaryKey + recordType
SyncMetadata.ParentID    // Parent record reference

All PrimaryKeyedTable types have:

extension PrimaryKeyedTableDefinition {
  var syncMetadataID: SyncMetadata.ID { get }
}

SharedRecord

Contains the CKShare returned from SyncEngine.share(). The id is a CKRecord.ID (see /skill sqd-sharing).

public struct SharedRecord: Hashable, Identifiable, Sendable {
  public let share: CKShare
  public var id: CKRecord.ID { share.recordID }
}

IdentifierStringConvertible

For custom identifier types (non-UUID):

public protocol IdentifierStringConvertible {
  var identifierString: String { get }
  init?(identifierString: String)
}

UUID conforms by default.


Test Support (SQLiteDataTestSupport)

public func assertQuery<V: QueryRepresentable, S: Statement<V>>(
  includeSQL: Bool = false,
  _ query: S,
  database: (any DatabaseWriter)? = nil,
  sql: (() -> String)? = nil,
  results: (() -> String)? = nil,
  // + source location params
)

Usage:

@Test
func queryResults() throws {
  try assertQuery(
    Item.order(by: \.title),
    results: {
      """
      ┌─────────────────────┐
      │ "Buy groceries"     │
      │ "Call accountant"   │
      └─────────────────────┘
      """
    }
  )
}

Advanced Patterns


Platform Availability

  • iOS 13+ / macOS 10.15+ / tvOS 13+ / watchOS 7+ — Core library
  • iOS 17+ / macOS 14+ / tvOS 17+ / watchOS 10+ — SyncEngine (CloudKit)
  • Swift 6.0 with strict concurrency

Package Dependencies

PackageVersionPurpose
GRDB.swift7.6.0+SQLite wrapper
swift-structured-queries0.31.0+Type-safe SQL builder
swift-sharing2.3.0+SharedReader observation
swift-dependencies1.9.0+Dependency injection
swift-perception2.0.0+Observation backport
swift-collectionsOrderedCollections
swift-concurrency-extrasAsync utilities
swift-tagged0.10.0Tagged types (optional)

Custom Database Functions

@DatabaseFunction
nonisolated func createDefaultList() {
  Task {
    @Dependency(\.defaultDatabase) var database
    try await database.write { db in
      try List.insert { List.Draft(title: "Personal") }.execute(db)
    }
  }
}

// Register in prepareDatabase:
configuration.prepareDatabase { db in
  db.add(function: $createDefaultList)
}

Seeding Data (DEBUG only)

#if DEBUG
extension DatabaseWriter {
  func seedSampleData() throws {
    try write { db in
      try db.seed {
        Item(id: uuid(), title: "Groceries", listID: listIDs[0])
        Item(id: uuid(), title: "Haircut", listID: listIDs[0])
      }
    }
  }
}
#endif

Updates Extension Pattern

extension Updates<Reminder> {
  mutating func toggleStatus() {
    self.status = Case(self.status)
      .when(#bind(.incomplete), then: #bind(.completing))
      .else(#bind(.incomplete))
  }
}

FTS5 Full-Text Search

@Table
struct ReminderText: FTS5 {
  let rowid: Int
  let title: String
  let notes: String
  let tags: String
}

Schema: CREATE VIRTUAL TABLE "reminderTexts" USING fts5("title", "notes", "tags", tokenize = 'trigram')

Keep FTS in sync via triggers on the source table.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,970. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.