1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """
17 (Very partial) support for builds in the database
18 """
19
20 from twisted.internet import reactor
21 from buildbot.db import base
22 from buildbot.util import epoch2datetime
23
25 """
26 A DBConnectorComponent to handle a little bit of information about builds.
27 Avaialble at C{master.db.buildrequests}.
28
29 NOTE: The interface for this module will change - the builds table
30 duplicates some information available in pickles, without including all
31 such information. Do not depend on this API.
32
33 Note that a single build may be represented in many rows in the builds
34 table, as it the builds table represents
35
36 Builds are represented as dictionaries with keys C{bid} (the build ID,
37 globally unique), C{number} (the build number, unique only within this
38 master and builder), C{brid} (the ID of the build request that caused this
39 build), C{start_time}, and C{finish_time} (datetime objects, or None).
40 """
41
43 """
44 Get a single build, in the format described above. Returns
45 C{None} if there is no such build.
46
47 @param bid: build id
48 @type bid: integer
49
50 @returns: Build dictionary as above or None, via Deferred
51 """
52 def thd(conn):
53 tbl = self.db.model.builds
54 res = conn.execute(tbl.select(whereclause=(tbl.c.id == bid)))
55 row = res.fetchone()
56
57 rv = None
58 if row:
59 rv = self._bdictFromRow(row)
60 res.close()
61 return rv
62 return self.db.pool.do(thd)
63
65 """
66 Get a list of builds for the given build request. The resulting
67 build dictionaries are in exactly the same format as for L{getBuild}.
68
69 @param brids: list of build request ids
70
71 @returns: List of build dictionaries as above, via Deferred
72 """
73 def thd(conn):
74 tbl = self.db.model.builds
75 q = tbl.select(whereclause=(tbl.c.brid == brid))
76 res = conn.execute(q)
77 return [ self._bdictFromRow(row) for row in res.fetchall() ]
78 return self.db.pool.do(thd)
79
81 """
82 Add a new build, recorded as having started now.
83
84 @param brid: build request id
85 @param number: build number
86
87 @param _reactor: reactor to use (for testing)
88 @param _race_hook: hook for testing
89
90 @returns: build ID via Deferred
91 """
92
93 def thd(conn):
94 start_time = _reactor.seconds()
95 r = conn.execute(self.db.model.builds.insert(),
96 dict(number=number, brid=brid, start_time=start_time,
97 finish_time=None))
98 return r.inserted_primary_key[0]
99 return self.db.pool.do(thd)
100
102 """
103
104 Mark builds as finished, with C{finish_time} now. This is done
105 unconditionally, even if the builds are already finished.
106
107 @param bids: build ids
108 @type bids: list
109
110 @param _reactor: reactor to use (for testing)
111
112 @returns: Deferred
113 """
114 def thd(conn):
115 tbl = self.db.model.builds
116 now = _reactor.seconds()
117
118
119
120 remaining = bids
121 while remaining:
122 batch, remaining = remaining[:100], remaining[100:]
123 q = tbl.update(whereclause=(tbl.c.id.in_(batch)))
124 conn.execute(q, finish_time=now)
125 return self.db.pool.do(thd)
126
128 def mkdt(epoch):
129 if epoch:
130 return epoch2datetime(epoch)
131
132 return dict(
133 bid=row.id,
134 brid=row.brid,
135 number=row.number,
136 start_time=mkdt(row.start_time),
137 finish_time=mkdt(row.finish_time))
138