<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body><p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">Fedora 29 is quite old by now...</p>
<br /><p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">Op maandag 13 juli 2026 02:28:16 Midden-Europese zomertijd schreef Derek Atkins:</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> Maybe that was the issue.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> [root@code ~]# rpm -q doxygen</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> doxygen-1.8.14-7.fc29.x86_64</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> -derek</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> On Sun, July 12, 2026 2:10 pm, John Ralls wrote:</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> > Derek,</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> > </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> > That doesn’t square with the last build being two years ago, we removed</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> > auto tools in 2017. https://github.com/Gnucash/gnucash/pull/1943, which</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> > was merged immediately after the last successful docs build is the</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> > culprit. What version of Doxygen are you running?</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> > https://github.com/Gnucash/gnucash/pull/1943/changes/891b921c811f32e214fe9</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> > fc1a87e392b58ed7757 bumped the Doxyfile version from 1.8.3 to 1.9.7.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> > </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> > Regards,</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> > John Ralls</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> > </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >> On Jul 11, 2026, at 18:08, Derek Atkins <derek@ihtfp.com> wrote:</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >> Yes, doxygen not building is a known issue. The build requirements</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >> changed and I've never spent the time to figure out how to update the</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >> script to meet the new requirements. Specifically I used to be able to</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >> build the doxygen.cfg manually by calling the Makefile.am with the right</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >> rule. But that was removed for CMake, and I think to get that to work I</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >> might need to install a complete build system, which I kinda don't want</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >> to do. Worst case I'll have to make VM just for that.. But it just</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >> hasn't been high on my priority list.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >> -derek</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >> Sent using my mobile device. Please excuse any typos.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >> On July 11, 2026 16:18:15 John Ralls <jralls@ceridwen.us> wrote:</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> Noah,</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> Please always copy one of the mailing lists when you email one of the</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> GnuCash developers unless it’s to send something like a GnuCash book;</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> in that case the email should just have the file, all of the discussion</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> around it should be copied to the list.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> I’ve passed on to Derek via IRC the Doxygen-docs problem just in case</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> he misses it here.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> Yup, readonly-mode is largely cosmetic and applied only to the GUI.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> GnuCash is not designed for use by more than one user at a time and</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> read-only mode is very simplistic.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> I don’t think it would be too hard to extend its force to the backend</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> so that a read-only session is blocked from writing. But if you want a</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> read-only session to lock the database then it’s not really read-only</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> anymore.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> How about leveraging the database’s locking? Wrap all of the queries</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> with dbi_conn_transaction_begin and dbi_conn_transaction_commit. That</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> will make multi-table writes atomic with an exclusive lock, blocking a</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> reader from reading them until the whole write is complete, while a</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> read query while loading will block the exclusive write lock until the</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> read is complete.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> Regards,</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> John Ralls</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> On Jul 11, 2026, at 12:24 PM, array_hourly_0u@icloud.com wrote:</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> Thanks for merging #2264 and #2266 John.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> Arrg. As I've started to poke more into this read-only and lock</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> topic, I've found some surprises and ultimately a correctness matter.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> What SESSION_READ_ONLY actually means</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> ------------------------------------------------------------</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> 1. At the engine level, SESSION_READ_ONLY doesn't actually enforce</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> read-only. The mode only affects lock handling -- it does not mark the</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> book read-only. Book write-protection is applied separately by the GUI</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> only, which calls qof_book_mark_readonly() after opening. I confirmed</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> with an API bindings test that a SESSION_READ_ONLY session can still</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> edit an account and have the change persisted to the SQL store. So an</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> API/bindings consumer that opens SESSION_READ_ONLY expecting the book</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> to be unwritable does not get that guarantee unless it also calls</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> qof_book_mark_readonly() itself. [a bug if one interprets</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> SESSION_READ_ONLY reading the enum name while not carefully parsing</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> the header comments ]</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> 2. SESSION_READ_ONLY ignores the lock. A read-only consumer opens a</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> book even while another process holds it open, perhaps mid-write,</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> which is exactly when the state can be inconsistent; and because the</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> SQL backend commits incrementally, a reader can catch a</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> partially-applied edit. [ a read-only client correctness bug ]</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> So today the mode neither protects read consistency (it ignores the</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> lock) nor guarantees read-only-ness (that's a GUI add-on), even though</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> the name implies both.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> Proposed path forward</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> -----------------------------------</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> For building read-only tools on the API, what I'd want is a read-only</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> session mode that (a) takes the lock, so a writer cannot be active</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> while the tool reads, and (b) actually enforces no writes.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> A possible direction would be to replace SESSION_READ_ONLY with two</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> modes whose names state what they do, and have both mark the book</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> read-only so enforcement is intrinsic rather than GUI-only:</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> - SESSION_READ_ONLY_EXCLUSIVE -- takes the lock (fails if the book is</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> already locked); for tools that need a consistent, uninterrupted read.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> Calls qof_book_mark_readonly(). Obviously a SQL backend user would</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> need sufficient permissions to take the lock. I'd want to add some</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> user guide documentation about this where none exists today.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> - SESSION_READ_ONLY_IGNORE_LOCK -- opens regardless of the lock state;</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> the path the GUI's "open read-only anyway" override would use. (i.e.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> today's SESSION_READ_ONLY behavior, but with qof_book_mark_readonly()</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> )</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> These could be added now, with SESSION_READ_ONLY marked deprecated,</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> and SESSION_READ_ONLY removed in a later release (v6? whatever that</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> timeframe turns out to be). I believe the deprecation warning would</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> only apply to users of the API `SESSION_READ_ONLY` mode today. (The</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> GUI internal use would be swapped to SESSION_READ_ONLY_IGNORE_LOCK.)"</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> Does folding read-only enforcement into the mode (so bindings</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> consumers get it too), plus splitting the lock behavior, sound like an</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> OK path?</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> Aside, is it a known issue Doxygen isn't updating / is stale? (title</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> says "GnuCash 5.6-150-g038405b370+" )</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> https://code.gnucash.org/docs/STABLE/qofsession_8h.html</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> I was initially looking for the enum descriptions but didn't find them</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> outside of the code. Double btw: There is a documentation bug in the</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> source here in that the five /** … */ comments need to be trailing</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> /**< … */ comments (Doxygen trailing-member syntax). Right now, when</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> the comments are rendered, they are offset by one.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> Regards,</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> Noah</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>> On Sat, Jul 11, 2026 at 8:47 AM Noah <> wrote:</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> Thanks, John.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> Your premise that the database was necessarily written by a GnuCash</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> session is false.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> You're right, I was biasing by my own use principles.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> I never want to modify my production book through anything but the</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> GnuCash GUI or the official GnuCash API / bindings.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> My household moved our finances to GnuCash 14 years ago motivated by</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> two challenges.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> - need to support two users on different computers (in serial, not</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> simultaneously). We were bit too many times with filesystem-based</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> commercial options at the time.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> - a Q* commercial software was dropping support for Mac, or</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> non-cloud, or both</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> In more recent years, our financial institutions have been making it</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> harder to get our transaction data into GnuCash (eg. removing OFX/QFX</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> download)</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> In order to hold the line at home, I've been doing more and more work</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> adopting use of the API & Python bindings to help a lot in this</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> regard. I've also been creating some reporting and exploration tools</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> that don't need write access (and tinkering with other's work like</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> piecash). Since they don’t need write access, I want them to access</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> MySQL with the minimum privileges necessary.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> The ffastmath problem underlying bug 611936 was on the write side of</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> libdii so a read-only test wouldn’t find the problem.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> That settles it for me: since the -ffast-math defect in #611936 is on</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> the write side of libdbi, a read-only session can neither trigger nor</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> detect it, so running the probe on a read-only open guards nothing.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> I've opened a PR that skips dbi_library_test() for SESSION_READ_ONLY</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> and leaves all write-capable modes untouched:</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> https://github.com/Gnucash/gnucash/pull/2266</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> I'm not trying to bolt access control onto GnuCash, and I agree that</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> wouldn't end well. The narrower goal is just to let a read-only</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> consumer honor a least-privilege credential a DBA may already have in</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> place -- and, independently, to stop running a write-only probe on a</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> read-only open. The PR stands on that second part alone.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> Thanks again,</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> Noah</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> On Thu, Jul 9, 2026 at 8:31 PM John Ralls</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>> <jralls_at_ceridwen_us_pgk183pwhb49kj_sc4m4741@icloud.com> wrote:</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> On Jul 9, 2026, at 14:34, array_hourly_0u@icloud.com wrote:</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> Hello again,</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> Obviously backend stuff is on my mind lately and there's been a</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> quirk impacting read-only access to SQL back-ed books that has</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> bothered me for a while.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> Opening a book with SESSION_READ_ONLY through the SQL/DBI backend</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> still requires the database user to have permission to create a</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> temporary table. On every session_begin (regardless of mode),</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> dbi_library_test() runs the 64-bit round-trip guard from Bug</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> #611936</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> -- CREATE TEMPORARY TABLE / INSERT / SELECT / DROP -- to detect a</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> 15-year-old -ffast-math libdbi miscompilation. A least-privileged,</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> SELECT-only database user therefore cannot open the book at all:</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> the</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> create fails and begin returns ERR_SQL_DBI_UNTESTABLE.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> (SESSION_READ_ONLY already skips the gnclock lock, so this probe is</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> the only remaining reason a read-only open needs write-ish rights.)</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> I'd like to propose making a read-only open work without those</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> privileges. Two possible directions:</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> 1. Skip dbi_library_test() when the session is opened</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> SESSION_READ_ONLY.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> 2. Or, for read-only, replace it with a check that needs no write</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> privileges -- for example, verify the driver retrieves large</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> int64/uint64 and a high-precision FLOAT8 via a SELECT of</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> literals/casts (dbi_result_get_longlong / get_ulonglong /</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> get_double),</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> so the reader's conversion path is still validated. I'd welcome</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> suggestions on the best minimal form.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> The justification for either approach: the data already in the</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> database was written by a GnuCash session, and dbi_library_test()</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> ran</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> for that session, so any book that was successfully saved was</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> necessarily saved by a driver that passed the round-trip test --</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> the</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> stored 64-bit and FLOAT8 values are therefore correct at rest. A</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> read-only session never writes back, so the only thing left to</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> guard</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> against is a reader-side retrieval defect. For a modern 64-bit</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> libdbi</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> that is the 2011, 32-bit / -ffast-math case from #611936, which is</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> essentially historical (or maybe never existed on the read)</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>>> If there is a preferred direction, I'm happy to prepare a PR.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> Your premise that the database was necessarily written by a GnuCash</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> session is false. Anybody with db write access (and for a SQLite3</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> database that means anyone with write access to the filesystem) can</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> write (or delete) whatever they want into the database. There is at</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> least one public Python library that reads and writes GnuCash</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> SQLite3 files (https://github.com/sdementen/piecash). The databases</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> have no integrity checks enabled: Any integrity checking (and it’s</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> pretty minimal) is in GnuCash’s engine.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> The ffastmath problem underlying bug 611936 was on the write side of</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> libdii so a read-only test wouldn’t find the problem. I think it</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> unlikely that anyone is using that version of gcc anymore so it’s</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> probably safe to remove the test.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> That said, I have my doubts about the value of having users without</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> database write access. Access control hasn’t ever been a</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> consideration in GnuCash’s design and trying to bolt it on 30 years</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> later isn’t likely to produce a satisfactory result.</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> Regards,</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>>>>> John Ralls</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> _______________________________________________</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> gnucash-devel mailing list</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> gnucash-devel@gnucash.org</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> >>> https://lists.gnucash.org/mailman/listinfo/gnucash-devel</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> > </p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> > _______________________________________________</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> > gnucash-devel mailing list</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> > gnucash-devel@gnucash.org</p>
<p style="margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">> > https://lists.gnucash.org/mailman/listinfo/gnucash-devel</p>
<br /><br /></body>
</html>