aboutsummaryrefslogtreecommitdiff
blob: 23821be0a5e3dbebc0c7128f99f1730df0ff0b1c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
import sys
import os
import settings as config
from django.conf import settings
os.environ["DJANGO_SETTINGS_MODULE"]="matchbox.db.settings"



from main.models import *
from django.db import reset_queries, close_connection, _rollback_on_exception

class DbIface(object):
    """
    Class representing interface to database for Matchbox

    All of these functions have to be implemented in subclasses
    for Matchbox to work correcly
    """

    def __init__(self, dbcon):
        raise NotImplementedError("DbIface is only interface, create real object for database functions")

    def add_package(self, name):
        """
        @param name: name of package to add without category or version (e.g. kdevelop)
        @type name: string

        @rtype: integer
        @returns: id of package added to database
        """
        pass

    def add_category(self, name):
        """
        @param name: name of category to add
        @type name: string

        @rtype: integer
        @returns: id of category added to database
        """
        pass

    def add_package_version(self, package_id, category_id, version):
        """
        @param package_id: id of row in package table
        @type package_id: integer
        @param category_id: id of row in category table
        @type category_id: integer
        @param version: version string to add (including revision)
        @type version: string

        @rtype: integer
        @returns: id of package version added
        """
        pass

    def add_dependency(self, packageversion_id, dependency_id):
        """
        Adds dependency that package was compiled with

        @param packageversion_id: id of row in packageversion table
        @type packageversion_id: integer
        @param dependency_id: id of row in packageversion table
        @type dependency_id: integer
        """
        pass

    def add_package_info(self, pi):
        """
        @param pi: package info to add to database
        @type pi: protocol.PackageInfo

        @rtype: integer
        @returns: id of package info added to database
        """
        pass

    def add_tinderbox(self, ip):
        """
        @param ip: ip address of tinderbox slave
        @type ip: string in form of xxx.xxx.xxx.xxx
        """
        pass

    def add_attachment(self, packageproperties_id, name, content, mimetype):
        """
        @param packageproperties_id: id of row in packageproperties table
        @type packageproperties_id: integer
        @param name: name of attachment (usually filename)
        @type name: string
        @param content: data of attachment
        @type content: string blob
        @param mimetype: mime-type of attachment (e.g. text/html, text/plain etc)
        @type mimetype: string
        """
        pass

    def add_portage_profile(self, name):
        """
        @param name: name of portage profile to add
        @type name: string

        @rtype: integer
        @returns: row id of profile added to database
        """
        pass


    def add_useflag(self, name):
        """
        @param name: name of use flag to add
        @type name: string

        @rtype: integer
        @returns: row id of use flag added to database
        """
        pass

    def add_packageproperties(self, packageversion_id, profile_id, tinderbox_id, error_code):
        """

        @param packageversion_id: id of row in packageversion table
        @type packageversion_id: integer
        @param profile_id: id of row in portageprofile table
        @type profile_id: integer
        @param tinderbox_id: id of row in tinderbox_id
        @type tinderbox_id: integer
        @param error_code: error code for this compile try
        @type error_code: integer

        @returns: row id of packageproperties added to database
        @rtype: integer
        """
        pass

    def add_useflags_to_packageproperies(self, packageproperties_id, useflag_ids):
        """
        @param packageproperties_id: id of row in packageproperies table
        @type packageproperties_id: integer
        @param useflag_ids: list of row ids in useflag table
        @type useflag_ids: list
        """
        pass

    def add_contents_to_packageproperties(self, packageproperties_id, contents):
        """
        @param packageproperties_id: id of row in packageproperties table
        @type packageproperties_id: integer
        @param contents: dict of files in packageproperties (path is key, value is list of information about path)
                         see dblink.getcontents() for more info
        @type contents: dict
        """
        pass

