1 | # -*- coding: utf-8 -*-
|
---|
2 | # $Id: dbobjcache.py 82968 2020-02-04 10:35:17Z vboxsync $
|
---|
3 |
|
---|
4 | """
|
---|
5 | Test Manager - Database object cache.
|
---|
6 | """
|
---|
7 |
|
---|
8 | __copyright__ = \
|
---|
9 | """
|
---|
10 | Copyright (C) 2012-2020 Oracle Corporation
|
---|
11 |
|
---|
12 | This file is part of VirtualBox Open Source Edition (OSE), as
|
---|
13 | available from http://www.virtualbox.org. This file is free software;
|
---|
14 | you can redistribute it and/or modify it under the terms of the GNU
|
---|
15 | General Public License (GPL) as published by the Free Software
|
---|
16 | Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
17 | VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
---|
18 | hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
---|
19 |
|
---|
20 | The contents of this file may alternatively be used under the terms
|
---|
21 | of the Common Development and Distribution License Version 1.0
|
---|
22 | (CDDL) only, as it comes in the "COPYING.CDDL" file of the
|
---|
23 | VirtualBox OSE distribution, in which case the provisions of the
|
---|
24 | CDDL are applicable instead of those of the GPL.
|
---|
25 |
|
---|
26 | You may elect to license modified versions of this file under the
|
---|
27 | terms and conditions of either the GPL or the CDDL or both.
|
---|
28 | """
|
---|
29 | __version__ = "$Revision: 82968 $"
|
---|
30 |
|
---|
31 |
|
---|
32 | # Validation Kit imports.
|
---|
33 | from testmanager.core.base import ModelLogicBase;
|
---|
34 |
|
---|
35 |
|
---|
36 | class DatabaseObjCache(ModelLogicBase):
|
---|
37 | """
|
---|
38 | Database object cache.
|
---|
39 |
|
---|
40 | This is mainly for reports and test results where we wish to get further
|
---|
41 | information on a data series or similar. The cache should reduce database
|
---|
42 | lookups as well as pyhon memory footprint.
|
---|
43 |
|
---|
44 | Note! Dependecies are imported when needed to avoid potential cylic dependency issues.
|
---|
45 | """
|
---|
46 |
|
---|
47 | ## @name Cache object types.
|
---|
48 | ## @{
|
---|
49 | ksObjType_TestResultStrTab_idStrName = 0;
|
---|
50 | ksObjType_BuildCategory_idBuildCategory = 1;
|
---|
51 | ksObjType_TestBox_idTestBox = 2;
|
---|
52 | ksObjType_TestBox_idGenTestBox = 3;
|
---|
53 | ksObjType_TestCase_idTestCase = 4;
|
---|
54 | ksObjType_TestCase_idGenTestCase = 5;
|
---|
55 | ksObjType_TestCaseArgs_idTestCaseArgs = 6;
|
---|
56 | ksObjType_TestCaseArgs_idGenTestCaseArgs = 7;
|
---|
57 | ksObjType_VcsRevision_sRepository_iRevision = 8;
|
---|
58 | ksObjType_End = 9;
|
---|
59 | ## @}
|
---|
60 |
|
---|
61 | def __init__(self, oDb, tsNow = None, sPeriodBack = None, cHoursBack = None):
|
---|
62 | ModelLogicBase.__init__(self, oDb);
|
---|
63 |
|
---|
64 | self.tsNow = tsNow;
|
---|
65 | self.sPeriodBack = sPeriodBack;
|
---|
66 | if sPeriodBack is None and cHoursBack is not None:
|
---|
67 | self.sPeriodBack = '%u hours' % cHoursBack;
|
---|
68 |
|
---|
69 | self._adCache = (
|
---|
70 | dict(), dict(), dict(), dict(),
|
---|
71 | dict(), dict(), dict(), dict(),
|
---|
72 | dict(),
|
---|
73 | );
|
---|
74 | assert(len(self._adCache) == self.ksObjType_End);
|
---|
75 |
|
---|
76 | def _handleDbException(self):
|
---|
77 | """ Deals with database exceptions. """
|
---|
78 | #self._oDb.rollback();
|
---|
79 | return False;
|
---|
80 |
|
---|
81 | def getTestResultString(self, idStrName):
|
---|
82 | """ Gets a string from the TestResultStrTab. """
|
---|
83 | sRet = self._adCache[self.ksObjType_TestResultStrTab_idStrName].get(idStrName);
|
---|
84 | if sRet is None:
|
---|
85 | # Load cache entry.
|
---|
86 | self._oDb.execute('SELECT sValue FROM TestResultStrTab WHERE idStr = %s', (idStrName,));
|
---|
87 | sRet = self._oDb.fetchOne()[0];
|
---|
88 | self._adCache[self.ksObjType_TestResultStrTab_idStrName][idStrName] = sRet
|
---|
89 | return sRet;
|
---|
90 |
|
---|
91 | def getBuildCategory(self, idBuildCategory):
|
---|
92 | """ Gets the corresponding BuildCategoryData object. """
|
---|
93 | oRet = self._adCache[self.ksObjType_BuildCategory_idBuildCategory].get(idBuildCategory);
|
---|
94 | if oRet is None:
|
---|
95 | # Load cache entry.
|
---|
96 | from testmanager.core.build import BuildCategoryData;
|
---|
97 | oRet = BuildCategoryData();
|
---|
98 | try: oRet.initFromDbWithId(self._oDb, idBuildCategory);
|
---|
99 | except: self._handleDbException(); raise;
|
---|
100 | self._adCache[self.ksObjType_BuildCategory_idBuildCategory][idBuildCategory] = oRet;
|
---|
101 | return oRet;
|
---|
102 |
|
---|
103 | def getTestBox(self, idTestBox):
|
---|
104 | """ Gets the corresponding TestBoxData object. """
|
---|
105 | oRet = self._adCache[self.ksObjType_TestBox_idTestBox].get(idTestBox);
|
---|
106 | if oRet is None:
|
---|
107 | # Load cache entry.
|
---|
108 | from testmanager.core.testbox import TestBoxData;
|
---|
109 | oRet = TestBoxData();
|
---|
110 | try: oRet.initFromDbWithId(self._oDb, idTestBox, self.tsNow, self.sPeriodBack);
|
---|
111 | except: self._handleDbException(); raise;
|
---|
112 | else: self._adCache[self.ksObjType_TestBox_idGenTestBox][oRet.idGenTestBox] = oRet;
|
---|
113 | self._adCache[self.ksObjType_TestBox_idTestBox][idTestBox] = oRet;
|
---|
114 | return oRet;
|
---|
115 |
|
---|
116 | def getTestCase(self, idTestCase):
|
---|
117 | """ Gets the corresponding TestCaseData object. """
|
---|
118 | oRet = self._adCache[self.ksObjType_TestCase_idTestCase].get(idTestCase);
|
---|
119 | if oRet is None:
|
---|
120 | # Load cache entry.
|
---|
121 | from testmanager.core.testcase import TestCaseData;
|
---|
122 | oRet = TestCaseData();
|
---|
123 | try: oRet.initFromDbWithId(self._oDb, idTestCase, self.tsNow, self.sPeriodBack);
|
---|
124 | except: self._handleDbException(); raise;
|
---|
125 | else: self._adCache[self.ksObjType_TestCase_idGenTestCase][oRet.idGenTestCase] = oRet;
|
---|
126 | self._adCache[self.ksObjType_TestCase_idTestCase][idTestCase] = oRet;
|
---|
127 | return oRet;
|
---|
128 |
|
---|
129 | def getTestCaseArgs(self, idTestCaseArgs):
|
---|
130 | """ Gets the corresponding TestCaseArgsData object. """
|
---|
131 | oRet = self._adCache[self.ksObjType_TestCaseArgs_idTestCaseArgs].get(idTestCaseArgs);
|
---|
132 | if oRet is None:
|
---|
133 | # Load cache entry.
|
---|
134 | from testmanager.core.testcaseargs import TestCaseArgsData;
|
---|
135 | oRet = TestCaseArgsData();
|
---|
136 | try: oRet.initFromDbWithId(self._oDb, idTestCaseArgs, self.tsNow, self.sPeriodBack);
|
---|
137 | except: self._handleDbException(); raise;
|
---|
138 | else: self._adCache[self.ksObjType_TestCaseArgs_idGenTestCaseArgs][oRet.idGenTestCaseArgs] = oRet;
|
---|
139 | self._adCache[self.ksObjType_TestCaseArgs_idTestCaseArgs][idTestCaseArgs] = oRet;
|
---|
140 | return oRet;
|
---|
141 |
|
---|
142 | def preloadVcsRevInfo(self, sRepository, aiRevisions):
|
---|
143 | """
|
---|
144 | Preloads VCS revision information.
|
---|
145 | ASSUMES aiRevisions does not contain duplicate keys.
|
---|
146 | """
|
---|
147 | from testmanager.core.vcsrevisions import VcsRevisionData;
|
---|
148 | dRepo = self._adCache[self.ksObjType_VcsRevision_sRepository_iRevision].get(sRepository);
|
---|
149 | if dRepo is None:
|
---|
150 | dRepo = dict();
|
---|
151 | self._adCache[self.ksObjType_VcsRevision_sRepository_iRevision][sRepository] = dRepo;
|
---|
152 | aiFiltered = aiRevisions;
|
---|
153 | else:
|
---|
154 | aiFiltered = [];
|
---|
155 | for iRevision in aiRevisions:
|
---|
156 | if iRevision not in dRepo:
|
---|
157 | aiFiltered.append(iRevision);
|
---|
158 | if aiFiltered:
|
---|
159 | self._oDb.execute('SELECT *\n'
|
---|
160 | 'FROM VcsRevisions\n'
|
---|
161 | 'WHERE sRepository = %s\n'
|
---|
162 | ' AND iRevision IN (' + ','.join([str(i) for i in aiFiltered]) + ')'
|
---|
163 | , ( sRepository, ));
|
---|
164 | for aoRow in self._oDb.fetchAll():
|
---|
165 | oInfo = VcsRevisionData().initFromDbRow(aoRow);
|
---|
166 | dRepo[oInfo.iRevision] = oInfo;
|
---|
167 | return True;
|
---|
168 |
|
---|
169 | def getVcsRevInfo(self, sRepository, iRevision):
|
---|
170 | """
|
---|
171 | Gets the corresponding VcsRevisionData object.
|
---|
172 | May return a default (all NULLs) VcsRevisionData object if the revision
|
---|
173 | information isn't available in the database yet.
|
---|
174 | """
|
---|
175 | dRepo = self._adCache[self.ksObjType_VcsRevision_sRepository_iRevision].get(sRepository);
|
---|
176 | if dRepo is not None:
|
---|
177 | oRet = dRepo.get(iRevision);
|
---|
178 | else:
|
---|
179 | dRepo = dict();
|
---|
180 | self._adCache[self.ksObjType_VcsRevision_sRepository_iRevision][sRepository] = dRepo;
|
---|
181 | oRet = None;
|
---|
182 | if oRet is None:
|
---|
183 | from testmanager.core.vcsrevisions import VcsRevisionLogic;
|
---|
184 | oRet = VcsRevisionLogic(self._oDb).tryFetch(sRepository, iRevision);
|
---|
185 | if oRet is None:
|
---|
186 | from testmanager.core.vcsrevisions import VcsRevisionData;
|
---|
187 | oRet = VcsRevisionData();
|
---|
188 | dRepo[iRevision] = oRet;
|
---|
189 | return oRet;
|
---|
190 |
|
---|