Start reconcile

This commit is contained in:
John Doty 2024-07-22 16:20:22 -07:00
parent 5a834d5d26
commit c6bd8d8556
2 changed files with 60 additions and 3 deletions

View file

@ -248,3 +248,35 @@ def unsubscribe(url):
@cli.command("serve") @cli.command("serve")
def serve(): def serve():
web.serve() web.serve()
@cli.command("reconcile")
def reconcile():
local_db = database.Database.local()
local_version = local_db.get_property("version", 0)
for p in database.databases_directory().glob("*.db"):
if not p.is_file():
continue
try:
other_db = database.Database.from_file(p)
if local_db.origin == other_db.origin:
continue
other_version = other_db.get_property("version", 0)
if other_version != local_version:
click.echo(
f"{other_db.origin}: Not reconciling version {other_version} against {local_version}"
)
continue
# TODO: GET CLOCK OF BOTH.
other_clock = other_db.get_clock()
reconciled_clock = local_db.get_reconcile_clock(other_db.origin)
if other_clock == reconciled_clock:
continue
# TODO: RECONCILE FOR REALS
except Exception as e:
click.echo(f"Error loading {p}: {e}")

View file

@ -99,6 +99,12 @@ SCHEMA_STATEMENTS = [
UPDATE properties SET value=value + 1 WHERE name='clock'; UPDATE properties SET value=value + 1 WHERE name='clock';
END; END;
""", """,
"""
CREATE TABLE reconcile_status (
origin VARCHAR NOT NULL PRIMARY KEY,
clock INT NOT NULL
);
""",
] ]
@ -129,8 +135,12 @@ def local_origin(path: pathlib.Path | None = None) -> str:
return origin return origin
def databases_directory() -> pathlib.Path:
return pathlib.Path.home() / "Dropbox" / "cry"
def database_path(origin: str) -> pathlib.Path: def database_path(origin: str) -> pathlib.Path:
return pathlib.Path.home() / "Dropbox" / "cry" / f"{origin}.db" return databases_directory() / f"{origin}.db"
# TODO: Refactor into: # TODO: Refactor into:
@ -141,13 +151,18 @@ class Database:
db: sqlite3.Connection db: sqlite3.Connection
origin: str origin: str
def __init__(self, path: pathlib.Path | str, origin: str): def __init__(self, path: pathlib.Path | str, origin: str, readonly: bool = False):
uri = False
if not isinstance(path, str): if not isinstance(path, str):
path.parent.mkdir(parents=True, exist_ok=True) path.parent.mkdir(parents=True, exist_ok=True)
path = f"file:{str(path)}"
uri = True
if readonly:
path = f"{path}?mode=ro"
# Enable autocommit as a separate step so that I can enable foreign # Enable autocommit as a separate step so that I can enable foreign
# keys cleanly. (Can't enable foreign keys in a transaction.) # keys cleanly. (Can't enable foreign keys in a transaction.)
db = sqlite3.Connection(str(path)) db = sqlite3.connect(str(path), uri=uri)
db.execute("PRAGMA foreign_keys = ON") db.execute("PRAGMA foreign_keys = ON")
db.autocommit = False db.autocommit = False
@ -165,6 +180,16 @@ class Database:
db = Database(database_path(origin), origin) db = Database(database_path(origin), origin)
db.ensure_database_schema() db.ensure_database_schema()
db.set_property("origin", origin)
return db
@classmethod
def from_file(cls, path: pathlib.Path) -> "Database":
db = Database(path, "", readonly=True)
origin = db.get_property("origin")
if origin is None:
raise Exception("No origin!")
db.origin = str(origin)
return db return db
def get_property(self, prop: str, default=None) -> typing.Any: def get_property(self, prop: str, default=None) -> typing.Any: