1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """
17 Support for creating and reading source stamps
18 """
19
20 import base64
21 from twisted.python import log
22 from buildbot.db import base
26
28 """
29 A DBConnectorComponent to handle source stamps in the database
30 """
31
32 - def addSourceStamp(self, branch, revision, repository, project,
33 patch_body=None, patch_level=0, patch_author="",
34 patch_comment="", patch_subdir=None, changeids=[]):
35 """
36 Create a new SourceStamp instance with the given attributes, and return
37 its sourcestamp ID, via a Deferred.
38 """
39 def thd(conn):
40
41 patchid = None
42 if patch_body is not None:
43 ins = self.db.model.patches.insert()
44 r = conn.execute(ins, dict(
45 patchlevel=patch_level,
46 patch_base64=base64.b64encode(patch_body),
47 patch_author=patch_author,
48 patch_comment=patch_comment,
49 subdir=patch_subdir))
50 patchid = r.inserted_primary_key[0]
51
52
53 ins = self.db.model.sourcestamps.insert()
54 r = conn.execute(ins, dict(
55 branch=branch,
56 revision=revision,
57 patchid=patchid,
58 repository=repository,
59 project=project))
60 ssid = r.inserted_primary_key[0]
61
62
63 if changeids:
64 ins = self.db.model.sourcestamp_changes.insert()
65 conn.execute(ins, [
66 dict(sourcestampid=ssid, changeid=changeid)
67 for changeid in changeids ])
68
69
70 return ssid
71 return self.db.pool.do(thd)
72
73 @base.cached("ssdicts")
75 """
76 Get a dictionary representing the given source stamp, or None if no
77 such source stamp exists.
78
79 The dictionary has keys C{ssid}, C{branch}, C{revision}, C{patch_body},
80 C{patch_level}, C{patch_subdir}, C{patch_author}, C{patch_comment},
81 C{repository}, C{project}, and C{changeids}. Most are simple strings.
82 The C{changeids} key contains a set of change IDs. The C{patch_*}
83 arguments will be C{None} if no patch is attached. The last is a set of
84 changeids for this source stamp.
85
86 @param bsid: buildset ID
87
88 @param no_cache: bypass cache and always fetch from database
89 @type no_cache: boolean
90
91 @returns: dictionary as above, or None, via Deferred
92 """
93 def thd(conn):
94 tbl = self.db.model.sourcestamps
95 q = tbl.select(whereclause=(tbl.c.id == ssid))
96 res = conn.execute(q)
97 row = res.fetchone()
98 if not row:
99 return None
100 ssdict = SsDict(ssid=ssid, branch=row.branch,
101 revision=row.revision, patch_body=None, patch_level=None,
102 patch_author=None, patch_comment=None, patch_subdir=None,
103 repository=row.repository, project=row.project,
104 changeids=set([]))
105 patchid = row.patchid
106 res.close()
107
108
109 if patchid is not None:
110 tbl = self.db.model.patches
111 q = tbl.select(whereclause=(tbl.c.id == patchid))
112 res = conn.execute(q)
113 row = res.fetchone()
114 if row:
115
116 ssdict['patch_level'] = row.patchlevel
117 ssdict['patch_subdir'] = row.subdir
118 ssdict['patch_author'] = row.patch_author
119 ssdict['patch_comment'] = row.patch_comment
120 body = base64.b64decode(row.patch_base64)
121 ssdict['patch_body'] = body
122 else:
123 log.msg('patchid %d, referenced from ssid %d, not found'
124 % (patchid, ssid))
125 res.close()
126
127
128 tbl = self.db.model.sourcestamp_changes
129 q = tbl.select(whereclause=(tbl.c.sourcestampid == ssid))
130 res = conn.execute(q)
131 for row in res:
132 ssdict['changeids'].add(row.changeid)
133 res.close()
134
135 return ssdict
136 return self.db.pool.do(thd)
137