"""Builds a seed database using table definitions taken from the app (4.53).""" import sqlite3 import zipfile from pathlib import Path _ID = '"ID" TEXT PRIMARY KEY NOT NULL UNIQUE, "Timestamp" REAL DEFAULT 0' _ACTIVITY = f'{_ID}, "Time" REAL NOT NULL, "Note" TEXT, "HasPicture" INTEGER' SCHEMA = f""" CREATE TABLE "Baby" ({_ID}, "Name" TEXT NOT NULL UNIQUE, "DOB" REAL, "DueDay" REAL, "Gender" INTEGER, "Picture" TEXT); CREATE TABLE "MergedTransaction" ("DeviceID" TEXT PRIMARY KEY NOT NULL UNIQUE, "SyncID" INTEGER); CREATE TABLE "Diaper" ({_ACTIVITY}, "BabyID" TEXT NOT NULL, "Status" INTEGER NOT NULL, "PeeColor" INTEGER DEFAULT 5, "PooColor" INTEGER DEFAULT 5, "Amount" INTEGER DEFAULT 5, "Texture" INTEGER DEFAULT 5, "Flag" INTEGER DEFAULT 0); CREATE TABLE "Sleep" ({_ACTIVITY}, "BabyID" TEXT NOT NULL, "Duration" INTEGER DEFAULT 0, "LocationID" TEXT, "DescID" TEXT); CREATE TABLE "Formula" ({_ACTIVITY}, "BabyID" TEXT NOT NULL, "DescID" TEXT, "Amount" REAL NOT NULL, "IsEnglishScale" INTEGER NOT NULL); CREATE TABLE "Pumped" ({_ACTIVITY}, "BabyID" TEXT NOT NULL, "DescID" TEXT, "Amount" REAL NOT NULL, "IsEnglishScale" INTEGER NOT NULL, "PumpID" TEXT); CREATE TABLE "Nursing" ({_ACTIVITY}, "BabyID" TEXT NOT NULL, "DescID" TEXT, "FinishSide" INTEGER, "LeftDuration" INTEGER DEFAULT 0, "RightDuration" INTEGER DEFAULT 0, "BothDuration" INTEGER DEFAULT 0); CREATE TABLE "Temperature" ({_ACTIVITY}, "BabyID" TEXT NOT NULL, "Temp" REAL NOT NULL, "IsEnglishScale" INTEGER NOT NULL); CREATE TABLE "Growth" ({_ACTIVITY}, "BabyID" TEXT NOT NULL, "Weight" REAL DEFAULT 0, "Length" REAL DEFAULT 0, "Head" READ DEFAULT 0, "IsEnglishLengthScale" INTEGER DEFAULT 1, "IsEnglishWeightScale" INTEGER DEFAULT 1); CREATE TABLE "Medicine" ({_ACTIVITY}, "BabyID" TEXT NOT NULL, "MedID" TEXT NOT NULL, "Amount" REAL); CREATE TABLE "MedicineSelection" ({_ID}, "Name" TEXT NOT NULL UNIQUE, "Description" TEXT, "IsPrescription" INTEGER, "AmountPerTime" REAL, "Unit" TEXT, "Interval" INTEGER); CREATE TABLE "Pump" ({_ACTIVITY}, "FinishSide" INTEGER, "Sides" INTEGER, "Amount" REAL, "IsEnglishScale" INTEGER, "Label" TEXT, "PumpedID" TEXT); CREATE TABLE "Sick" ({_ACTIVITY}, "BabyID" TEXT NOT NULL, "Symptom" TEXT); """ BABY_ID = "baby-1" def build_seed_db(path: Path, now: float) -> Path: """Write a database with one baby, Sam, whose entries are relative to ``now``.""" connection = sqlite3.connect(path) connection.executescript(SCHEMA) connection.execute( 'INSERT INTO "Baby" VALUES (?, ?, ?, ?, ?, ?, ?)', (BABY_ID, now - 86400, "Sam", now - 90 * 86400, 0, 1, None) ) connection.execute('INSERT INTO "MergedTransaction" VALUES (?, ?)', ("phone", 3)) hour = 3600 rows = { '"Diaper" ("ID","Timestamp","Time","Note","BabyID","Status","Amount")': [ ("d-old", now, now - 40 * hour, "", BABY_ID, 0, 2), ("d-dry", now, now - 2 * hour, "", BABY_ID, 0, 0), ("d-new", now, now - 60, "messy", BABY_ID, 1, 3), ], '"Sleep" ("ID","Timestamp","Time","BabyID","Duration")': [("s-1", now, now - 3 * hour, BABY_ID, 45)], '"Formula" ("ID","Timestamp","Time","BabyID","Amount","IsEnglishScale")': [ ("f-oz", now, now - 120, BABY_ID, 4, 1), ("f-ml", now, now - 180, BABY_ID, 100, 0), ], '"Nursing" ("ID","Timestamp","Time","BabyID","FinishSide","LeftDuration","RightDuration")': [ ("n-1", now, now - 5 * hour, BABY_ID, 2, 5, 7) ], '"Temperature" ("ID","Timestamp","Time","BabyID","Temp","IsEnglishScale")': [ ("t-1", now, now - 6 * hour, BABY_ID, 98.6, 1) ], '"Growth" ("ID","Timestamp","Time","BabyID","Weight","Length","Head","IsEnglishLengthScale","IsEnglishWeightScale")': [ ("g-old", now, now - 50 * hour, BABY_ID, 5.5, 60, 40, 0, 0), ("g-new", now, now - 7 * hour, BABY_ID, 13.2277, 0, 0, 1, 1), ], '"MedicineSelection" ("ID","Timestamp","Name")': [("med-1", now, "Vitamin D")], '"Medicine" ("ID","Timestamp","Time","BabyID","MedID","Amount")': [("m-1", now, now - 8 * hour, BABY_ID, "med-1", 1)], '"Pump" ("ID","Timestamp","Time","Amount","IsEnglishScale")': [("p-1", now, now - 9 * hour, 80, 0)], '"Sick" ("ID","Timestamp","Time","BabyID","Symptom")': [("k-1", now, now - 10 * hour, BABY_ID, "cough")], } for target, values in rows.items(): marks = ",".join("?" * len(values[0])) connection.executemany(f"INSERT INTO {target} VALUES ({marks})", values) connection.commit() connection.close() return path def build_seed_zip(folder: Path, now: float) -> bytes: db = build_seed_db(folder / "fixture.db", now) zip_path = folder / "fixture.zip" with zipfile.ZipFile(zip_path, "w") as archive: archive.write(db, "EasyLog.db") return zip_path.read_bytes()