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