1 1.1 jmmv -- Copyright 2013 Google Inc. 2 1.1 jmmv -- All rights reserved. 3 1.1 jmmv -- 4 1.1 jmmv -- Redistribution and use in source and binary forms, with or without 5 1.1 jmmv -- modification, are permitted provided that the following conditions are 6 1.1 jmmv -- met: 7 1.1 jmmv -- 8 1.1 jmmv -- * Redistributions of source code must retain the above copyright 9 1.1 jmmv -- notice, this list of conditions and the following disclaimer. 10 1.1 jmmv -- * Redistributions in binary form must reproduce the above copyright 11 1.1 jmmv -- notice, this list of conditions and the following disclaimer in the 12 1.1 jmmv -- documentation and/or other materials provided with the distribution. 13 1.1 jmmv -- * Neither the name of Google Inc. nor the names of its contributors 14 1.1 jmmv -- may be used to endorse or promote products derived from this software 15 1.1 jmmv -- without specific prior written permission. 16 1.1 jmmv -- 17 1.1 jmmv -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 1.1 jmmv -- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 1.1 jmmv -- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 1.1 jmmv -- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 1.1 jmmv -- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 1.1 jmmv -- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 1.1 jmmv -- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 1.1 jmmv -- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 1.1 jmmv -- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 1.1 jmmv -- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 1.1 jmmv -- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 1.1 jmmv 29 1.1 jmmv -- \file store/v1-to-v2.sql 30 1.1 jmmv -- Migration of a database with version 1 of the schema to version 2. 31 1.1 jmmv -- 32 1.1 jmmv -- Version 2 appeared in revision 9a73561a1e3975bba4cbfd19aee6b2365a39519e 33 1.1 jmmv -- and its changes were: 34 1.1 jmmv -- 35 1.1 jmmv -- * Changed the primary key of the metadata table to be the 36 1.1 jmmv -- schema_version, not the timestamp. Because timestamps only have 37 1.1 jmmv -- second resolution, the old schema made testing of schema migrations 38 1.1 jmmv -- difficult. 39 1.1 jmmv -- 40 1.1 jmmv -- * Introduced the metadatas table, which holds the metadata of all test 41 1.1 jmmv -- programs and test cases in an abstract manner regardless of their 42 1.1 jmmv -- interface. 43 1.1 jmmv -- 44 1.1 jmmv -- * Added the metadata_id field to the test_programs and test_cases 45 1.1 jmmv -- tables, referencing the new metadatas table. 46 1.1 jmmv -- 47 1.1 jmmv -- * Changed the precision of the timeout metadata field to be in seconds 48 1.1 jmmv -- rather than in microseconds. There is no data loss, and the code that 49 1.1 jmmv -- writes the metadata is simplified. 50 1.1 jmmv -- 51 1.1 jmmv -- * Removed the atf_* and plain_* tables. 52 1.1 jmmv -- 53 1.1 jmmv -- * Added missing indexes to improve the performance of reports. 54 1.1 jmmv -- 55 1.1 jmmv -- * Added missing column affinities to the absolute_path and relative_path 56 1.1 jmmv -- columns of the test_programs table. 57 1.1 jmmv 58 1.1 jmmv 59 1.1 jmmv -- TODO(jmmv): Implement addition of missing affinities. 60 1.1 jmmv 61 1.1 jmmv 62 1.1 jmmv -- 63 1.1 jmmv -- Change primary key of the metadata table. 64 1.1 jmmv -- 65 1.1 jmmv 66 1.1 jmmv 67 1.1 jmmv CREATE TABLE new_metadata ( 68 1.1 jmmv schema_version INTEGER PRIMARY KEY CHECK (schema_version >= 1), 69 1.1 jmmv timestamp TIMESTAMP NOT NULL CHECK (timestamp >= 0) 70 1.1 jmmv ); 71 1.1 jmmv 72 1.1 jmmv INSERT INTO new_metadata (schema_version, timestamp) 73 1.1 jmmv SELECT schema_version, timestamp FROM metadata; 74 1.1 jmmv 75 1.1 jmmv DROP TABLE metadata; 76 1.1 jmmv ALTER TABLE new_metadata RENAME TO metadata; 77 1.1 jmmv 78 1.1 jmmv 79 1.1 jmmv -- 80 1.1 jmmv -- Add the new tables, columns and indexes. 81 1.1 jmmv -- 82 1.1 jmmv 83 1.1 jmmv 84 1.1 jmmv CREATE TABLE metadatas ( 85 1.1 jmmv metadata_id INTEGER NOT NULL, 86 1.1 jmmv property_name TEXT NOT NULL, 87 1.1 jmmv property_value TEXT, 88 1.1 jmmv 89 1.1 jmmv PRIMARY KEY (metadata_id, property_name) 90 1.1 jmmv ); 91 1.1 jmmv 92 1.1 jmmv 93 1.1 jmmv -- Upgrade the test_programs table by adding missing column affinities and 94 1.1 jmmv -- the new metadata_id column. 95 1.1 jmmv CREATE TABLE new_test_programs ( 96 1.1 jmmv test_program_id INTEGER PRIMARY KEY AUTOINCREMENT, 97 1.1 jmmv action_id INTEGER REFERENCES actions, 98 1.1 jmmv 99 1.1 jmmv absolute_path TEXT NOT NULL, 100 1.1 jmmv root TEXT NOT NULL, 101 1.1 jmmv relative_path TEXT NOT NULL, 102 1.1 jmmv test_suite_name TEXT NOT NULL, 103 1.1 jmmv metadata_id INTEGER, 104 1.1 jmmv interface TEXT NOT NULL 105 1.1 jmmv ); 106 1.1 jmmv PRAGMA foreign_keys = OFF; 107 1.1 jmmv INSERT INTO new_test_programs (test_program_id, action_id, absolute_path, 108 1.1 jmmv root, relative_path, test_suite_name, 109 1.1 jmmv interface) 110 1.1 jmmv SELECT test_program_id, action_id, absolute_path, root, relative_path, 111 1.1 jmmv test_suite_name, interface FROM test_programs; 112 1.1 jmmv DROP TABLE test_programs; 113 1.1 jmmv ALTER TABLE new_test_programs RENAME TO test_programs; 114 1.1 jmmv PRAGMA foreign_keys = ON; 115 1.1 jmmv 116 1.1 jmmv 117 1.1 jmmv ALTER TABLE test_cases ADD COLUMN metadata_id INTEGER; 118 1.1 jmmv 119 1.1 jmmv 120 1.1 jmmv CREATE INDEX index_metadatas_by_id 121 1.1 jmmv ON metadatas (metadata_id); 122 1.1 jmmv CREATE INDEX index_test_programs_by_action_id 123 1.1 jmmv ON test_programs (action_id); 124 1.1 jmmv CREATE INDEX index_test_cases_by_test_programs_id 125 1.1 jmmv ON test_cases (test_program_id); 126 1.1 jmmv 127 1.1 jmmv 128 1.1 jmmv -- 129 1.1 jmmv -- Data migration 130 1.1 jmmv -- 131 1.1 jmmv -- This is, by far, the trickiest part of the migration. 132 1.1 jmmv -- TODO(jmmv): Describe the trickiness in here. 133 1.1 jmmv -- 134 1.1 jmmv 135 1.1 jmmv 136 1.1 jmmv -- Auxiliary table to construct the final contents of the metadatas table. 137 1.1 jmmv -- 138 1.1 jmmv -- We construct the contents by writing a row for every metadata property of 139 1.1 jmmv -- every test program and test case. Entries corresponding to a test program 140 1.1 jmmv -- will have the test_program_id field set to not NULL and entries corresponding 141 1.1 jmmv -- to test cases will have the test_case_id set to not NULL. 142 1.1 jmmv -- 143 1.1 jmmv -- The tricky part, however, is to create the individual identifiers for every 144 1.1 jmmv -- metadata entry. We do this by picking the minimum ROWID of a particular set 145 1.1 jmmv -- of properties that map to a single test_program_id or test_case_id. 146 1.1 jmmv CREATE TABLE tmp_metadatas ( 147 1.1 jmmv test_program_id INTEGER DEFAULT NULL, 148 1.1 jmmv test_case_id INTEGER DEFAULT NULL, 149 1.1 jmmv interface TEXT NOT NULL, 150 1.1 jmmv property_name TEXT NOT NULL, 151 1.1 jmmv property_value TEXT NOT NULL, 152 1.1 jmmv 153 1.1 jmmv UNIQUE (test_program_id, test_case_id, property_name) 154 1.1 jmmv ); 155 1.1 jmmv CREATE INDEX index_tmp_metadatas_by_test_case_id 156 1.1 jmmv ON tmp_metadatas (test_case_id); 157 1.1 jmmv CREATE INDEX index_tmp_metadatas_by_test_program_id 158 1.1 jmmv ON tmp_metadatas (test_program_id); 159 1.1 jmmv 160 1.1 jmmv 161 1.1 jmmv -- Populate default metadata values for all test programs and test cases. 162 1.1 jmmv -- 163 1.1 jmmv -- We do this first to ensure that all test programs and test cases have 164 1.1 jmmv -- explicit values for their metadata. Because we want to keep historical data 165 1.1 jmmv -- for the tests, we must record these values unconditionally instead of relying 166 1.1 jmmv -- on the built-in values in the code. 167 1.1 jmmv -- 168 1.1 jmmv -- Once this is done, we override any values explicity set by the tests. 169 1.1 jmmv CREATE TABLE tmp_default_metadata ( 170 1.1 jmmv default_name TEXT PRIMARY KEY, 171 1.1 jmmv default_value TEXT NOT NULL 172 1.1 jmmv ); 173 1.1 jmmv INSERT INTO tmp_default_metadata VALUES ('allowed_architectures', ''); 174 1.1 jmmv INSERT INTO tmp_default_metadata VALUES ('allowed_platforms', ''); 175 1.1 jmmv INSERT INTO tmp_default_metadata VALUES ('description', ''); 176 1.1 jmmv INSERT INTO tmp_default_metadata VALUES ('has_cleanup', 'false'); 177 1.1 jmmv INSERT INTO tmp_default_metadata VALUES ('required_configs', ''); 178 1.1 jmmv INSERT INTO tmp_default_metadata VALUES ('required_files', ''); 179 1.1 jmmv INSERT INTO tmp_default_metadata VALUES ('required_memory', '0'); 180 1.1 jmmv INSERT INTO tmp_default_metadata VALUES ('required_programs', ''); 181 1.1 jmmv INSERT INTO tmp_default_metadata VALUES ('required_user', ''); 182 1.1 jmmv INSERT INTO tmp_default_metadata VALUES ('timeout', '300'); 183 1.1 jmmv INSERT INTO tmp_metadatas 184 1.1 jmmv SELECT test_program_id, NULL, interface, default_name, default_value 185 1.1 jmmv FROM test_programs JOIN tmp_default_metadata; 186 1.1 jmmv INSERT INTO tmp_metadatas 187 1.1 jmmv SELECT NULL, test_case_id, interface, default_name, default_value 188 1.1 jmmv FROM test_programs JOIN test_cases 189 1.1 jmmv ON test_cases.test_program_id = test_programs.test_program_id 190 1.1 jmmv JOIN tmp_default_metadata; 191 1.1 jmmv DROP TABLE tmp_default_metadata; 192 1.1 jmmv 193 1.1 jmmv 194 1.1 jmmv -- Populate metadata overrides from plain test programs. 195 1.1 jmmv UPDATE tmp_metadatas 196 1.1 jmmv SET property_value = ( 197 1.1 jmmv SELECT CAST(timeout / 1000000 AS TEXT) FROM plain_test_programs AS aux 198 1.1 jmmv WHERE aux.test_program_id = tmp_metadatas.test_program_id) 199 1.1 jmmv WHERE test_program_id IS NOT NULL AND property_name = 'timeout' 200 1.1 jmmv AND interface = 'plain'; 201 1.1 jmmv UPDATE tmp_metadatas 202 1.1 jmmv SET property_value = ( 203 1.1 jmmv SELECT DISTINCT CAST(timeout / 1000000 AS TEXT) 204 1.1 jmmv FROM test_cases AS aux JOIN plain_test_programs 205 1.1 jmmv ON aux.test_program_id == plain_test_programs.test_program_id 206 1.1 jmmv WHERE aux.test_case_id = tmp_metadatas.test_case_id) 207 1.1 jmmv WHERE test_case_id IS NOT NULL AND property_name = 'timeout' 208 1.1 jmmv AND interface = 'plain'; 209 1.1 jmmv 210 1.1 jmmv 211 1.1 jmmv -- Populate metadata overrides from ATF test cases. 212 1.1 jmmv UPDATE atf_test_cases SET description = '' WHERE description IS NULL; 213 1.1 jmmv UPDATE atf_test_cases SET required_user = '' WHERE required_user IS NULL; 214 1.1 jmmv 215 1.1 jmmv UPDATE tmp_metadatas 216 1.1 jmmv SET property_value = ( 217 1.1 jmmv SELECT description FROM atf_test_cases AS aux 218 1.1 jmmv WHERE aux.test_case_id = tmp_metadatas.test_case_id) 219 1.1 jmmv WHERE test_case_id IS NOT NULL AND property_name = 'description' 220 1.1 jmmv AND interface = 'atf'; 221 1.1 jmmv UPDATE tmp_metadatas 222 1.1 jmmv SET property_value = ( 223 1.1 jmmv SELECT has_cleanup FROM atf_test_cases AS aux 224 1.1 jmmv WHERE aux.test_case_id = tmp_metadatas.test_case_id) 225 1.1 jmmv WHERE test_case_id IS NOT NULL AND property_name = 'has_cleanup' 226 1.1 jmmv AND interface = 'atf'; 227 1.1 jmmv UPDATE tmp_metadatas 228 1.1 jmmv SET property_value = ( 229 1.1 jmmv SELECT CAST(timeout / 1000000 AS TEXT) FROM atf_test_cases AS aux 230 1.1 jmmv WHERE aux.test_case_id = tmp_metadatas.test_case_id) 231 1.1 jmmv WHERE test_case_id IS NOT NULL AND property_name = 'timeout' 232 1.1 jmmv AND interface = 'atf'; 233 1.1 jmmv UPDATE tmp_metadatas 234 1.1 jmmv SET property_value = ( 235 1.1 jmmv SELECT CAST(required_memory AS TEXT) FROM atf_test_cases AS aux 236 1.1 jmmv WHERE aux.test_case_id = tmp_metadatas.test_case_id) 237 1.1 jmmv WHERE test_case_id IS NOT NULL AND property_name = 'required_memory' 238 1.1 jmmv AND interface = 'atf'; 239 1.1 jmmv UPDATE tmp_metadatas 240 1.1 jmmv SET property_value = ( 241 1.1 jmmv SELECT required_user FROM atf_test_cases AS aux 242 1.1 jmmv WHERE aux.test_case_id = tmp_metadatas.test_case_id) 243 1.1 jmmv WHERE test_case_id IS NOT NULL AND property_name = 'required_user' 244 1.1 jmmv AND interface = 'atf'; 245 1.1 jmmv UPDATE tmp_metadatas 246 1.1 jmmv SET property_value = ( 247 1.1 jmmv SELECT GROUP_CONCAT(aux.property_value, ' ') 248 1.1 jmmv FROM atf_test_cases_multivalues AS aux 249 1.1 jmmv WHERE aux.test_case_id = tmp_metadatas.test_case_id AND 250 1.1 jmmv aux.property_name = 'require.arch') 251 1.1 jmmv WHERE test_case_id IS NOT NULL AND property_name = 'allowed_architectures' 252 1.1 jmmv AND interface = 'atf' 253 1.1 jmmv AND EXISTS(SELECT 1 FROM atf_test_cases_multivalues AS aux 254 1.1 jmmv WHERE aux.test_case_id = tmp_metadatas.test_case_id 255 1.1 jmmv AND property_name = 'require.arch'); 256 1.1 jmmv UPDATE tmp_metadatas 257 1.1 jmmv SET property_value = ( 258 1.1 jmmv SELECT GROUP_CONCAT(aux.property_value, ' ') 259 1.1 jmmv FROM atf_test_cases_multivalues AS aux 260 1.1 jmmv WHERE aux.test_case_id = tmp_metadatas.test_case_id AND 261 1.1 jmmv aux.property_name = 'require.machine') 262 1.1 jmmv WHERE test_case_id IS NOT NULL AND property_name = 'allowed_platforms' 263 1.1 jmmv AND interface = 'atf' 264 1.1 jmmv AND EXISTS(SELECT 1 FROM atf_test_cases_multivalues AS aux 265 1.1 jmmv WHERE aux.test_case_id = tmp_metadatas.test_case_id 266 1.1 jmmv AND property_name = 'require.machine'); 267 1.1 jmmv UPDATE tmp_metadatas 268 1.1 jmmv SET property_value = ( 269 1.1 jmmv SELECT GROUP_CONCAT(aux.property_value, ' ') 270 1.1 jmmv FROM atf_test_cases_multivalues AS aux 271 1.1 jmmv WHERE aux.test_case_id = tmp_metadatas.test_case_id AND 272 1.1 jmmv aux.property_name = 'require.config') 273 1.1 jmmv WHERE test_case_id IS NOT NULL AND property_name = 'required_configs' 274 1.1 jmmv AND interface = 'atf' 275 1.1 jmmv AND EXISTS(SELECT 1 FROM atf_test_cases_multivalues AS aux 276 1.1 jmmv WHERE aux.test_case_id = tmp_metadatas.test_case_id 277 1.1 jmmv AND property_name = 'require.config'); 278 1.1 jmmv UPDATE tmp_metadatas 279 1.1 jmmv SET property_value = ( 280 1.1 jmmv SELECT GROUP_CONCAT(aux.property_value, ' ') 281 1.1 jmmv FROM atf_test_cases_multivalues AS aux 282 1.1 jmmv WHERE aux.test_case_id = tmp_metadatas.test_case_id AND 283 1.1 jmmv aux.property_name = 'require.files') 284 1.1 jmmv WHERE test_case_id IS NOT NULL AND property_name = 'required_files' 285 1.1 jmmv AND interface = 'atf' 286 1.1 jmmv AND EXISTS(SELECT 1 FROM atf_test_cases_multivalues AS aux 287 1.1 jmmv WHERE aux.test_case_id = tmp_metadatas.test_case_id 288 1.1 jmmv AND property_name = 'require.files'); 289 1.1 jmmv UPDATE tmp_metadatas 290 1.1 jmmv SET property_value = ( 291 1.1 jmmv SELECT GROUP_CONCAT(aux.property_value, ' ') 292 1.1 jmmv FROM atf_test_cases_multivalues AS aux 293 1.1 jmmv WHERE aux.test_case_id = tmp_metadatas.test_case_id AND 294 1.1 jmmv aux.property_name = 'require.progs') 295 1.1 jmmv WHERE test_case_id IS NOT NULL AND property_name = 'required_programs' 296 1.1 jmmv AND interface = 'atf' 297 1.1 jmmv AND EXISTS(SELECT 1 FROM atf_test_cases_multivalues AS aux 298 1.1 jmmv WHERE aux.test_case_id = tmp_metadatas.test_case_id 299 1.1 jmmv AND property_name = 'require.progs'); 300 1.1 jmmv 301 1.1 jmmv 302 1.1 jmmv -- Fill metadata_id pointers in the test_programs and test_cases tables. 303 1.1 jmmv UPDATE test_programs 304 1.1 jmmv SET metadata_id = ( 305 1.1 jmmv SELECT MIN(ROWID) FROM tmp_metadatas 306 1.1 jmmv WHERE tmp_metadatas.test_program_id = test_programs.test_program_id 307 1.1 jmmv ); 308 1.1 jmmv UPDATE test_cases 309 1.1 jmmv SET metadata_id = ( 310 1.1 jmmv SELECT MIN(ROWID) FROM tmp_metadatas 311 1.1 jmmv WHERE tmp_metadatas.test_case_id = test_cases.test_case_id 312 1.1 jmmv ); 313 1.1 jmmv 314 1.1 jmmv 315 1.1 jmmv -- Populate the metadatas table based on tmp_metadatas. 316 1.1 jmmv INSERT INTO metadatas (metadata_id, property_name, property_value) 317 1.1 jmmv SELECT ( 318 1.1 jmmv SELECT MIN(ROWID) FROM tmp_metadatas AS s 319 1.1 jmmv WHERE s.test_program_id = tmp_metadatas.test_program_id 320 1.1 jmmv ), property_name, property_value 321 1.1 jmmv FROM tmp_metadatas WHERE test_program_id IS NOT NULL; 322 1.1 jmmv INSERT INTO metadatas (metadata_id, property_name, property_value) 323 1.1 jmmv SELECT ( 324 1.1 jmmv SELECT MIN(ROWID) FROM tmp_metadatas AS s 325 1.1 jmmv WHERE s.test_case_id = tmp_metadatas.test_case_id 326 1.1 jmmv ), property_name, property_value 327 1.1 jmmv FROM tmp_metadatas WHERE test_case_id IS NOT NULL; 328 1.1 jmmv 329 1.1 jmmv 330 1.1 jmmv -- Drop temporary entities used during the migration. 331 1.1 jmmv DROP INDEX index_tmp_metadatas_by_test_program_id; 332 1.1 jmmv DROP INDEX index_tmp_metadatas_by_test_case_id; 333 1.1 jmmv DROP TABLE tmp_metadatas; 334 1.1 jmmv 335 1.1 jmmv 336 1.1 jmmv -- 337 1.1 jmmv -- Drop obsolete tables. 338 1.1 jmmv -- 339 1.1 jmmv 340 1.1 jmmv 341 1.1 jmmv DROP TABLE atf_test_cases; 342 1.1 jmmv DROP TABLE atf_test_cases_multivalues; 343 1.1 jmmv DROP TABLE plain_test_programs; 344 1.1 jmmv 345 1.1 jmmv 346 1.1 jmmv -- 347 1.1 jmmv -- Update the metadata version. 348 1.1 jmmv -- 349 1.1 jmmv 350 1.1 jmmv 351 1.1 jmmv INSERT INTO metadata (timestamp, schema_version) 352 1.1 jmmv VALUES (strftime('%s', 'now'), 2); 353