HN user

groue

83 karma

[ my public key: https://keybase.io/groue; my proof: https://keybase.io/groue/sigs/knREShdojU_VyeRJ_ykxWtiYquBB3txRSZW2yAi4uAg ]

Posts19
Comments47
View on HN
old.reddit.com 4y ago

GRDB 5.17 with async/await (SQLite toolkit for Swift)

groue
1pts1
forums.swift.org 5y ago

New release: GRDB 5.0.0 (Swift toolkit for SQLite databases)

groue
1pts0
forums.swift.org 6y ago

Swift Evolution – [Accepted] SE-0279: Multiple Trailing Closures

groue
1pts0
forums.swift.org 6y ago

Announcement: Version 5.0.0-beta of GRDB, the Swift toolkit for SQLite databases

groue
1pts0
forums.swift.org 7y ago

Announcing GRBD 4, a Swift Toolkit for SQLite Databases

groue
1pts0
github.com 8y ago

SQLite: FMDB-compatible bindings to GRDB.swift

groue
1pts0
medium.com 9y ago

Unexpected SQLite with Swift

groue
1pts5
medium.com 9y ago

How Swift protocols and immutability impact database accesses

groue
4pts1
medium.com 10y ago

Four different ways to handle SQLite concurrency

groue
5pts0
github.com 10y ago

Writing a Swift iOS App with GRDB and FetchedRecordsController

groue
2pts0
github.com 10y ago

A Swift library with support for SQLite WAL mode

groue
1pts0
github.com 10y ago

Show HN: Performance comparison of Swift SQLite libraries

groue
2pts0
github.com 10y ago

A Mustache template engine that builds with the Swift Package Manager

groue
3pts0
github.com 10y ago

Show HN: GRDB.swift – a versatile SQLite toolkit for Swift 2

groue
2pts0
github.com 11y ago

Swift rendering engine for Mustache templates

groue
1pts0
www.madore.org 11y ago

Why English sucks as the language for international and scientific communication

groue
2pts1
blog.oleganza.com 13y ago

Efficiency and Bullying

groue
2pts0
engineering.tumblr.com 13y ago

Tumblr for iPhone is now 100% native

groue
2pts0
github.com 13y ago

Mustache support for "Filters"

groue
1pts0

Yes. GRDB encourages Codable because the user can profit from the code generated by the compiler, and this implies that database values are accessed by column name, on top of the Codable runtime, and those layers have a high cost. When necessary it is possible to access database values by position, and in this case GRDB achieves speed of light (performance nearly identical as raw SQLite).

Thank you (GRDB author here).

It is not mentioned in the README of the repository, but SQLiteData wraps GRDB to access the database and get notified of database changes (the meat and butter).

GRDB is by itself a solid "toolkit for SQLite databases, with a focus on application development", with both high levels APIs for everyday coding, and expert SQLite features for the demanding developers. Many apps rely on GRDB alone.

I do, for JSON columns. I store UTF8 strings in SQLite, so that it is easy to see JSON values with a plain `SELECT *`). And I load blobs, because I code in Swift and the standard JSON decoder eats raw UTF8 memory buffers, not strings.

This avoids two useless conversions:

- first from a C string loaded from SQLite to a Swift Unicode string (with UTF8 validation).

- next from this Swift Unicode string to a UTF8 memory buffer (so that JSONDecoder can do its job).

SQLite is smart enough to strip the trailing \0 when you load a blob from a string stored in the database :-)

Yes. Now, many short writes look exactly as one very long write from the point of view of an enqueued write that is waiting for its turn :-) I don't quite remember how fair is SQLite scheduling, in practice.

