Skip to content

Commit 1cb9eeb

Browse files
committed
Handle nullable latest_file_history_ids
This prevent missing item in project version files when list of history ids has not been cached yet.
1 parent a7aea9c commit 1cb9eeb

File tree

1 file changed

+40
-2
lines changed

1 file changed

+40
-2
lines changed

server/mergin/sync/models.py

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,36 @@ def workspace(self):
135135
project_workspace = current_app.ws_handler.get(self.workspace_id)
136136
return project_workspace
137137

138+
def get_latest_file_history_ids(self) -> List[int]:
139+
"""Get latest file history ids either from cached table or calculate them on the fly"""
140+
if self.latest_project_files.file_history_ids is not None:
141+
return self.latest_project_files.file_history_ids
142+
143+
query = f"""
144+
WITH latest_changes AS (
145+
SELECT
146+
fp.id,
147+
pv.project_id,
148+
max(pv.name) AS version
149+
FROM
150+
project_version pv
151+
LEFT OUTER JOIN file_history fh ON fh.version_id = pv.id
152+
LEFT OUTER JOIN project_file_path fp ON fp.id = fh.file_path_id
153+
WHERE
154+
pv.project_id = :project_id
155+
AND pv.name <= :latest_version
156+
GROUP BY
157+
fp.id, pv.project_id
158+
)
159+
SELECT
160+
fh.id
161+
FROM latest_changes ch
162+
LEFT OUTER JOIN file_history fh ON (fh.file_path_id = ch.id AND fh.project_version_name = ch.version AND fh.change != 'delete')
163+
WHERE fh.id IS NOT NULL;
164+
"""
165+
params = {"project_id": self.id, "latest_version": self.latest_version}
166+
return [row.id for row in db.session.execute(text(query), params).fetchall()]
167+
138168
def cache_latest_files(self) -> None:
139169
"""Get project files from changes (FileHistory) and save them for later use."""
140170
if self.latest_version is None:
@@ -514,7 +544,11 @@ def generate_diff_name(self):
514544

515545

516546
class LatestProjectFiles(db.Model):
517-
"""Store project latest version files history ids"""
547+
"""Store project latest version files history ids.
548+
549+
This is a caching table to store the latest relevant files history ids for further use in
550+
Project.files and ProjectVersion.files. It is updated when ProjectVersion itself is created.
551+
"""
518552

519553
project_id = db.Column(
520554
UUID(as_uuid=True),
@@ -1434,7 +1468,7 @@ def __init__(
14341468
latest_files_map = {
14351469
fh.path: fh.id
14361470
for fh in FileHistory.query.filter(
1437-
FileHistory.id.in_(self.project.latest_project_files.file_history_ids)
1471+
FileHistory.id.in_(self.project.get_latest_file_history_ids())
14381472
).all()
14391473
}
14401474

@@ -1565,6 +1599,10 @@ def _files_from_end(self):
15651599
files that were delete after the version (and thus not necessarily present now). From these candidates
15661600
get the latest file change before or at the specific version. If that change was not 'delete', file is present.
15671601
"""
1602+
# if we do not have cached file history ids use different strategy where it is not necessary
1603+
if self.project.latest_project_files.file_history_ids is None:
1604+
return self._files_from_start()
1605+
15681606
query = f"""
15691607
WITH files_changes_before_version AS (
15701608
WITH files_candidates AS (

0 commit comments

Comments
 (0)