FOSSology  4.4.0
Open Source License Compliance by Open Source Software
dbmigrate_3.5-3.6.php
Go to the documentation of this file.
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2019 Siemens AG
4  Author: Gaurav Mishra <mishra.gaurav@siemens.com>
5 
6  SPDX-License-Identifier: GPL-2.0-only
7 */
8 
10 
27 function calculateNumberOfRecordsToBeProcessed($dbManager, $tableName, $columnName)
28 {
29  $sql = "SELECT count(*) AS cnt FROM $tableName WHERE $tableName.$columnName is NULL;";
30  $totalPfile = $dbManager->getSingleRow($sql, [], __METHOD__ .
31  ".calculateNumberOfRecordsToBeProcesses" . $tableName);
32  $count = 0;
33  if ($totalPfile['cnt'] > 10000) {
34  $count = 10000;
35  } else {
36  $count = $totalPfile['cnt'];
37  }
38  return array($count, $totalPfile['cnt']);
39 }
40 
49 function cleanDecisionTable($dbManager, $tableName)
50 {
51  if($dbManager == null){
52  echo "No connection object passed!\n";
53  return false;
54  }
55 
56  echo "*** Removing any duplicate manual findings from $tableName ***\n";
57  // First remove only duplicate deactivated statements
58  $sql = "
59  DELETE FROM $tableName
60  WHERE " . $tableName . "_pk IN (SELECT " . $tableName . "_pk
61  FROM (SELECT " . $tableName . "_pk, is_enabled,
62  ROW_NUMBER() OVER (PARTITION BY textfinding, pfile_fk
63  ORDER BY " . $tableName . "_pk) AS rnum
64  FROM $tableName) AS a
65  WHERE a.is_enabled = FALSE AND a.rnum > 1);";
66 
67  $dbManager->begin();
68  $dbManager->queryOnce($sql);
69  $dbManager->commit();
70 
71  // Then remove any active duplicate statements
72  $sql = "
73  DELETE FROM $tableName
74  WHERE " . $tableName . "_pk IN (SELECT " . $tableName . "_pk
75  FROM (SELECT " . $tableName . "_pk,
76  ROW_NUMBER() OVER (PARTITION BY textfinding, pfile_fk
77  ORDER BY " . $tableName . "_pk) AS rnum
78  FROM $tableName) AS a
79  WHERE a.rnum > 1);";
80 
81  $dbManager->begin();
82  $dbManager->queryOnce($sql);
83  $dbManager->commit();
84 }
85 
92 function updateHash($dbManager, $tableName)
93 {
94  $totalCount = 0;
95  if($dbManager == null){
96  echo "No connection object passed!\n";
97  return false;
98  }
99  if(DB_TableExists($tableName) != 1) {
100  // Table does not exists (migrating from old version)
101  echo "Table $tableName does not exists, not updating!\n";
102  return 0;
103  }
104 
105  $numberOfRecords = calculateNumberOfRecordsToBeProcessed($dbManager, $tableName, "hash");
106  $numberOfRecords = $numberOfRecords[0];
107  while (!empty($numberOfRecords)) {
108  $sql = "SELECT " . $tableName . "_pk AS id, textfinding " .
109  "FROM $tableName WHERE hash IS NULL LIMIT $numberOfRecords;";
110  $statement = __METHOD__ . ".getNullHash.$tableName.$numberOfRecords";
111  $rows = $dbManager->getRows($sql, [], $statement);
112 
113  $sql = "UPDATE $tableName AS m " .
114  "SET hash = c.sha256 FROM (VALUES ";
115  $fileShaList = [];
116  foreach ($rows as $row) {
117  $fileShaList[] = "(" . $row["id"] . ",'" .
118  hash('sha256', $row['textfinding']) . "')";
119  }
120  $sql .= join(",", $fileShaList);
121  $sql .= ") AS c(id, sha256) WHERE c.id = m.$tableName" . "_pk;";
122  $dbManager->begin();
123  $dbManager->queryOnce($sql, __METHOD__ . ".update.$tableName.hash");
124  $dbManager->commit();
125 
126  $totalCount = $totalCount + $numberOfRecords;
127  $numberOfRecords = calculateNumberOfRecordsToBeProcessed($dbManager, $tableName, "hash");
128  $numberOfRecords = $numberOfRecords[0];
129  }
130  return $totalCount;
131 }
132 
133 
140 function updateSHA256($dbManager, $tableName)
141 {
142  $totalCount = 0;
143  if ($dbManager == null) {
144  echo "No connection object passed!\n";
145  return false;
146  }
147 
148  if (DB_TableExists($tableName) != 1) {
149  // Table does not exists (migrating from old version)
150  echo "Table $tableName does not exists, not updating!\n";
151  return 0;
152  }
153 
154  $records = calculateNumberOfRecordsToBeProcessed($dbManager, $tableName, $tableName."_sha256");
155  $lastCount = $records[1];
156  $numberOfRecords = $records[0];
157  while (!empty($numberOfRecords)) {
158  $sql = "SELECT ".$tableName.".".$tableName . "_pk AS id " .
159  "FROM $tableName WHERE $tableName." . $tableName . "_sha256 is NULL " .
160  "LIMIT $numberOfRecords";
161  $statement = __METHOD__ . ".getNullSHA256.$tableName.$numberOfRecords";
162  $rows = $dbManager->getRows($sql, [], $statement);
163 
164  $sql = "UPDATE $tableName AS m " .
165  "SET " . $tableName . "_sha256 = c.sha256 " .
166  "FROM (VALUES ";
167  $fileShaList = [];
168  foreach ($rows as $row) {
169  $oneRow = "(" . $row["id"];
170  $filePath = RepPath($row['id'], "files");
171  if (file_exists($filePath)) {
172  $hash = strtoupper(hash_file('sha256', $filePath));
173  $oneRow .= ",'$hash')";
174  } else {
175  $oneRow .= ",null)";
176  }
177  $fileShaList[] = $oneRow;
178  }
179  $sql .= join(",", $fileShaList);
180  $sql .= ") AS c(id, sha256) WHERE c.id = m.$tableName" . "_pk;";
181  $dbManager->begin();
182  $dbManager->queryOnce($sql, __METHOD__ . ".updatePfile_SHA256");
183  $dbManager->commit();
184 
185  $totalCount = $totalCount + $numberOfRecords;
186  echo "* $totalCount pfile records updated *\n";
187 
188  $records = calculateNumberOfRecordsToBeProcessed($dbManager, $tableName, $tableName."_sha256");
189  if ($lastCount == $records[1]) {
190  // NULL files in last loop and this loop are same.
191  // All remaining records does not exist in FS
192  // Prevent from infinite loop
193  break;
194  }
195  $lastCount = $records[1];
196  $numberOfRecords = $records[0];
197  }
198  return $totalCount;
199 }
200 
208 function isColumnUpperCase($dbManager, $tableName, $colName, $where)
209 {
210  if (!empty($where)) {
211  $where = "AND $where";
212  }
213  $sql = "SELECT count(*) AS cnt FROM $tableName " .
214  "WHERE $colName != UPPER($colName) $where;";
215  $row = $dbManager->getSingleRow($sql, [], __METHOD__ .
216  ".checkLowerCaseIn.$tableName".strlen($where));
217  return ($row["cnt"] == 0);
218 }
219 
220 function updatePfileSha256($dbManager, $force = false)
221 {
222  if (! isColumnUpperCase($dbManager, "pfile", "pfile_sha256", "pfile_sha256 IS NOT NULL")) {
223  // Uppercase already existing hashes
224  $sql = "UPDATE pfile SET pfile_sha256 = UPPER(pfile_sha256);";
225  $statement = __METHOD__ . ".updatePfileSHA256ToUpper";
226  $dbManager->begin();
227  $dbManager->queryOnce($sql, $statement);
228  $dbManager->commit();
229  }
230  $totalPfile = 0;
231  $totalPfile = calculateNumberOfRecordsToBeProcessed($dbManager, "pfile", "pfile_sha256");
232  if (!empty($totalPfile)) {
233  $totalPfile = $totalPfile[1];
234  } else {
235  $totalPfile = 0;
236  }
237 
238  if ($totalPfile == 0) {
239  // Migration not required
240  return 0;
241  }
242  $envYes = getenv('FOSSPFILE');
243  if (!$force) {
244  $force = !empty($envYes);
245  }
246 
247  $timePerJob = 0.00905919;
248  $totalTime = floatval($totalPfile) * $timePerJob;
249  $minutes = intval($totalTime / 60.0);
250  $hours = floor($minutes / 60);
251  $actualMinutes = $minutes - ($hours * 60);
252 
253  echo "*** Calculation of SHA256 for pfiles will require approx $hours hrs " .
254  "$actualMinutes mins. ***\n";
255 
256  if (!$force && $minutes > 45) {
257  $REDCOLOR = "\033[0;31m";
258  $NOCOLOR = "\033[0m";
259  echo "\n*********************************************************" .
260  "***********************\n";
261  echo "*** " . $REDCOLOR . "Error, script will take too much time. Not " .
262  "calculating SHA256 for pfile." . $NOCOLOR . " ***\n";
263  echo "*** Either rerun the fo-postinstall with \"--force-pfile\" flag " .
264  "or set ***\n" .
265  "*** \"FOSSPFILE=1\" in environment or run script at " .
266  " ***\n";
267  echo "*** \"" . dirname(__FILE__) .
268  "/dbmigrate_pfile_calculate_sha256.php\" to continue as a separate process ***\n";
269  echo "*********************************************************" .
270  "***********************\n";
271  return 0;
272  }
273 
274  try {
275  echo "*** Updating the sha256 values of pfiles ***\n";
276  $countPfile = updateSHA256($dbManager, "pfile");
277  echo "*** Updated sha256 of $countPfile/$totalPfile records of pfile ***\n";
278  } catch (Exception $e) {
279  echo "*** Something went wrong. Try again! ***\n";
280  $dbManager->rollback();
281  return -1;
282  }
283 }
284 
290 function migrate_35_36($dbManager, $force = false)
291 {
292  $total = 0;
293  $tables = [
294  "copyright_decision",
295  "ecc_decision",
296  "keyword_decision"
297  ];
298  if (!$force) {
299  $sql = "WITH decision_tables AS(".
300  " SELECT count(*) AS cnt FROM $tables[0] WHERE hash IS NULL" .
301  " UNION" .
302  " SELECT count(*) AS cnt FROM $tables[1] WHERE hash IS NULL" .
303  " UNION" .
304  " SELECT count(*) AS cnt FROM $tables[2] WHERE hash IS NULL" .
305  ") SELECT SUM(cnt) AS total FROM decision_tables;";
306  $total = $dbManager->getSingleRow($sql, [], __METHOD__ .
307  ".checkIfMigrationDone");
308  $total = intval($total["total"]);
309 
310  if ($total == 0) {
311  // Migration not required
312  return;
313  }
314  }
315 
316  try {
317  $count = 0;
318  // Updating the copyright/ecc/keyword findings
319  echo "*** Updating the hash values of manual copyright/ecc/keyword findings ***\n";
320 
321  foreach ($tables as $table) {
322  cleanDecisionTable($dbManager, $table);
323  $count += updateHash($dbManager, $table);
324  }
325 
326  echo "*** Updated hash of $count/$total manual copyright/ecc/keyword findings ***\n";
327  } catch (Exception $e) {
328  echo "*** Something went wrong. Try running postinstall again! ***\n";
329  $dbManager->rollback();
330  }
331 }
DB_TableExists($tableName)
Check if table exists.
Definition: common-db.php:214
RepPath($PfilePk, $Repo="files")
Given a pfile id, retrieve the pfile path.
Definition: common-repo.php:58
updateSHA256($dbManager, $tableName)
Update the sha256 column of the table with value from textfinding.
calculateNumberOfRecordsToBeProcessed($dbManager, $tableName, $columnName)
calculate number of records and return offset
isColumnUpperCase($dbManager, $tableName, $colName, $where)
Check if the given column contains only upper case entries.
cleanDecisionTable($dbManager, $tableName)
Removes duplicate decisions based on same textfinding for same pfile.
migrate_35_36($dbManager, $force=false)
updateHash($dbManager, $tableName)
Update the hash column of the table with value from textfinding.
FUNCTION char * strtoupper(char *s)
Helper function to upper case a string.
Definition: utils.c:39