VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/testmanager/core/testbox.pgsql@ 61478

Last change on this file since 61478 was 61468, checked in by vboxsync, 9 years ago

testmanager: Adding sComment and fRawMode fields to TestBoxes and moves the strings into a separate shared string table.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.4 KB
Line 
1-- $Id: testbox.pgsql 61468 2016-06-05 02:55:32Z vboxsync $
2--- @file
3-- VBox Test Manager Database Stored Procedures - TestBoxes.
4--
5
6--
7-- Copyright (C) 2012-2016 Oracle Corporation
8--
9-- This file is part of VirtualBox Open Source Edition (OSE), as
10-- available from http://www.virtualbox.org. This file is free software;
11-- you can redistribute it and/or modify it under the terms of the GNU
12-- General Public License (GPL) as published by the Free Software
13-- Foundation, in version 2 as it comes in the "COPYING" file of the
14-- VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15-- hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16--
17-- The contents of this file may alternatively be used under the terms
18-- of the Common Development and Distribution License Version 1.0
19-- (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20-- VirtualBox OSE distribution, in which case the provisions of the
21-- CDDL are applicable instead of those of the GPL.
22--
23-- You may elect to license modified versions of this file under the
24-- terms and conditions of either the GPL or the CDDL or both.
25--
26
27
28---
29-- Checks if the test box name is unique, ignoring a_idTestCaseIgnore.
30-- Raises exception if duplicates are found.
31--
32-- @internal
33--
34CREATE OR REPLACE FUNCTION TestBoxLogic_checkUniqueName(a_sName TEXT, a_idTestBoxIgnore INTEGER)
35 RETURNS VOID AS $$
36 DECLARE
37 v_cRows INTEGER;
38 BEGIN
39 SELECT COUNT(*) INTO v_cRows
40 FROM TestBoxes
41 WHERE sName = a_sName
42 AND tsExpire = 'infinity'::TIMESTAMP
43 AND idTestBox <> a_idTestBoxIgnore;
44 IF v_cRows <> 0 THEN
45 RAISE EXCEPTION 'Duplicate test box name "%" (% times)', a_sName, v_cRows;
46 END IF;
47 END;
48$$ LANGUAGE plpgsql;
49
50
51---
52-- Historize a row.
53-- @internal
54--
55CREATE OR REPLACE FUNCTION TestBoxLogic_historizeEntry(a_idGenTestBox INTEGER, a_tsExpire TIMESTAMP WITH TIME ZONE)
56 RETURNS VOID AS $$
57 DECLARE
58 v_cUpdatedRows INTEGER;
59 BEGIN
60 UPDATE TestBoxes
61 SET tsExpire = a_tsExpire
62 WHERE idGenTestBox = a_idGenTestBox
63 AND tsExpire = 'infinity'::TIMESTAMP;
64 GET DIAGNOSTICS v_cUpdatedRows = ROW_COUNT;
65 IF v_cUpdatedRows <> 1 THEN
66 IF v_cUpdatedRows = 0 THEN
67 RAISE EXCEPTION 'Test box generation ID % is no longer valid', a_idGenTestBox;
68 END IF;
69 RAISE EXCEPTION 'Integrity error in TestBoxes: % current rows with idGenTestBox=%', v_cUpdatedRows, a_idGenTestBox;
70 END IF;
71 END;
72$$ LANGUAGE plpgsql;
73
74
75---
76-- Translate string via the string table.
77--
78-- @returns NULL if a_sValue is NULL, otherwise a string ID.
79--
80CREATE OR REPLACE FUNCTION TestBoxLogic_lookupOrFindString(a_sValue TEXT)
81 RETURNS INTEGER AS $$
82 DECLARE
83 v_idStr INTEGER;
84 v_cRows INTEGER;
85 BEGIN
86 IF a_sValue IS NULL THEN
87 RETURN NULL;
88 END IF;
89
90 SELECT idStr
91 INTO v_idStr
92 FROM TestBoxStrTab
93 WHERE sValue = a_sValue;
94 GET DIAGNOSTICS v_cRows = ROW_COUNT;
95 IF v_cRows = 0 THEN
96 INSERT INTO TestBoxStrTab (sValue)
97 VALUES (a_sValue)
98 RETURNING idStr INTO v_idStr;
99 END IF;
100 RETURN v_idStr;
101 END;
102$$ LANGUAGE plpgsql;
103
104
105---
106-- Only adds the user settable parts of the row, i.e. not what TestBoxLogic_updateOnSignOn touches.
107--
108CREATE OR REPLACE function TestBoxLogic_addEntry(a_uidAuthor INTEGER,
109 a_ip inet,
110 a_uuidSystem uuid,
111 a_sName TEXT,
112 a_sDescription TEXT,
113 a_idSchedGroup INTEGER,
114 a_fEnabled BOOLEAN,
115 a_enmLomKind LomKind_T,
116 a_ipLom inet,
117 a_pctScaleTimeout INTEGER, -- Actually smallint, but default typing fun.
118 a_sComment TEXT,
119 a_enmPendingCmd TestBoxCmd_T,
120 OUT r_idTestBox INTEGER,
121 OUT r_idGenTestBox INTEGER,
122 OUT r_tsEffective TIMESTAMP WITH TIME ZONE
123 ) AS $$
124 DECLARE
125 v_idStrDescription INTEGER;
126 v_idStrComment INTEGER;
127 BEGIN
128 PERFORM TestBoxLogic_checkUniqueName(a_sName, -1);
129
130 SELECT TestBoxLogic_lookupOrFindString(a_sDescription) INTO v_idStrDescription;
131 SELECT TestBoxLogic_lookupOrFindString(a_sComment) INTO v_idStrComment;
132
133 INSERT INTO TestBoxes (
134 tsEffective, -- 1
135 uidAuthor, -- 2
136 ip, -- 3
137 uuidSystem, -- 4
138 sName, -- 5
139 idStrDescription, -- 6
140 idSchedGroup, -- 7
141 fEnabled, -- 8
142 enmLomKind, -- 9
143 ipLom, -- 10
144 pctScaleTimeout, -- 11
145 idStrComment, -- 12
146 enmPendingCmd ) -- 13
147 VALUES (CURRENT_TIMESTAMP, -- 1
148 a_uidAuthor, -- 2
149 a_ip, -- 3
150 a_uuidSystem, -- 4
151 a_sName, -- 5
152 v_idStrDescription, -- 6
153 a_idSchedGroup, -- 7
154 a_fEnabled, -- 8
155 a_enmLomKind, -- 9
156 a_ipLom, -- 10
157 a_pctScaleTimeout, -- 11
158 v_idStrComment, -- 12
159 a_enmPendingCmd ) -- 13
160 RETURNING idTestBox, idGenTestBox, tsEffective INTO r_idTestBox, r_idGenTestBox, r_tsEffective;
161 END;
162$$ LANGUAGE plpgsql;
163
164---
165-- Only adds the user settable parts of the row, i.e. not what TestBoxLogic_updateOnSignOn touches.
166--
167CREATE OR REPLACE function TestBoxLogic_editEntry(a_uidAuthor INTEGER,
168 a_idTestBox INTEGER,
169 a_ip inet,
170 a_uuidSystem uuid,
171 a_sName TEXT,
172 a_sDescription TEXT,
173 a_idSchedGroup INTEGER,
174 a_fEnabled BOOLEAN,
175 a_enmLomKind LomKind_T,
176 a_ipLom inet,
177 a_pctScaleTimeout INTEGER, -- Actually smallint, but default typing fun.
178 a_sComment TEXT,
179 a_enmPendingCmd TestBoxCmd_T,
180 OUT r_idGenTestBox INTEGER,
181 OUT r_tsEffective TIMESTAMP WITH TIME ZONE
182 ) AS $$
183 DECLARE
184 v_Row TestBoxes%ROWTYPE;
185 v_idStrDescription INTEGER;
186 v_idStrComment INTEGER;
187 BEGIN
188 PERFORM TestBoxLogic_checkUniqueName(a_sName, a_idTestBox);
189
190 SELECT TestBoxLogic_lookupOrFindString(a_sDescription) INTO v_idStrDescription;
191 SELECT TestBoxLogic_lookupOrFindString(a_sComment) INTO v_idStrComment;
192
193 -- Fetch and historize the current row - there must be one.
194 UPDATE TestBoxes
195 SET tsExpire = CURRENT_TIMESTAMP
196 WHERE idTestBox = a_idTestBox
197 AND tsExpire = 'infinity'::TIMESTAMP
198 RETURNING * INTO STRICT v_Row;
199
200 -- Modify the row with the new data.
201 v_Row.uidAuthor := a_uidAuthor;
202 v_Row.ip := a_ip;
203 v_Row.uuidSystem := a_uuidSystem;
204 v_Row.sName := a_sName;
205 v_Row.idStrDescription := v_idStrDescription;
206 v_Row.idSchedGroup := a_idSchedGroup;
207 v_Row.fEnabled := a_fEnabled;
208 v_Row.enmLomKind := a_enmLomKind;
209 v_Row.ipLom := a_ipLom;
210 v_Row.pctScaleTimeout := a_pctScaleTimeout;
211 v_Row.idStrComment := v_idStrComment;
212 v_Row.enmPendingCmd := a_enmPendingCmd;
213 v_Row.tsEffective := v_Row.tsExpire;
214 r_tsEffective := v_Row.tsExpire;
215 v_Row.tsExpire := 'infinity'::TIMESTAMP;
216
217 -- Get a new generation ID.
218 SELECT NEXTVAL('TestBoxGenIdSeq') INTO v_Row.idGenTestBox;
219 r_idGenTestBox := v_Row.idGenTestBox;
220
221 -- Insert the modified row.
222 INSERT INTO TestBoxes VALUES (v_Row.*);
223 END;
224$$ LANGUAGE plpgsql;
225
226
227DROP FUNCTION IF EXISTS TestBoxLogic_removeEntry(INTEGER, INTEGER, BOOLEAN);
228CREATE OR REPLACE FUNCTION TestBoxLogic_removeEntry(a_uidAuthor INTEGER, a_idTestBox INTEGER, a_fCascade BOOLEAN)
229 RETURNS VOID AS $$
230 DECLARE
231 v_Row TestBoxes%ROWTYPE;
232 v_tsEffective TIMESTAMP WITH TIME ZONE;
233 v_Rec RECORD;
234 v_sErrors TEXT;
235 BEGIN
236 --
237 -- Check preconditions.
238 --
239 IF a_fCascade <> TRUE THEN
240 -- @todo implement checks which throws useful exceptions.
241 ELSE
242 RAISE EXCEPTION 'CASCADE test box deletion is not implemented';
243 END IF;
244
245 --
246 -- To preserve the information about who deleted the record, we try to
247 -- add a dummy record which expires immediately. I say try because of
248 -- the primary key, we must let the new record be valid for 1 us. :-(
249 --
250 SELECT * INTO STRICT v_Row
251 FROM TestBoxes
252 WHERE idTestBox = a_idTestBox
253 AND tsExpire = 'infinity'::TIMESTAMP;
254
255 v_tsEffective := CURRENT_TIMESTAMP - INTERVAL '1 microsecond';
256 IF v_Row.tsEffective < v_tsEffective THEN
257 PERFORM TestBoxLogic_historizeEntry(v_Row.idGenTestBox, v_tsEffective);
258
259 v_Row.tsEffective := v_tsEffective;
260 v_Row.tsExpire := CURRENT_TIMESTAMP;
261 v_Row.uidAuthor := a_uidAuthor;
262 SELECT NEXTVAL('TestBoxGenIdSeq') INTO v_Row.idGenTestBox;
263 INSERT INTO TestBoxes VALUES (v_Row.*);
264 ELSE
265 PERFORM TestBoxLogic_historizeEntry(v_Row.idGenTestBox, CURRENT_TIMESTAMP);
266 END IF;
267
268 EXCEPTION
269 WHEN NO_DATA_FOUND THEN
270 RAISE EXCEPTION 'Test box with ID % does not currently exist', a_idTestBox;
271 WHEN TOO_MANY_ROWS THEN
272 RAISE EXCEPTION 'Integrity error in TestBoxes: Too many current rows for %', a_idTestBox;
273 END;
274$$ LANGUAGE plpgsql;
275
276
277---
278-- Sign on update
279--
280CREATE OR REPLACE function TestBoxLogic_updateOnSignOn(a_idTestBox INTEGER,
281 a_ip inet,
282 a_sOs TEXT,
283 a_sOsVersion TEXT,
284 a_sCpuVendor TEXT,
285 a_sCpuArch TEXT,
286 a_sCpuName TEXT,
287 a_lCpuRevision bigint,
288 a_cCpus INTEGER, -- Actually smallint, but default typing fun.
289 a_fCpuHwVirt boolean,
290 a_fCpuNestedPaging boolean,
291 a_fCpu64BitGuest boolean,
292 a_fChipsetIoMmu boolean,
293 a_fRawMode boolean,
294 a_cMbMemory bigint,
295 a_cMbScratch bigint,
296 a_sReport TEXT,
297 a_iTestBoxScriptRev INTEGER,
298 a_iPythonHexVersion INTEGER,
299 OUT r_idGenTestBox INTEGER
300 ) AS $$
301 DECLARE
302 v_Row TestBoxes%ROWTYPE;
303 v_idStrOs INTEGER;
304 v_idStrOsVersion INTEGER;
305 v_idStrCpuVendor INTEGER;
306 v_idStrCpuArch INTEGER;
307 v_idStrCpuName INTEGER;
308 v_idStrReport INTEGER;
309 BEGIN
310 SELECT TestBoxLogic_lookupOrFindString(a_sOs) INTO v_idStrOs;
311 SELECT TestBoxLogic_lookupOrFindString(a_sOsVersion) INTO v_idStrOsVersion;
312 SELECT TestBoxLogic_lookupOrFindString(a_sCpuVendor) INTO v_idStrCpuVendor;
313 SELECT TestBoxLogic_lookupOrFindString(a_sCpuArch) INTO v_idStrCpuArch;
314 SELECT TestBoxLogic_lookupOrFindString(a_sCpuName) INTO v_idStrCpuName;
315 SELECT TestBoxLogic_lookupOrFindString(a_sReport) INTO v_idStrReport;
316
317 -- Fetch and historize the current row - there must be one.
318 UPDATE TestBoxes
319 SET tsExpire = CURRENT_TIMESTAMP
320 WHERE idTestBox = a_idTestBox
321 AND tsExpire = 'infinity'::TIMESTAMP
322 RETURNING * INTO STRICT v_Row;
323
324 -- Modify the row with the new data.
325 v_Row.uidAuthor := NULL;
326 v_Row.ip := a_ip;
327 v_Row.idStrOs := v_idStrOs;
328 v_Row.idStrOsVersion := v_idStrOsVersion;
329 v_Row.idStrCpuVendor := v_idStrCpuVendor;
330 v_Row.idStrCpuArch := v_idStrCpuArch;
331 v_Row.idStrCpuName := v_idStrCpuName;
332 v_Row.lCpuRevision := a_lCpuRevision;
333 v_Row.cCpus := a_cCpus;
334 v_Row.fCpuHwVirt := a_fCpuHwVirt;
335 v_Row.fCpuNestedPaging := a_fCpuNestedPaging;
336 v_Row.fCpu64BitGuest := a_fCpu64BitGuest;
337 v_Row.fChipsetIoMmu := a_fChipsetIoMmu;
338 v_Row.fRawMode := a_fRawMode;
339 v_Row.cMbMemory := a_cMbMemory;
340 v_Row.cMbScratch := a_cMbScratch;
341 v_Row.idStrReport := v_idStrReport;
342 v_Row.iTestBoxScriptRev := a_iTestBoxScriptRev;
343 v_Row.iPythonHexVersion := a_iPythonHexVersion;
344 v_Row.tsEffective := v_Row.tsExpire;
345 v_Row.tsExpire := 'infinity'::TIMESTAMP;
346
347 -- Get a new generation ID.
348 SELECT NEXTVAL('TestBoxGenIdSeq') INTO v_Row.idGenTestBox;
349 r_idGenTestBox := v_Row.idGenTestBox;
350
351 -- Insert the modified row.
352 INSERT INTO TestBoxes VALUES (v_Row.*);
353 END;
354$$ LANGUAGE plpgsql;
355
356
357---
358-- Set new command.
359--
360CREATE OR REPLACE function TestBoxLogic_setCommand(a_uidAuthor INTEGER,
361 a_idTestBox INTEGER,
362 a_enmOldCmd TestBoxCmd_T,
363 a_enmNewCmd TestBoxCmd_T,
364 a_sComment TEXT,
365 OUT r_idGenTestBox INTEGER,
366 OUT r_tsEffective TIMESTAMP WITH TIME ZONE
367 ) AS $$
368 DECLARE
369 v_Row TestBoxes%ROWTYPE;
370 v_idStrComment INTEGER;
371 BEGIN
372 SELECT TestBoxLogic_lookupOrFindString(a_sComment) INTO v_idStrComment;
373
374 -- Fetch and historize the current row - there must be one.
375 UPDATE TestBoxes
376 SET tsExpire = CURRENT_TIMESTAMP
377 WHERE idTestBox = a_idTestBox
378 AND tsExpire = 'infinity'::TIMESTAMP
379 AND enmPendingCmd = a_enmOldCmd
380 RETURNING * INTO STRICT v_Row;
381
382 -- Modify the row with the new data.
383 v_Row.enmPendingCmd := a_enmNewCmd;
384 IF v_idStrComment IS NOT NULL THEN
385 v_Row.idStrComment := v_idStrComment;
386 END IF;
387 v_Row.tsEffective := v_Row.tsExpire;
388 r_tsEffective := v_Row.tsExpire;
389 v_Row.tsExpire := 'infinity'::TIMESTAMP;
390
391 -- Get a new generation ID.
392 SELECT NEXTVAL('TestBoxGenIdSeq') INTO v_Row.idGenTestBox;
393 r_idGenTestBox := v_Row.idGenTestBox;
394
395 -- Insert the modified row.
396 INSERT INTO TestBoxes VALUES (v_Row.*);
397 END;
398$$ LANGUAGE plpgsql;
399
400
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette