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 if (!empty($constraints_on_column)) {
333 foreach ($constraints_on_column as $conname) {
334 $sql =
"ALTER TABLE \"$table\" DROP CONSTRAINT \"$conname\"";
340 $sql = $modification[
'ADD'];
345 $this->dbman->queryOnce($sql);
347 if (!empty($rename)) {
349 $this->
applyOrEchoOnce($sql =
"UPDATE \"$table\" SET \"$column\" = \"$rename\"");
350 $this->
applyOrEchoOnce($sql =
"ALTER TABLE \"$table\" DROP COLUMN \"$rename\"");
354 $this->currSchema[
'TABLE'][$table][$column][
'ALTER'] != $modification[
'ALTER'] && isset($modification[
'ALTER'])) {
355 $sql = $modification[
'ALTER'];
358 }
else if (!empty ($sql)) {
359 $this->dbman->queryOnce($sql);
363 $this->currSchema[
'TABLE'][$table][$column][
'DESC'] != $modification[
'DESC']) {
364 $sql = empty($modification[
'DESC']) ?
"COMMENT ON COLUMN \"$table\".\"$column\" IS ''" : $modification[
'DESC'];
365 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
"$table.$column.comment");
376 if (empty($this->schema[
'VIEW'])) {
379 $newViews = !array_key_exists(
'VIEW', $this->currSchema);
380 foreach ($this->schema[
'VIEW'] as $name => $sql) {
381 if (empty($name) || (!$newViews &&
382 array_key_exists($name, $this->currSchema[
'VIEW']) &&
383 $this->currSchema[
'VIEW'][$name] == $sql)) {
386 if (!$newViews && !empty($this->currSchema[
'VIEW'][$name])) {
387 $sqlDropView =
"DROP VIEW IF EXISTS $name";
401 if (!array_key_exists(
'CONSTRAINT', $this->currSchema) ||
402 empty($this->currSchema[
'CONSTRAINT'])) {
405 foreach ($this->currSchema[
'CONSTRAINT'] as $name => $sql) {
407 if (empty($name) || !array_key_exists($name, $this->schema[
'CONSTRAINT'])
408 || ($this->schema[
'CONSTRAINT'][$name] == $sql)
414 $table = preg_replace(
"/^ALTER TABLE \"(.*)\" ADD CONSTRAINT.*/",
'${1}', $sql);
415 $TableFk = preg_replace(
"/^.*FOREIGN KEY .* REFERENCES \"(.*)\" \(.*/",
'${1}', $sql);
416 if ($TableFk == $sql) {
420 if (empty($this->schema[
'TABLE'][$table]) && empty($this->schema[
'TABLE'][$TableFk])) {
423 $sql =
"ALTER TABLE \"$table\" DROP CONSTRAINT \"$name\" CASCADE";
433 if (!array_key_exists(
'INDEX', $this->currSchema) ||
434 empty($this->currSchema[
'INDEX'])) {
437 foreach ($this->currSchema[
'INDEX'] as $table => $IndexInfo) {
438 if (empty($table) || (empty($this->schema[
'TABLE'][$table]) && empty($this->schema[
'INHERITS'][$table]))) {
441 foreach ($IndexInfo as $name => $sql) {
442 if (empty($name) || $this->schema[
'INDEX'][$table][$name] == $sql) {
445 $sql =
"DROP INDEX \"$name\"";
456 if (empty($this->schema[
'INDEX'])) {
459 foreach ($this->schema[
'INDEX'] as $table => $indexInfo) {
463 if (!array_key_exists($table, $this->schema[
"TABLE"]) && !array_key_exists($table, $this->schema[
'INHERITS'])) {
464 echo
"skipping orphan table: $table\n";
468 if (!array_key_exists(
'INDEX', $this->currSchema) ||
469 !array_key_exists($table, $this->currSchema[
'INDEX'])) {
472 foreach ($indexInfo as $name => $sql) {
473 if (empty($name) || (!$newIndexes &&
474 array_key_exists($name, $this->currSchema[
'INDEX'][$table]) &&
475 $this->currSchema[
'INDEX'][$table][$name] == $sql)) {
479 $sql =
"REINDEX INDEX \"$name\"";
491 if (empty($this->schema[
'CONSTRAINT'])) {
495 $orderedConstraints = array(
'primary' => array(),
'unique' => array(),
'foreign' => array(),
'other' => array());
496 foreach ($this->schema[
'CONSTRAINT'] as $Name => $sql) {
497 $newConstraint =
false;
498 if (!array_key_exists(
'CONSTRAINT', $this->currSchema) ||
499 !array_key_exists($Name, $this->currSchema[
'CONSTRAINT'])) {
500 $newConstraint =
true;
502 if (empty($Name) || (!$newConstraint &&
503 $this->currSchema[
'CONSTRAINT'][$Name] == $sql)) {
506 if (preg_match(
"/PRIMARY KEY/", $sql)) {
507 $orderedConstraints[
'primary'][] = $sql;
508 } elseif (preg_match(
"/UNIQUE/", $sql)) {
509 $orderedConstraints[
'unique'][] = $sql;
510 } elseif (preg_match(
"/FOREIGN KEY/", $sql)) {
511 $orderedConstraints[
'foreign'][] = $sql;
513 $orderedConstraints[
'other'][] = $sql;
516 foreach ($orderedConstraints as $type => $constraints) {
517 foreach ($constraints as $sql) {
518 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
".constraint.$type");
534 $sql =
"SELECT view_name,vcs.table_name,column_name
535 FROM information_schema.view_column_usage AS vcs
536 INNER JOIN information_schema.views AS v
537 ON vcs.view_name = v.table_name
538 WHERE vcs.table_catalog='$catalog'
539 AND v.table_schema = 'public'
540 ORDER BY view_name,vcs.table_name,column_name;";
542 $this->dbman->prepare($stmt, $sql);
543 $result = $this->dbman->execute($stmt);
544 while ($row = $this->dbman->fetchArray($result)) {
545 $View = $row[
'view_name'];
546 $table = $row[
'table_name'];
547 $column = $row[
'column_name'];
548 if (empty($this->schema[
'TABLE'][$table]) || empty($this->schema[
'TABLE'][$table][$column])) {
549 $sql =
"DROP VIEW IF EXISTS \"$View\";";
553 $result = $this->dbman->freeResult($result);
563 if (empty($table) || empty($this->schema[
'TABLE'][$table])) {
566 foreach ($columns as $column) {
567 if (empty($column)) {
570 if (empty($this->schema[
'TABLE'][$table][$column])) {
571 $sql =
"ALTER TABLE \"$table\" DROP COLUMN \"$column\";";
585 $this->currSchema = array();
587 $referencedSequencesInTableColumns = $this->
addTables();
588 if (!empty($SysConf[
'DBCONF'][
'user'])) {
589 $viewowner = $SysConf[
'DBCONF'][
'user'];
591 $viewowner = pg_parameter_status(
$PG_CONN,
'session_authorization');
593 if (empty($viewowner)) {
594 throw new \Exception(
595 "Unable to load schema views: could not determine the view owner. " .
596 "Ensure \$SysConf['DBCONF']['user'] is set or a valid \$PG_CONN is available."
600 $this->
addSequences($referencedSequencesInTableColumns);
603 unset($this->currSchema[
'TABLEID']);
612 $sql =
"SELECT class.relname AS \"table\", daddy.relname AS inherits_from
613 FROM pg_class AS class
614 INNER JOIN pg_catalog.pg_inherits ON pg_inherits.inhrelid = class.oid
615 INNER JOIN pg_class daddy ON pg_inherits.inhparent = daddy.oid";
616 $this->dbman->prepare($stmt=__METHOD__, $sql);
617 $res = $this->dbman->execute($stmt);
618 $relations = array();
619 while ($row=$this->dbman->fetchArray($res)) {
620 $relations[$row[
'table']] = $row[
'inherits_from'];
622 $this->dbman->freeResult($res);
623 $this->currSchema[
'INHERITS'] = $relations;
631 $referencedSequencesInTableColumns = array();
634 table_name AS \"table\", ordinal_position AS ordinal, column_name,
635 udt_name AS type, character_maximum_length AS modifier,
636 CASE is_nullable WHEN 'YES' THEN false WHEN 'NO' THEN true END AS \"notnull\",
637 column_default AS \"default\",
638 col_description(table_name::regclass, ordinal_position) AS description
639 FROM information_schema.columns
640 WHERE table_schema = 'public'
641 ORDER BY table_name, ordinal_position;";
643 $this->dbman->prepare($stmt, $sql);
644 $result = $this->dbman->execute($stmt);
645 while ($R = $this->dbman->fetchArray($result)) {
646 $Table = $R[
'table'];
647 $Column = $R[
'column_name'];
648 if (array_key_exists($Table, $this->currSchema[
'INHERITS'])) {
649 $this->currSchema[
'TABLEID'][$Table][$R[
'ordinal']] = $Column;
653 if ($Type ==
'bpchar') {
656 if ($R[
'modifier'] > 0) {
657 $Type .=
'(' . $R[
'modifier'] .
')';
659 if (!empty($R[
'description'])) {
660 $Desc = str_replace(
"'",
"''", $R[
'description']);
664 $this->currSchema[
'TABLEID'][$Table][$R[
'ordinal']] = $Column;
666 $this->currSchema[
'TABLE'][$Table][$Column][
'DESC'] =
"COMMENT ON COLUMN \"$Table\".\"$Column\" IS '$Desc'";
668 $this->currSchema[
'TABLE'][$Table][$Column][
'DESC'] =
"";
670 $this->currSchema[
'TABLE'][$Table][$Column][
'ADD'] =
"ALTER TABLE \"$Table\" ADD COLUMN \"$Column\" $Type";
671 $this->currSchema[
'TABLE'][$Table][$Column][
'ALTER'] =
"ALTER TABLE \"$Table\"";
672 $Alter =
"ALTER COLUMN \"$Column\"";
673 if ($R[
'notnull'] ==
't') {
674 $this->currSchema[
'TABLE'][$Table][$Column][
'ALTER'] .=
" $Alter SET NOT NULL";
676 $this->currSchema[
'TABLE'][$Table][$Column][
'ALTER'] .=
" $Alter DROP NOT NULL";
678 if ($R[
'default'] !=
'') {
679 $R[
'default'] = preg_replace(
"/::bpchar/",
"::char", $R[
'default']);
680 $R[
'default'] = str_replace(
"public.",
"", $R[
'default']);
681 $this->currSchema[
'TABLE'][$Table][$Column][
'ALTER'] .=
", $Alter SET DEFAULT " . $R[
'default'];
682 $this->currSchema[
'TABLE'][$Table][$Column][
'ADD'] .=
" DEFAULT " . $R[
'default'];
684 $rgx =
"/nextval\('([a-z_]*)'.*\)/";
686 if (preg_match($rgx, $R[
'default'], $matches)) {
687 $sequence = $matches[1];
688 $referencedSequencesInTableColumns[$sequence] = array(
"table" => $Table,
"column" => $Column);
692 $this->dbman->freeResult($result);
694 return $referencedSequencesInTableColumns;
703 $sql =
"SELECT viewname,definition FROM pg_views WHERE viewowner = $1";
705 $this->dbman->prepare($stmt, $sql);
706 $result = $this->dbman->execute($stmt, array($viewowner));
707 while ($row = $this->dbman->fetchArray($result)) {
708 $sql =
"CREATE VIEW \"" . $row[
'viewname'] .
"\" AS " . $row[
'definition'];
709 $this->currSchema[
'VIEW'][$row[
'viewname']] = $sql;
711 $this->dbman->freeResult($result);
720 $sql =
"SELECT relname
723 AND relnamespace IN (
724 SELECT oid FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'
728 $this->dbman->prepare($stmt, $sql);
729 $result = $this->dbman->execute($stmt);
731 while ($row = $this->dbman->fetchArray($result)) {
732 $sequence = $row[
'relname'];
733 if (empty($sequence)) {
737 $sqlCreate =
"CREATE SEQUENCE \"" . $sequence .
"\"";
738 $this->currSchema[
'SEQUENCE'][$sequence][
'CREATE'] = $sqlCreate;
740 if (array_key_exists($sequence, $referencedSequencesInTableColumns)) {
741 $table = $referencedSequencesInTableColumns[$sequence][
'table'];
742 $column = $referencedSequencesInTableColumns[$sequence][
'column'];
744 $sqlUpdate =
"SELECT setval('$sequence',(SELECT greatest(1,max($column)) val FROM $table))";
745 $this->currSchema[
'SEQUENCE'][$sequence][
'UPDATE'] = $sqlUpdate;
749 $this->dbman->freeResult($result);
757 $sql =
"SELECT c.conname AS constraint_name,
759 WHEN 'c' THEN 'CHECK'
760 WHEN 'f' THEN 'FOREIGN KEY'
761 WHEN 'p' THEN 'PRIMARY KEY'
762 WHEN 'u' THEN 'UNIQUE'
764 CASE WHEN c.condeferrable = 'f' THEN 0 ELSE 1 END AS is_deferrable,
765 CASE WHEN c.condeferred = 'f' THEN 0 ELSE 1 END AS is_deferred,
766 t.relname AS table_name, array_to_string(c.conkey, ' ') AS constraint_key,
768 WHEN 'a' THEN 'NO ACTION'
769 WHEN 'r' THEN 'RESTRICT'
770 WHEN 'c' THEN 'CASCADE'
771 WHEN 'n' THEN 'SET NULL'
772 WHEN 'd' THEN 'SET DEFAULT'
775 WHEN 'a' THEN 'NO ACTION'
776 WHEN 'r' THEN 'RESTRICT'
777 WHEN 'c' THEN 'CASCADE'
778 WHEN 'n' THEN 'SET NULL'
779 WHEN 'd' THEN 'SET DEFAULT' END AS on_delete,
781 WHEN 'u' THEN 'UNSPECIFIED'
783 WHEN 'p' THEN 'PARTIAL'
785 t2.relname AS references_table,
786 array_to_string(c.confkey, ' ') AS fk_constraint_key
787 FROM pg_constraint AS c
788 LEFT JOIN pg_class AS t ON c.conrelid = t.oid
789 INNER JOIN information_schema.tables AS tab ON t.relname = tab.table_name
790 LEFT JOIN pg_class AS t2 ON c.confrelid = t2.oid
791 ORDER BY constraint_name,table_name
794 $this->dbman->prepare($stmt, $sql);
795 $result = $this->dbman->execute($stmt);
796 $Results = $this->dbman->fetchAll($result);
797 $this->dbman->freeResult($result);
799 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
801 $Keys = explode(
" ", $Results[$i][
'constraint_key']);
802 foreach ($Keys as $K) {
809 if (!empty($this->currSchema[
'TABLEID'][$Results[$i][
'table_name']][$K])) {
810 $Key .=
'"' . $this->currSchema[
'TABLEID'][$Results[$i][
'table_name']][$K] .
'"';
813 $Results[$i][
'constraint_key'] = $Key;
815 if (!empty($Results[$i][
'fk_constraint_key'])) {
816 $Keys = explode(
" ", $Results[$i][
'fk_constraint_key']);
820 foreach ($Keys as $K) {
827 $Key .=
'"' . $this->currSchema[
'TABLEID'][$Results[$i][
'references_table']][$K] .
'"';
829 $Results[$i][
'fk_constraint_key'] = $Key;
834 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
835 if ($Results[$i][
'type'] !=
'PRIMARY KEY') {
838 $sql =
"ALTER TABLE \"" . $Results[$i][
'table_name'] .
"\"";
839 $sql .=
" ADD CONSTRAINT \"" . $Results[$i][
'constraint_name'] .
'"';
840 $sql .=
" " . $Results[$i][
'type'];
841 $sql .=
" (" . $Results[$i][
'constraint_key'] .
")";
842 if (!empty($Results[$i][
'references_table'])) {
843 $sql .=
" REFERENCES \"" . $Results[$i][
'references_table'] .
"\"";
844 $sql .=
" (" . $Results[$i][
'fk_constraint_key'] .
")";
847 $this->currSchema[
'CONSTRAINT'][$Results[$i][
'constraint_name']] = $sql;
848 $Results[$i][
'processed'] = 1;
851 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
852 if ($Results[$i][
'type'] !=
'UNIQUE') {
855 $sql =
"ALTER TABLE \"" . $Results[$i][
'table_name'] .
"\"";
856 $sql .=
" ADD CONSTRAINT \"" . $Results[$i][
'constraint_name'] .
'"';
857 $sql .=
" " . $Results[$i][
'type'];
858 $sql .=
" (" . $Results[$i][
'constraint_key'] .
")";
859 if (!empty($Results[$i][
'references_table'])) {
860 $sql .=
" REFERENCES \"" . $Results[$i][
'references_table'] .
"\"";
861 $sql .=
" (" . $Results[$i][
'fk_constraint_key'] .
")";
864 $this->currSchema[
'CONSTRAINT'][$Results[$i][
'constraint_name']] = $sql;
865 $Results[$i][
'processed'] = 1;
869 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
870 if ($Results[$i][
'type'] !=
'FOREIGN KEY') {
873 $sql =
"ALTER TABLE \"" . $Results[$i][
'table_name'] .
"\"";
874 $sql .=
" ADD CONSTRAINT \"" . $Results[$i][
'constraint_name'] .
'"';
875 $sql .=
" " . $Results[$i][
'type'];
876 $sql .=
" (" . $Results[$i][
'constraint_key'] .
")";
877 if (!empty($Results[$i][
'references_table'])) {
878 $sql .=
" REFERENCES \"" . $Results[$i][
'references_table'] .
"\"";
879 $sql .=
" (" . $Results[$i][
'fk_constraint_key'] .
")";
882 if (!empty($Results[$i][
'on_update'])) {
883 $sql .=
" ON UPDATE " . $Results[$i][
'on_update'];
885 if (!empty($Results[$i][
'on_delete'])) {
886 $sql .=
" ON DELETE " . $Results[$i][
'on_delete'];
890 $this->currSchema[
'CONSTRAINT'][$Results[$i][
'constraint_name']] = $sql;
891 $Results[$i][
'processed'] = 1;
895 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
896 if (!empty($Results[$i][
'processed']) && $Results[$i][
'processed'] == 1) {
900 $sql =
"ALTER TABLE \"" . $Results[$i][
'table_name'] .
"\"";
901 $sql .=
" ADD CONSTRAINT \"" . $Results[$i][
'constraint_name'] .
'"';
902 $sql .=
" " . $Results[$i][
'type'];
903 $sql .=
" (" . $Results[$i][
'constraint_key'] .
")";
904 if (!empty($Results[$i][
'references_table'])) {
905 $sql .=
" REFERENCES \"" . $Results[$i][
'references_table'] .
"\"";
906 $sql .=
" (" . $Results[$i][
'fk_constraint_key'] .
")";
909 $this->currSchema[
'CONSTRAINT'][$Results[$i][
'constraint_name']] = $sql;
910 $Results[$i][
'processed'] = 1;
919 $sql =
"SELECT tablename AS \"table\", indexname AS index, indexdef AS define
921 INNER JOIN information_schema.tables ON table_name = tablename
922 AND table_type = 'BASE TABLE'
923 AND table_schema = 'public'
924 AND schemaname = 'public'
925 ORDER BY tablename,indexname;
928 $this->dbman->prepare($stmt, $sql);
929 $result = $this->dbman->execute($stmt);
930 while ($row = $this->dbman->fetchArray($result)) {
932 if (empty($this->currSchema[
'CONSTRAINT'][$row[
'index']])) {
933 $this->currSchema[
'INDEX'][$row[
'table']][$row[
'index']] = str_replace(
"public.",
"", $row[
'define']) .
";";
936 $this->dbman->freeResult($result);
948 $sql =
"SELECT proname AS name,
949 pronargs AS input_num,
950 proargnames AS input_names,
951 proargtypes AS input_type,
952 proargmodes AS input_modes,
954 prorettype AS output_type
956 INNER JOIN pg_language AS lang ON proc.prolang = lang.oid
957 WHERE lang.lanname = 'plpgsql'
960 $this->dbman->prepare($stmt, $sql);
961 $result = $this->dbman->execute($stmt);
962 while ($row = $this->dbman->fetchArray($result)) {
963 $sql =
"CREATE or REPLACE function " . $row[
'proname'] .
"()";
964 $sql .=
' RETURNS ' .
"TBD" .
' AS $$';
965 $sql .=
" " . $row[
'prosrc'];
966 $schema[
'FUNCTION'][$row[
'proname']] = $sql;
968 $this->dbman->freeResult($result);
981 $varname .=
'["' . str_replace(
'"',
'\"', $key) .
'"]';
982 if (!is_array($value)) {
983 $value = str_replace(
'"',
'\"', $value);
984 fwrite($fout,
"$varname = \"$value\";\n");
987 foreach ($value as $k => $v) {
1003 if (empty($filename)) {
1004 $filename =
'php://stdout';
1007 $fout = fopen($filename,
"w");
1009 return (
"Failed to write to $filename\n");
1012 fwrite($fout,
"<?php\n");
1013 fwrite($fout,
"/* This file is generated by " . $Name .
" */\n");
1014 fwrite($fout,
"/* Do not manually edit this file */\n\n");
1015 fwrite($fout,
' $Schema=array();' .
"\n\n");
1016 foreach ($Schema as $K1 => $V1) {
1028 print
" Applying database functions\n";
1034 $sql =
'drop function if exists uploadtree2path(integer);';
1035 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
'.uploadtree2path.drop');
1038 CREATE function uploadtree2path(uploadtree_pk_in int) returns setof uploadtree as $$
1044 UTpk := uploadtree_pk_in;
1046 sql := ' .
"'" .
'select * from uploadtree where uploadtree_pk=' .
"'" .
' || UTpk;
1047 execute sql into UTrec;
1048 IF ((UTrec.ufile_mode & (1<<28)) = 0) THEN RETURN NEXT UTrec; END IF;
1049 UTpk := UTrec.parent;
1056 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
'.uploadtree2path.create');
1062 $sql =
'drop function if exists getItemParent(integer);';
1063 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
'.getItemParent.drop');
1066 CREATE OR REPLACE FUNCTION getItemParent(itemId Integer) RETURNS Integer AS $$
1067 WITH RECURSIVE file_tree(uploadtree_pk, parent, jump, path, cycle) AS (
1068 SELECT ut.uploadtree_pk, ut.parent,
1070 ARRAY[ut.uploadtree_pk],
1073 WHERE ut.uploadtree_pk = $1
1075 SELECT ut.uploadtree_pk, ut.parent,
1076 ut.ufile_mode & (1<<28) != 0,
1077 path || ut.uploadtree_pk,
1078 ut.uploadtree_pk = ANY(path)
1079 FROM uploadtree ut, file_tree ft
1080 WHERE ut.uploadtree_pk = ft.parent AND jump AND NOT cycle
1082 SELECT uploadtree_pk from file_tree ft WHERE NOT jump
1086 RETURNS NULL ON NULL INPUT
1088 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
'.getItemParent.create');
1097 if (empty($this->schema[
'INHERITS'])) {
1100 foreach ($this->schema[
'INHERITS'] as $table => $fromTable) {
1101 if (empty($table)) {
1104 if (!$this->dbman->existsTable($table) && $this->dbman->existsTable($fromTable)) {
1105 $sql =
"CREATE TABLE \"$table\" () INHERITS (\"$fromTable\")";
1114 if (empty($dbManager) || !($dbManager instanceof
DbManager)) {
1115 $logLevel = Logger::INFO;
1116 $logger =
new Logger(__FILE__);
1117 $logger->pushHandler(
new ErrorLogHandler(ErrorLogHandler::OPERATING_SYSTEM, $logLevel));
1122 $sysconfdir = getenv(
'SYSCONFDIR');
1123 if (empty($sysconfdir)) {
1124 $sysconfdir =
"/usr/local/etc/fossology";
1126 $foConf = $sysconfdir .
"/fossology.conf";
1127 if (file_exists($foConf)) {
1128 require_once(__DIR__ .
"/common-db.php");
1131 if (!isset($GLOBALS[
'SysConf']) && isset($SysConf)) {
1132 $GLOBALS[
'SysConf'] = $SysConf;
1145 function ApplySchema($Filename = NULL, $Debug =
false, $Catalog =
'fossology')
1148 return $libschema->applySchema($Filename, $Debug, $Catalog);
1157 return $libschema->getCurrSchema();
1169 return $libschema->exportSchema($filename);
1178 $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.
DB_ColumnConstraints($table, $column)
Get constraints on a specific column.
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