]> git.ipfire.org Git - people/jschlag/pbs.git/blame - src/buildservice/repository.py
Remove useless indices from packages table
[people/jschlag/pbs.git] / src / buildservice / repository.py
CommitLineData
9137135a
MT
1#!/usr/bin/python
2
f6e6ff79
MT
3import os.path
4
2c909128
MT
5from . import base
6from . import logs
9137135a 7
e459cbba
MT
8from .decorators import *
9
9137135a 10class Repositories(base.Object):
e459cbba
MT
11 def _get_repository(self, query, *args):
12 res = self.db.get(query, *args)
9137135a 13
e459cbba
MT
14 if res:
15 return Repository(self.backend, res.id, data=res)
9137135a 16
e459cbba
MT
17 def _get_repositories(self, query, *args):
18 res = self.db.query(query, *args)
19
20 for row in res:
21 yield Repository(self.backend, row.id, data=row)
22
23 def __iter__(self):
24 repositories = self._get_repositories("SELECT * FROM repositories \
25 ORDER BY distro_id, name")
9137135a 26
e459cbba
MT
27 return iter(repositories)
28
29 def get_by_id(self, repo_id):
30 return self._get_repository("SELECT * FROM repositories \
31 WHERE id = %s", repo_id)
9137135a
MT
32
33 def get_needs_update(self, limit=None):
34 query = "SELECT id FROM repositories WHERE needs_update = 'Y'"
35 query += " ORDER BY last_update ASC"
36
37 # Append limit if any
38 if limit:
39 query += " LIMIT %d" % limit
40
41 repos = self.db.query(query)
42
43 return [Repository(self.pakfire, r.id) for r in repos]
44
f6e6ff79
MT
45 def get_history(self, limit=None, offset=None, build=None, repo=None, user=None):
46 query = "SELECT * FROM repositories_history"
47 args = []
9137135a 48
f6e6ff79 49 query += " ORDER BY time DESC"
9137135a 50
f6e6ff79
MT
51 if limit:
52 if offset:
53 query += " LIMIT %s,%s"
54 args += [offset, limit,]
55 else:
56 query += " LIMIT %s"
57 args += [limit,]
9137135a 58
f6e6ff79
MT
59 entries = []
60 for entry in self.db.query(query, *args):
61 entry = logs.RepositoryLogEntry(self.pakfire, entry)
62 entries.append(entry)
9137135a 63
f6e6ff79 64 return entries
9137135a
MT
65
66
67class Repository(base.Object):
9fa1787c 68 def __init__(self, pakfire, id, data=None):
9137135a
MT
69 base.Object.__init__(self, pakfire)
70 self.id = id
71
f6e6ff79 72 # Cache.
9fa1787c 73 self._data = data
f6e6ff79
MT
74 self._next = None
75 self._prev = None
76 self._key = None
77 self._distro = None
78
79 @property
80 def data(self):
81 if self._data is None:
9fa1787c 82 self._data = self.db.get("SELECT * FROM repositories WHERE id = %s", self.id)
f6e6ff79
MT
83
84 return self._data
9137135a
MT
85
86 def __cmp__(self, other):
f6e6ff79
MT
87 if other is None:
88 return 1
89
90 if self.id == other.id:
9137135a
MT
91 return 0
92
f6e6ff79
MT
93 elif self.id == other.parent_id:
94 return 1
95
96 elif self.parent_id == other.id:
9137135a
MT
97 return -1
98
f6e6ff79 99 return 1
9137135a
MT
100
101 def next(self):
f6e6ff79
MT
102 if self._next is None:
103 repo = self.db.get("SELECT id FROM repositories \
104 WHERE parent_id = %s LIMIT 1", self.id)
9137135a 105
f6e6ff79
MT
106 if not repo:
107 return
9137135a 108
f6e6ff79 109 self._next = Repository(self.pakfire, repo.id)
9137135a 110
f6e6ff79
MT
111 return self._next
112
113 def prev(self):
114 if not self.parent_id:
115 return
116
117 if self._prev is None:
118 self._prev = Repository(self.pakfire, self.parent_id)
119
120 return self._prev
9137135a
MT
121
122 @property
f6e6ff79
MT
123 def parent(self):
124 return self.prev()
9137135a
MT
125
126 @classmethod
f6e6ff79 127 def create(cls, pakfire, distro, name, description):
9137135a
MT
128 id = pakfire.db.execute("INSERT INTO repositories(distro_id, name, description)"
129 " VALUES(%s, %s, %s)", distro.id, name, description)
130
131 return cls(pakfire, id)
132
e459cbba 133 @lazy_property
9137135a 134 def distro(self):
e459cbba 135 return self.backend.distros.get_by_id(self.data.distro_id)
9137135a
MT
136
137 @property
138 def info(self):
139 return {
140 "id" : self.id,
141 "distro" : self.distro.info,
142 "name" : self.name,
143 "arches" : self.arches,
144 }
145
146 @property
f6e6ff79
MT
147 def url(self):
148 url = os.path.join(
149 self.settings.get("repository_baseurl", "http://pakfire.ipfire.org/repositories/"),
150 self.distro.identifier,
151 self.identifier,
152 "%{arch}"
153 )
154
155 return url
156
157 @property
158 def mirrorlist(self):
159 url = os.path.join(
160 self.settings.get("mirrorlist_baseurl", "https://pakfire.ipfire.org/"),
161 "distro", self.distro.identifier,
162 "repo", self.identifier,
163 "mirrorlist?arch=%{arch}"
164 )
165
166 return url
167
168 def get_conf(self):
169 prioritymap = {
170 "stable" : 500,
171 "unstable" : 200,
172 "testing" : 100,
173 }
174
175 try:
176 priority = prioritymap[self.type]
177 except KeyError:
178 priority = None
179
180 lines = [
181 "[repo:%s]" % self.identifier,
182 "description = %s - %s" % (self.distro.name, self.summary),
183 "enabled = 1",
184 "baseurl = %s" % self.url,
185 "mirrors = %s" % self.mirrorlist,
186 ]
187
188 if priority:
189 lines.append("priority = %s" % priority)
190
191 return "\n".join(lines)
9137135a
MT
192
193 @property
194 def name(self):
195 return self.data.name
196
197 @property
f6e6ff79
MT
198 def identifier(self):
199 return self.name.lower()
9137135a
MT
200
201 @property
f6e6ff79
MT
202 def type(self):
203 return self.data.type
9137135a
MT
204
205 @property
f6e6ff79
MT
206 def summary(self):
207 lines = self.description.splitlines()
9137135a 208
f6e6ff79
MT
209 if lines:
210 return lines[0]
9137135a 211
f6e6ff79 212 return "N/A"
9137135a 213
f6e6ff79
MT
214 @property
215 def description(self):
216 return self.data.description or ""
9137135a 217
f6e6ff79
MT
218 @property
219 def parent_id(self):
220 return self.data.parent_id
9137135a
MT
221
222 @property
f6e6ff79
MT
223 def key(self):
224 if not self.data.key_id:
225 return
9137135a 226
f6e6ff79
MT
227 if self._key is None:
228 self._key = self.pakfire.keys.get_by_id(self.data.key_id)
229 assert self._key
9137135a 230
f6e6ff79 231 return self._key
9137135a 232
f6e6ff79
MT
233 @property
234 def arches(self):
235 return self.distro.arches
236
237 @property
238 def mirrored(self):
239 return self.data.mirrored == "Y"
9137135a 240
f6e6ff79
MT
241 def get_enabled_for_builds(self):
242 return self.data.enabled_for_builds == "Y"
9137135a 243
f6e6ff79
MT
244 def set_enabled_for_builds(self, state):
245 if state:
246 state = "Y"
247 else:
248 state = "N"
9137135a 249
f6e6ff79
MT
250 self.db.execute("UPDATE repositories SET enabled_for_builds = %s WHERE id = %s",
251 state, self.id)
9137135a 252
f6e6ff79
MT
253 if self._data:
254 self._data["enabled_for_builds"] = state
255
256 enabled_for_builds = property(get_enabled_for_builds, set_enabled_for_builds)
9137135a
MT
257
258 @property
f6e6ff79
MT
259 def score_needed(self):
260 return self.data.score_needed
9137135a
MT
261
262 @property
f6e6ff79
MT
263 def time_min(self):
264 return self.data.time_min
9137135a
MT
265
266 @property
f6e6ff79
MT
267 def time_max(self):
268 return self.data.time_max
9137135a 269
f6e6ff79
MT
270 def _log_build(self, action, build, from_repo=None, to_repo=None, user=None):
271 user_id = None
272 if user:
273 user_id = user.id
9137135a 274
f6e6ff79
MT
275 from_repo_id = None
276 if from_repo:
277 from_repo_id = from_repo.id
9137135a 278
f6e6ff79
MT
279 to_repo_id = None
280 if to_repo:
281 to_repo_id = to_repo.id
9137135a 282
f6e6ff79
MT
283 self.db.execute("INSERT INTO repositories_history(action, build_id, from_repo_id, to_repo_id, user_id, time) \
284 VALUES(%s, %s, %s, %s, %s, NOW())", action, build.id, from_repo_id, to_repo_id, user_id)
9137135a 285
f6e6ff79
MT
286 def add_build(self, build, user=None, log=True):
287 self.db.execute("INSERT INTO repositories_builds(repo_id, build_id, time_added)"
288 " VALUES(%s, %s, NOW())", self.id, build.id)
9137135a 289
f6e6ff79
MT
290 # Update bug status.
291 build._update_bugs_helper(self)
9137135a 292
f6e6ff79
MT
293 if log:
294 self._log_build("added", build, to_repo=self, user=user)
9137135a 295
f6e6ff79
MT
296 def rem_build(self, build, user=None, log=True):
297 self.db.execute("DELETE FROM repositories_builds \
298 WHERE repo_id = %s AND build_id = %s", self.id, build.id)
9137135a 299
f6e6ff79
MT
300 if log:
301 self._log_build("removed", build, from_repo=self, user=user)
9137135a 302
f6e6ff79
MT
303 def move_build(self, build, to_repo, user=None, log=True):
304 self.db.execute("UPDATE repositories_builds SET repo_id = %s, time_added = NOW() \
305 WHERE repo_id = %s AND build_id = %s", to_repo.id, self.id, build.id)
9137135a 306
f6e6ff79
MT
307 # Update bug status.
308 build._update_bugs_helper(to_repo)
9137135a 309
f6e6ff79
MT
310 if log:
311 self._log_build("moved", build, from_repo=self, to_repo=to_repo,
312 user=user)
9137135a 313
f6e6ff79
MT
314 def build_count(self):
315 query = self.db.get("SELECT COUNT(*) AS count FROM repositories_builds \
316 WHERE repo_id = %s", self.id)
9137135a 317
f6e6ff79
MT
318 if query:
319 return query.count
9137135a 320
f6e6ff79
MT
321 def get_builds(self, limit=None, offset=None):
322 query = "SELECT build_id AS id FROM repositories_builds \
323 WHERE repo_id = %s ORDER BY time_added DESC"
324 args = [self.id,]
9137135a 325
f6e6ff79
MT
326 if limit:
327 if offset:
328 query += " LIMIT %s,%s"
329 args += [offset, limit,]
330 else:
331 query += " LIMIT %s"
332 args += [limit,]
333
334 _builds = []
335 for build in self.db.query(query, *args):
2c909128 336 build = self.pakfire.builds.get_by_id(build.id)
f6e6ff79
MT
337 build._repo = self
338
339 _builds.append(build)
340
341 return _builds
342
83be3106 343 def _get_packages(self, arch):
f6e6ff79 344 if arch.name == "src":
83be3106 345 pkgs = self.db.query("SELECT packages.id AS id, packages.path AS path FROM packages \
f6e6ff79
MT
346 JOIN builds ON builds.pkg_id = packages.id \
347 JOIN repositories_builds ON builds.id = repositories_builds.build_id \
348 WHERE packages.arch = %s AND repositories_builds.repo_id = %s",
22b715d7 349 arch.name, self.id)
9137135a 350
f6e6ff79
MT
351 else:
352 noarch = self.pakfire.arches.get_by_name("noarch")
353 assert noarch
9137135a 354
83be3106 355 pkgs = self.db.query("SELECT packages.id AS id, packages.path AS path FROM packages \
f6e6ff79
MT
356 JOIN jobs_packages ON jobs_packages.pkg_id = packages.id \
357 JOIN jobs ON jobs_packages.job_id = jobs.id \
358 JOIN builds ON builds.id = jobs.build_id \
359 JOIN repositories_builds ON builds.id = repositories_builds.build_id \
22b715d7 360 WHERE (jobs.arch = %s OR jobs.arch = %s) AND \
f6e6ff79 361 repositories_builds.repo_id = %s",
22b715d7 362 arch.name, noarch.name, self.id)
9137135a 363
83be3106
MT
364 return pkgs
365
366 def get_packages(self, arch):
2c909128 367 pkgs = [self.pakfire.packages.get_by_id(p.id) for p in self._get_packages(arch)]
83be3106
MT
368 pkgs.sort()
369
370 return pkgs
371
372 def get_paths(self, arch):
373 paths = [p.path for p in self._get_packages(arch)]
374 paths.sort()
375
376 return paths
f6e6ff79
MT
377
378 @property
379 def packages(self):
380 return self.get_packages()
9137135a 381
f6e6ff79
MT
382 def get_unpushed_builds(self):
383 query = self.db.query("SELECT build_id FROM repositories_builds \
384 WHERE repo_id = %s AND \
385 time_added > (SELECT last_update FROM repositories WHERE id = %s)",
386 self.id, self.id)
387
388 ret = []
389 for row in query:
2c909128 390 b = self.pakfire.builds.get_by_id(row.build_id)
f6e6ff79
MT
391 ret.append(b)
392
393 return ret
394
395 def get_obsolete_builds(self):
396 #query = self.db.query("SELECT build_id AS id FROM repositories_builds \
397 # JOIN builds ON repositories.build_id = builds.id \
398 # WHERE repositories_builds.repo_id = %s AND builds.state = 'obsolete'",
399 # self.id)
400 #
401 #ret = []
402 #for row in query:
403 # b = builds.Build(self.pakfire, row.id)
404 # ret.append(b)
405 #
406 #return ret
407 return self.pakfire.builds.get_obsolete(self)
408
409 def needs_update(self):
410 if self.get_unpushed_builds:
9137135a
MT
411 return True
412
9137135a
MT
413 return False
414
f6e6ff79
MT
415 def updated(self):
416 self.db.execute("UPDATE repositories SET last_update = NOW() \
417 WHERE id = %s", self.id)
9137135a 418
f6e6ff79
MT
419 def get_history(self, **kwargs):
420 kwargs.update({
421 "repo" : self,
422 })
9137135a 423
f6e6ff79 424 return self.pakfire.repos.get_history(**kwargs)
9137135a 425
f6e6ff79 426 def get_build_times(self):
f6e6ff79 427 times = []
e459cbba
MT
428 for arch in self.arches:
429 time = self.db.get("SELECT SUM(jobs.time_finished - jobs.time_started) AS time FROM jobs \
f6e6ff79
MT
430 JOIN builds ON builds.id = jobs.build_id \
431 JOIN repositories_builds ON builds.id = repositories_builds.build_id \
e459cbba 432 WHERE (jobs.arch = %s OR jobs.arch = %s) AND \
a577f40c 433 jobs.type = 'build' AND \
e459cbba 434 repositories_builds.repo_id = %s", arch, "noarch", self.id)
f6e6ff79 435
e459cbba 436 times.append((arch, time.time.total_seconds()))
f6e6ff79
MT
437
438 return times
9137135a 439
9137135a 440
f6e6ff79
MT
441class RepositoryAux(base.Object):
442 def __init__(self, pakfire, id):
443 base.Object.__init__(self, pakfire)
444
445 self.id = id
446
447 # Cache.
448 self._data = None
449 self._distro = None
9137135a 450
f6e6ff79
MT
451 @property
452 def data(self):
453 if self._data is None:
454 self._data = self.db.get("SELECT * FROM repositories_aux WHERE id = %s", self.id)
455 assert self._data
456
457 return self._data
458
459 @property
460 def name(self):
461 return self.data.name
462
463 @property
464 def description(self):
465 return self.data.description or ""
466
467 @property
468 def url(self):
469 return self.data.url
470
471 @property
472 def identifier(self):
473 return self.name.lower()
474
475 @property
476 def distro(self):
477 if self._distro is None:
478 self._distro = self.pakfire.distros.get_by_id(self.data.distro_id)
479 assert self._distro
480
481 return self._distro
482
483 def get_conf(self):
484 lines = [
485 "[repo:%s]" % self.identifier,
486 "description = %s - %s" % (self.distro.name, self.name),
487 "enabled = 1",
488 "baseurl = %s" % self.url,
489 "priority = 0",
490 ]
491
492 return "\n".join(lines)