Skip to content

Repair only where writing is allowed - #1258

Merged
noha merged 6 commits into
mainfrom
repair-only-where-writing-is-allowed
Sep 15, 2026
Merged

noha merged 6 commits into
mainfrom
repair-only-where-writing-is-allowed

Conversation

@noha

@noha noha commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

No description provided.

noha and others added 6 commits September 15, 2026 11:25
A database created with #initializeFilesystem left an empty journal
directory behind, and the first #open closed that gap by checkpointing.
That is a write, and it happened whether or not the database had been
opened read-only. The checkpoint now runs where creating files is the
point, so a database is complete the moment it is created.

A backup target is created the same way and now brings its own first
fragment file along, carrying the same name as the source's first one.
The backup clears the target's journal before copying the source's
fragments over, because #copyTo: fails on a name that already exists.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#cycleFragmentFile read the instance variable, so it failed with a nil
receiver whenever no fragment file had been opened yet. Recovery reaches
it in exactly that state: when the fragment file the last checkpoint
names has gone missing, it cycles to a fresh one before anything else
has touched the journal.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The journal's #open created a fragment file and checkpointed whenever
the journal directory held none. That is a repair, and it ran from
#basicOpen, ahead of the only place that asks whether this image may
write to the database at all - so a database opened read-only had files
written into it regardless.

Recovery already covers a missing fragment file and sits behind
#canRecover: with write access it starts a fresh fragment and
checkpoints, and without it the reader is told through
SoilDatabaseNeedsRecovery while nothing is written.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#basicOpen created the metadata file for databases that did not have
one, which only ever applied to databases predating the file. It has
been created by #initializeFilesystem ever since, and a database opened
read-only has no business writing it in any case.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
SoilJournalFragmentFile built its own lockable stream instead of asking
the database for one, which made it the single file that ignored
#readOnly - and a configured lockableStreamClass along with it. It now
answers its database and inherits #open from SoilBinaryFile, so a
database opened read-only hands out a read stream here too.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two properties had no test: that creating a database leaves a journal
fragment file and a checkpoint behind, and that opening such a database
read-only writes nothing. The second one is the case that used to fail
from inside a write.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@noha
noha merged commit 244fbca into main Sep 15, 2026
5 checks passed
@noha
noha requested a review from MarcusDenker September 15, 2026 09:42
@noha
noha deleted the repair-only-where-writing-is-allowed branch September 15, 2026 20:10

@MarcusDenker MarcusDenker left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants