agentsclimarketplace

Sqlite data

Skill onmyway133/skills/skills/sqlite-data

SQLiteData persistence library (Point-Free) - a fast SwiftData alternative using SQLite/GRDB. Use when working with SQLiteData, GRDB, type-safe SQL queries, @Table macro, @FetchAll/@FetchOne property wrappers, or migrating from SwiftData to SQLite-based persistence.From its SKILL.md

Install
npx -y skills add onmyway133/skills --skill sqlite-data

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

  • 2 stars2 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.

SKILL.md

5.8 KB, as published. Nobody here has run it

SQLiteData

You are a SQLiteData expert. Apply these patterns when working with SQLite persistence using Point-Free's SQLiteData library.

When to Use

  • Building apps with SQLite persistence using SQLiteData
  • Migrating from SwiftData to SQLiteData
  • Using GRDB with type-safe queries
  • Implementing CloudKit sync with SQLite
  • Working with @Table, @FetchAll, @FetchOne, or @Fetch
  • Need better performance than SwiftData
  • Need to work outside SwiftUI views (@Observable, UIKit)

Decision Tree

NeedReference
Define models with @Table macromodel-basics.md
Fetch data with @FetchAll/@FetchOne/@Fetchfetching.md
Insert, update, delete dataqueries-crud.md
Dynamic queries, search, FetchKeyRequestdynamic-queries.md
Joins and multi-table queriesrelationships-joins.md
Database setup, migrations, seedingdatabase-setup.md
CloudKit synchronization and sharingcloudkit-sync.md
Testing patterns and utilitiestesting.md
SwiftData comparison and migrationmigration-comparison.md
Debug and troubleshootcommon-issues.md

Core Principles

  1. Use @Table for persistent structs - Unlike SwiftData's @Model (classes only), @Table works with value types
  2. Use @Dependency(.defaultDatabase) for writes - Property wrappers are read-only; use dependency for mutations
  3. Property wrappers auto-observe changes - @FetchAll/@FetchOne automatically update when database changes
  4. Type-safe queries via StructuredQueries - Use fluent API or #sql macro for safe SQL
  5. Explicit database writes - No autosave; use database.write { } for all mutations

Quick Reference

Basic Model

import SQLiteData

@Table
struct Reminder: Identifiable {
    let id: UUID
    var title = ""
    var isCompleted = false
    var dueDate: Date?
}

App Setup

@main
struct MyApp: App {
    init() {
        prepareDependencies {
            $0.defaultDatabase = try! appDatabase()
        }
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

func appDatabase() throws -> any DatabaseWriter {
    let database = try defaultDatabase()
    var migrator = DatabaseMigrator()
    migrator.registerMigration("Create tables") { db in
        try #sql("""
            CREATE TABLE "reminders" (
                "id" TEXT PRIMARY KEY NOT NULL,
                "title" TEXT NOT NULL DEFAULT '',
                "isCompleted" INTEGER NOT NULL DEFAULT 0,
                "dueDate" TEXT
            ) STRICT
            """).execute(db)
    }
    try migrator.migrate(database)
    return database
}

Fetch in SwiftUI

struct ReminderList: View {
    @FetchAll(Reminder.order(by: \.title))
    var reminders

    @FetchOne(Reminder.count())
    var count = 0

    var body: some View {
        List(reminders) { reminder in
            Text(reminder.title)
        }
    }
}

CRUD Operations

@Dependency(\.defaultDatabase) var database

// Create
try await database.write { db in
    try Reminder.insert(Reminder(id: UUID(), title: "Buy milk"))
        .execute(db)
}

// Read with filtering
@FetchAll(Reminder.where(\.isCompleted).order { $0.title.desc() })
var completedReminders

// Update
reminder.title = "Updated Title"
try await database.write { db in
    try Reminder.update(reminder).execute(db)
}

// Delete
try await database.write { db in
    try Reminder.delete(reminder).execute(db)
}

Dynamic Query with Search

struct SearchView: View {
    @Fetch(RemindersRequest()) var data = RemindersRequest.Value()
    @State var searchText = ""

    var body: some View {
        List(data.reminders) { reminder in
            Text(reminder.title)
        }
        .searchable(text: $searchText)
        .task(id: searchText) {
            try? await $data.load(RemindersRequest(query: searchText)).task
        }
    }
}

struct RemindersRequest: FetchKeyRequest {
    var query = ""

    struct Value {
        var reminders: [Reminder] = []
        var count = 0
    }

    func fetch(_ db: Database) throws -> Value {
        let filtered = Reminder
            .where { $0.title.contains(query) }
            .order(by: \.title)
        return try Value(
            reminders: filtered.fetchAll(db),
            count: filtered.fetchCount(db)
        )
    }
}

References

Keep looking

Skills are one crate of 627,801. 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.