1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """
17 Support for buildsets in the database
18 """
19
20 import sqlalchemy as sa
21 from twisted.internet import reactor
22 from buildbot.util import json
23 from buildbot.db import base
24 from buildbot.util import epoch2datetime, datetime2epoch
25
28
30
31
32 - def addBuildset(self, sourcestampsetid, reason, properties, builderNames,
33 external_idstring=None, _reactor=reactor):
34 def thd(conn):
35 buildsets_tbl = self.db.model.buildsets
36 submitted_at = _reactor.seconds()
37
38 self.check_length(buildsets_tbl.c.reason, reason)
39 self.check_length(buildsets_tbl.c.external_idstring,
40 external_idstring)
41
42 transaction = conn.begin()
43
44
45 r = conn.execute(buildsets_tbl.insert(), dict(
46 sourcestampsetid=sourcestampsetid, submitted_at=submitted_at,
47 reason=reason, complete=0, complete_at=None, results=-1,
48 external_idstring=external_idstring))
49 bsid = r.inserted_primary_key[0]
50
51
52 if properties:
53 bs_props_tbl = self.db.model.buildset_properties
54
55 inserts = [
56 dict(buildsetid=bsid, property_name=k,
57 property_value=json.dumps([v,s]))
58 for k,(v,s) in properties.iteritems() ]
59 for i in inserts:
60 self.check_length(bs_props_tbl.c.property_name,
61 i['property_name'])
62 self.check_length(bs_props_tbl.c.property_value,
63 i['property_value'])
64
65 conn.execute(bs_props_tbl.insert(), inserts)
66
67
68
69
70
71 brids = {}
72 br_tbl = self.db.model.buildrequests
73 ins = br_tbl.insert()
74 for buildername in builderNames:
75 self.check_length(br_tbl.c.buildername, buildername)
76 r = conn.execute(ins,
77 dict(buildsetid=bsid, buildername=buildername, priority=0,
78 claimed_at=0, claimed_by_name=None,
79 claimed_by_incarnation=None, complete=0, results=-1,
80 submitted_at=submitted_at, complete_at=None))
81
82 brids[buildername] = r.inserted_primary_key[0]
83
84 transaction.commit()
85
86 return (bsid, brids)
87 return self.db.pool.do(thd)
88
91 if complete_at is not None:
92 complete_at = datetime2epoch(complete_at)
93 else:
94 complete_at = _reactor.seconds()
95
96 def thd(conn):
97 tbl = self.db.model.buildsets
98
99 q = tbl.update(whereclause=(
100 (tbl.c.id == bsid) &
101 ((tbl.c.complete == None) | (tbl.c.complete != 1))))
102 res = conn.execute(q,
103 complete=1,
104 results=results,
105 complete_at=complete_at)
106
107 if res.rowcount != 1:
108 raise KeyError
109 return self.db.pool.do(thd)
110
112 def thd(conn):
113 bs_tbl = self.db.model.buildsets
114 q = bs_tbl.select(whereclause=(bs_tbl.c.id == bsid))
115 res = conn.execute(q)
116 row = res.fetchone()
117 if not row:
118 return None
119 return self._row2dict(row)
120 return self.db.pool.do(thd)
121
123 def thd(conn):
124 bs_tbl = self.db.model.buildsets
125 q = bs_tbl.select()
126 if complete is not None:
127 if complete:
128 q = q.where(bs_tbl.c.complete != 0)
129 else:
130 q = q.where((bs_tbl.c.complete == 0) |
131 (bs_tbl.c.complete == None))
132 res = conn.execute(q)
133 return [ self._row2dict(row) for row in res.fetchall() ]
134 return self.db.pool.do(thd)
135
137 """
138 Return the properties for a buildset, in the same format they were
139 given to L{addBuildset}.
140
141 Note that this method does not distinguish a nonexistent buildset from
142 a buildset with no properties, and returns C{{}} in either case.
143
144 @param buildsetid: buildset ID
145
146 @returns: dictionary mapping property name to (value, source), via
147 Deferred
148 """
149 def thd(conn):
150 bsp_tbl = self.db.model.buildset_properties
151 q = sa.select(
152 [ bsp_tbl.c.property_name, bsp_tbl.c.property_value ],
153 whereclause=(bsp_tbl.c.buildsetid == buildsetid))
154 l = []
155 for row in conn.execute(q):
156 try:
157 properties = json.loads(row.property_value)
158 l.append((row.property_name,
159 tuple(properties)))
160 except ValueError:
161 pass
162 return dict(l)
163 return self.db.pool.do(thd)
164
166 def mkdt(epoch):
167 if epoch:
168 return epoch2datetime(epoch)
169 return BsDict(external_idstring=row.external_idstring,
170 reason=row.reason, sourcestampsetid=row.sourcestampsetid,
171 submitted_at=mkdt(row.submitted_at),
172 complete=bool(row.complete),
173 complete_at=mkdt(row.complete_at), results=row.results,
174 bsid=row.id)
175