1 |
commit: 3c76d3040d63aaaa34905be0c486c8e28ae455e1 |
2 |
Author: Slava Bacherikov <slava <AT> bacher09 <DOT> org> |
3 |
AuthorDate: Thu Jun 28 15:34:34 2012 +0000 |
4 |
Commit: Slava Bacherikov <slava <AT> bacherikov <DOT> org <DOT> ua> |
5 |
CommitDate: Thu Jun 28 15:34:34 2012 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/gentoo-packages.git;a=commit;h=3c76d304 |
7 |
|
8 |
Add prefetch keywords for packages manager |
9 |
|
10 |
--- |
11 |
gpackages/apps/packages/managers.py | 48 ++++++++++++++++++++++++++++------ |
12 |
gpackages/apps/packages/models.py | 9 +++++- |
13 |
gpackages/apps/packages/views.py | 4 +- |
14 |
3 files changed, 48 insertions(+), 13 deletions(-) |
15 |
|
16 |
diff --git a/gpackages/apps/packages/managers.py b/gpackages/apps/packages/managers.py |
17 |
index 012b40d..cfe0166 100644 |
18 |
--- a/gpackages/apps/packages/managers.py |
19 |
+++ b/gpackages/apps/packages/managers.py |
20 |
@@ -4,6 +4,8 @@ from package_info.abstract import AbstarctPackage, AbstractEbuild, \ |
21 |
import packages.models |
22 |
from package_info.generic import get_from_kwargs_and_del |
23 |
from collections import defaultdict |
24 |
+from prefetch import PrefetchManagerMixin, PrefetchManager, PrefetchQuerySet, \ |
25 |
+ Prefetcher, P |
26 |
|
27 |
def _gen_query_and_manager(MixinClass, QueryClassName, ManagerClassName): |
28 |
QueryClass = type(QueryClassName, (MixinClass, models.query.QuerySet), {}) |
29 |
@@ -23,6 +25,19 @@ def _gen_all_query_and_manager(mixin_name, name_for_query, name_for_manager, *ar |
30 |
q, m = _gen_query_and_manager(arg, q_name, m_name) |
31 |
globals()[q_name], globals()[m_name] = q, m |
32 |
|
33 |
+class EbuildsWithKeywrods(Prefetcher): |
34 |
+ def __init__(self, keywords): |
35 |
+ self.keywords = keywords |
36 |
+ |
37 |
+ def filter(self, ids): |
38 |
+ return packages.models.EbuildModel.objects.filter(package__in = ids).order_by('-version', '-revision').prefetch_with_keywords(self.keywords) |
39 |
+ |
40 |
+ def reverse_mapper(self, ebuild): |
41 |
+ return [ebuild.package_id] |
42 |
+ |
43 |
+ def decorator(self, package, ebuilds = ()): |
44 |
+ setattr(package, 'ebuilds', ebuilds) |
45 |
+ |
46 |
|
47 |
class PackageMixin(object): |
48 |
def get(self, package = None, *args, **kwargs): |
49 |
@@ -54,6 +69,16 @@ class PackageMixin(object): |
50 |
|
51 |
return super(PackageMixin, self).filter(**kwargs) |
52 |
|
53 |
+class PackageQuerySet(PackageMixin, PrefetchQuerySet): |
54 |
+ def prefetch_keywords(self, arch_list): |
55 |
+ return self.prefetch(P('ebuilds', keywords = arch_list)) |
56 |
+ |
57 |
+class PackageManager(PackageMixin, PrefetchManagerMixin): |
58 |
+ @classmethod |
59 |
+ def get_query_set_class(cls): |
60 |
+ return PackageQuerySet |
61 |
+ |
62 |
+ prefetch_definitions = {'ebuilds': EbuildsWithKeywrods} |
63 |
|
64 |
class KeywordMixin(object):#{{{ |
65 |
def get_or_create(self, keyword=None, **kwargs): |
66 |
@@ -68,7 +93,7 @@ class KeywordMixin(object):#{{{ |
67 |
return super(KeywordMixin, self).get_or_create(**kwargs)#}}} |
68 |
|
69 |
|
70 |
-class EbuildMixin(object):#{{{ |
71 |
+class EbuildMixin(object): |
72 |
|
73 |
def get(self, ebuild=None, package = None, *args, **kwargs): |
74 |
if ebuild is not None and isinstance(ebuild, AbstractEbuild): |
75 |
@@ -80,13 +105,15 @@ class EbuildMixin(object):#{{{ |
76 |
kwargs.update({'package': package}) |
77 |
kwargs.update({ 'version': ebuild.version, |
78 |
'revision': ebuild.revision }) |
79 |
- return super(EbuildMixin, self).get(*args, **kwargs)#}}} |
80 |
+ return super(EbuildMixin, self).get(*args, **kwargs) |
81 |
|
82 |
def all_by_numbers(self): |
83 |
return super(EbuildMixin, self).order_by('version', 'revision') |
84 |
|
85 |
+class EbuildQuerySet(EbuildMixin, models.query.QuerySet): |
86 |
+ |
87 |
def __init__(self, *args, **kwargs): |
88 |
- super(EbuildMixin, self).__init__(*args, **kwargs) |
89 |
+ super(EbuildQuerySet, self).__init__(*args, **kwargs) |
90 |
self._arches_set = None |
91 |
self._cache_keywords = None |
92 |
|
93 |
@@ -98,18 +125,19 @@ class EbuildMixin(object):#{{{ |
94 |
return self |
95 |
|
96 |
def __old_iter__(self): |
97 |
- return super(EbuildMixin, self).__iter__() |
98 |
+ return super(EbuildQuerySet, self).__iter__() |
99 |
|
100 |
def _clone(self, *args, **kwargs): |
101 |
- c = super(EbuildMixin, self)._clone(*args, **kwargs) |
102 |
+ c = super(EbuildQuerySet, self)._clone(*args, **kwargs) |
103 |
c._arches_set = self._arches_set |
104 |
return c |
105 |
|
106 |
def _prefetch_keywords(self): |
107 |
arch_set = self._arches_set |
108 |
pk_keys = [ebuild.pk for ebuild in self.__old_iter__()] |
109 |
- query = packages.models.Keyword.objects.filter(ebuild__in = pk_keys, |
110 |
- arch__name__in = arch_set).select_related('arch') |
111 |
+ query = packages.models.Keyword.objects.\ |
112 |
+ filter(ebuild__in = pk_keys, arch__name__in = arch_set). \ |
113 |
+ select_related('arch') |
114 |
|
115 |
cache_query = defaultdict(list) |
116 |
for keyword in query: |
117 |
@@ -132,7 +160,9 @@ class EbuildMixin(object):#{{{ |
118 |
ebuild._prefetched_keywords = cache_query[ebuild.pk] |
119 |
yield ebuild |
120 |
|
121 |
- |
122 |
+class EbuildManager(EbuildMixin, models.Manager): |
123 |
+ def get_query_set(self): |
124 |
+ return EbuildQuerySet(self.model, using = self._db) |
125 |
|
126 |
class HerdsMixin(object):#{{{ |
127 |
def filter(self, *args, **kwargs): |
128 |
@@ -174,6 +204,6 @@ class RepositoryMixin(object): |
129 |
|
130 |
|
131 |
_gen_all_query_and_manager('Mixin', 'QuerySet', 'Manager', |
132 |
- PackageMixin, KeywordMixin, EbuildMixin, HerdsMixin, |
133 |
+ KeywordMixin, HerdsMixin, |
134 |
MaintainerMixin, VirtualPackageMixin, |
135 |
RepositoryMixin) |
136 |
|
137 |
diff --git a/gpackages/apps/packages/models.py b/gpackages/apps/packages/models.py |
138 |
index caa7156..aa7bd65 100644 |
139 |
--- a/gpackages/apps/packages/models.py |
140 |
+++ b/gpackages/apps/packages/models.py |
141 |
@@ -12,6 +12,7 @@ from django.core.exceptions import ValidationError |
142 |
|
143 |
validate_url = URLValidator() |
144 |
|
145 |
+ |
146 |
class AbstractDateTimeModel(models.Model): |
147 |
created_datetime = models.DateTimeField(auto_now_add = True) |
148 |
updated_datetime = models.DateTimeField(auto_now = True) |
149 |
@@ -308,8 +309,12 @@ class PackageModel(AbstractDateTimeModel): |
150 |
|
151 |
def get_ebuilds_and_keywords(self, arch_list): |
152 |
l = [] |
153 |
- for ebuild in self.ebuildmodel_set.order_by('-version', '-revision'): |
154 |
- l.extend(ebuild.get_ebuilds_and_keywords(arch_list)) |
155 |
+ if not hasattr(self, 'ebuilds'): |
156 |
+ for ebuild in self.ebuildmodel_set.order_by('-version', '-revision'): |
157 |
+ l.extend(ebuild.get_ebuilds_and_keywords(arch_list)) |
158 |
+ else: |
159 |
+ for ebuild in self.ebuilds: |
160 |
+ l.extend(ebuild.get_ebuilds_and_keywords(arch_list)) |
161 |
return l |
162 |
|
163 |
class Meta: |
164 |
|
165 |
diff --git a/gpackages/apps/packages/views.py b/gpackages/apps/packages/views.py |
166 |
index 16c74e2..21fa07c 100644 |
167 |
--- a/gpackages/apps/packages/views.py |
168 |
+++ b/gpackages/apps/packages/views.py |
169 |
@@ -52,5 +52,5 @@ class PackagesListsView(ContextListView): |
170 |
template_name = 'packages.html' |
171 |
context_object_name = 'packages' |
172 |
queryset = PackageModel.objects.all(). \ |
173 |
- select_related('virtual_package', 'virtual_package__category') |
174 |
- #prefetch_related('ebuildmodel_set') |
175 |
+ select_related('virtual_package', 'virtual_package__category'). \ |
176 |
+ prefetch_keywords(arches) |