Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove some DB todos #17311

Merged
merged 3 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
12 changes: 4 additions & 8 deletions conan/internal/cache/db/cache_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ def __init__(self, filename):
self._packages.create_table()

def exists_prev(self, ref):
# TODO: This logic could be done directly against DB
matching_prevs = self.get_package_revisions_references(ref)
return len(matching_prevs) > 0
return self._packages.get_package_revisions_reference_exists(ref)

def get_latest_package_reference(self, ref):
prevs = self.get_package_revisions_references(ref, True)
Expand Down Expand Up @@ -61,11 +59,9 @@ def remove_build_id(self, pref):
self._packages.remove_build_id(pref)

def get_matching_build_id(self, ref, build_id):
# TODO: This can also be done in a single query in DB
for d in self._packages.get_package_references(ref):
existing_build_id = d["build_id"]
if existing_build_id == build_id:
return d["pref"]
result = self._packages.get_package_references_with_build_id_match(ref, build_id)
AbrilRBS marked this conversation as resolved.
Show resolved Hide resolved
if result:
return result["pref"]
return None

def get_recipe(self, ref: RecipeReference):
Expand Down
41 changes: 41 additions & 0 deletions conan/internal/cache/db/packages_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,22 @@ def get_package_revisions_references(self, pref: PkgReference, only_latest_prev=
for row in r.fetchall():
yield self._as_dict(self.row_type(*row))

def get_package_revisions_reference_exists(self, pref: PkgReference):
assert pref.ref.revision, "To check package revision existence you must provide a recipe revision."
assert pref.package_id, "To check package revisions existence you must provide a package id."
check_prev = f"AND {self.columns.prev} = '{pref.revision}' " if pref.revision else ""
query = f'SELECT 1 FROM {self.table_name} ' \
f"WHERE {self.columns.rrev} = '{pref.ref.revision}' " \
f"AND {self.columns.reference} = '{str(pref.ref)}' " \
f"AND {self.columns.pkgid} = '{pref.package_id}' " \
f'{check_prev} ' \
f'AND {self.columns.prev} IS NOT NULL ' \
'LIMIT 1 '
with self.db_connection() as conn:
r = conn.execute(query)
row = r.fetchone()
return bool(row)

def get_package_references(self, ref: RecipeReference, only_latest_prev=True):
# Return the latest revisions
assert ref.revision, "To search for package id's you must provide a recipe revision."
Expand Down Expand Up @@ -198,3 +214,28 @@ def get_package_references(self, ref: RecipeReference, only_latest_prev=True):
r = conn.execute(query)
for row in r.fetchall():
yield self._as_dict(self.row_type(*row))

def get_package_references_with_build_id_match(self, ref: RecipeReference, build_id):
# Return the latest revisions
assert ref.revision, "To search for package id's you must provide a recipe revision."
# we select the latest prev for each package_id
query = f'SELECT {self.columns.reference}, ' \
AbrilRBS marked this conversation as resolved.
Show resolved Hide resolved
f'{self.columns.rrev}, ' \
f'{self.columns.pkgid}, ' \
f'{self.columns.prev}, ' \
f'{self.columns.path}, ' \
f'MAX({self.columns.timestamp}), ' \
f'{self.columns.build_id}, ' \
f'{self.columns.lru} ' \
f'FROM {self.table_name} ' \
f"WHERE {self.columns.rrev} = '{ref.revision}' " \
f"AND {self.columns.reference} = '{str(ref)}' " \
f"AND {self.columns.build_id} = '{build_id}' " \
f'GROUP BY {self.columns.pkgid} '

with self.db_connection() as conn:
r = conn.execute(query)
row = r.fetchone()
if row:
return self._as_dict(self.row_type(*row))
return None