What's cool with WAL mode is that SQLITE_BUSY won't happen for readers (except very rare scenarios: https://www.sqlite.org/wal.html#sometimes_queries_return_sql...)

One should only expect SQLITE_BUSY for writes (if a writer is already holding the lock, and the busy timeout expires before the other writer releases the lock). So yes, prefer short writes, or adjust your timeout. Generally speaking, SQLITE_BUSY can not be 100% prevented for writes.

It is always safe, and by "safe" I mean "safe for data". You won't have to deal with data corruption. Precisely, see "How To Corrupt An SQLite Database File": https://www.sqlite.org/howtocorrupt.html

Now concurrent accesses from different processes/connections can lead to runtime errors (SQLITE_BUSY), because the database happens to be locked by one connection.

Those errors are greatly reduced by the WAL mode (https://sqlite.org/wal.html) which provides ultra-robust single-writer/multiple-readers semantics:

- Writes can not happen concurrently (SQLITE_BUSY).

- One can reduce the occurrences of such SQLITE_BUSY errors by using a built-in timeout (https://www.sqlite.org/c3ref/busy_timeout.html).

- Several reads can happen concurrently, including with writers.

- A writer connection can enter the "Serializable" isolation level.

- A reader connection can enter the "Snapshot Isolation" level.

For more details, see https://www.sqlite.org/isolation.html

During all the years I've been developing the GRDB library (https://github.com/groue/GRDB.swift), I could never see SQLite fail its documented guarantees. This made it possible to build one of the most concurrency-focused SQLite toolkit for Swift, and I'm pretty happy with it (https://github.com/groue/GRDB.swift/blob/master/Documentatio...).

The music is quite good! The covers of Freddie Freeloader and Flamenco Sketches are quite worth it, IMHO :-)

We start to see ORMs like Diesel (https://diesel.rs) or GRDB (http://github.com/groue/GRDB.swift) that radically simplify their domain by removing traditional ORM features like implicit uniquing, lazy-loading, or auto-updates. This of course gives more work to do on the client side. But this work is positive and often simpler than expected. With traditional ORMs, there is still some work to do, which often looks like fights: against misunderstandings, against leaky abstractions, against configuration levels that don't match the needs of application, and generally speaking against the framework.

ORMs are not done yet :-)

Unique to GRDB.swift, as far as I know, is the ability to perform database writes and then wait until snapshot isolation has been reached in another connection before releasing the writing lock. This allows to read from a known database state, while allowing other writes to be performed. The ability to read for a precisely known database state allows nice features like database observation and reactive patterns, while taking advantage from the WAL mode by not holding locks longer than necessary.

I'd also like to thank the other for his attempt at raising the general awareness of transaction isolation. Even when you deal with simpler databases like SQLite, isolation is a serious topic. When serializing accesses hinders performances, dealing with the "WAL mode" that grants SQLite with single-writer-multipler-readers abilities is everything but trivial, because of the huge amount of documentation that has to be read in order to reach the desired level of isolation. I've written an SQLite library in Swift that provides by default the snapshot isolation level which grants most developers with both peace of mind, and non-blocking reads. Check out its "concurrency guide" if you're interested: https://github.com/groue/GRDB.swift/blob/master/README.md#co...

They sound similar to change data capture in SQLServer.

Yes. There is a difference, though: SQLite is embedded, and there is zero latency between an application and its database.

This means that change notifications can be emitted synchronously right after a committed transaction, allowing the application to process the change before any other change could be performed.

This makes it much easier to get a very robust solution for a whole class of database synchronization problems.

Simplest way would be to embed public key in the application

Yes, but one eventually faces the need to update the certificate on the server, and still support installed applications (which fails when apps have an obsolete certificate pinned). Hence the need for smooth certificate updates, and the good smell of HPKP. But it addresses another need, hence my confusion.

Mobile apps typically have other key pinning mechanisms that are preloaded (i.e. baked into the binary), but that's typically easy to bypass if you're the owner of a device; it's not really effective as a mechanism against reverse engineering.

Your comment makes me realize that HPKP can bootstrap itself, and is unlike regular pinning (with certificate bundled in the binary, as you say).

So do you agree that a powerful enough owner of the device should be considered able to setup a server which poses as the regular server the app talks to, and sniff any request the app sends to its server?

(edited for spelling)

May I ask a stupid question? Last time I heard about HPKP was as a solution to prevent an attacker from installing a fake root CA certificate in the client system (a mobile device), so that it could observe the behavior of a mobile app, by posing as its API server (for any purpose of reverse-engineering). Is such an attack possible, and HPKP a reasonable solution to it?

After one year in the making, GRDB.swift has acquired experience about the impact of protocol-oriented programming and immutability on the way applications can access SQLite databases. First, those new paradigms actually help avoiding some hard-to-reproduce concurrency bugs. Next, they are fundamentally incompatible with frameworks like Core Data and Realm, which rely heavily on both class inheritance and mutability. This has consequences on application architecture.