{"id":27329492,"url":"https://github.com/pointfreeco/sharing-grdb","last_synced_at":"2025-05-16T15:08:16.799Z","repository":{"id":277607022,"uuid":"902097949","full_name":"pointfreeco/sharing-grdb","owner":"pointfreeco","description":"A lightweight replacement for SwiftData and the Query macro.","archived":false,"fork":false,"pushed_at":"2025-05-15T16:33:02.000Z","size":857,"stargazers_count":476,"open_issues_count":0,"forks_count":15,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-05-15T17:43:22.048Z","etag":null,"topics":["persistence","sqlite"],"latest_commit_sha":null,"homepage":"https://www.pointfree.co","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pointfreeco.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-12-11T22:44:01.000Z","updated_at":"2025-05-14T09:01:43.000Z","dependencies_parsed_at":"2025-02-14T22:23:05.204Z","dependency_job_id":"531f817f-f655-4be2-b8bf-85bb26d78db7","html_url":"https://github.com/pointfreeco/sharing-grdb","commit_stats":null,"previous_names":["pointfreeco/sharing-grdb"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pointfreeco%2Fsharing-grdb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pointfreeco%2Fsharing-grdb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pointfreeco%2Fsharing-grdb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pointfreeco%2Fsharing-grdb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pointfreeco","download_url":"https://codeload.github.com/pointfreeco/sharing-grdb/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254393892,"owners_count":22063973,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["persistence","sqlite"],"created_at":"2025-04-12T12:55:31.230Z","updated_at":"2025-05-16T15:08:11.784Z","avatar_url":"https://github.com/pointfreeco.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SharingGRDB\n\nA lightweight replacement for SwiftData and `@Query`.\n\n[![CI](https://github.com/pointfreeco/sharing-grdb/workflows/CI/badge.svg)](https://github.com/pointfreeco/sharing-grdb/actions?query=workflow%3ACI)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fpointfreeco%2Fsharing-grdb%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/pointfreeco/sharing-grdb)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fpointfreeco%2Fsharing-grdb%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/pointfreeco/sharing-grdb)\n\n* [Learn more](#Learn-more)\n* [Overview](#Overview)\n* [Demos](#Demos)\n* [Documentation](#Documentation)\n* [Installation](#Installation)\n* [Community](#Community)\n* [License](#License)\n\n## Learn more\n\nThis library was motivated and designed over the course of many episodes on\n[Point-Free](https://www.pointfree.co), a video series exploring advanced programming topics in the\nSwift language, hosted by [Brandon Williams](https://twitter.com/mbrandonw) and\n[Stephen Celis](https://twitter.com/stephencelis). To support the continued development of this\nlibrary, [subscribe today](https://www.pointfree.co/pricing).\n\n\u003ca href=\"https://www.pointfree.co/collections/sqlite/sharing-with-sqlite\"\u003e\n  \u003cimg alt=\"video poster image\" src=\"https://d3rccdn33rt8ze.cloudfront.net/episodes/0309.jpeg\" width=\"600\"\u003e\n\u003c/a\u003e\n\n## Overview\n\nSharingGRDB is lightweight replacement for SwiftData and the `@Query` macro that deploys all the way\nback to the iOS 13 generation of targets.\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003cth\u003eSharingGRDB\u003c/th\u003e\n\u003cth\u003eSwiftData\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr valign=top\u003e\n\u003ctd width=415\u003e\n      \n```swift\n@SharedReader(\n  .fetchAll(\n    sql: \"SELECT * FROM items\"\n  )\n)\nvar items: [Item]\n```\n\n\u003c/td\u003e\n\u003ctd width=415\u003e\n\n```swift\n@Query\nvar items: [Item]\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\nBoth of the above examples fetch items from an external data store, and both are automatically\nobserved by SwiftUI so that views are recomputed when the external data changes, but SharingGRDB is\npowered directly by SQLite using [Sharing][sharing-gh] and [GRDB][grdb], and is\nusable from UIKit, `@Observable` models, and more.\n\n\u003e Note: It is not required to write queries as a raw SQL string, and a query builder can be used \n\u003e instead. For more information on SharingGRDB's querying capabilities, see \n[Fetching model data][fetching-article].\n\n## Quick start\n\nBefore SharingGRDB's property wrappers can fetch data from SQLite, you need to provide–at\nruntime–the default database it should use. This is typically done as early as possible in your\napp's lifetime, like the app entry point in SwiftUI, and is analogous to configuring model storage\nin SwiftData:\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003cth\u003eSharingGRDB\u003c/th\u003e\n\u003cth\u003eSwiftData\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr valign=top\u003e\n\u003ctd width=415\u003e\n\n```swift\n@main\nstruct MyApp: App {\n  init() {\n    prepareDependencies {\n      let db = try! DatabaseQueue(\n        // Create/migrate a database \n        // connection\n      )\n      $0.defaultDatabase = db\n    }\n  }\n  // ...\n}\n```\n\n\u003c/td\u003e\n\u003ctd width=415\u003e\n\n```swift\n@main\nstruct MyApp: App {\n  let container = { \n    // Create/configure a container\n    try! ModelContainer(/* ... */)\n  }()\n  \n  var body: some Scene {\n    WindowGroup {\n      ContentView()\n        .modelContainer(container)\n    }\n  }\n}\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003e Note: For more information on preparing a SQLite database, see \n[Preparing a SQLite database][preparing-db-article].\n\nThis `defaultDatabase` connection is used implicitly by SharingGRDB's strategies, like \n [`fetchAll`][fetchall-docs]:\n\n```swift\n@SharedReader(.fetchAll(sql: \"SELECT * FROM items\"))\nvar items: [Item]\n```\n\nAnd you can access this database throughout your application in a way similar to how one accesses\na model context, via a property wrapper:\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003cth\u003eSharingGRDB\u003c/th\u003e\n\u003cth\u003eSwiftData\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr valign=top\u003e\n\u003ctd width=415\u003e\n\n```swift\n@Dependency(\\.defaultDatabase) \nvar database\n    \nvar newItem = Item(/* ... */)\ntry database.write { db in\n  try newItem.insert(db)\n}\n```\n\n\u003c/td\u003e\n\u003ctd width=415\u003e\n\n```swift\n@Environment(\\.modelContext) \nvar modelContext\n    \nlet newItem = Item(/* ... */)\nmodelContext.insert(newItem)\ntry modelContext.save()\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003e Note: For more information on how SharingGRDB compares to SwiftData, see\n\u003e [Comparison with SwiftData][comparison-swiftdata-article].\n\nThis is all you need to know to get started with SharingGRDB, but there's much more to learn. Read\nthe [articles][articles] below to learn how to best utilize this library:\n\n* [Fetching model data][fetching-article]\n* [Observing changes to model data][observing-article]\n* [Preparing a SQLite database][preparing-db-article]\n* [Dynamic queries][dynamic-queries-article]\n* [Comparison with SwiftData][comparison-swiftdata-article]\n\n[observing-article]: https://swiftpackageindex.com/pointfreeco/sharing-grdb/main/documentation/sharinggrdb/observing\n[dynamic-queries-article]: https://swiftpackageindex.com/pointfreeco/sharing-grdb/main/documentation/sharinggrdb/dynamicqueries\n[articles]: https://swiftpackageindex.com/pointfreeco/sharing-grdb/main/documentation/sharinggrdb#Essentials\n[comparison-swiftdata-article]: https://swiftpackageindex.com/pointfreeco/sharing-grdb/main/documentation/sharinggrdb/comparisonwithswiftdata\n[fetching-article]: https://swiftpackageindex.com/pointfreeco/sharing-grdb/main/documentation/sharinggrdb/fetching\n[preparing-db-article]: https://swiftpackageindex.com/pointfreeco/sharing-grdb/main/documentation/sharinggrdb/preparingdatabase \n [fetchall-docs]: https://swiftpackageindex.com/pointfreeco/sharing-grdb/main/documentation/sharinggrdb/sharing/sharedreaderkey/fetchall(sql:arguments:database:animation:)\n\n## SQLite knowledge required\n\nSQLite is one of the \n [most established and widely distributed](https://www.sqlite.org/mostdeployed.html) pieces of \nsoftware in the history of software. Knowledge of SQLite is a great skill for any app developer to\nhave, and this library does not want to conceal it from you. So, we feel that to best wield this\nlibrary you should be familiar with the basics of SQLite, including schema design and normalization,\nSQL queries, including joins and aggregates, and performance, including indices.\n\nWith some basic knowledge you can apply this library to your database schema in order to query\nfor data and keep your views up-to-date when data in the database changes. You can use GRDB's\n[query builder][query-interface] APIs to query your database, or you can use raw SQL queries, \nalong with all of the power that SQL has to offer.\n\n[query-interface]: https://swiftpackageindex.com/groue/grdb.swift/master/documentation/grdb/queryinterface\n[sharing-gh]: http://github.com/pointfreeco/swift-sharing\n[grdb]: http://github.com/groue/grdb.swift\n[swift-nav-gh]: https://github.com/pointfreeco/swift-navigation\n[observe-docs]: https://swiftpackageindex.com/pointfreeco/swift-navigation/main/documentation/swiftnavigation/objectivec/nsobject/observe(_:)-94oxy\n\n## Demos\n\nThis repo comes with _lots_ of examples to demonstrate how to solve common and complex problems with\nSharing. Check out [this](./Examples) directory to see them all, including:\n\n  * [Case Studies](./Examples/CaseStudies):\n    A number of case studies demonstrating the built-in features of the library.\n\n  * [SyncUps](./Examples/SyncUps): We also rebuilt Apple's [Scrumdinger][scrumdinger] demo\n    application using modern, best practices for SwiftUI development, including using this library\n    to query and persist state using SQLite.\n    \n  * [Reminders](./Examples/Reminders): A rebuild of Apple's [Reminders][reminders-app-store] app\n    that uses a SQLite database to model the reminders, lists and tags. It features many advanced\n    queries, such as searching, and stats aggregation.\n\n[scrumdinger]: https://developer.apple.com/tutorials/app-dev-training/getting-started-with-scrumdinger\n[reminders-app-store]: https://apps.apple.com/us/app/reminders/id1108187841\n\n## Documentation\n\nThe documentation for releases and `main` are available here:\n\n* [`main`](https://swiftpackageindex.com/pointfreeco/sharing-grdb/main/documentation/sharinggrdb/)\n* [0.1.x](https://swiftpackageindex.com/pointfreeco/sharing-grdb/~/documentation/sharinggrdb/)\n\n## Installation\n\nYou can add SharingGRDB to an Xcode project by adding it to your project as a package.\n\n\u003e https://github.com/pointfreeco/sharing-grdb\n\nIf you want to use SharingGRDB in a [SwiftPM](https://swift.org/package-manager/) project, it's as\nsimple as adding it to your `Package.swift`:\n\n``` swift\ndependencies: [\n  .package(url: \"https://github.com/pointfreeco/sharing-grdb\", from: \"0.1.0\")\n]\n```\n\nAnd then adding the product to any target that needs access to the library:\n\n```swift\n.product(name: \"SharingGRDB\", package: \"sharing-grdb\"),\n```\n\n## Community\n\nIf you want to discuss this library or have a question about how to use it to solve a particular\nproblem, there are a number of places you can discuss with fellow\n[Point-Free](http://www.pointfree.co) enthusiasts:\n\n  * For long-form discussions, we recommend the\n    [discussions](http://github.com/pointfreeco/sharing-grdb/discussions) tab of this repo.\n\n  * For casual chat, we recommend the\n    [Point-Free Community Slack](http://www.pointfree.co/slack-invite).\n\n## License\n\nThis library is released under the MIT license. See [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpointfreeco%2Fsharing-grdb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpointfreeco%2Fsharing-grdb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpointfreeco%2Fsharing-grdb/lists"}