15 require_once(__DIR__ .
'/../../vendor/autoload.php');
21 use Monolog\Handler\ErrorLogHandler;
60 $this->dbman = $dbManager;
69 $this->dbman->setDriver($dbDriver);
79 $driver = $this->dbman->getDriver();
86 $this->dbman->setDriver($pgDriver);
90 "No database connection available: \$PG_CONN is not set and no driver " .
91 "was injected into \$dbManager before calling this function."
106 $this->dbman->queryOnce($sql, $stmt);
119 function applySchema($filename = NULL,
$debug =
false, $catalog =
'fossology', $migrateColumns = array())
124 $result = $this->dbman->getSingleRow(
125 "SELECT lanname FROM pg_language WHERE lanname = 'plpgsql'",
127 __METHOD__ .
'.checkPlpgsql'
131 if (empty($result)) {
132 $this->dbman->queryOnce(
"CREATE LANGUAGE plpgsql", __METHOD__ .
'.createPlpgsql');
135 $result = $this->dbman->getSingleRow(
136 "SELECT extname FROM pg_extension WHERE extname = 'uuid-ossp'",
138 __METHOD__ .
'.checkUuid'
142 if (empty($result)) {
143 $this->dbman->queryOnce(
'CREATE EXTENSION "uuid-ossp"', __METHOD__ .
'.createUuid');
147 if (!file_exists($filename)) {
148 return "$filename does not exist.";
152 $this->schema = $Schema;
155 if ((count($this->schema[
'TABLE']) < 5) || (count($this->schema[
'SEQUENCE']) < 5)
156 || (count($this->schema[
'INDEX']) < 5) || (count($this->schema[
'CONSTRAINT']) < 5)
158 return "Schema from '$filename' appears invalid.";
162 $result = $this->dbman->getSingleRow(
"show statement_timeout", array(), $stmt = __METHOD__ .
'.getTimeout');
163 $statementTimeout = $result[
'statement_timeout'];
164 $this->dbman->queryOnce(
"SET statement_timeout = 0", $stmt = __METHOD__ .
'.setTimeout');
169 $errlev = error_reporting(E_ERROR | E_WARNING | E_PARSE);
185 error_reporting($errlev);
191 foreach ($this->currSchema[
'TABLE'] as $table => $columns) {
192 $skipColumns = array_key_exists($table, $migrateColumns) ? $migrateColumns[$table] : array();
193 $dropColumns = array_diff(array_keys($columns), $skipColumns);
200 $this->dbman->getSingleRow(
"SET statement_timeout = $statementTimeout", array(), $stmt = __METHOD__ .
'.resetTimeout');
201 print
"DB schema has been updated for $catalog.\n";
203 print
"These queries could update DB schema for $catalog.\n";
216 if (empty($this->schema[
'SEQUENCE'])) {
219 foreach ($this->schema[
'SEQUENCE'] as $name => $import) {
224 if (!array_key_exists(
'SEQUENCE', $this->currSchema)
225 || !array_key_exists($name, $this->currSchema[
'SEQUENCE'])) {
226 $createSql = is_string($import) ? $import : $import[
'CREATE'];
227 $this->
applyOrEchoOnce($createSql, $stmt = __METHOD__ .
"." . $name .
".CREATE");
239 if (empty($this->schema[
'CLUSTER'])) {
242 foreach ($this->schema[
'CLUSTER'] as $name => $sql) {
247 if (!array_key_exists(
'CLUSTER', $this->currSchema)
248 || !array_key_exists($name, $this->currSchema[
'CLUSTER'])) {
249 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
"." . $name .
".CREATE");
263 if (empty($this->schema[
'SEQUENCE']) ||
264 !(array_key_exists(
'SEQUENCE', $this->currSchema))) {
267 foreach ($this->schema[
'SEQUENCE'] as $name => $import) {
272 if (is_array($import) && array_key_exists(
'UPDATE', $import)) {
273 $this->
applyOrEchoOnce($import[
'UPDATE'], $stmt = __METHOD__ .
"." . $name);
286 if (empty($this->schema[
'TABLE'])) {
289 foreach ($this->schema[
'TABLE'] as $table => $columns) {
290 if (empty($table) || $inherits^array_key_exists($table,$this->schema[
'INHERITS']) ) {
295 $sql =
"CREATE TABLE IF NOT EXISTS \"$table\" ()";
298 } elseif (!array_key_exists($table, $this->currSchema[
'TABLE'])) {
303 "DO \$cleanup\$ DECLARE r RECORD; BEGIN
305 SELECT column_name FROM information_schema.columns
306 WHERE table_name = '$table' AND column_name LIKE '%_old'
308 EXECUTE 'ALTER TABLE \"$table\" DROP COLUMN IF EXISTS \"' || r.column_name || '\"';
311 $stmt = __METHOD__ .
".$table.purge_old_cols"
314 foreach ($columns as $column => $modification) {
315 if (!$newTable && !array_key_exists($column, $this->currSchema[
'TABLE'][$table])) {
318 $colNewTable = $newTable;
321 $this->currSchema[
'TABLE'][$table][$column][
'ADD'] != $modification[
'ADD']) {
326 $rename = $column .
'_old';
327 $sql =
"ALTER TABLE \"$table\" RENAME COLUMN \"$column\" TO \"$rename\"";
331 $sql = $modification[
'ADD'];
336 $this->dbman->queryOnce($sql);
338 if (!empty($rename)) {
340 $this->
applyOrEchoOnce($sql =
"UPDATE \"$table\" SET \"$column\" = \"$rename\"");
341 $this->
applyOrEchoOnce($sql =
"ALTER TABLE \"$table\" DROP COLUMN \"$rename\"");
345 $this->currSchema[
'TABLE'][$table][$column][
'ALTER'] != $modification[
'ALTER'] && isset($modification[
'ALTER'])) {
346 $sql = $modification[
'ALTER'];
349 }
else if (!empty ($sql)) {
350 $this->dbman->queryOnce($sql);
354 $this->currSchema[
'TABLE'][$table][$column][
'DESC'] != $modification[
'DESC']) {
355 $sql = empty($modification[
'DESC']) ?
"COMMENT ON COLUMN \"$table\".\"$column\" IS ''" : $modification[
'DESC'];
356 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
"$table.$column.comment");
367 if (empty($this->schema[
'VIEW'])) {
370 $newViews = !array_key_exists(
'VIEW', $this->currSchema);
371 foreach ($this->schema[
'VIEW'] as $name => $sql) {
372 if (empty($name) || (!$newViews &&
373 $this->currSchema[
'VIEW'][$name] == $sql)) {
376 if (!$newViews && !empty($this->currSchema[
'VIEW'][$name])) {
377 $sqlDropView =
"DROP VIEW IF EXISTS $name";
391 if (!array_key_exists(
'CONSTRAINT', $this->currSchema) ||
392 empty($this->currSchema[
'CONSTRAINT'])) {
395 foreach ($this->currSchema[
'CONSTRAINT'] as $name => $sql) {
397 if (empty($name) || !array_key_exists($name, $this->schema[
'CONSTRAINT'])
398 || ($this->schema[
'CONSTRAINT'][$name] == $sql)
404 $table = preg_replace(
"/^ALTER TABLE \"(.*)\" ADD CONSTRAINT.*/",
'${1}', $sql);
405 $TableFk = preg_replace(
"/^.*FOREIGN KEY .* REFERENCES \"(.*)\" \(.*/",
'${1}', $sql);
406 if ($TableFk == $sql) {
410 if (empty($this->schema[
'TABLE'][$table]) && empty($this->schema[
'TABLE'][$TableFk])) {
413 $sql =
"ALTER TABLE \"$table\" DROP CONSTRAINT \"$name\" CASCADE";
423 if (!array_key_exists(
'INDEX', $this->currSchema) ||
424 empty($this->currSchema[
'INDEX'])) {
427 foreach ($this->currSchema[
'INDEX'] as $table => $IndexInfo) {
428 if (empty($table) || (empty($this->schema[
'TABLE'][$table]) && empty($this->schema[
'INHERITS'][$table]))) {
431 foreach ($IndexInfo as $name => $sql) {
432 if (empty($name) || $this->schema[
'INDEX'][$table][$name] == $sql) {
435 $sql =
"DROP INDEX \"$name\"";
446 if (empty($this->schema[
'INDEX'])) {
449 foreach ($this->schema[
'INDEX'] as $table => $indexInfo) {
453 if (!array_key_exists($table, $this->schema[
"TABLE"]) && !array_key_exists($table, $this->schema[
'INHERITS'])) {
454 echo
"skipping orphan table: $table\n";
458 if (!array_key_exists(
'INDEX', $this->currSchema) ||
459 !array_key_exists($table, $this->currSchema[
'INDEX'])) {
462 foreach ($indexInfo as $name => $sql) {
463 if (empty($name) || (!$newIndexes &&
464 array_key_exists($name, $this->currSchema[
'INDEX'][$table]) &&
465 $this->currSchema[
'INDEX'][$table][$name] == $sql)) {
469 $sql =
"REINDEX INDEX \"$name\"";
481 if (empty($this->schema[
'CONSTRAINT'])) {
485 $orderedConstraints = array(
'primary' => array(),
'unique' => array(),
'foreign' => array(),
'other' => array());
486 foreach ($this->schema[
'CONSTRAINT'] as $Name => $sql) {
487 $newConstraint =
false;
488 if (!array_key_exists(
'CONSTRAINT', $this->currSchema) ||
489 !array_key_exists($Name, $this->currSchema[
'CONSTRAINT'])) {
490 $newConstraint =
true;
492 if (empty($Name) || (!$newConstraint &&
493 $this->currSchema[
'CONSTRAINT'][$Name] == $sql)) {
496 if (preg_match(
"/PRIMARY KEY/", $sql)) {
497 $orderedConstraints[
'primary'][] = $sql;
498 } elseif (preg_match(
"/UNIQUE/", $sql)) {
499 $orderedConstraints[
'unique'][] = $sql;
500 } elseif (preg_match(
"/FOREIGN KEY/", $sql)) {
501 $orderedConstraints[
'foreign'][] = $sql;
503 $orderedConstraints[
'other'][] = $sql;
506 foreach ($orderedConstraints as $type => $constraints) {
507 foreach ($constraints as $sql) {
508 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
".constraint.$type");
524 $sql =
"SELECT view_name,vcs.table_name,column_name
525 FROM information_schema.view_column_usage AS vcs
526 INNER JOIN information_schema.views AS v
527 ON vcs.view_name = v.table_name
528 WHERE vcs.table_catalog='$catalog'
529 AND v.table_schema = 'public'
530 ORDER BY view_name,vcs.table_name,column_name;";
532 $this->dbman->prepare($stmt, $sql);
533 $result = $this->dbman->execute($stmt);
534 while ($row = $this->dbman->fetchArray($result)) {
535 $View = $row[
'view_name'];
536 $table = $row[
'table_name'];
537 $column = $row[
'column_name'];
538 if (empty($this->schema[
'TABLE'][$table]) || empty($this->schema[
'TABLE'][$table][$column])) {
539 $sql =
"DROP VIEW IF EXISTS \"$View\";";
543 $result = $this->dbman->freeResult($result);
553 if (empty($table) || empty($this->schema[
'TABLE'][$table])) {
556 foreach ($columns as $column) {
557 if (empty($column)) {
560 if (empty($this->schema[
'TABLE'][$table][$column])) {
561 $sql =
"ALTER TABLE \"$table\" DROP COLUMN \"$column\";";
575 $this->currSchema = array();
577 $referencedSequencesInTableColumns = $this->
addTables();
578 if (!empty($SysConf[
'DBCONF'][
'user'])) {
579 $viewowner = $SysConf[
'DBCONF'][
'user'];
581 $viewowner = pg_parameter_status(
$PG_CONN,
'session_authorization');
583 if (empty($viewowner)) {
584 throw new \Exception(
585 "Unable to load schema views: could not determine the view owner. " .
586 "Ensure \$SysConf['DBCONF']['user'] is set or a valid \$PG_CONN is available."
590 $this->
addSequences($referencedSequencesInTableColumns);
593 unset($this->currSchema[
'TABLEID']);
602 $sql =
"SELECT class.relname AS \"table\", daddy.relname AS inherits_from
603 FROM pg_class AS class
604 INNER JOIN pg_catalog.pg_inherits ON pg_inherits.inhrelid = class.oid
605 INNER JOIN pg_class daddy ON pg_inherits.inhparent = daddy.oid";
606 $this->dbman->prepare($stmt=__METHOD__, $sql);
607 $res = $this->dbman->execute($stmt);
608 $relations = array();
609 while ($row=$this->dbman->fetchArray($res)) {
610 $relations[$row[
'table']] = $row[
'inherits_from'];
612 $this->dbman->freeResult($res);
613 $this->currSchema[
'INHERITS'] = $relations;
621 $referencedSequencesInTableColumns = array();
624 table_name AS \"table\", ordinal_position AS ordinal, column_name,
625 udt_name AS type, character_maximum_length AS modifier,
626 CASE is_nullable WHEN 'YES' THEN false WHEN 'NO' THEN true END AS \"notnull\",
627 column_default AS \"default\",
628 col_description(table_name::regclass, ordinal_position) AS description
629 FROM information_schema.columns
630 WHERE table_schema = 'public'
631 ORDER BY table_name, ordinal_position;";
633 $this->dbman->prepare($stmt, $sql);
634 $result = $this->dbman->execute($stmt);
635 while ($R = $this->dbman->fetchArray($result)) {
636 $Table = $R[
'table'];
637 $Column = $R[
'column_name'];
638 if (array_key_exists($Table, $this->currSchema[
'INHERITS'])) {
639 $this->currSchema[
'TABLEID'][$Table][$R[
'ordinal']] = $Column;
643 if ($Type ==
'bpchar') {
646 if ($R[
'modifier'] > 0) {
647 $Type .=
'(' . $R[
'modifier'] .
')';
649 if (!empty($R[
'description'])) {
650 $Desc = str_replace(
"'",
"''", $R[
'description']);
654 $this->currSchema[
'TABLEID'][$Table][$R[
'ordinal']] = $Column;
656 $this->currSchema[
'TABLE'][$Table][$Column][
'DESC'] =
"COMMENT ON COLUMN \"$Table\".\"$Column\" IS '$Desc'";
658 $this->currSchema[
'TABLE'][$Table][$Column][
'DESC'] =
"";
660 $this->currSchema[
'TABLE'][$Table][$Column][
'ADD'] =
"ALTER TABLE \"$Table\" ADD COLUMN \"$Column\" $Type";
661 $this->currSchema[
'TABLE'][$Table][$Column][
'ALTER'] =
"ALTER TABLE \"$Table\"";
662 $Alter =
"ALTER COLUMN \"$Column\"";
663 if ($R[
'notnull'] ==
't') {
664 $this->currSchema[
'TABLE'][$Table][$Column][
'ALTER'] .=
" $Alter SET NOT NULL";
666 $this->currSchema[
'TABLE'][$Table][$Column][
'ALTER'] .=
" $Alter DROP NOT NULL";
668 if ($R[
'default'] !=
'') {
669 $R[
'default'] = preg_replace(
"/::bpchar/",
"::char", $R[
'default']);
670 $R[
'default'] = str_replace(
"public.",
"", $R[
'default']);
671 $this->currSchema[
'TABLE'][$Table][$Column][
'ALTER'] .=
", $Alter SET DEFAULT " . $R[
'default'];
672 $this->currSchema[
'TABLE'][$Table][$Column][
'ADD'] .=
" DEFAULT " . $R[
'default'];
674 $rgx =
"/nextval\('([a-z_]*)'.*\)/";
676 if (preg_match($rgx, $R[
'default'], $matches)) {
677 $sequence = $matches[1];
678 $referencedSequencesInTableColumns[$sequence] = array(
"table" => $Table,
"column" => $Column);
682 $this->dbman->freeResult($result);
684 return $referencedSequencesInTableColumns;
693 $sql =
"SELECT viewname,definition FROM pg_views WHERE viewowner = $1";
695 $this->dbman->prepare($stmt, $sql);
696 $result = $this->dbman->execute($stmt, array($viewowner));
697 while ($row = $this->dbman->fetchArray($result)) {
698 $sql =
"CREATE VIEW \"" . $row[
'viewname'] .
"\" AS " . $row[
'definition'];
699 $this->currSchema[
'VIEW'][$row[
'viewname']] = $sql;
701 $this->dbman->freeResult($result);
710 $sql =
"SELECT relname
713 AND relnamespace IN (
714 SELECT oid FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'
718 $this->dbman->prepare($stmt, $sql);
719 $result = $this->dbman->execute($stmt);
721 while ($row = $this->dbman->fetchArray($result)) {
722 $sequence = $row[
'relname'];
723 if (empty($sequence)) {
727 $sqlCreate =
"CREATE SEQUENCE \"" . $sequence .
"\"";
728 $this->currSchema[
'SEQUENCE'][$sequence][
'CREATE'] = $sqlCreate;
730 if (array_key_exists($sequence, $referencedSequencesInTableColumns)) {
731 $table = $referencedSequencesInTableColumns[$sequence][
'table'];
732 $column = $referencedSequencesInTableColumns[$sequence][
'column'];
734 $sqlUpdate =
"SELECT setval('$sequence',(SELECT greatest(1,max($column)) val FROM $table))";
735 $this->currSchema[
'SEQUENCE'][$sequence][
'UPDATE'] = $sqlUpdate;
739 $this->dbman->freeResult($result);
747 $sql =
"SELECT c.conname AS constraint_name,
749 WHEN 'c' THEN 'CHECK'
750 WHEN 'f' THEN 'FOREIGN KEY'
751 WHEN 'p' THEN 'PRIMARY KEY'
752 WHEN 'u' THEN 'UNIQUE'
754 CASE WHEN c.condeferrable = 'f' THEN 0 ELSE 1 END AS is_deferrable,
755 CASE WHEN c.condeferred = 'f' THEN 0 ELSE 1 END AS is_deferred,
756 t.relname AS table_name, array_to_string(c.conkey, ' ') AS constraint_key,
758 WHEN 'a' THEN 'NO ACTION'
759 WHEN 'r' THEN 'RESTRICT'
760 WHEN 'c' THEN 'CASCADE'
761 WHEN 'n' THEN 'SET NULL'
762 WHEN 'd' THEN 'SET DEFAULT'
765 WHEN 'a' THEN 'NO ACTION'
766 WHEN 'r' THEN 'RESTRICT'
767 WHEN 'c' THEN 'CASCADE'
768 WHEN 'n' THEN 'SET NULL'
769 WHEN 'd' THEN 'SET DEFAULT' END AS on_delete,
771 WHEN 'u' THEN 'UNSPECIFIED'
773 WHEN 'p' THEN 'PARTIAL'
775 t2.relname AS references_table,
776 array_to_string(c.confkey, ' ') AS fk_constraint_key
777 FROM pg_constraint AS c
778 LEFT JOIN pg_class AS t ON c.conrelid = t.oid
779 INNER JOIN information_schema.tables AS tab ON t.relname = tab.table_name
780 LEFT JOIN pg_class AS t2 ON c.confrelid = t2.oid
781 ORDER BY constraint_name,table_name
784 $this->dbman->prepare($stmt, $sql);
785 $result = $this->dbman->execute($stmt);
786 $Results = $this->dbman->fetchAll($result);
787 $this->dbman->freeResult($result);
789 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
791 $Keys = explode(
" ", $Results[$i][
'constraint_key']);
792 foreach ($Keys as $K) {
799 if (!empty($this->currSchema[
'TABLEID'][$Results[$i][
'table_name']][$K])) {
800 $Key .=
'"' . $this->currSchema[
'TABLEID'][$Results[$i][
'table_name']][$K] .
'"';
803 $Results[$i][
'constraint_key'] = $Key;
805 if (!empty($Results[$i][
'fk_constraint_key'])) {
806 $Keys = explode(
" ", $Results[$i][
'fk_constraint_key']);
810 foreach ($Keys as $K) {
817 $Key .=
'"' . $this->currSchema[
'TABLEID'][$Results[$i][
'references_table']][$K] .
'"';
819 $Results[$i][
'fk_constraint_key'] = $Key;
824 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
825 if ($Results[$i][
'type'] !=
'PRIMARY KEY') {
828 $sql =
"ALTER TABLE \"" . $Results[$i][
'table_name'] .
"\"";
829 $sql .=
" ADD CONSTRAINT \"" . $Results[$i][
'constraint_name'] .
'"';
830 $sql .=
" " . $Results[$i][
'type'];
831 $sql .=
" (" . $Results[$i][
'constraint_key'] .
")";
832 if (!empty($Results[$i][
'references_table'])) {
833 $sql .=
" REFERENCES \"" . $Results[$i][
'references_table'] .
"\"";
834 $sql .=
" (" . $Results[$i][
'fk_constraint_key'] .
")";
837 $this->currSchema[
'CONSTRAINT'][$Results[$i][
'constraint_name']] = $sql;
838 $Results[$i][
'processed'] = 1;
841 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
842 if ($Results[$i][
'type'] !=
'UNIQUE') {
845 $sql =
"ALTER TABLE \"" . $Results[$i][
'table_name'] .
"\"";
846 $sql .=
" ADD CONSTRAINT \"" . $Results[$i][
'constraint_name'] .
'"';
847 $sql .=
" " . $Results[$i][
'type'];
848 $sql .=
" (" . $Results[$i][
'constraint_key'] .
")";
849 if (!empty($Results[$i][
'references_table'])) {
850 $sql .=
" REFERENCES \"" . $Results[$i][
'references_table'] .
"\"";
851 $sql .=
" (" . $Results[$i][
'fk_constraint_key'] .
")";
854 $this->currSchema[
'CONSTRAINT'][$Results[$i][
'constraint_name']] = $sql;
855 $Results[$i][
'processed'] = 1;
859 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
860 if ($Results[$i][
'type'] !=
'FOREIGN KEY') {
863 $sql =
"ALTER TABLE \"" . $Results[$i][
'table_name'] .
"\"";
864 $sql .=
" ADD CONSTRAINT \"" . $Results[$i][
'constraint_name'] .
'"';
865 $sql .=
" " . $Results[$i][
'type'];
866 $sql .=
" (" . $Results[$i][
'constraint_key'] .
")";
867 if (!empty($Results[$i][
'references_table'])) {
868 $sql .=
" REFERENCES \"" . $Results[$i][
'references_table'] .
"\"";
869 $sql .=
" (" . $Results[$i][
'fk_constraint_key'] .
")";
872 if (!empty($Results[$i][
'on_update'])) {
873 $sql .=
" ON UPDATE " . $Results[$i][
'on_update'];
875 if (!empty($Results[$i][
'on_delete'])) {
876 $sql .=
" ON DELETE " . $Results[$i][
'on_delete'];
880 $this->currSchema[
'CONSTRAINT'][$Results[$i][
'constraint_name']] = $sql;
881 $Results[$i][
'processed'] = 1;
885 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
886 if (!empty($Results[$i][
'processed']) && $Results[$i][
'processed'] == 1) {
890 $sql =
"ALTER TABLE \"" . $Results[$i][
'table_name'] .
"\"";
891 $sql .=
" ADD CONSTRAINT \"" . $Results[$i][
'constraint_name'] .
'"';
892 $sql .=
" " . $Results[$i][
'type'];
893 $sql .=
" (" . $Results[$i][
'constraint_key'] .
")";
894 if (!empty($Results[$i][
'references_table'])) {
895 $sql .=
" REFERENCES \"" . $Results[$i][
'references_table'] .
"\"";
896 $sql .=
" (" . $Results[$i][
'fk_constraint_key'] .
")";
899 $this->currSchema[
'CONSTRAINT'][$Results[$i][
'constraint_name']] = $sql;
900 $Results[$i][
'processed'] = 1;
909 $sql =
"SELECT tablename AS \"table\", indexname AS index, indexdef AS define
911 INNER JOIN information_schema.tables ON table_name = tablename
912 AND table_type = 'BASE TABLE'
913 AND table_schema = 'public'
914 AND schemaname = 'public'
915 ORDER BY tablename,indexname;
918 $this->dbman->prepare($stmt, $sql);
919 $result = $this->dbman->execute($stmt);
920 while ($row = $this->dbman->fetchArray($result)) {
922 if (empty($this->currSchema[
'CONSTRAINT'][$row[
'index']])) {
923 $this->currSchema[
'INDEX'][$row[
'table']][$row[
'index']] = str_replace(
"public.",
"", $row[
'define']) .
";";
926 $this->dbman->freeResult($result);
938 $sql =
"SELECT proname AS name,
939 pronargs AS input_num,
940 proargnames AS input_names,
941 proargtypes AS input_type,
942 proargmodes AS input_modes,
944 prorettype AS output_type
946 INNER JOIN pg_language AS lang ON proc.prolang = lang.oid
947 WHERE lang.lanname = 'plpgsql'
950 $this->dbman->prepare($stmt, $sql);
951 $result = $this->dbman->execute($stmt);
952 while ($row = $this->dbman->fetchArray($result)) {
953 $sql =
"CREATE or REPLACE function " . $row[
'proname'] .
"()";
954 $sql .=
' RETURNS ' .
"TBD" .
' AS $$';
955 $sql .=
" " . $row[
'prosrc'];
956 $schema[
'FUNCTION'][$row[
'proname']] = $sql;
958 $this->dbman->freeResult($result);
971 $varname .=
'["' . str_replace(
'"',
'\"', $key) .
'"]';
972 if (!is_array($value)) {
973 $value = str_replace(
'"',
'\"', $value);
974 fwrite($fout,
"$varname = \"$value\";\n");
977 foreach ($value as $k => $v) {
993 if (empty($filename)) {
994 $filename =
'php://stdout';
997 $fout = fopen($filename,
"w");
999 return (
"Failed to write to $filename\n");
1002 fwrite($fout,
"<?php\n");
1003 fwrite($fout,
"/* This file is generated by " . $Name .
" */\n");
1004 fwrite($fout,
"/* Do not manually edit this file */\n\n");
1005 fwrite($fout,
' $Schema=array();' .
"\n\n");
1006 foreach ($Schema as $K1 => $V1) {
1019 print
" Applying database functions\n";
1025 $sql =
'drop function if exists uploadtree2path(integer);';
1026 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
'.uploadtree2path.drop');
1029 CREATE function uploadtree2path(uploadtree_pk_in int) returns setof uploadtree as $$
1035 UTpk := uploadtree_pk_in;
1037 sql := ' .
"'" .
'select * from uploadtree where uploadtree_pk=' .
"'" .
' || UTpk;
1038 execute sql into UTrec;
1039 IF ((UTrec.ufile_mode & (1<<28)) = 0) THEN RETURN NEXT UTrec; END IF;
1040 UTpk := UTrec.parent;
1047 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
'.uploadtree2path.create');
1053 $sql =
'drop function if exists getItemParent(integer);';
1054 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
'.getItemParent.drop');
1057 CREATE OR REPLACE FUNCTION getItemParent(itemId Integer) RETURNS Integer AS $$
1058 WITH RECURSIVE file_tree(uploadtree_pk, parent, jump, path, cycle) AS (
1059 SELECT ut.uploadtree_pk, ut.parent,
1061 ARRAY[ut.uploadtree_pk],
1064 WHERE ut.uploadtree_pk = $1
1066 SELECT ut.uploadtree_pk, ut.parent,
1067 ut.ufile_mode & (1<<28) != 0,
1068 path || ut.uploadtree_pk,
1069 ut.uploadtree_pk = ANY(path)
1070 FROM uploadtree ut, file_tree ft
1071 WHERE ut.uploadtree_pk = ft.parent AND jump AND NOT cycle
1073 SELECT uploadtree_pk from file_tree ft WHERE NOT jump
1077 RETURNS NULL ON NULL INPUT
1079 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
'.getItemParent.create');
1088 if (empty($this->schema[
'INHERITS'])) {
1091 foreach ($this->schema[
'INHERITS'] as $table => $fromTable) {
1092 if (empty($table)) {
1095 if (!$this->dbman->existsTable($table) && $this->dbman->existsTable($fromTable)) {
1096 $sql =
"CREATE TABLE \"$table\" () INHERITS (\"$fromTable\")";
1105 if (empty($dbManager) || !($dbManager instanceof
DbManager)) {
1106 $logLevel = Logger::INFO;
1107 $logger =
new Logger(__FILE__);
1108 $logger->pushHandler(
new ErrorLogHandler(ErrorLogHandler::OPERATING_SYSTEM, $logLevel));
1113 $sysconfdir = getenv(
'SYSCONFDIR');
1114 if (empty($sysconfdir)) {
1115 $sysconfdir =
"/usr/local/etc/fossology";
1117 $foConf = $sysconfdir .
"/fossology.conf";
1118 if (file_exists($foConf)) {
1119 require_once(__DIR__ .
"/common-db.php");
1122 if (!isset($GLOBALS[
'SysConf']) && isset($SysConf)) {
1123 $GLOBALS[
'SysConf'] = $SysConf;
1136 function ApplySchema($Filename = NULL, $Debug =
false, $Catalog =
'fossology')
1139 return $libschema->applySchema($Filename, $Debug, $Catalog);
1148 return $libschema->getCurrSchema();
1160 return $libschema->exportSchema($filename);
1169 $libschema->makeFunctions($Debug);
Class to handle database schema.
writeArrayEntries($fout, $key, $value, $varname)
applyTables($inherits=false)
Add tables/columns (dependent on sequences for default values)
applySchema($filename=NULL, $debug=false, $catalog='fossology', $migrateColumns=array())
Make schema match $Filename. This is a single transaction.
exportSchema($filename=NULL)
Export the schema of the connected database to a file in the format readable by GetSchema().
__construct(DbManager &$dbManager)
applySequences()
Add sequences to the database.
applyClusters()
Add clusters.
applyOrEchoOnce($sql, $stmt='')
dropColumnsFromTable($columns, $table)
dropViews($catalog)
Delete views.
updateSequences()
Add sequences.
addSequences($referencedSequencesInTableColumns)
dropConstraints()
Delete constraints.
makeFunctions()
Create any required DB functions.
getCurrSchema()
Load the schema from the db into an array.
setDriver(Driver &$dbDriver)
applyInheritedRelations()
ReportCachePurgeAll()
Purge all records from the report cache.
DBconnect($sysconfdir, $options="", $exitOnFail=true)
Connect to database engine. This is a no-op if $PG_CONN already has a value.
DB_ColExists($tableName, $colName, $DBName='fossology')
Check if a column exists.
DB_ConstraintExists($ConstraintName, $DBName='fossology')
Check if a constraint exists.
DB_TableExists($tableName)
Check if table exists.
ExportSchema($filename=NULL)
Export the schema of the connected database to a file in the format readable by GetSchema().
GetSchema()
Load the schema from the db into an array.
MakeFunctions($Debug)
Create any required DB functions.
ApplySchema($Filename=NULL, $Debug=false, $Catalog='fossology')
Make schema match $Filename. This is a single transaction.
foreach($Options as $Option=> $OptVal) if(0==$reference_flag &&0==$nomos_flag) $PG_CONN