Remote sync of webdav

This commit is contained in:
Courtney Arnold 2026-08-13 17:05:10 -05:00
parent f01186df79
commit 483fbeafb6
44 changed files with 4842 additions and 975 deletions

View file

@ -1,10 +1,8 @@
const createVehiclesTableSql = '''
CREATE TABLE vehicles (
id TEXT PRIMARY KEY,
make TEXT NOT NULL,
model TEXT NOT NULL,
color TEXT NOT NULL,
license_plate TEXT NOT NULL,
vin TEXT NOT NULL,
nickname TEXT,
updated_at INTEGER NOT NULL,
deleted_at INTEGER,
dirty INTEGER NOT NULL DEFAULT 1
@ -30,15 +28,33 @@ const createFuelEntriesTableSql = '''
const createFuelEntriesIndexSql =
'CREATE INDEX idx_fuel_entries_vehicle_id ON fuel_entries(vehicle_id)';
/// Selects fuel entries whose receipt photo still needs uploading to
/// Drive. Deliberately requires `receipt_drive_file_id IS NULL`, not just
/// "has a local path": once a row is uploaded, its local copy may still be
/// kept around (see the "keep photos on this phone" setting) — matching on
/// the local path alone would re-upload that same photo as a duplicate
/// Drive file on every subsequent sync.
const pendingReceiptUploadWhereClause = 'dirty = 1 AND receipt_image_path IS NOT NULL '
'AND receipt_drive_file_id IS NULL AND deleted_at IS NULL';
/// Merges attached `remote_db` rows into `main` (the live local database):
/// any remote row that's new to us, or newer than our copy, replaces ours.
/// Rows this doesn't touch — including our own not-yet-pushed edits — are
/// left alone, since the WHERE clause only matches rows remote should win;
/// no separate "keep local" statement is needed.
///
/// Merges on `id` (the hidden, immutable identifier), not `vin` — VIN is
/// user-editable, so it can't be relied on as a stable merge key. VIN
/// uniqueness among active vehicles is enforced at the app layer instead
/// (see `DatabaseService.vinExists`), not by a database constraint here,
/// since two devices could in principle each independently add a vehicle
/// with the same VIN while offline; that's an accepted rare-conflict edge
/// case (see the "field-level conflicts aren't merged" caveat in the
/// README) rather than something this merge statement tries to resolve.
const mergeVehiclesSql = '''
INSERT OR REPLACE INTO main.vehicles
(id, make, model, color, license_plate, updated_at, deleted_at, dirty)
SELECT r.id, r.make, r.model, r.color, r.license_plate, r.updated_at, r.deleted_at, 0
(id, vin, nickname, updated_at, deleted_at, dirty)
SELECT r.id, r.vin, r.nickname, r.updated_at, r.deleted_at, 0
FROM remote_db.vehicles r
LEFT JOIN main.vehicles l ON l.id = r.id
WHERE l.id IS NULL OR r.updated_at > l.updated_at