0%

Eindproject: een uitleenprogramma dat gegevens bewaart · oefening

Initialiseer de catalogus expliciet

Een ontbrekend catalogusbestand mag alleen worden aangemaakt omdat iemand om init heeft gevraagd. Als available een typefout bevat of --help is gevraagd, moet het databasepad onaangeroerd blijven. lending.py heeft nu zijn eerste keuzetak en zijn eerste opdrachtfunctie nodig.

Run doet precies deze aanroep met een pad in een tijdelijke map:

database_path = temporary_directory / "catalog.db"
main(["init", str(database_path)])

Nadat argparse is geslaagd, bevat de namespace args.command == "init" en args.database == str(database_path). Voeg setup_error_is_documented(error) precies zoals getoond toe, voeg daarna init_command(args) toe en zet de expliciete tak args.command == "init" in main:

def setup_error_is_documented(error):
    message = str(error)
    if message == "Database has tables but no schema version.":
        return True
    if message.startswith("Schema version "):
        if message.endswith(" is not supported."):
            return True
        if message.endswith(" does not match the expected tables and columns."):
            return True
    return False


if args.command == "init":
    return init_command(args)

Laat het parsen boven de tak staan. Deze volgorde voorkomt dat help en parserfouten de databasevoorbereiding bereiken.

Geef binnen init_command het argument args.database door aan prepare_database. Die ene aanroep beheert de volledige compatibiliteitsmatrix al: ze maakt een ontbrekende of lege database van versie 2 aan, migreert een exacte database van versie 1, laat een exacte versie 2 ongewijzigd en weigert elke niet-ondersteunde versie of afwijking tussen markering en structuur zonder wijzigingen. Kopieer die logica niet naar lending.py.

Alleen een ValueError die door setup_error_is_documented wordt geaccepteerd, is hier een verwachte applicatieweigering. Vang ValueError op, werp die opnieuw op als de functie False teruggeeft en geef die anders door aan report_error voor één regel op stderr en status 1. Zo blijft een losstaande ValueError, OperationalError, ProgrammingError of TypeError zichtbaar met het oorspronkelijke type. Succes afdrukken voordat prepare_database terugkeert, zou niet kloppen wanneer de voorbereiding later mislukt. Druk het daarom pas daarna af:

Database ready (schema version 2).

Geef 0 terug nadat de regel is geschreven. De functie opent niet nog een verbinding alleen om de versie te inspecteren. prepare_database heeft het resultaat al gecontroleerd en de eigen voorbereidingsverbinding gesloten.

Druk op Run. demo.py roept main(["init", str(database_path)]) aan, vangt de teruggegeven status en beide uitvoerstromen op en opent het tijdelijke bestand daarna alleen lang genoeg om de opgeslagen markering te lezen:

== init ==
Status: 0
stdout: Database ready (schema version 2).
stderr: <empty>
Schema version after reopening: 2

Een grondige controle herhaalt de aanroep met ontbrekende databases, exacte versies 1 en 2 en incompatibele databases. Die veroorzaakt ook een losstaande databasefout. Verwachte compatibiliteitsmeldingen worden status 1; de losstaande fout moet zichtbaar blijven zodat je die kunt herstellen.

Opdracht

Voeg de exacte functie setup_error_is_documented(error) uit de instructies toe, voeg init_command(args) toe of maak die af en zet deze tak in main:

if args.command == "init":
    return init_command(args)

Roep prepare_database(args.database) aan. Druk bij succes Database ready (schema version 2). af en geef 0 terug. Meld alleen een ValueError die door de classificatiefunctie wordt geaccepteerd; werp elke andere opnieuw op. Maak geen database aan en open er geen voordat argparse deze opdracht heeft gekozen.