r1346 + last changes before RackTables 0.14.7 release
[racktables] / upgrade.php
1 <?php
2
3 // At the moment we assume, that for any two releases we can
4 // sequentally execute all batches, that separate them, and
5 // nothing will break. If this changes one day, the function
6 // below will have to generate smarter upgrade paths, while
7 // the upper layer will remain the same.
8 // Returning an empty array means that no upgrade is necessary.
9 function getDBUpgradePath ($v1, $v2)
10 {
11 $versionhistory = array ('0.14.4', '0.14.5', '0.14.6', '0.14.7');
12 if (!in_array ($v1, $versionhistory) || !in_array ($v2, $versionhistory))
13 {
14 showError ("An upgrade path has been requested for versions '${v1}' and '${v2}', " .
15 "and at least one of those isn't known to me.");
16 die;
17 }
18 $skip = TRUE;
19 $path = array();
20 // Now collect all versions > $v1 and <= $v2
21 foreach ($versionhistory as $v)
22 {
23 if ($v == $v1)
24 {
25 $skip = FALSE;
26 continue;
27 }
28 if ($skip)
29 continue;
30 $path[] = $v;
31 if ($v == $v2)
32 break;
33 }
34 return $path;
35 }
36
37 // Upgrade batches are name exactly as the release where they first appear.
38 // That simple, but seems sufficient for beginning.
39 function executeUpgradeBatch ($batchid)
40 {
41 $query = array();
42 global $dbxlink;
43 switch ($batchid)
44 {
45 case '0.14.5':
46 // We can't realiably distinguish between 0.14.4 and 0.14.5, but
47 // luckily the SQL statements below can be safely executed for both.
48
49
50 // This has to be checked once more to be sure IPAddress allocation
51 // conventions are correct.
52 $query[] = "delete from IPAddress where name = '' and reserved = 'no'";
53
54 // In the 0.14.4 release we had AUTO_INCREMENT low in the dictionary and auth
55 // data tables, thus causing new user's data to take primary keys equal to
56 // the values of shipped data in future releases. Let's shift user's data
57 // up and keep DB consistent.
58 $query[] = "alter table Attribute AUTO_INCREMENT = 10000";
59 $query[] = "alter table Chapter AUTO_INCREMENT = 10000";
60 $query[] = "alter table Dictionary AUTO_INCREMENT = 10000";
61 $query[] = "alter table UserAccount AUTO_INCREMENT = 10000";
62 $query[] = "update UserAccount set user_id = user_id + 10000 where user_id between 2 and 10000";
63 $query[] = "update UserPermission set user_id = user_id + 10000 where user_id between 2 and 10000";
64 $query[] = "update Attribute set attr_id = attr_id + 10000 where attr_id between 25 and 10000";
65 $query[] = "update AttributeMap set attr_id = attr_id + 10000 where attr_id between 25 and 10000";
66 $query[] = "update Chapter set chapter_no = chapter_no + 10000 where chapter_no between 21 and 10000";
67 $query[] = "update AttributeMap set chapter_no = chapter_no + 10000 where chapter_no between 21 and 10000";
68 break; // --------------------------------------------
69 case '0.14.6':
70 // This version features new dictionary entries, the correction above should allow us
71 // inject them w/o a problem.
72 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (13,25,'FreeBSD 1.x')";
73 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (13,26,'FreeBSD 2.x')";
74 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (13,27,'FreeBSD 3.x')";
75 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (13,28,'FreeBSD 4.x')";
76 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (13,29,'FreeBSD 5.x')";
77 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (13,30,'FreeBSD 6.x')";
78 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (13,31,'RHFC8')";
79 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (13,32,'ALTLinux Master 4.0')";
80 $query[] = "INSERT INTO `PortCompat` (`type1`, `type2`) VALUES (20,20)";
81 $query[] = "INSERT INTO `PortCompat` (`type1`, `type2`) VALUES (21,21)";
82 $query[] = "INSERT INTO `PortCompat` (`type1`, `type2`) VALUES (22,22)";
83 $query[] = "INSERT INTO `PortCompat` (`type1`, `type2`) VALUES (23,23)";
84 $query[] = "INSERT INTO `PortCompat` (`type1`, `type2`) VALUES (24,24)";
85 $query[] = "INSERT INTO `PortCompat` (`type1`, `type2`) VALUES (25,25)";
86 $query[] = "INSERT INTO `PortCompat` (`type1`, `type2`) VALUES (26,26)";
87 $query[] = "INSERT INTO `PortCompat` (`type1`, `type2`) VALUES (27,27)";
88 $query[] = "INSERT INTO `PortCompat` (`type1`, `type2`) VALUES (28,28)";
89 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (2,20,'KVM')";
90 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (2,21,'1000Base-ZX')";
91 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (2,22,'10GBase-ER')";
92 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (2,23,'10GBase-LR')";
93 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (2,24,'10GBase-LRM')";
94 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (2,25,'10GBase-ZR')";
95 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (2,26,'10GBase-LX4')";
96 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (2,27,'10GBase-CX4')";
97 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (2,28,'10GBase-Kx')";
98 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (12,114,'Cisco Catalyst 2970G-24T')";
99 $query[] = "INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) VALUES (12,115,'Cisco Catalyst 2970G-24TS')";
100 $query[] = "INSERT INTO `UserPermission` (`user_id`, `page`, `tab`, `access`) VALUES (0,'help','%','yes')";
101 // And 0.14.6 is the first release, which features Config table. Let's create
102 // and fill it with default values.
103 $query[] = "
104 CREATE TABLE `Config` (
105 `varname` char(32) NOT NULL,
106 `varvalue` char(64) NOT NULL,
107 `vartype` enum('string','uint') NOT NULL default 'string',
108 `emptyok` enum('yes','no') NOT NULL default 'no',
109 `is_hidden` enum('yes','no') NOT NULL default 'yes',
110 `description` text,
111 PRIMARY KEY (`varname`)
112 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
113 ";
114 $query[] = "INSERT INTO `Config` VALUES ('rtwidth_0','9','uint','no','yes','')";
115 $query[] = "INSERT INTO `Config` VALUES ('rtwidth_1','21','uint','no','yes','')";
116 $query[] = "INSERT INTO `Config` VALUES ('rtwidth_2','9','uint','no','yes','')";
117 $query[] = "INSERT INTO `Config` VALUES ('color_F','8fbfbf','string','no','no','HSV: 180-25-75. Free atoms, they are available for allocation to objects.')";
118 $query[] = "INSERT INTO `Config` VALUES ('color_A','bfbfbf','string','no','no','HSV: 0-0-75. Absent atoms.')";
119 $query[] = "INSERT INTO `Config` VALUES ('color_U','bf8f8f','string','no','no','HSV: 0-25-75. Unusable atoms. Some problems keep them from being free.')";
120 $query[] = "INSERT INTO `Config` VALUES ('color_T','408080','string','no','no','HSV: 180-50-50. Taken atoms, object_id should be set for such.')";
121 $query[] = "INSERT INTO `Config` VALUES ('color_Th','80ffff','string','no','no','HSV: 180-50-100. Taken atoms with highlight. They are not stored in the database and are only used for highlighting.')";
122 $query[] = "INSERT INTO `Config` VALUES ('color_Tw','804040','string','no','no','HSV: 0-50-50. Taken atoms with object problem. This is detected at runtime.')";
123 $query[] = "INSERT INTO `Config` VALUES ('color_Thw','ff8080','string','no','no','HSV: 0-50-100. An object can be both current and problematic. We run highlightObject() first and markupObjectProblems() second.')";
124 $query[] = "INSERT INTO `Config` VALUES ('default_port_type','11','uint','no','no','Default value for port type selects.')";
125 $query[] = "INSERT INTO `Config` VALUES ('MASSCOUNT','15','uint','no','no','Number of lines in object mass-adding form.')";
126 $query[] = "INSERT INTO `Config` VALUES ('MAXSELSIZE','30','uint','no','no','Maximum size of a SELECT HTML element.')";
127 $query[] = "INSERT INTO `Config` VALUES ('enterprise','MyCompanyName','string','no','no','Fit to your needs.')";
128 $query[] = "INSERT INTO `Config` VALUES ('NAMEFUL_OBJTYPES','4,7,8','string','yes','no','These are the object types, which assume a common name to be normally configured. If a name is absent for an object of one of such types, HTML output is corrected to accent this misconfiguration.')";
129 $query[] = "INSERT INTO `Config` VALUES ('ROW_SCALE','2','uint','no','no','Row-scope picture scale factor.')";
130 $query[] = "INSERT INTO `Config` VALUES ('PORTS_PER_ROW','12','uint','no','yes','Max switch port per one row on the switchvlans dynamic tab.')";
131 $query[] = "INSERT INTO `Config` VALUES ('DB_VERSION','0.14.6','string','no','yes','Database version.')";
132 break; // --------------------------------------------
133 case '0.14.7':
134 // IPAddress is hopefully fixed now finally.
135 $query[] = "delete from IPAddress where name = '' and reserved != 'yes'";
136
137 // Now rebuild the dictionary into a new table with the same data,
138 // but proper indexing. We are going to convert compound index
139 // into 1-field one to employ AUTO_INCREMENT properly. This means
140 // renumbering lots of records in Dictionary and adjusting records
141 // in related tables. After that we can safely swap the tables.
142 $query[] = "
143 CREATE TABLE `Dictionary_0_14_7_new` (
144 `chapter_no` int(10) unsigned NOT NULL,
145 `dict_key` int(10) unsigned NOT NULL auto_increment,
146 `dict_value` char(128) default NULL,
147 PRIMARY KEY (`dict_key`),
148 UNIQUE KEY `chap_to_key` (`chapter_no`,`dict_key`),
149 UNIQUE KEY `chap_to_val` (`chapter_no`,`dict_value`)
150 ) TYPE=MyISAM AUTO_INCREMENT=50000
151 ";
152
153 echo '<pre>';
154 // Find all chapter numbers, which will require AttributeValue adjustment.
155 $q2 = 'select distinct chapter_no from AttributeMap where chapter_no != 0';
156 $r2 = $dbxlink->query ($q2);
157 $chaplist = array();
158 while ($row = $r2->fetch (PDO::FETCH_NUM))
159 $chaplist[] = $row[0];
160 print_r ($chaplist);
161 $r2->closeCursor();
162 unset ($r2);
163
164 $stock = array();
165 // Below I list the records, which are known to be the stock
166 // dictionary records of 0.14.6 release.
167 $stock[1] = array
168 (
169 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16
170 );
171 $stock[2] = array
172 (
173 3, 4, 5, 6, 7, 8, 9,
174 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
175 20, 21, 22, 23, 24, 25, 26, 27, 28
176 );
177 $stock[11] = array
178 (
179 1, 3, 4, 5, 6, 7, 8, 9,
180 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
181 21, 22, 24, 25, 26, 27, 28, 29,
182 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
183 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
184 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
185 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
186 70, 71, 72, 73, 74, 75, 76
187 );
188 $stock[12] = array
189 (
190 1, 11, 13, 14, 15, 16, 17, 18, 19, 20, 26, 29,
191 31, 32, 33, 34, 35, 36, 37, 38, 39,
192 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
193 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
194 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
195 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
196 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
197 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
198 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
199 110, 111, 112, 113, 114, 115
200 );
201 $stock[13] = array
202 (
203 1, 2, 3, 4, 5, 6, 7, 8, 9,
204 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
205 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
206 30, 31, 32
207 );
208 $stock[14] = array
209 (
210 1, 2, 9, 11, 13, 15, 19, 20, 21, 22
211 );
212 $stock[16] = array
213 (
214 1, 2, 3, 4, 5, 6, 7, 8
215 );
216 $stock[17] = array
217 (
218 1, 2, 3, 4, 5, 6, 7, 8, 9,
219 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
220 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
221 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
222 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
223 50
224 );
225 $stock[18] = array
226 (
227 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
228 );
229 $stock[19] = array
230 (
231 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
232 );
233 $stock[20] = array
234 (
235 1, 2
236 );
237
238 // Load dictionary and transform into two tree structures for
239 // stock and user record sets.
240 $dict = array();
241 $q3 = 'select chapter_no, dict_key, dict_value from Dictionary order by chapter_no, dict_key';
242 $r3 = $dbxlink->query ($q3);
243
244 while ($row = $r3->fetch (PDO::FETCH_ASSOC))
245 {
246 $tree = 'user';
247 $dict_key = $row['dict_key'];
248 $chapter_no = $row['chapter_no'];
249 switch ($chapter_no)
250 {
251 case 1: // RackObjectType
252 case 2: // PortType
253 case 11: // server models
254 case 12: // network switch models
255 case 13: // server OS type
256 case 14: // network switch OS type
257 case 16: // router OS type
258 case 17: // router models
259 case 18: // disk array models
260 case 19: // tape library models
261 case 20: // Protocols
262 if (in_array ($dict_key, $stock[$chapter_no]))
263 $tree = 'stock';
264 break;
265 }
266 $dict[$tree][$chapter_no][$dict_key] = array ('value' => $row['dict_value']);
267 }
268 $r3->closeCursor();
269 unset ($r3);
270
271
272 // Now we store stock dataset first, bump up key value and store
273 // user's data. After that we will know the new dict_key for all
274 // records.
275 // The result of both datasets processing is saved in $new_dict.
276 // Save on calling LAST_ISERT_ID() each time by keeping own key.
277 $newkey = 1;
278 $new_dict = array();
279 foreach ($dict['stock'] as $chapter_no => $words)
280 {
281 $new_dict[$chapter_no] = array();
282 foreach ($words as $dict_key => $entry)
283 {
284 $query[] = "insert into Dictionary_0_14_7_new (chapter_no, dict_key, dict_value) " .
285 "values (${chapter_no}, ${newkey}, '${entry['value']}')";
286 $new_dict[$chapter_no][$dict_key] = $entry;
287 $new_dict[$chapter_no][$dict_key]['newkey'] = $newkey;
288 $newkey++;
289 }
290 }
291 $newkey = 50000;
292 foreach ($dict['user'] as $chapter_no => $words)
293 {
294 // Some chapters may appear on the user dataset only.
295 if (!isset ($new_dict[$chapter_no]))
296 $new_dict[$chapter_no] = array();
297 foreach ($words as $dict_key => $entry)
298 {
299 $query[] = "insert into Dictionary_0_14_7_new " .
300 "values (${chapter_no}, ${newkey}, '${entry['value']}')";
301 $new_dict[$chapter_no][$dict_key] = $entry;
302 $new_dict[$chapter_no][$dict_key]['newkey'] = $newkey;
303 $newkey++;
304 }
305 }
306 // The new table should now have adequate AUTO_INCREMENT w/o our care.
307 // Install the new data.
308 $query[] = 'drop table Dictionary';
309 $query[] = 'alter table Dictionary_0_14_7_new rename to Dictionary';
310
311 // Now we iterate over the joint dataset, picking some chapters and
312 // performing additional processing:
313 // 1 (RackObjectType) --- adjust RackObject and regenerate AttributeMap
314 // 2 (PortType) --- adjust Port and regenerate PortCompat (at a latter point)
315 // 3 (RackRow) --- adjust Rack
316 // 20 (Protocols) --- adjust PortForwarding
317 // All other chapters listed in $chaplist --- adjust AttributeValue
318
319 $query[] = "delete from AttributeMap";
320 foreach ($new_dict as $chapter_no => $words)
321 {
322 echo "Processing chapter ${chapter_no}\n";
323 foreach ($words as $oldkey => $data)
324 {
325 $value = $data['value'];
326 $newkey = $data['newkey'];
327 // Even if the key doesn't change, go on to have
328 // AttributeMap regenerated completely.
329 #echo "oldkey == ${oldkey} newkey == ${newkey} value == ${value}\n";
330 if ($chapter_no == 1)
331 {
332 $q4 = "select id from RackObject where objtype_id = ${oldkey}";
333 $r4 = $dbxlink->query ($q4);
334 while ($row = $r4->fetch (PDO::FETCH_ASSOC))
335 $query[] = "update RackObject set objtype_id = ${newkey} where id = ${row['id']} limit 1";
336 $r4->closeCursor();
337 unset ($r4);
338
339 $q5 = "select attr_id, chapter_no from AttributeMap where objtype_id = ${oldkey}";
340 $r5 = $dbxlink->query ($q5);
341 while ($row = $r5->fetch (PDO::FETCH_ASSOC))
342 $query[] = "insert into AttributeMap (objtype_id, attr_id, chapter_no) values (${newkey}, ${row['attr_id']}, ${row['chapter_no']})";
343 $r5->closeCursor();
344 unset ($r5);
345 }
346 elseif ($chapter_no == 2)
347 {
348 $q46 = "select id from Port where type = ${oldkey}";
349 $r46 = $dbxlink->query ($q46);
350 if ($r46 == NULL)
351 echo 'ERROR';
352 while ($row = $r46->fetch (PDO::FETCH_ASSOC))
353 $query[] = "update Port set type = ${newkey} where id = ${row['id']} limit 1";
354 $r46->closeCursor();
355 unset ($r46);
356 }
357 elseif ($chapter_no == 3)
358 {
359 $q7 = "select id from Rack where row_id = ${oldkey}";
360 $r7 = $dbxlink->query ($q7);
361 while ($row = $r7->fetch (PDO::FETCH_ASSOC))
362 $query[] = "update Rack set row_id = ${newkey} where id = ${row['id']} limit 1";
363 $r7->closeCursor();
364 unset ($r7);
365 }
366 elseif ($chapter_no == 20)
367 {
368 $q8 = "select object_id, localip, localport, remoteip, remoteport from PortForwarding where proto = ${oldkey}";
369 $r8 = $dbxlink->query ($q8);
370 while ($row = $r8->fetch (PDO::FETCH_ASSOC))
371 $query[] = "update PortForwarding set proto = ${newkey} where " .
372 "object_id = ${row['object_id']} and localip = ${row['localip']} and " .
373 "localport = ${row['localport']} and remoteip = ${row['remoteip']} and " .
374 "remoteport = ${row['remoteport']} and proto = ${oldkey} limit 1";
375 $r8->closeCursor();
376 unset ($r8);
377 }
378 elseif (in_array ($chapter_no, $chaplist))
379 {
380 $q81 = "select object_id, attr_id from " .
381 "AttributeValue natural join Attribute natural join AttributeMap " .
382 "inner join RackObject on RackObject.id = object_id and RackObject.objtype_id = AttributeMap.objtype_id " .
383 "where attr_type = 'dict' and chapter_no = ${chapter_no} and uint_value = ${oldkey}";
384 $r81 = $dbxlink->query ($q81);
385 while ($row = $r81->fetch (PDO::FETCH_ASSOC))
386 $query[] = "update AttributeValue set uint_value = ${newkey} " .
387 "where object_id = ${row['object_id']} and attr_id = ${row['attr_id']}";
388 $r81->closeCursor();
389 unset ($r81);
390 }
391 }
392 }
393 // Now it's possible to schedule PortCompat regeneration.
394 // Convert the fields to unsigned on occasion.
395 $query[] = 'drop table PortCompat';
396 $query[] = 'create table PortCompat (type1 int(10) unsigned NOT NULL, type2 int(10) unsigned NOT NULL)';
397 $q9 = "select type1, type2 from PortCompat";
398 $r9 = $dbxlink->query ($q9);
399 while ($row = $r9->fetch (PDO::FETCH_ASSOC))
400 {
401 $new_type1 = $new_dict[2][$row['type1']]['newkey'];
402 $new_type2 = $new_dict[2][$row['type2']]['newkey'];
403 $query[] = "insert into PortCompat (type1, type2) values (${new_type1}, ${new_type2})";
404 }
405 $r9->closeCursor();
406 unset ($r9);
407 echo '</pre>';
408
409 // Give the configuration some finish
410 $query[] = "update Config set is_hidden = 'yes' where varname = 'color_F'";
411 $query[] = "update Config set is_hidden = 'yes' where varname = 'color_A'";
412 $query[] = "update Config set is_hidden = 'yes' where varname = 'color_U'";
413 $query[] = "update Config set is_hidden = 'yes' where varname = 'color_T'";
414 $query[] = "update Config set is_hidden = 'yes' where varname = 'color_Th'";
415 $query[] = "update Config set is_hidden = 'yes' where varname = 'color_Tw'";
416 $query[] = "update Config set is_hidden = 'yes' where varname = 'color_Thw'";
417 $query[] = "update Config set description = 'Default port type' where varname = 'default_port_type'";
418 $query[] = "update Config set description = 'Picture scale for rack row display' where varname = 'ROW_SCALE'";
419 $query[] = "update Config set description = 'Organization name' where varname = 'enterprise'";
420 $query[] = "update Config set description = 'Expect common name configured for the following object types' where varname = 'NAMEFUL_OBJTYPES'";
421 $query[] = "update Config set description = '&lt;SELECT&gt; lists height' where varname = 'MAXSELSIZE'";
422 $query[] = "update Config set description = '&quot;Fast&quot; form is this many records tall' where varname = 'MASSCOUNT'";
423 $query[] = "update Config set is_hidden = 'no', description = 'Ports per row in VLANs tab' where varname = 'PORTS_PER_ROW'";
424 $query[] = "INSERT INTO `Config` VALUES ('IPV4_ADDRS_PER_PAGE','256','uint','no','no','IPv4 addresses per page')";
425 $query[] = "INSERT INTO `Config` VALUES ('DEFAULT_RACK_HEIGHT','42','uint','yes','no','Default rack height')";
426 // After Dictionary transformation we ought to list 337 stock records in DB. Add more.
427 $new_words = array();
428 $new_words[338] = array (12 => 'Dell PowerConnect 2216');
429 $new_words[] = array (12 => 'Dell PowerConnect 2224');
430 $new_words[] = array (12 => 'Dell PowerConnect 2324');
431 $new_words[] = array (12 => 'Dell PowerConnect 2708');
432 $new_words[] = array (12 => 'Dell PowerConnect 2716');
433 $new_words[] = array (12 => 'Dell PowerConnect 2724');
434 $new_words[] = array (12 => 'Dell PowerConnect 2748');
435 $new_words[] = array (12 => 'Dell PowerConnect 3424');
436 $new_words[] = array (12 => 'Dell PowerConnect 3424P');
437 $new_words[] = array (12 => 'Dell PowerConnect 3448');
438 $new_words[] = array (12 => 'Dell PowerConnect 3448P');
439 $new_words[] = array (12 => 'Dell PowerConnect 5324');
440 $new_words[] = array (12 => 'Dell PowerConnect 6224');
441 $new_words[] = array (12 => 'Dell PowerConnect 6224P');
442 $new_words[] = array (12 => 'Dell PowerConnect 6224F');
443 $new_words[] = array (12 => 'Dell PowerConnect 6248');
444 $new_words[] = array (12 => 'Dell PowerConnect 6248P');
445 $new_words[] = array (11 => 'Dell PowerEdge 6850');
446 $new_words[] = array (11 => 'Dell PowerEdge 6950');
447 $new_words[] = array (11 => 'Dell PowerEdge R900');
448 $new_words[] = array (11 => 'Dell PowerEdge 4400');
449 $new_words[] = array (11 => 'Dell PowerEdge 2650');
450 $new_words[] = array (11 => 'Dell PowerEdge 2550');
451 $new_words[] = array (11 => 'Dell PowerEdge 750');
452 $new_words[] = array (11 => 'Dell PowerEdge 2450');
453 $new_words[] = array (11 => 'Dell PowerEdge 850');
454 $new_words[] = array (11 => 'Dell PowerEdge 1850');
455 $new_words[] = array (11 => 'Dell PowerEdge 860');
456 $new_words[] = array (11 => 'Dell PowerEdge 2900');
457 $new_words[] = array (11 => 'Dell PowerEdge 2970');
458 $new_words[] = array (11 => 'Dell PowerEdge SC1435');
459 $new_words[] = array (12 => 'Cisco Catalyst 6509');
460 $new_words[] = array (12 => 'Cisco ME 6524GS-8S');
461 $new_words[] = array (12 => 'Cisco ME 6524GT-8S');
462 $new_words[] = array (12 => 'Cisco Catalyst 4503-E');
463 $new_words[] = array (12 => 'Cisco Catalyst 4506-E');
464 $new_words[] = array (12 => 'Cisco Catalyst 4507R-E');
465 $new_words[] = array (12 => 'Cisco Catalyst 4510R-E');
466 $new_words[] = array (12 => 'Cisco Catalyst 3750-24TE-M');
467 $new_words[] = array (12 => 'Cisco Catalyst 4948-10GE');
468 $new_words[] = array (12 => 'Cisco ME 4924-10GE');
469 $new_words[] = array (12 => 'Cisco Catalyst 2960-24');
470 $new_words[] = array (12 => 'Cisco Catalyst 2950-24');
471 $new_words[] = array (12 => 'Cisco Catalyst 2950-12');
472 $new_words[] = array (12 => 'Cisco Catalyst 2950C-24');
473 $new_words[] = array (12 => 'Cisco Catalyst 2950G-24-DC');
474 $new_words[] = array (12 => 'Cisco Catalyst 2950SX-48');
475 $new_words[] = array (12 => 'Cisco Catalyst 2950SX-24');
476 $new_words[] = array (12 => 'Cisco Catalyst 2950T-24');
477 $new_words[] = array (12 => 'Cisco Catalyst 2950T-48');
478 $new_words[] = array (12 => 'Cisco Catalyst 2950G-12');
479 $new_words[] = array (12 => 'Cisco Catalyst 2950G-24');
480 $new_words[] = array (12 => 'Cisco Catalyst 2950G-48');
481 $new_words[] = array (12 => 'Cisco Catalyst 3508G XL');
482 $new_words[] = array (12 => 'Cisco Catalyst 3512 XL');
483 $new_words[] = array (12 => 'Cisco Catalyst 3524 XL');
484 $new_words[] = array (12 => 'Cisco Catalyst 3524 PWR XL');
485 $new_words[] = array (12 => 'Cisco Catalyst 3548 XL');
486 $new_words[] = array (12 => 'Cisco ME 2400-24TS-A');
487 $new_words[] = array (12 => 'Cisco ME 2400-24TS-D');
488 $new_words[] = array (12 => 'Cisco Catalyst 3550-12T');
489 $new_words[] = array (12 => 'Cisco Catalyst 3550-12G');
490 $new_words[] = array (12 => 'Cisco Catalyst 3550-24');
491 $new_words[] = array (12 => 'Cisco Catalyst 3550-24 FX');
492 $new_words[] = array (12 => 'Cisco Catalyst 3550-24 DC');
493 $new_words[] = array (12 => 'Cisco Catalyst 3550-24 PWR');
494 $new_words[] = array (12 => 'Cisco Catalyst 3550-48');
495 $new_words[] = array (12 => 'Cisco ME 3400G-12CS-A');
496 $new_words[] = array (12 => 'Cisco ME 3400G-12CS-D');
497 $new_words[] = array (12 => 'Cisco ME 3400G-2CS-A');
498 $new_words[] = array (12 => 'Cisco ME 3400-24TS-A');
499 $new_words[] = array (12 => 'Cisco ME 3400-24TS-D');
500 $new_words[] = array (12 => 'Cisco ME 3400-24FS-A');
501 $new_words[] = array (12 => 'Foundry FastIron GS 624XGP');
502 $new_words[] = array (12 => 'Foundry FastIron GS 624XGP-POE');
503 $new_words[] = array (12 => 'Foundry FastIron LS 624');
504 $new_words[] = array (12 => 'Foundry FastIron LS 648');
505 $new_words[] = array (12 => 'Foundry NetIron M2404F');
506 $new_words[] = array (12 => 'Foundry NetIron M2404C');
507 $new_words[] = array (17 => 'Foundry BigIron RX-32');
508 $new_words[] = array (13 => 'Debian 2.0 (hamm)');
509 $new_words[] = array (13 => 'Debian 2.1 (slink)');
510 $new_words[] = array (13 => 'Debian 2.2 (potato)');
511 $new_words[] = array (13 => 'Debian 4.0 (etch)');
512 $new_words[] = array (13 => 'ALTLinux Server 4.0');
513 $new_words[] = array (13 => 'ALTLinux Sisyphus');
514 $new_words[] = array (13 => 'openSUSE 10.0');
515 $new_words[] = array (13 => 'openSUSE 10.1');
516 $new_words[] = array (13 => 'openSUSE 10.2');
517 $new_words[] = array (13 => 'openSUSE 10.3');
518 $new_words[] = array (13 => 'Ubuntu 4.10');
519 $new_words[] = array (13 => 'Ubuntu 5.04');
520 $new_words[] = array (13 => 'Ubuntu 5.10');
521 $new_words[] = array (13 => 'Ubuntu 6.06 LTS');
522 $new_words[] = array (13 => 'Ubuntu 6.10');
523 $new_words[] = array (13 => 'Ubuntu 7.04');
524 $new_words[] = array (13 => 'Ubuntu 7.10');
525 $new_words[] = array (13 => 'Ubuntu 8.04 LTS');
526 $new_words[] = array (13 => 'RHEL5');
527 $new_words[] = array (18 => 'Dell PowerVault 210S');
528 $new_words[] = array (18 => 'Dell PowerVault 221S');
529 $new_words[] = array (2 => 'dry contact');
530 $new_words[] = array (2 => 'unknown');
531 // Two above records ought to take keys 439 and 440.
532 $query[] = "INSERT INTO `PortCompat` (`type1`, `type2`) VALUES (439,439)";
533 $new_words[] = array (13 => 'CentOS-2');
534 $new_words[] = array (13 => 'CentOS-3');
535 $new_words[] = array (13 => 'CentOS-4');
536 $new_words[] = array (13 => 'CentOS-5');
537
538
539
540 foreach ($new_words as $dict_key => $tmp)
541 foreach ($tmp as $chapter_no => $dict_value)
542 $query[] = 'INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`) ' .
543 "VALUES (${chapter_no}, ${dict_key}, '${dict_value}')";
544 // Resetting to defaults is worse, than remapping, but better than
545 // leaving messed values.
546 $query[] = "update Config set varvalue = '24' where varname = 'default_port_type' limit 1";
547 // We are done.
548 # $query[] = "update Config set varvalue = '0.14.7' where varname = 'DB_VERSION'";
549 break; // --------------------------------------------
550 default:
551 showError ("executeUpgradeBatch () failed, because batch '${batchid}' isn't defined");
552 die;
553 break;
554 }
555 $failures = array();
556 $ndots = 0;
557 echo "<pre>Executing database upgrade batch '${batchid}:\n";
558 foreach ($query as $q)
559 {
560 $result = $dbxlink->query ($q);
561 if ($result != NULL)
562 echo '.';
563 else
564 {
565 echo '!';
566 $errorInfo = $dbxlink->errorInfo();
567 $failures[] = array ($q, $errorInfo[2]);
568 }
569 if (++$ndots == 50)
570 {
571 echo "\n";
572 flush();
573 $ndots = 0;
574 }
575 }
576 echo '<br>';
577 if (!count ($failures))
578 echo "No errors!\n";
579 else
580 {
581 echo "The following queries failed:\n";
582 foreach ($failures as $f)
583 {
584 list ($q, $i) = $f;
585 echo "${q} // ${i}\n";
586 }
587 }
588 echo '</pre>';
589 }
590
591 // ******************************************************************
592 //
593 // Execution starts here
594 //
595 // ******************************************************************
596
597 $root = (empty($_SERVER['HTTPS'])?'http':'https').
598 '://'.
599 (isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:($_SERVER['SERVER_NAME'].($_SERVER['SERVER_PORT']=='80'?'':$_SERVER['SERVER_PORT']))).
600 dirname($_SERVER['PHP_SELF']).'/';
601
602 // The below will be necessary as long as we rely on showError()
603 require_once 'inc/interface.php';
604
605 require_once 'inc/config.php';
606 require_once 'inc/database.php';
607 if (file_exists ('inc/secret.php'))
608 require_once 'inc/secret.php';
609 else
610 die ("Database connection parameters are read from inc/secret.php file, " .
611 "which cannot be found.\nCopy provided inc/secret-sample.php to " .
612 "inc/secret.php and modify to your setup.\n\nThen reload the page.");
613
614 try
615 {
616 $dbxlink = new PDO ($pdo_dsn, $db_username, $db_password);
617 }
618 catch (PDOException $e)
619 {
620 die ("Database connection failed:\n\n" . $e->getMessage());
621 }
622
623 if (isset ($_SERVER['PHP_AUTH_USER']))
624 $_SERVER['PHP_AUTH_USER'] = escapeString ($_SERVER['PHP_AUTH_USER']);
625 if (isset ($_SERVER['PHP_AUTH_PW']))
626 $_SERVER['PHP_AUTH_PW'] = escapeString ($_SERVER['PHP_AUTH_PW']);
627
628 // Now we need to be sure that the current user is the administrator.
629 // The rest doesn't matter within this context.
630 // We still continue to use the current authenticator though, but this will
631 // last only till the UserAccounts remains the same. After that this file
632 // will have to dig into the DB for the user accounts.
633 require_once 'inc/auth.php';
634
635 // This will not fail sanely, because getUserAccounts() depends on showError()
636 $accounts = getUserAccounts();
637
638 // Auth prompt risk being a little broken here due to config cache absence.
639 $configCache = array();
640 authenticate();
641 if ($accounts[$_SERVER['PHP_AUTH_USER']]['user_id'] != 1)
642 die ('You are not allowed to upgrade the database. Ask your RackTables administrator to do this.');
643
644 $dbver = getDatabaseVersion();
645 echo 'Code version == ' . CODE_VERSION;
646 echo '<br>Database version == ' . $dbver;
647 if ($dbver == CODE_VERSION)
648 {
649 die ("<p align=justify>Your database seems to be up-to-date. " .
650 "Now the best thing to do would be to follow to the <a href='${root}'>main page</a> " .
651 "and explore your data. Have a nice day.</p>");
652 }
653
654 foreach (getDBUpgradePath ($dbver, CODE_VERSION) as $batchid)
655 executeUpgradeBatch ($batchid);
656
657 echo '<br>Database version == ' . getDatabaseVersion();
658 echo "<p align=justify>Your database seems to be up-to-date. " .
659 "Now the best thing to do would be to follow to the <a href='${root}'>main page</a> " .
660 "and explore your data. Have a nice day.</p>";
661
662 ?>