15 require_once(__DIR__ .
'/../../vendor/autoload.php');
21 use Monolog\Handler\ErrorLogHandler;
60 $this->dbman = $dbManager;
69 $this->dbman->setDriver($dbDriver);
83 $this->dbman->queryOnce($sql, $stmt);
96 function applySchema($filename = NULL,
$debug =
false, $catalog =
'fossology', $migrateColumns = array())
101 $sql_statement =
"select lanname from pg_language where lanname = 'plpgsql'";
103 $result = pg_query(
$PG_CONN, $sql_statement);
105 throw new Exception(
"Could not check the database for plpgsql language");
108 $plpgsql_already_installed =
false;
109 if ( pg_fetch_row($result) ) {
110 $plpgsql_already_installed =
true;
114 if ($plpgsql_already_installed ==
false) {
115 $sql_statement =
"CREATE LANGUAGE plpgsql";
116 $result = pg_query(
$PG_CONN, $sql_statement);
118 throw new Exception(
"Could not create plpgsql language in the database");
122 $sql_statement =
"select extname from pg_extension where extname = 'uuid-ossp'";
124 $result = pg_query(
$PG_CONN, $sql_statement);
126 throw new Exception(
"Could not check the database for uuid-ossp extension");
129 $uuid_already_installed =
false;
130 if ( pg_fetch_row($result) ) {
131 $uuid_already_installed =
true;
135 if ( $uuid_already_installed ==
false ) {
136 $sql_statement =
'CREATE EXTENSION "uuid-ossp";';
137 $result = pg_query(
$PG_CONN, $sql_statement);
139 throw new Exception(
"Could not create uuid-ossp extension in the database");
144 if (!file_exists($filename)) {
145 return "$filename does not exist.";
149 $this->schema = $Schema;
152 if ((count($this->schema[
'TABLE']) < 5) || (count($this->schema[
'SEQUENCE']) < 5)
153 || (count($this->schema[
'INDEX']) < 5) || (count($this->schema[
'CONSTRAINT']) < 5)
155 return "Schema from '$filename' appears invalid.";
159 $result = $this->dbman->getSingleRow(
"show statement_timeout", array(), $stmt = __METHOD__ .
'.getTimeout');
160 $statementTimeout = $result[
'statement_timeout'];
161 $this->dbman->queryOnce(
"SET statement_timeout = 0", $stmt = __METHOD__ .
'.setTimeout');
166 $errlev = error_reporting(E_ERROR | E_WARNING | E_PARSE);
182 error_reporting($errlev);
188 foreach ($this->currSchema[
'TABLE'] as $table => $columns) {
189 $skipColumns = array_key_exists($table, $migrateColumns) ? $migrateColumns[$table] : array();
190 $dropColumns = array_diff(array_keys($columns), $skipColumns);
197 $this->dbman->getSingleRow(
"SET statement_timeout = $statementTimeout", array(), $stmt = __METHOD__ .
'.resetTimeout');
198 print
"DB schema has been updated for $catalog.\n";
200 print
"These queries could update DB schema for $catalog.\n";
213 if (empty($this->schema[
'SEQUENCE'])) {
216 foreach ($this->schema[
'SEQUENCE'] as $name => $import) {
221 if (!array_key_exists(
'SEQUENCE', $this->currSchema)
222 || !array_key_exists($name, $this->currSchema[
'SEQUENCE'])) {
223 $createSql = is_string($import) ? $import : $import[
'CREATE'];
224 $this->
applyOrEchoOnce($createSql, $stmt = __METHOD__ .
"." . $name .
".CREATE");
236 if (empty($this->schema[
'CLUSTER'])) {
239 foreach ($this->schema[
'CLUSTER'] as $name => $sql) {
244 if (!array_key_exists(
'CLUSTER', $this->currSchema)
245 || !array_key_exists($name, $this->currSchema[
'CLUSTER'])) {
246 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
"." . $name .
".CREATE");
260 if (empty($this->schema[
'SEQUENCE']) ||
261 !(array_key_exists(
'SEQUENCE', $this->currSchema))) {
264 foreach ($this->schema[
'SEQUENCE'] as $name => $import) {
269 if (is_array($import) && array_key_exists(
'UPDATE', $import)) {
270 $this->
applyOrEchoOnce($import[
'UPDATE'], $stmt = __METHOD__ .
"." . $name);
283 if (empty($this->schema[
'TABLE'])) {
286 foreach ($this->schema[
'TABLE'] as $table => $columns) {
287 if (empty($table) || $inherits^array_key_exists($table,$this->schema[
'INHERITS']) ) {
292 $sql =
"CREATE TABLE IF NOT EXISTS \"$table\" ()";
295 } elseif (!array_key_exists($table, $this->currSchema[
'TABLE'])) {
298 foreach ($columns as $column => $modification) {
299 if (!$newTable && !array_key_exists($column, $this->currSchema[
'TABLE'][$table])) {
302 $colNewTable = $newTable;
305 $this->currSchema[
'TABLE'][$table][$column][
'ADD'] != $modification[
'ADD']) {
310 $rename = $column .
'_old';
311 $sql =
"ALTER TABLE \"$table\" RENAME COLUMN \"$column\" TO \"$rename\"";
315 $sql = $modification[
'ADD'];
320 $this->dbman->queryOnce($sql);
322 if (!empty($rename)) {
324 $this->
applyOrEchoOnce($sql =
"UPDATE \"$table\" SET \"$column\" = \"$rename\"");
325 $this->
applyOrEchoOnce($sql =
"ALTER TABLE \"$table\" DROP COLUMN \"$rename\"");
329 $this->currSchema[
'TABLE'][$table][$column][
'ALTER'] != $modification[
'ALTER'] && isset($modification[
'ALTER'])) {
330 $sql = $modification[
'ALTER'];
333 }
else if (!empty ($sql)) {
334 $this->dbman->queryOnce($sql);
338 $this->currSchema[
'TABLE'][$table][$column][
'DESC'] != $modification[
'DESC']) {
339 $sql = empty($modification[
'DESC']) ?
"COMMENT ON COLUMN \"$table\".\"$column\" IS ''" : $modification[
'DESC'];
340 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
"$table.$column.comment");
351 if (empty($this->schema[
'VIEW'])) {
354 $newViews = !array_key_exists(
'VIEW', $this->currSchema);
355 foreach ($this->schema[
'VIEW'] as $name => $sql) {
356 if (empty($name) || (!$newViews &&
357 $this->currSchema[
'VIEW'][$name] == $sql)) {
360 if (!$newViews && !empty($this->currSchema[
'VIEW'][$name])) {
361 $sqlDropView =
"DROP VIEW IF EXISTS $name";
375 if (!array_key_exists(
'CONSTRAINT', $this->currSchema) ||
376 empty($this->currSchema[
'CONSTRAINT'])) {
379 foreach ($this->currSchema[
'CONSTRAINT'] as $name => $sql) {
381 if (empty($name) || !array_key_exists($name, $this->schema[
'CONSTRAINT'])
382 || ($this->schema[
'CONSTRAINT'][$name] == $sql)
388 $table = preg_replace(
"/^ALTER TABLE \"(.*)\" ADD CONSTRAINT.*/",
'${1}', $sql);
389 $TableFk = preg_replace(
"/^.*FOREIGN KEY .* REFERENCES \"(.*)\" \(.*/",
'${1}', $sql);
390 if ($TableFk == $sql) {
394 if (empty($this->schema[
'TABLE'][$table]) && empty($this->schema[
'TABLE'][$TableFk])) {
397 $sql =
"ALTER TABLE \"$table\" DROP CONSTRAINT \"$name\" CASCADE";
407 if (!array_key_exists(
'INDEX', $this->currSchema) ||
408 empty($this->currSchema[
'INDEX'])) {
411 foreach ($this->currSchema[
'INDEX'] as $table => $IndexInfo) {
412 if (empty($table) || (empty($this->schema[
'TABLE'][$table]) && empty($this->schema[
'INHERITS'][$table]))) {
415 foreach ($IndexInfo as $name => $sql) {
416 if (empty($name) || $this->schema[
'INDEX'][$table][$name] == $sql) {
419 $sql =
"DROP INDEX \"$name\"";
430 if (empty($this->schema[
'INDEX'])) {
433 foreach ($this->schema[
'INDEX'] as $table => $indexInfo) {
437 if (!array_key_exists($table, $this->schema[
"TABLE"]) && !array_key_exists($table, $this->schema[
'INHERITS'])) {
438 echo
"skipping orphan table: $table\n";
442 if (!array_key_exists(
'INDEX', $this->currSchema) ||
443 !array_key_exists($table, $this->currSchema[
'INDEX'])) {
446 foreach ($indexInfo as $name => $sql) {
447 if (empty($name) || (!$newIndexes &&
448 array_key_exists($name, $this->currSchema[
'INDEX'][$table]) &&
449 $this->currSchema[
'INDEX'][$table][$name] == $sql)) {
453 $sql =
"REINDEX INDEX \"$name\"";
465 if (empty($this->schema[
'CONSTRAINT'])) {
469 $orderedConstraints = array(
'primary' => array(),
'unique' => array(),
'foreign' => array(),
'other' => array());
470 foreach ($this->schema[
'CONSTRAINT'] as $Name => $sql) {
471 $newConstraint =
false;
472 if (!array_key_exists(
'CONSTRAINT', $this->currSchema) ||
473 !array_key_exists($Name, $this->currSchema[
'CONSTRAINT'])) {
474 $newConstraint =
true;
476 if (empty($Name) || (!$newConstraint &&
477 $this->currSchema[
'CONSTRAINT'][$Name] == $sql)) {
480 if (preg_match(
"/PRIMARY KEY/", $sql)) {
481 $orderedConstraints[
'primary'][] = $sql;
482 } elseif (preg_match(
"/UNIQUE/", $sql)) {
483 $orderedConstraints[
'unique'][] = $sql;
484 } elseif (preg_match(
"/FOREIGN KEY/", $sql)) {
485 $orderedConstraints[
'foreign'][] = $sql;
487 $orderedConstraints[
'other'][] = $sql;
490 foreach ($orderedConstraints as $type => $constraints) {
491 foreach ($constraints as $sql) {
492 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
".constraint.$type");
508 $sql =
"SELECT view_name,vcs.table_name,column_name
509 FROM information_schema.view_column_usage AS vcs
510 INNER JOIN information_schema.views AS v
511 ON vcs.view_name = v.table_name
512 WHERE vcs.table_catalog='$catalog'
513 AND v.table_schema = 'public'
514 ORDER BY view_name,vcs.table_name,column_name;";
516 $this->dbman->prepare($stmt, $sql);
517 $result = $this->dbman->execute($stmt);
518 while ($row = $this->dbman->fetchArray($result)) {
519 $View = $row[
'view_name'];
520 $table = $row[
'table_name'];
521 $column = $row[
'column_name'];
522 if (empty($this->schema[
'TABLE'][$table]) || empty($this->schema[
'TABLE'][$table][$column])) {
523 $sql =
"DROP VIEW IF EXISTS \"$View\";";
527 $result = $this->dbman->freeResult($result);
537 if (empty($table) || empty($this->schema[
'TABLE'][$table])) {
540 foreach ($columns as $column) {
541 if (empty($column)) {
544 if (empty($this->schema[
'TABLE'][$table][$column])) {
545 $sql =
"ALTER TABLE \"$table\" DROP COLUMN \"$column\";";
558 $this->currSchema = array();
560 $referencedSequencesInTableColumns = $this->
addTables();
561 $this->
addViews($viewowner = $SysConf[
'DBCONF'][
'user']);
562 $this->
addSequences($referencedSequencesInTableColumns);
565 unset($this->currSchema[
'TABLEID']);
574 $sql =
"SELECT class.relname AS \"table\", daddy.relname AS inherits_from
575 FROM pg_class AS class
576 INNER JOIN pg_catalog.pg_inherits ON pg_inherits.inhrelid = class.oid
577 INNER JOIN pg_class daddy ON pg_inherits.inhparent = daddy.oid";
578 $this->dbman->prepare($stmt=__METHOD__, $sql);
579 $res = $this->dbman->execute($stmt);
580 $relations = array();
581 while ($row=$this->dbman->fetchArray($res)) {
582 $relations[$row[
'table']] = $row[
'inherits_from'];
584 $this->dbman->freeResult($res);
585 $this->currSchema[
'INHERITS'] = $relations;
593 $referencedSequencesInTableColumns = array();
596 table_name AS \"table\", ordinal_position AS ordinal, column_name,
597 udt_name AS type, character_maximum_length AS modifier,
598 CASE is_nullable WHEN 'YES' THEN false WHEN 'NO' THEN true END AS \"notnull\",
599 column_default AS \"default\",
600 col_description(table_name::regclass, ordinal_position) AS description
601 FROM information_schema.columns
602 WHERE table_schema = 'public'
603 ORDER BY table_name, ordinal_position;";
605 $this->dbman->prepare($stmt, $sql);
606 $result = $this->dbman->execute($stmt);
607 while ($R = $this->dbman->fetchArray($result)) {
608 $Table = $R[
'table'];
609 $Column = $R[
'column_name'];
610 if (array_key_exists($Table, $this->currSchema[
'INHERITS'])) {
611 $this->currSchema[
'TABLEID'][$Table][$R[
'ordinal']] = $Column;
615 if ($Type ==
'bpchar') {
618 if ($R[
'modifier'] > 0) {
619 $Type .=
'(' . $R[
'modifier'] .
')';
621 if (!empty($R[
'description'])) {
622 $Desc = str_replace(
"'",
"''", $R[
'description']);
626 $this->currSchema[
'TABLEID'][$Table][$R[
'ordinal']] = $Column;
628 $this->currSchema[
'TABLE'][$Table][$Column][
'DESC'] =
"COMMENT ON COLUMN \"$Table\".\"$Column\" IS '$Desc'";
630 $this->currSchema[
'TABLE'][$Table][$Column][
'DESC'] =
"";
632 $this->currSchema[
'TABLE'][$Table][$Column][
'ADD'] =
"ALTER TABLE \"$Table\" ADD COLUMN \"$Column\" $Type";
633 $this->currSchema[
'TABLE'][$Table][$Column][
'ALTER'] =
"ALTER TABLE \"$Table\"";
634 $Alter =
"ALTER COLUMN \"$Column\"";
635 if ($R[
'notnull'] ==
't') {
636 $this->currSchema[
'TABLE'][$Table][$Column][
'ALTER'] .=
" $Alter SET NOT NULL";
638 $this->currSchema[
'TABLE'][$Table][$Column][
'ALTER'] .=
" $Alter DROP NOT NULL";
640 if ($R[
'default'] !=
'') {
641 $R[
'default'] = preg_replace(
"/::bpchar/",
"::char", $R[
'default']);
642 $R[
'default'] = str_replace(
"public.",
"", $R[
'default']);
643 $this->currSchema[
'TABLE'][$Table][$Column][
'ALTER'] .=
", $Alter SET DEFAULT " . $R[
'default'];
644 $this->currSchema[
'TABLE'][$Table][$Column][
'ADD'] .=
" DEFAULT " . $R[
'default'];
646 $rgx =
"/nextval\('([a-z_]*)'.*\)/";
648 if (preg_match($rgx, $R[
'default'], $matches)) {
649 $sequence = $matches[1];
650 $referencedSequencesInTableColumns[$sequence] = array(
"table" => $Table,
"column" => $Column);
654 $this->dbman->freeResult($result);
656 return $referencedSequencesInTableColumns;
665 $sql =
"SELECT viewname,definition FROM pg_views WHERE viewowner = $1";
667 $this->dbman->prepare($stmt, $sql);
668 $result = $this->dbman->execute($stmt, array($viewowner));
669 while ($row = $this->dbman->fetchArray($result)) {
670 $sql =
"CREATE VIEW \"" . $row[
'viewname'] .
"\" AS " . $row[
'definition'];
671 $this->currSchema[
'VIEW'][$row[
'viewname']] = $sql;
673 $this->dbman->freeResult($result);
682 $sql =
"SELECT relname
685 AND relnamespace IN (
686 SELECT oid FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'
690 $this->dbman->prepare($stmt, $sql);
691 $result = $this->dbman->execute($stmt);
693 while ($row = $this->dbman->fetchArray($result)) {
694 $sequence = $row[
'relname'];
695 if (empty($sequence)) {
699 $sqlCreate =
"CREATE SEQUENCE \"" . $sequence .
"\"";
700 $this->currSchema[
'SEQUENCE'][$sequence][
'CREATE'] = $sqlCreate;
702 if (array_key_exists($sequence, $referencedSequencesInTableColumns)) {
703 $table = $referencedSequencesInTableColumns[$sequence][
'table'];
704 $column = $referencedSequencesInTableColumns[$sequence][
'column'];
706 $sqlUpdate =
"SELECT setval('$sequence',(SELECT greatest(1,max($column)) val FROM $table))";
707 $this->currSchema[
'SEQUENCE'][$sequence][
'UPDATE'] = $sqlUpdate;
711 $this->dbman->freeResult($result);
719 $sql =
"SELECT c.conname AS constraint_name,
721 WHEN 'c' THEN 'CHECK'
722 WHEN 'f' THEN 'FOREIGN KEY'
723 WHEN 'p' THEN 'PRIMARY KEY'
724 WHEN 'u' THEN 'UNIQUE'
726 CASE WHEN c.condeferrable = 'f' THEN 0 ELSE 1 END AS is_deferrable,
727 CASE WHEN c.condeferred = 'f' THEN 0 ELSE 1 END AS is_deferred,
728 t.relname AS table_name, array_to_string(c.conkey, ' ') AS constraint_key,
730 WHEN 'a' THEN 'NO ACTION'
731 WHEN 'r' THEN 'RESTRICT'
732 WHEN 'c' THEN 'CASCADE'
733 WHEN 'n' THEN 'SET NULL'
734 WHEN 'd' THEN 'SET DEFAULT'
737 WHEN 'a' THEN 'NO ACTION'
738 WHEN 'r' THEN 'RESTRICT'
739 WHEN 'c' THEN 'CASCADE'
740 WHEN 'n' THEN 'SET NULL'
741 WHEN 'd' THEN 'SET DEFAULT' END AS on_delete,
743 WHEN 'u' THEN 'UNSPECIFIED'
745 WHEN 'p' THEN 'PARTIAL'
747 t2.relname AS references_table,
748 array_to_string(c.confkey, ' ') AS fk_constraint_key
749 FROM pg_constraint AS c
750 LEFT JOIN pg_class AS t ON c.conrelid = t.oid
751 INNER JOIN information_schema.tables AS tab ON t.relname = tab.table_name
752 LEFT JOIN pg_class AS t2 ON c.confrelid = t2.oid
753 ORDER BY constraint_name,table_name
756 $this->dbman->prepare($stmt, $sql);
757 $result = $this->dbman->execute($stmt);
758 $Results = $this->dbman->fetchAll($result);
759 $this->dbman->freeResult($result);
761 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
763 $Keys = explode(
" ", $Results[$i][
'constraint_key']);
764 foreach ($Keys as $K) {
771 if (!empty($this->currSchema[
'TABLEID'][$Results[$i][
'table_name']][$K])) {
772 $Key .=
'"' . $this->currSchema[
'TABLEID'][$Results[$i][
'table_name']][$K] .
'"';
775 $Results[$i][
'constraint_key'] = $Key;
777 if (!empty($Results[$i][
'fk_constraint_key'])) {
778 $Keys = explode(
" ", $Results[$i][
'fk_constraint_key']);
782 foreach ($Keys as $K) {
789 $Key .=
'"' . $this->currSchema[
'TABLEID'][$Results[$i][
'references_table']][$K] .
'"';
791 $Results[$i][
'fk_constraint_key'] = $Key;
796 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
797 if ($Results[$i][
'type'] !=
'PRIMARY KEY') {
800 $sql =
"ALTER TABLE \"" . $Results[$i][
'table_name'] .
"\"";
801 $sql .=
" ADD CONSTRAINT \"" . $Results[$i][
'constraint_name'] .
'"';
802 $sql .=
" " . $Results[$i][
'type'];
803 $sql .=
" (" . $Results[$i][
'constraint_key'] .
")";
804 if (!empty($Results[$i][
'references_table'])) {
805 $sql .=
" REFERENCES \"" . $Results[$i][
'references_table'] .
"\"";
806 $sql .=
" (" . $Results[$i][
'fk_constraint_key'] .
")";
809 $this->currSchema[
'CONSTRAINT'][$Results[$i][
'constraint_name']] = $sql;
810 $Results[$i][
'processed'] = 1;
813 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
814 if ($Results[$i][
'type'] !=
'UNIQUE') {
817 $sql =
"ALTER TABLE \"" . $Results[$i][
'table_name'] .
"\"";
818 $sql .=
" ADD CONSTRAINT \"" . $Results[$i][
'constraint_name'] .
'"';
819 $sql .=
" " . $Results[$i][
'type'];
820 $sql .=
" (" . $Results[$i][
'constraint_key'] .
")";
821 if (!empty($Results[$i][
'references_table'])) {
822 $sql .=
" REFERENCES \"" . $Results[$i][
'references_table'] .
"\"";
823 $sql .=
" (" . $Results[$i][
'fk_constraint_key'] .
")";
826 $this->currSchema[
'CONSTRAINT'][$Results[$i][
'constraint_name']] = $sql;
827 $Results[$i][
'processed'] = 1;
831 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
832 if ($Results[$i][
'type'] !=
'FOREIGN KEY') {
835 $sql =
"ALTER TABLE \"" . $Results[$i][
'table_name'] .
"\"";
836 $sql .=
" ADD CONSTRAINT \"" . $Results[$i][
'constraint_name'] .
'"';
837 $sql .=
" " . $Results[$i][
'type'];
838 $sql .=
" (" . $Results[$i][
'constraint_key'] .
")";
839 if (!empty($Results[$i][
'references_table'])) {
840 $sql .=
" REFERENCES \"" . $Results[$i][
'references_table'] .
"\"";
841 $sql .=
" (" . $Results[$i][
'fk_constraint_key'] .
")";
844 if (!empty($Results[$i][
'on_update'])) {
845 $sql .=
" ON UPDATE " . $Results[$i][
'on_update'];
847 if (!empty($Results[$i][
'on_delete'])) {
848 $sql .=
" ON DELETE " . $Results[$i][
'on_delete'];
852 $this->currSchema[
'CONSTRAINT'][$Results[$i][
'constraint_name']] = $sql;
853 $Results[$i][
'processed'] = 1;
857 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
858 if (!empty($Results[$i][
'processed']) && $Results[$i][
'processed'] == 1) {
862 $sql =
"ALTER TABLE \"" . $Results[$i][
'table_name'] .
"\"";
863 $sql .=
" ADD CONSTRAINT \"" . $Results[$i][
'constraint_name'] .
'"';
864 $sql .=
" " . $Results[$i][
'type'];
865 $sql .=
" (" . $Results[$i][
'constraint_key'] .
")";
866 if (!empty($Results[$i][
'references_table'])) {
867 $sql .=
" REFERENCES \"" . $Results[$i][
'references_table'] .
"\"";
868 $sql .=
" (" . $Results[$i][
'fk_constraint_key'] .
")";
871 $this->currSchema[
'CONSTRAINT'][$Results[$i][
'constraint_name']] = $sql;
872 $Results[$i][
'processed'] = 1;
881 $sql =
"SELECT tablename AS \"table\", indexname AS index, indexdef AS define
883 INNER JOIN information_schema.tables ON table_name = tablename
884 AND table_type = 'BASE TABLE'
885 AND table_schema = 'public'
886 AND schemaname = 'public'
887 ORDER BY tablename,indexname;
890 $this->dbman->prepare($stmt, $sql);
891 $result = $this->dbman->execute($stmt);
892 while ($row = $this->dbman->fetchArray($result)) {
894 if (empty($this->currSchema[
'CONSTRAINT'][$row[
'index']])) {
895 $this->currSchema[
'INDEX'][$row[
'table']][$row[
'index']] = str_replace(
"public.",
"", $row[
'define']) .
";";
898 $this->dbman->freeResult($result);
910 $sql =
"SELECT proname AS name,
911 pronargs AS input_num,
912 proargnames AS input_names,
913 proargtypes AS input_type,
914 proargmodes AS input_modes,
916 prorettype AS output_type
918 INNER JOIN pg_language AS lang ON proc.prolang = lang.oid
919 WHERE lang.lanname = 'plpgsql'
922 $this->dbman->prepare($stmt, $sql);
923 $result = $this->dbman->execute($stmt);
924 while ($row = $this->dbman->fetchArray($result)) {
925 $sql =
"CREATE or REPLACE function " . $row[
'proname'] .
"()";
926 $sql .=
' RETURNS ' .
"TBD" .
' AS $$';
927 $sql .=
" " . $row[
'prosrc'];
928 $schema[
'FUNCTION'][$row[
'proname']] = $sql;
930 $this->dbman->freeResult($result);
943 $varname .=
'["' . str_replace(
'"',
'\"', $key) .
'"]';
944 if (!is_array($value)) {
945 $value = str_replace(
'"',
'\"', $value);
946 fwrite($fout,
"$varname = \"$value\";\n");
949 foreach ($value as $k => $v) {
968 $dbDriver = $this->dbman->getDriver();
969 if (empty($dbDriver)) {
971 $this->dbman->setDriver($pgDrive);
974 if (empty($filename)) {
975 $filename =
'php://stdout';
978 $fout = fopen($filename,
"w");
980 return (
"Failed to write to $filename\n");
983 fwrite($fout,
"<?php\n");
984 fwrite($fout,
"/* This file is generated by " . $Name .
" */\n");
985 fwrite($fout,
"/* Do not manually edit this file */\n\n");
986 fwrite($fout,
' $Schema=array();' .
"\n\n");
987 foreach ($Schema as $K1 => $V1) {
1000 print
" Applying database functions\n";
1006 $sql =
'drop function if exists uploadtree2path(integer);';
1007 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
'.uploadtree2path.drop');
1010 CREATE function uploadtree2path(uploadtree_pk_in int) returns setof uploadtree as $$
1016 UTpk := uploadtree_pk_in;
1018 sql := ' .
"'" .
'select * from uploadtree where uploadtree_pk=' .
"'" .
' || UTpk;
1019 execute sql into UTrec;
1020 IF ((UTrec.ufile_mode & (1<<28)) = 0) THEN RETURN NEXT UTrec; END IF;
1021 UTpk := UTrec.parent;
1028 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
'.uploadtree2path.create');
1034 $sql =
'drop function if exists getItemParent(integer);';
1035 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
'.getItemParent.drop');
1038 CREATE OR REPLACE FUNCTION getItemParent(itemId Integer) RETURNS Integer AS $$
1039 WITH RECURSIVE file_tree(uploadtree_pk, parent, jump, path, cycle) AS (
1040 SELECT ut.uploadtree_pk, ut.parent,
1042 ARRAY[ut.uploadtree_pk],
1045 WHERE ut.uploadtree_pk = $1
1047 SELECT ut.uploadtree_pk, ut.parent,
1048 ut.ufile_mode & (1<<28) != 0,
1049 path || ut.uploadtree_pk,
1050 ut.uploadtree_pk = ANY(path)
1051 FROM uploadtree ut, file_tree ft
1052 WHERE ut.uploadtree_pk = ft.parent AND jump AND NOT cycle
1054 SELECT uploadtree_pk from file_tree ft WHERE NOT jump
1058 RETURNS NULL ON NULL INPUT
1060 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
'.getItemParent.create');
1069 if (empty($this->schema[
'INHERITS'])) {
1072 foreach ($this->schema[
'INHERITS'] as $table => $fromTable) {
1073 if (empty($table)) {
1076 if (!$this->dbman->existsTable($table) && $this->dbman->existsTable($fromTable)) {
1077 $sql =
"CREATE TABLE \"$table\" () INHERITS (\"$fromTable\")";
1086 if (empty($dbManager) || !($dbManager instanceof
DbManager)) {
1087 $logLevel = Logger::INFO;
1088 $logger =
new Logger(__FILE__);
1089 $logger->pushHandler(
new ErrorLogHandler(ErrorLogHandler::OPERATING_SYSTEM, $logLevel));
1091 $pgDriver =
new Postgres($GLOBALS[
'PG_CONN']);
1092 $dbManager->setDriver($pgDriver);
1103 function ApplySchema($Filename = NULL, $Debug =
false, $Catalog =
'fossology')
1106 return $libschema->applySchema($Filename, $Debug, $Catalog);
1115 return $libschema->getCurrSchema();
1127 return $libschema->exportSchema($filename);
1136 $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 ($PG_CONN) 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_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 ($PG_CONN) 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