Changeset 61502 in vbox for trunk/src/VBox/ValidationKit/testmanager/core/testbox.pgsql
- Timestamp:
- Jun 6, 2016 5:53:01 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 107838
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/testmanager/core/testbox.pgsql
r61468 r61502 26 26 27 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 -- 34 CREATE 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 -- 55 CREATE 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 -- 80 CREATE 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 -- 108 CREATE OR REPLACE function TestBoxLogic_addEntry(a_uidAuthor INTEGER, 28 -- 29 -- Old type signatures. 30 -- 31 DROP FUNCTION IF EXISTS TestBoxLogic_addEntry(a_uidAuthor INTEGER, 109 32 a_ip inet, 110 33 a_uuidSystem uuid, … … 120 43 OUT r_idTestBox INTEGER, 121 44 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 -- 167 CREATE OR REPLACE function TestBoxLogic_editEntry(a_uidAuthor INTEGER, 45 OUT r_tsEffective TIMESTAMP WITH TIME ZONE); 46 DROP FUNCTION IF EXISTS TestBoxLogic_editEntry(a_uidAuthor INTEGER, 168 47 a_idTestBox INTEGER, 169 48 a_ip inet, … … 179 58 a_enmPendingCmd TestBoxCmd_T, 180 59 OUT r_idGenTestBox INTEGER, 60 OUT r_tsEffective TIMESTAMP WITH TIME ZONE); 61 DROP FUNCTION IF EXISTS TestBoxLogic_removeEntry(INTEGER, INTEGER, BOOLEAN); 62 DROP FUNCTION IF EXISTS TestBoxLogic_addGroupEntry(a_uidAuthor INTEGER, 63 a_idTestBox INTEGER, 64 a_idSchedGroup INTEGER, 65 a_iSchedPriority INTEGER, 66 OUT r_tsEffective TIMESTAMP WITH TIME ZONE); 67 DROP FUNCTION IF EXISTS TestBoxLogic_editGroupEntry(a_uidAuthor INTEGER, 68 a_idTestBox INTEGER, 69 a_idSchedGroup INTEGER, 70 a_iSchedPriority INTEGER, 71 OUT r_tsEffective INTEGER); 72 73 74 --- 75 -- Checks if the test box name is unique, ignoring a_idTestCaseIgnore. 76 -- Raises exception if duplicates are found. 77 -- 78 -- @internal 79 -- 80 CREATE OR REPLACE FUNCTION TestBoxLogic_checkUniqueName(a_sName TEXT, a_idTestBoxIgnore INTEGER) 81 RETURNS VOID AS $$ 82 DECLARE 83 v_cRows INTEGER; 84 BEGIN 85 SELECT COUNT(*) INTO v_cRows 86 FROM TestBoxes 87 WHERE sName = a_sName 88 AND tsExpire = 'infinity'::TIMESTAMP 89 AND idTestBox <> a_idTestBoxIgnore; 90 IF v_cRows <> 0 THEN 91 RAISE EXCEPTION 'Duplicate test box name "%" (% times)', a_sName, v_cRows; 92 END IF; 93 END; 94 $$ LANGUAGE plpgsql; 95 96 97 --- 98 -- Checks that the given scheduling group exists. 99 -- Raises exception if it doesn't. 100 -- 101 -- @internal 102 -- 103 CREATE OR REPLACE FUNCTION TestBoxLogic_checkSchedGroupExists(a_idSchedGroup INTEGER) 104 RETURNS VOID AS $$ 105 DECLARE 106 v_cRows INTEGER; 107 BEGIN 108 SELECT COUNT(*) INTO v_cRows 109 FROM SchedGroups 110 WHERE idSchedGroup = a_idSchedGroup 111 AND tsExpire = 'infinity'::TIMESTAMP; 112 IF v_cRows <> 1 THEN 113 IF v_cRows = 0 THEN 114 RAISE EXCEPTION 'Scheduling group with ID % was not found', a_idSchedGroup; 115 END IF; 116 RAISE EXCEPTION 'Integrity error in SchedGroups: % current rows with idSchedGroup=%', v_cRows, a_idSchedGroup; 117 END IF; 118 END; 119 $$ LANGUAGE plpgsql; 120 121 122 --- 123 -- Checks that the given testbxo + scheduling group pair does not currently exists. 124 -- Raises exception if it does. 125 -- 126 -- @internal 127 -- 128 CREATE OR REPLACE FUNCTION TestBoxLogic_checkTestBoxNotInSchedGroup(a_idTestBox INTEGER, a_idSchedGroup INTEGER) 129 RETURNS VOID AS $$ 130 DECLARE 131 v_cRows INTEGER; 132 BEGIN 133 SELECT COUNT(*) INTO v_cRows 134 FROM TestBoxesInSchedGroups 135 WHERE idTestBox = a_idTestBox 136 AND idSchedGroup = a_idSchedGroup 137 AND tsExpire = 'infinity'::TIMESTAMP; 138 IF v_cRows <> 0 THEN 139 RAISE EXCEPTION 'TestBox % is already a member of scheduling group %', a_idTestBox, a_idSchedGroup; 140 END IF; 141 END; 142 $$ LANGUAGE plpgsql; 143 144 145 --- 146 -- Historize a row. 147 -- @internal 148 -- 149 CREATE OR REPLACE FUNCTION TestBoxLogic_historizeEntry(a_idGenTestBox INTEGER, a_tsExpire TIMESTAMP WITH TIME ZONE) 150 RETURNS VOID AS $$ 151 DECLARE 152 v_cUpdatedRows INTEGER; 153 BEGIN 154 UPDATE TestBoxes 155 SET tsExpire = a_tsExpire 156 WHERE idGenTestBox = a_idGenTestBox 157 AND tsExpire = 'infinity'::TIMESTAMP; 158 GET DIAGNOSTICS v_cUpdatedRows = ROW_COUNT; 159 IF v_cUpdatedRows <> 1 THEN 160 IF v_cUpdatedRows = 0 THEN 161 RAISE EXCEPTION 'Test box generation ID % is no longer valid', a_idGenTestBox; 162 END IF; 163 RAISE EXCEPTION 'Integrity error in TestBoxes: % current rows with idGenTestBox=%', v_cUpdatedRows, a_idGenTestBox; 164 END IF; 165 END; 166 $$ LANGUAGE plpgsql; 167 168 169 --- 170 -- Historize a in-scheduling-group row. 171 -- @internal 172 -- 173 CREATE OR REPLACE FUNCTION TestBoxLogic_historizeGroupEntry(a_idTestBox INTEGER, 174 a_idSchedGroup INTEGER, 175 a_tsExpire TIMESTAMP WITH TIME ZONE) 176 RETURNS VOID AS $$ 177 DECLARE 178 v_cUpdatedRows INTEGER; 179 BEGIN 180 UPDATE TestBoxesInSchedGroups 181 SET tsExpire = a_tsExpire 182 WHERE idTestBox = a_idTestBox 183 AND idSchedGroup = a_idSchedGroup 184 AND tsExpire = 'infinity'::TIMESTAMP; 185 GET DIAGNOSTICS v_cUpdatedRows = ROW_COUNT; 186 IF v_cUpdatedRows <> 1 THEN 187 IF v_cUpdatedRows = 0 THEN 188 RAISE EXCEPTION 'TestBox ID % / SchedGroup ID % is no longer a valid combination', a_idTestBox, a_idSchedGroup; 189 END IF; 190 RAISE EXCEPTION 'Integrity error in TestBoxesInSchedGroups: % current rows for % / %', 191 v_cUpdatedRows, a_idTestBox, a_idSchedGroup; 192 END IF; 193 END; 194 $$ LANGUAGE plpgsql; 195 196 197 --- 198 -- Translate string via the string table. 199 -- 200 -- @returns NULL if a_sValue is NULL, otherwise a string ID. 201 -- 202 CREATE OR REPLACE FUNCTION TestBoxLogic_lookupOrFindString(a_sValue TEXT) 203 RETURNS INTEGER AS $$ 204 DECLARE 205 v_idStr INTEGER; 206 v_cRows INTEGER; 207 BEGIN 208 IF a_sValue IS NULL THEN 209 RETURN NULL; 210 END IF; 211 212 SELECT idStr 213 INTO v_idStr 214 FROM TestBoxStrTab 215 WHERE sValue = a_sValue; 216 GET DIAGNOSTICS v_cRows = ROW_COUNT; 217 IF v_cRows = 0 THEN 218 INSERT INTO TestBoxStrTab (sValue) 219 VALUES (a_sValue) 220 RETURNING idStr INTO v_idStr; 221 END IF; 222 RETURN v_idStr; 223 END; 224 $$ LANGUAGE plpgsql; 225 226 227 --- 228 -- Only adds the user settable parts of the row, i.e. not what TestBoxLogic_updateOnSignOn touches. 229 -- 230 CREATE OR REPLACE function TestBoxLogic_addEntry(a_uidAuthor INTEGER, 231 a_ip inet, 232 a_uuidSystem uuid, 233 a_sName TEXT, 234 a_sDescription TEXT, 235 a_fEnabled BOOLEAN, 236 a_enmLomKind LomKind_T, 237 a_ipLom inet, 238 a_pctScaleTimeout INTEGER, -- Actually smallint, but default typing fun. 239 a_sComment TEXT, 240 a_enmPendingCmd TestBoxCmd_T, 241 OUT r_idTestBox INTEGER, 242 OUT r_idGenTestBox INTEGER, 243 OUT r_tsEffective TIMESTAMP WITH TIME ZONE 244 ) AS $$ 245 DECLARE 246 v_idStrDescription INTEGER; 247 v_idStrComment INTEGER; 248 BEGIN 249 PERFORM TestBoxLogic_checkUniqueName(a_sName, -1); 250 251 SELECT TestBoxLogic_lookupOrFindString(a_sDescription) INTO v_idStrDescription; 252 SELECT TestBoxLogic_lookupOrFindString(a_sComment) INTO v_idStrComment; 253 254 INSERT INTO TestBoxes ( 255 tsEffective, -- 1 256 uidAuthor, -- 2 257 ip, -- 3 258 uuidSystem, -- 4 259 sName, -- 5 260 idStrDescription, -- 6 261 fEnabled, -- 7 262 enmLomKind, -- 8 263 ipLom, -- 9 264 pctScaleTimeout, -- 10 265 idStrComment, -- 11 266 enmPendingCmd ) -- 12 267 VALUES (CURRENT_TIMESTAMP, -- 1 268 a_uidAuthor, -- 2 269 a_ip, -- 3 270 a_uuidSystem, -- 4 271 a_sName, -- 5 272 v_idStrDescription, -- 6 273 a_fEnabled, -- 7 274 a_enmLomKind, -- 8 275 a_ipLom, -- 9 276 a_pctScaleTimeout, -- 10 277 v_idStrComment, -- 11 278 a_enmPendingCmd ) -- 12 279 RETURNING idTestBox, idGenTestBox, tsEffective INTO r_idTestBox, r_idGenTestBox, r_tsEffective; 280 END; 281 $$ LANGUAGE plpgsql; 282 283 284 CREATE OR REPLACE function TestBoxLogic_addGroupEntry(a_uidAuthor INTEGER, 285 a_idTestBox INTEGER, 286 a_idSchedGroup INTEGER, 287 a_iSchedPriority INTEGER, 288 OUT r_tsEffective TIMESTAMP WITH TIME ZONE 289 ) AS $$ 290 BEGIN 291 PERFORM TestBoxLogic_checkSchedGroupExists(a_idSchedGroup); 292 PERFORM TestBoxLogic_checkTestBoxNotInSchedGroup(a_idTestBox, a_idSchedGroup); 293 294 INSERT INTO TestBoxesInSchedGroups ( 295 idTestBox, 296 idSchedGroup, 297 tsEffective, 298 tsExpire, 299 uidAuthor, 300 iSchedPriority) 301 VALUES (a_idTestBox, 302 a_idSchedGroup, 303 CURRENT_TIMESTAMP, 304 'infinity'::TIMESTAMP, 305 a_uidAuthor, 306 a_iSchedPriority) 307 RETURNING tsEffective INTO r_tsEffective; 308 END; 309 $$ LANGUAGE plpgsql; 310 311 312 --- 313 -- Only adds the user settable parts of the row, i.e. not what TestBoxLogic_updateOnSignOn touches. 314 -- 315 CREATE OR REPLACE function TestBoxLogic_editEntry(a_uidAuthor INTEGER, 316 a_idTestBox INTEGER, 317 a_ip inet, 318 a_uuidSystem uuid, 319 a_sName TEXT, 320 a_sDescription TEXT, 321 a_fEnabled BOOLEAN, 322 a_enmLomKind LomKind_T, 323 a_ipLom inet, 324 a_pctScaleTimeout INTEGER, -- Actually smallint, but default typing fun. 325 a_sComment TEXT, 326 a_enmPendingCmd TestBoxCmd_T, 327 OUT r_idGenTestBox INTEGER, 181 328 OUT r_tsEffective TIMESTAMP WITH TIME ZONE 182 329 ) AS $$ … … 204 351 v_Row.sName := a_sName; 205 352 v_Row.idStrDescription := v_idStrDescription; 206 v_Row.idSchedGroup := a_idSchedGroup;207 353 v_Row.fEnabled := a_fEnabled; 208 354 v_Row.enmLomKind := a_enmLomKind; … … 225 371 226 372 227 DROP FUNCTION IF EXISTS TestBoxLogic_removeEntry(INTEGER, INTEGER, BOOLEAN); 373 CREATE OR REPLACE function TestBoxLogic_editGroupEntry(a_uidAuthor INTEGER, 374 a_idTestBox INTEGER, 375 a_idSchedGroup INTEGER, 376 a_iSchedPriority INTEGER, 377 OUT r_tsEffective TIMESTAMP WITH TIME ZONE 378 ) AS $$ 379 DECLARE 380 v_Row TestBoxesInSchedGroups%ROWTYPE; 381 v_idStrDescription INTEGER; 382 v_idStrComment INTEGER; 383 BEGIN 384 PERFORM TestBoxLogic_checkSchedGroupExists(a_idSchedGroup); 385 386 -- Fetch and historize the current row - there must be one. 387 UPDATE TestBoxesInSchedGroups 388 SET tsExpire = CURRENT_TIMESTAMP 389 WHERE idTestBox = a_idTestBox 390 AND idSchedGroup = a_idSchedGroup 391 AND tsExpire = 'infinity'::TIMESTAMP 392 RETURNING * INTO STRICT v_Row; 393 394 -- Modify the row with the new data. 395 v_Row.uidAuthor := a_uidAuthor; 396 v_Row.iSchedPriority := a_iSchedPriority; 397 v_Row.tsEffective := v_Row.tsExpire; 398 r_tsEffective := v_Row.tsExpire; 399 v_Row.tsExpire := 'infinity'::TIMESTAMP; 400 401 -- Insert the modified row. 402 INSERT INTO TestBoxesInSchedGroups VALUES (v_Row.*); 403 END; 404 $$ LANGUAGE plpgsql; 405 406 228 407 CREATE OR REPLACE FUNCTION TestBoxLogic_removeEntry(a_uidAuthor INTEGER, a_idTestBox INTEGER, a_fCascade BOOLEAN) 229 408 RETURNS VOID AS $$ … … 242 421 RAISE EXCEPTION 'CASCADE test box deletion is not implemented'; 243 422 END IF; 423 424 -- 425 -- Delete all current groups, skipping history since we're also deleting the testbox. 426 -- 427 UPDATE TestBoxesInSchedGroups 428 SET tsExpire = CURRENT_TIMESTAMP 429 WHERE idTestBox = a_idTestBox 430 AND tsExpire = 'infinity'::TIMESTAMP; 244 431 245 432 -- … … 271 458 WHEN TOO_MANY_ROWS THEN 272 459 RAISE EXCEPTION 'Integrity error in TestBoxes: Too many current rows for %', a_idTestBox; 460 END; 461 $$ LANGUAGE plpgsql; 462 463 464 CREATE OR REPLACE FUNCTION TestBoxLogic_removeGroupEntry(a_uidAuthor INTEGER, a_idTestBox INTEGER, a_idSchedGroup INTEGER) 465 RETURNS VOID AS $$ 466 DECLARE 467 v_Row TestBoxesInSchedGroups%ROWTYPE; 468 v_tsEffective TIMESTAMP WITH TIME ZONE; 469 BEGIN 470 -- 471 -- To preserve the information about who deleted the record, we try to 472 -- add a dummy record which expires immediately. I say try because of 473 -- the primary key, we must let the new record be valid for 1 us. :-( 474 -- 475 SELECT * INTO STRICT v_Row 476 FROM TestBoxesInSchedGroups 477 WHERE idTestBox = a_idTestBox 478 AND idSchedGroup = a_idSchedGroup 479 AND tsExpire = 'infinity'::TIMESTAMP; 480 481 v_tsEffective := CURRENT_TIMESTAMP - INTERVAL '1 microsecond'; 482 IF v_Row.tsEffective < v_tsEffective THEN 483 PERFORM TestBoxLogic_historizeGroupEntry(a_idTestBox, a_idSchedGroup, v_tsEffective); 484 485 v_Row.tsEffective := v_tsEffective; 486 v_Row.tsExpire := CURRENT_TIMESTAMP; 487 v_Row.uidAuthor := a_uidAuthor; 488 INSERT INTO TestBoxesInSchedGroups VALUES (v_Row.*); 489 ELSE 490 PERFORM TestBoxLogic_historizeGroupEntry(a_idTestBox, a_idSchedGroup, CURRENT_TIMESTAMP); 491 END IF; 492 493 EXCEPTION 494 WHEN NO_DATA_FOUND THEN 495 RAISE EXCEPTION 'TestBox #% does is not currently a member of scheduling group #%', a_idTestBox, a_idSchedGroup; 496 WHEN TOO_MANY_ROWS THEN 497 RAISE EXCEPTION 'Integrity error in TestBoxesInSchedGroups: Too many current rows for % / %', 498 a_idTestBox, a_idSchedGroup; 273 499 END; 274 500 $$ LANGUAGE plpgsql;
Note:
See TracChangeset
for help on using the changeset viewer.