class DjangoDB(object):

    def dbquery(f):
        def newfunc(*args, **kwargs):
            reset_queries()
            try:
                return f(*args, **kwargs)
            except Exception, e:
                _rollback_on_exception()
                raise e
        return newfunc

    @dbquery
    def add_package(self, name):
        p = Package.objects.filter(name=name)
        if len(p) > 0:
            return p[0].id
        p = Package(name=name)
        p.save()
        return p.id


    @dbquery
    def add_category(self, name):
        c = PackageCategory.objects.filter(name=name)
        if len(c) > 0:
            return c[0].id
        c = PackageCategory(name=name)
        c.save()
        return c.id

    @dbquery
    def add_package_version(self, package_id, category_id, version):
        p = Package.objects.get(pk=package_id)
        c = PackageCategory.objects.get(pk=category_id)

        v = PackageVersion.objects.filter(version=version, category=c, package=p)
        if len(v) > 0:
            return v[0].id
        v = PackageVersion(version=version, package=p, category=c)
        v.save()
        return v.id

    @dbquery
    def get_package_version(self, package_id, category_id, version):
        p = Package.objects.get(pk=package_id)
        c = PackageCategory.objects.get(pk=category_id)

        v = PackageVersion.objects.filter(version=version, category=c, package=p)
        if len(v) > 0:
            return v[0].id
        return None

    @dbquery
    def add_dependency(self, packageversion_id, dependency_id):
        p = Package.objects.get(pk=packageversion_id)
        dep = Package.objects.get(pk=dependency_id)
        p.dependencies.add(dep)

    @dbquery
    def add_tinderbox(self, ip):
        t = Tinderbox.objects.filter(ip=ip)
        if len(t) > 0:
            return t[0].id

        t = Tinderbox(ip=ip)
        t.save()
        return t.id

    @dbquery
    def add_attachment(self, packageproperties_id, name, content, mimetype):
        pp = PackageProperties.objects.get(pk=packageproperties_id)

        attachments = Attachment.objects.filter(packageproperties=pp, name=name)
        if len(attachments) > 0:
            return attachments[0].id

        a = Attachment(packageproperties=pp, name=name, content=content, mimetype=mimetype)
        a.save()
        return a.id

    @dbquery
    def add_portage_profile(self, name):
        pp = PortageProfile.objects.filter(name=name)
        if len(pp) > 0:
            return pp[0].id
        pp = PortageProfile(name=name)
        pp.save()
        return pp.id

    @dbquery
    def add_useflag(self, name):
        u = Useflag.objects.filter(name=name)
        if len(u) > 0:
            return u[0].id
        u = Useflag(name=name)
        u.save()
        return u.id

    @dbquery
    def add_packageproperties(self, packageversion_id, profile_id, tinderbox_id, error_code):
        pv = PackageVersion.objects.get(pk=packageversion_id)
        profile = PortageProfile.objects.get(pk=profile_id)
        tinderbox = Tinderbox.objects.get(pk=tinderbox_id)

        pp = PackageProperties(packageversion=pv,
                               profile=profile,
                               tinderbox=tinderbox,
                               error_code=error_code)
        pp.save()

    @dbquery
    def add_useflags_to_packageproperies(self, packageproperties_id, useflag_ids):
        pp = PackageProperties.objects.get(pk=packageproperties_id)
        pp.useflags.clear()
        for id in useflag_ids:
            useflag = Useflag.objects.get(pk=id)
            pp.useflags.add(useflag)
        pp.save()

    @dbquery
    def add_contents_to_packageproperties(self, packageproperties_id, contents):
        pp = PackageProperties.objects.get(pk=packageproperties_id)

        for path in contents.keys():
            type = contents[path][0]
            file = File.objects.filter(path=path)
            if len(file) == 0:
                file = File(path=path)
                file.save()
            else:
                file = file[0]

            filetype = FileType.objects.filter(name=type)
            if len(filetype) == 0:
                raise DatabaseError ("Database not initialized from fixtures!!\nFile type loading failed (for type %s)" % type)
            filetype = filetype[0]
            hash = None
            size = None
            if type == 'obj':
                hash = contents[path][1]
                size = contents[path][2]

            ppf = PackageProperties_File(file=file,
                                         filetype=filetype,
                                         packageproperties=pp,
                                         hash=hash,
                                         size=size)
            ppf.save()