As @ryanashcraft says: "These mitigations may sound reasonable at first, but implementing all of them correctly and consistently is surprisingly difficult".
One of the difficulties lies in the OS apis, in order to detect when the app is about to get suspended, and when the app becomes able to acquire database locks again. See this forum thread with @justkwin: https://developer.apple.com/forums/thread/126438
The other difficulty is that if the app is writing (holding a lock) at the moment it is notified it will get suspended, then all it can do is aborting the write. Here you can give up and lose data, or plan for writing later 😖
https://mastodon.social/@ryanashcraft/114503016662115246
Look at this gorgeous +52/-153 commit from @autoreleasefool (thanks!) 🤩 Don't we all like the smell of deleted code in the morning?
https://github.com/autoreleasefool/approach/commit/52eedb4f4617e5f6a88fefd98e23725c5340e364
12.5.2025 09:54Look at this gorgeous +52/-153 commit from @autoreleasefool (thanks!) 🤩 Don't we all like the smell of deleted code in the...An expected benefit of this release is the ability to delete all trivial extensions to DerivableRequest: https://hachyderm.io/@groue/114490497380343501
11.5.2025 18:11An expected benefit of this release is the ability to delete all trivial extensions to DerivableRequest:...I was so excited with this release that two breaking changes have slipped in.
The first will impact projects that define `public` record types with a nested Columns enum. In the upgrade, you'll have to make Columns public as well.
The second, hopefully, should not affect anyone 🤞
Please check the above link to release notes for more information.
11.5.2025 13:15I was so excited with this release that two breaking changes have slipped in.The first will impact projects that define `public` record...🚀 Please welcome GRDB 7.5.0 and its new, streamlined way to write database requests!
The new features are based on the existing recommended practices, so most of you will be able to simplify database requests right away.
See the release notes for more information: https://github.com/groue/GRDB.swift/releases/tag/v7.5.0
Happy GRDB!
11.5.2025 13:03🚀 Please welcome GRDB 7.5.0 and its new, streamlined way to write database requests!The new features are based on the existing...Le 59 Rivoli, anciennement "le squat de la rue de Rivoli" accueille de nombreux artistes, et la visite est gratuite. Je me suis offert cette belle gravure de Louis Coiffard-Dulac, belle et inquiétante comme la mer, merci 🤩
3.5.2025 17:20Le 59 Rivoli, anciennement "le squat de la rue de Rivoli" accueille de nombreux artistes, et la visite est gratuite. Je me suis...C'est vrai que ça a l'air taloché avec les pieds 😬
https://www.reddit.com/r/typography/comments/1k90zg7/kerning_on_the_popes_tombstone/#lightbox
28.4.2025 17:55C'est vrai que ça a l'air taloché avec les pieds...It is sensible indeed to respect the time spent on genuine, effective, plain work. I admire my friends who work more than I do. Not "work" as in "make some random person more wealthy", but as in "suck less at great stuff".
https://dindon.one/@henry/114392095581209241
On an app that I'm working on, the diff is +60/-105. The main benefit is that I coud remove a lot of verbose extensions on DerivableRequest<MyRecord>. Now they are only needed when a scope would be needed in a Rails app (i.e. when the logic becomes complex, or when you want to encapsulate and hide database details). That's super cool :-)
12.4.2025 18:42On an app that I'm working on, the diff is +60/-105. The main benefit is that I coud remove a lot of verbose extensions on...> In order to avoid the breaking change, I'll have to choose a name that is not `Columns`.
Ah this is difficult. I could ask users to opt in for the new feature by renaming their existing `Columns` to, say, `TableComponents`. But there are still places where this type is used with its full name:
struct Player: FetchableRecord, PersistableRecord {
var id: String
var name: String
enum Columns { ... }
// Columns is used here
static var databaseSelection: [any SQLSelectable] {
[Columns.id, Columns.name]
}
// Columns is used here
init(row: Row) {
self.id = row[Columns.id]
self.name = row[Columns. name]
}
// etc
}
I need a name that is not `Columns`, and that could be used in the above sample code without seeming out of place. 🤯
12.4.2025 15:11> In order to avoid the breaking change, I'll have to choose a name that is not `Columns`.Ah this is difficult. I could ask users to...I have a nice #GRDB branch that simplifies the definition of SQLite requests from Swift code:
// 🙄 String-based (current state of the lib)
Player.filter(Column("score") > 1000)
// 😐 Enum-based (current state of the lib)
Player.filter(Player.Columns.score > 1000)
// 🤩 NEW
Player.filter { $0.score > 1000 }
It comes for free for record types that follow the recommended practices (i.e. define a nested `Columns` enum). 🎁
The commit that updates the demo app shows a nice win, at +9/-44 https://github.com/groue/GRDB.swift/commit/261c0ccf866029c0f65a88b881aabf46effc4f9e
The problem is that it breaks apps that define their records in packages/frameworks. The `Columns` enum must become `public` when the record type is, or the compiler won't compile it (even if its members are not public). 😖
In order to avoid the breaking change, I'll have to choose a name that is not `Columns`.
TableColumns? RecordColumns? Cols? Col? C?
In my own practice, this type sometimes contains expressions that are not columns, as below. Maybe the name should not refer to "columns", after all. TableLayout? TableComponents? SQLElements?
enum Columns {
// The date column
static let start = Column(CodingKeys.start)
// An expression derived from the date column
static let startDateUTC = SQL("date(\(Columns.start))").sqlExpression
}
🚀 GRDB 7.4.0, the Swift toolkit for SQLite database, is out.
It is a recommended upgrade, because it solves unexpected database observation errors in applications that `await` the database from tasks that get cancelled. And we all prefer when database observation has no known bugs whatsoever! 🐞
Check out the link for the most recent releases:
https://github.com/groue/GRDB.swift/releases
22.3.2025 17:20🚀 GRDB 7.4.0, the Swift toolkit for SQLite database, is out.It is a recommended upgrade, because it solves unexpected database...@mattiem To address the needs of @layoutSubviews (and peers) expressed in https://mastodon.social/@layoutSubviews/114032891799577133, I could declare both "sending" and @Sendable variants of the async methods, depending on the compiler(>=6.1) directive.
But this is VERY MESSY. And I'm not talking about online documentation that does not match the actual declaration, the unstable DocC hashes, and all the nasty consequences of bugs.
So I'd better be sure of the kind of bug I'm looking at: a fixed one, or a future one. The only one I'll eventually forget is the fixed one.
23.2.2025 19:58@mattiem To address the needs of @layoutSubviews (and peers) expressed in https://mastodon.social/@layoutSubviews/114032891799577133, I...@mattiem Minimum reproducing code: https://gist.github.com/groue/ab4dc13ae4b05f679008454169ea921b (fails with Xcode 16.2, compiles with Xcode 16.3)
23.2.2025 17:41@mattiem Minimum reproducing code: https://gist.github.com/groue/ab4dc13ae4b05f679008454169ea921b (fails with Xcode 16.2, compiles with...@mattiem Hello Matt! If you have a few minutes, would you play a concurrency game?
I was working on turning Sendable closures into plain "sending" ones. The context is https://hachyderm.io/@groue/114029639111178668
I met a problem: this change breaks user code. The snippet in the screenshot stops compiling with Xcode 16.2. And it compiles with Xcode 16.3 beta.
It's difficult to untangle. I'm sure the code was correct with Sendable closures. Switching to "sending" closures should not change its correctness. But there is a bad interaction with isolation inference (I do intend the closure to be nonisolated regardless of the isolation of the caller, but the compiler says otherwise with "sending" closures). This bad interaction may be a bug that has been fixed in Swift 6.1. But I'm not sure if I’m describing the reality, or if I'm making things up.
Do you have an idea about the exact cause of the problem with "sending" closures?
23.2.2025 17:18@mattiem Hello Matt! If you have a few minutes, would you play a concurrency game?I was working on turning Sendable closures into plain...More and more people are asking for SQLCipher support in GRDB + SPM.
Unfortunately, this is beyond my skills. I'm not a build expert.
There is a PR in progress at https://github.com/groue/GRDB.swift/pull/1708 that seems like it is going in the right direction. But it is still not the pull request I'm hoping for:
🤩 Provides built-in SQLCipher support that works for 80+% of people.
🤩 No extra dependency (we must control the SQLCipher compilation options).
🤩 No binaries (they rot).
🤩 A clear documentation that tells users what to do to get GRDB+SQLCipher with SPM, written for people who are not build experts.
🤩 Testable in GitHub CI.
🤩 Runs the full GRDB test suite with unencrypted databases, AND with encrypted databases (we already do that for SQLCipher with CocoaPods).
🤩 Requires minimum efforts for debugging (one can debug tests from Xcode).
🤩 Requires minimum efforts for maintenance (i.e. bumping SQLCipher version and adjusting compile options when needed)
🤩 A technique thats enables SQLCipher support in companion packages as well (GRDBQuery, GRDBSnapshotTesting, RxGRDB).
That would achieve the level of quality I would expect from my favorites libraries (simply the best 🎵)
If you use GRDB and SQLCipher with SPM, and your solution checks some of the above items, please consider contributing your solution for all GRDB users!
cc @marcprux
12.2.2025 10:30More and more people are asking for SQLCipher support in GRDB + SPM.Unfortunately, this is beyond my skills. I'm not a build...I stopped trying with Java, because my Java is so rusty I can't write "Hello World", and I can't find it behind the cookie banners.
5.2.2025 15:44I stopped trying with Java, because my Java is so rusty I can't write "Hello World", and I can't find it behind the cookie...It's even easier with Swift:
1. Edit myprogram.swift in any text editor
2. Run `swift myprogram.swift` in any terminal
3. There’s no step 3
I'm not sure what I was supposed to mean in my previous message 😅
5.2.2025 15:41It's even easier with Swift:1. Edit myprogram.swift in any text editor2. Run `swift myprogram.swift` in any terminal3. There’s no step...Very rarely, I write a small C program. My C is very rusty. That's how I can tell that C can have great ergonomics:
1. Edit myprogram.c in any text editor
2. Run `cc myprogram.c && ./a.out` in any terminal
3. There's no step 3
https://sqlite.org/forum/forumpost/d1eebbd331
5.2.2025 15:33Very rarely, I write a small C program. My C is very rusty. That's how I can tell that C can have great ergonomics:1. Edit myprogram.c...Trump reminds me of The Mule in Asimov's Foundation.
3.2.2025 17:36Trump reminds me of The Mule in Asimov's Foundation.⬆️
⬇️