镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Create and discard an archive database file #378

Description

@bjester

Overview

Morango can create a new SQLite archive file with only the morango tables, and it can discard that file cleanly. This work is part of milestone M5.

Background & Motivation

The archive is a second Django database. Morango must open it at run time, add the morango tables with the normal migrations, and remove every trace of it after a failure. The work happens in a partial file, and only a completed export gets the final name.

Design: spec. Plan: implementation plan, Task 17.

Description & Expected Outcomes

Archive.create(path) refuses a path that exists. It writes to <path>.partial and replaces a stale partial file. It registers an archive alias with the prefix morango_archive_, and it turns on incremental auto-vacuum before the tables exist. Then it runs the morango migrations on the archive alias and makes sure that every morango table exists.

If a table is missing, a host router blocked the migration. In that case, create raises MorangoArchiveError with a message about the router requirement. Archive.discard() closes the connection, removes the archive alias, and deletes the partial file.

An ArchiveDatabase handle gives the archive alias to other code. Every query through this handle goes to the archive.

Deliverables & Contracts

The change delivers these capabilities:

  • ARCHIVE_ALIAS_PREFIX, with the value "morango_archive_".
  • ArchiveDatabase, a subclass of SyncDatabase with a fixed alias.
  • Archive.create(path) and Archive.discard().
  • The errors MorangoArchiveError and MorangoArchiveExists.

Acceptance Criteria

  • create on a new path makes <path>.partial with a table for every morango model.
  • PRAGMA auto_vacuum on the new file returns 2 (incremental).
  • create on an existing path raises MorangoArchiveExists.
  • create replaces a stale <path>.partial.
  • If a router denies morango migrations on the prefix, create raises MorangoArchiveError, and no archive alias and no partial file remain.
  • discard removes the partial file and the archive alias, and a second discard does nothing.
  • The full test suite passes.

Technical Pointers & Architecture

  • Target Components / Context: morango/sync/archive.py, morango/errors.py.
  • Related Patterns: SyncDatabase from Explicit database handle for sync database access #365. The spike in Spike: prove that a Django-managed archive database works #362 records how alias registration and migrations work on Django 3.2.
  • Data Model & Schema Considerations: The archive uses the normal morango migrations, so its django_migrations table records its schema version.
  • Resilience & Failure Modes: Every failure after the alias registration must remove the archive alias and the partial file. Errors must propagate. A router that denies migration makes Django skip every table, record the migrations as applied, and raise no error (Spike: prove that a Django-managed archive database works #362). The table check is what detects it. Django connections are thread-local, so register, use and remove the alias on one thread.

Notes & Tradeoffs

Metadata

  • Complexity: Medium
  • Target Branch: release-v0.9.x

AI Usage

Drafted with Claude (Claude Code) from the approved design spec and implementation plan. The author reviewed the requirements, and the code references were checked against the release-v0.9.x codebase.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions