summaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2010-08-25 13:45:04 -0500
committerDan McGee <dan@archlinux.org>2010-08-25 13:45:04 -0500
commitae5483c230d08c65d91eb7cece106b4f13a56232 (patch)
tree95fd2c95d29da95a544e1ac110e94e363a91d179 /packages
parentebfc46026fd726222c32ed1251a4752dee88ca42 (diff)
downloadarchweb-ae5483c230d08c65d91eb7cece106b4f13a56232.tar.gz
archweb-ae5483c230d08c65d91eb7cece106b4f13a56232.zip
Package Differences by Architecture view
Implements FS#20416. Port over the architecture differences view from archlinux.de and reimplement in Django with our DB schema. Also use a far simpler SQL query to do the dirty work rather than the triple UNION operation. This is accomplished by doing a bit more of the fetching work in code once we know what packages are actually involved. Signed-off-by: Dan McGee <dan@archlinux.org>
Diffstat (limited to 'packages')
-rw-r--r--packages/views.py67
1 files changed, 67 insertions, 0 deletions
diff --git a/packages/views.py b/packages/views.py
index 277b7900..1ab4749d 100644
--- a/packages/views.py
+++ b/packages/views.py
@@ -342,4 +342,71 @@ def download(request, name='', repo='', arch=''):
url = string.Template('${host}${repo}/os/${arch}/${file}').substitute(details)
return HttpResponseRedirect(url)
+def arch_differences(request):
+ from django.db import connection
+ from operator import itemgetter
+ # This is a monster. Join packages against itself, looking for packages in
+ # our non-'any' architectures only, and not having a corresponding package
+ # entry in the other table (or having one with a different pkgver). We will
+ # then go and fetch all of these packages from the database and display
+ # them later using normal ORM models.
+ # TODO: we have some hardcoded magic here with respect to the arches.
+ arch_a = Arch.objects.get(name='i686')
+ arch_b = Arch.objects.get(name='x86_64')
+ sql = """
+SELECT p.id, q.id
+ FROM packages p
+ LEFT JOIN packages q
+ ON (
+ p.pkgname = q.pkgname
+ AND p.repo_id = q.repo_id
+ AND p.arch_id != q.arch_id
+ AND p.id != q.id
+ )
+ WHERE p.arch_id IN (%s, %s)
+ AND (
+ q.id IS NULL
+ OR
+ p.pkgver != q.pkgver
+ OR
+ p.pkgrel != q.pkgrel
+ )
+"""
+ cursor = connection.cursor()
+ cursor.execute(sql, [arch_a.id, arch_b.id])
+ results = cursor.fetchall()
+ to_fetch = []
+ for row in results:
+ # column A will always have a value, column B might be NULL
+ to_fetch.append(row[0])
+ # fetch all of the necessary packages
+ pkgs = Package.objects.in_bulk(to_fetch)
+ # now build a list of tuples containing differences
+ differences = []
+ for row in results:
+ pkg_a = pkgs.get(row[0])
+ pkg_b = pkgs.get(row[1])
+ # We want arch_a to always appear first
+ # pkg_a should never be None
+ if pkg_a.arch == arch_a:
+ item = (pkg_a.pkgname, pkg_a.repo, pkg_a, pkg_b)
+ else:
+ # pkg_b can be None in this case, so be careful
+ name = pkg_a.pkgname if pkg_a else pkg_b.pkgname
+ repo = pkg_a.repo if pkg_a else pkg_b.repo
+ item = (name, repo, pkg_b, pkg_a)
+ if item not in differences:
+ differences.append(item)
+
+ # now sort our list by repository, package name
+ differences.sort(key=lambda a: (a[1].name, a[0]))
+
+ context = {
+ 'arch_a': arch_a,
+ 'arch_b': arch_b,
+ 'differences': differences,
+ }
+ return render_to_response('packages/differences.html',
+ RequestContext(request, context))
+
# vim: set ts=4 sw=4 et: