Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions server/mergin/sync/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -725,21 +725,29 @@ def diffs_chain(
)
# file never existed prior that version
if not latest_change:
logging.warning(f"File {file_id} never existed prior version {version}")
return None, []

# the last update to file was a delete
if latest_change.change == PushChangeType.DELETE.value:
logging.warning(
f"File {file_id} latest change prior version {version} was delete"
)
return None, []

# the last update to file was a create / force update
if latest_change.change in (
PushChangeType.CREATE.value,
PushChangeType.UPDATE.value,
):
logging.warning(
f"File {file_id} latest change prior version {version} was {latest_change.change}"
)
return latest_change, []

basefile = cls.get_basefile(file_id, version)
if not basefile:
logging.warning(f"File {file_id} has no basefile prior version {version}")
return None, []

diffs = []
Expand Down Expand Up @@ -782,9 +790,16 @@ def diffs_chain(
.order_by(FileDiff.version)
.all()
)
logging.info(
f"File {file_id} checkpoint {item.end} of rank {item.rank} missing, "
f"replacing with {len(individual_diffs)} diffs"
)
diffs.extend(individual_diffs)
else:
# we asked for individual diff but there is no such diff as there was not change at that version
logging.warning(
f"File {file_id} checkpoint {item.end} of rank {item.rank} missing as there was no data change"
)
continue

return basefile, diffs
Expand Down
7 changes: 6 additions & 1 deletion server/mergin/sync/public_api_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,12 +337,17 @@ def download_project_file(
else:
file_path = fh.location

abs_path = os.path.join(project.storage.project_dir, file_path)

if version and not diff:
logging.info(f"Restoring {namespace}/{project_name}/{file} at {version}")
project.storage.restore_versioned_file(
file, ProjectVersion.from_v_name(version)
)
if not os.path.exists(abs_path):
logging.error(f"Could not restore {namespace}/{project_name}/{file_path}")
abort(404)

abs_path = os.path.join(project.storage.project_dir, file_path)
# check file exists (e.g. there might have been issue with restore)
if not os.path.exists(abs_path):
logging.error(f"Missing file {namespace}/{project_name}/{file_path}")
Expand Down
17 changes: 13 additions & 4 deletions server/mergin/sync/storages/disk.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,22 +375,28 @@ def restore_versioned_file(self, file: str, version: int):
)

if not is_versioned_file(file):
logging.warning(f"File {file} is not gpkg file")
return

# if project version is not found, return it
project_version = ProjectVersion.query.filter_by(
project_id=self.project.id, name=version
).first()
if not project_version:
logging.warning(f"Project version {version} for file {file} not found")
return

# check actual file from the version files
file_found = next((i for i in project_version.files if i.path == file), None)

# check the location that we found on the file
if not file_found or os.path.exists(
os.path.join(self.project_dir, file_found.location)
):
# check the file is found in files at particular version
if not file_found:
logging.warning(f"File {file} not found in version {version}")
return

# check if file already exists
if os.path.exists(os.path.join(self.project_dir, file_found.location)):
logging.info(f"File {file} already exists at {version}")
return

file_id = (
Expand All @@ -401,6 +407,9 @@ def restore_versioned_file(self, file: str, version: int):

base_meta, diffs = FileHistory.diffs_chain(file_id, version)
if not (base_meta and diffs):
logging.warning(
f"File {file} at version {version} does not have basefile or there are no diffs"
)
return

start = time.time()
Expand Down
Loading