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);
180 error_reporting($errlev);
186 foreach ($this->currSchema[
'TABLE'] as $table => $columns) {
187 $skipColumns = array_key_exists($table, $migrateColumns) ? $migrateColumns[$table] : array();
188 $dropColumns = array_diff(array_keys($columns), $skipColumns);
195 $this->dbman->getSingleRow(
"SET statement_timeout = $statementTimeout", array(), $stmt = __METHOD__ .
'.resetTimeout');
196 print
"DB schema has been updated for $catalog.\n";
198 print
"These queries could update DB schema for $catalog.\n";
211 if (empty($this->schema[
'SEQUENCE'])) {
214 foreach ($this->schema[
'SEQUENCE'] as $name => $import) {
219 if (!array_key_exists(
'SEQUENCE', $this->currSchema)
220 || !array_key_exists($name, $this->currSchema[
'SEQUENCE'])) {
221 $createSql = is_string($import) ? $import : $import[
'CREATE'];
222 $this->
applyOrEchoOnce($createSql, $stmt = __METHOD__ .
"." . $name .
".CREATE");
234 if (empty($this->schema[
'CLUSTER'])) {
237 foreach ($this->schema[
'CLUSTER'] as $name => $sql) {
242 if (!array_key_exists(
'CLUSTER', $this->currSchema)
243 || !array_key_exists($name, $this->currSchema[
'CLUSTER'])) {
244 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
"." . $name .
".CREATE");
258 if (empty($this->schema[
'SEQUENCE']) ||
259 !(array_key_exists(
'SEQUENCE', $this->currSchema))) {
262 foreach ($this->schema[
'SEQUENCE'] as $name => $import) {
267 if (is_array($import) && array_key_exists(
'UPDATE', $import)) {
268 $this->
applyOrEchoOnce($import[
'UPDATE'], $stmt = __METHOD__ .
"." . $name);
281 if (empty($this->schema[
'TABLE'])) {
284 foreach ($this->schema[
'TABLE'] as $table => $columns) {
285 if (empty($table) || $inherits^array_key_exists($table,$this->schema[
'INHERITS']) ) {
290 $sql =
"CREATE TABLE IF NOT EXISTS \"$table\" ()";
293 } elseif (!array_key_exists($table, $this->currSchema[
'TABLE'])) {
296 foreach ($columns as $column => $modification) {
297 if (!$newTable && !array_key_exists($column, $this->currSchema[
'TABLE'][$table])) {
300 $colNewTable = $newTable;
303 $this->currSchema[
'TABLE'][$table][$column][
'ADD'] != $modification[
'ADD']) {
308 $rename = $column .
'_old';
309 $sql =
"ALTER TABLE \"$table\" RENAME COLUMN \"$column\" TO \"$rename\"";
313 $sql = $modification[
'ADD'];
318 $this->dbman->queryOnce($sql);
320 if (!empty($rename)) {
322 $this->
applyOrEchoOnce($sql =
"UPDATE \"$table\" SET \"$column\" = \"$rename\"");
323 $this->
applyOrEchoOnce($sql =
"ALTER TABLE \"$table\" DROP COLUMN \"$rename\"");
327 $this->currSchema[
'TABLE'][$table][$column][
'ALTER'] != $modification[
'ALTER'] && isset($modification[
'ALTER'])) {
328 $sql = $modification[
'ALTER'];
331 }
else if (!empty ($sql)) {
332 $this->dbman->queryOnce($sql);
336 $this->currSchema[
'TABLE'][$table][$column][
'DESC'] != $modification[
'DESC']) {
337 $sql = empty($modification[
'DESC']) ?
"COMMENT ON COLUMN \"$table\".\"$column\" IS ''" : $modification[
'DESC'];
338 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
"$table.$column.comment");
349 if (empty($this->schema[
'VIEW'])) {
352 $newViews = !array_key_exists(
'VIEW', $this->currSchema);
353 foreach ($this->schema[
'VIEW'] as $name => $sql) {
354 if (empty($name) || (!$newViews &&
355 $this->currSchema[
'VIEW'][$name] == $sql)) {
358 if (!$newViews && !empty($this->currSchema[
'VIEW'][$name])) {
359 $sqlDropView =
"DROP VIEW IF EXISTS $name";
373 if (!array_key_exists(
'CONSTRAINT', $this->currSchema) ||
374 empty($this->currSchema[
'CONSTRAINT'])) {
377 foreach ($this->currSchema[
'CONSTRAINT'] as $name => $sql) {
379 if (empty($name) || !array_key_exists($name, $this->schema[
'CONSTRAINT'])
380 || ($this->schema[
'CONSTRAINT'][$name] == $sql)
386 $table = preg_replace(
"/^ALTER TABLE \"(.*)\" ADD CONSTRAINT.*/",
'${1}', $sql);
387 $TableFk = preg_replace(
"/^.*FOREIGN KEY .* REFERENCES \"(.*)\" \(.*/",
'${1}', $sql);
388 if ($TableFk == $sql) {
392 if (empty($this->schema[
'TABLE'][$table]) && empty($this->schema[
'TABLE'][$TableFk])) {
395 $sql =
"ALTER TABLE \"$table\" DROP CONSTRAINT \"$name\" CASCADE";
405 if (!array_key_exists(
'INDEX', $this->currSchema) ||
406 empty($this->currSchema[
'INDEX'])) {
409 foreach ($this->currSchema[
'INDEX'] as $table => $IndexInfo) {
410 if (empty($table) || (empty($this->schema[
'TABLE'][$table]) && empty($this->schema[
'INHERITS'][$table]))) {
413 foreach ($IndexInfo as $name => $sql) {
414 if (empty($name) || $this->schema[
'INDEX'][$table][$name] == $sql) {
417 $sql =
"DROP INDEX \"$name\"";
428 if (empty($this->schema[
'INDEX'])) {
431 foreach ($this->schema[
'INDEX'] as $table => $indexInfo) {
435 if (!array_key_exists($table, $this->schema[
"TABLE"]) && !array_key_exists($table, $this->schema[
'INHERITS'])) {
436 echo
"skipping orphan table: $table\n";
440 if (!array_key_exists(
'INDEX', $this->currSchema) ||
441 !array_key_exists($table, $this->currSchema[
'INDEX'])) {
444 foreach ($indexInfo as $name => $sql) {
445 if (empty($name) || (!$newIndexes &&
446 array_key_exists($name, $this->currSchema[
'INDEX'][$table]) &&
447 $this->currSchema[
'INDEX'][$table][$name] == $sql)) {
451 $sql =
"REINDEX INDEX \"$name\"";
463 if (empty($this->schema[
'CONSTRAINT'])) {
467 $orderedConstraints = array(
'primary' => array(),
'unique' => array(),
'foreign' => array(),
'other' => array());
468 foreach ($this->schema[
'CONSTRAINT'] as $Name => $sql) {
469 $newConstraint =
false;
470 if (!array_key_exists(
'CONSTRAINT', $this->currSchema) ||
471 !array_key_exists($Name, $this->currSchema[
'CONSTRAINT'])) {
472 $newConstraint =
true;
474 if (empty($Name) || (!$newConstraint &&
475 $this->currSchema[
'CONSTRAINT'][$Name] == $sql)) {
478 if (preg_match(
"/PRIMARY KEY/", $sql)) {
479 $orderedConstraints[
'primary'][] = $sql;
480 } elseif (preg_match(
"/UNIQUE/", $sql)) {
481 $orderedConstraints[
'unique'][] = $sql;
482 } elseif (preg_match(
"/FOREIGN KEY/", $sql)) {
483 $orderedConstraints[
'foreign'][] = $sql;
485 $orderedConstraints[
'other'][] = $sql;
488 foreach ($orderedConstraints as $type => $constraints) {
489 foreach ($constraints as $sql) {
490 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
".constraint.$type");
506 $sql =
"SELECT view_name,table_name,column_name
507 FROM information_schema.view_column_usage
508 WHERE table_catalog='$catalog'
509 ORDER BY view_name,table_name,column_name";
511 $this->dbman->prepare($stmt, $sql);
512 $result = $this->dbman->execute($stmt);
513 while ($row = $this->dbman->fetchArray($result)) {
514 $View = $row[
'view_name'];
515 $table = $row[
'table_name'];
516 if (empty($this->schema[
'TABLE'][$table])) {
519 $column = $row[
'column_name'];
520 if (empty($this->schema[
'TABLE'][$table][$column])) {
521 $sql =
"DROP VIEW \"$View\";";
525 $result = $this->dbman->freeResult($result);
535 if (empty($table) || empty($this->schema[
'TABLE'][$table])) {
538 foreach ($columns as $column) {
539 if (empty($column)) {
542 if (empty($this->schema[
'TABLE'][$table][$column])) {
543 $sql =
"ALTER TABLE \"$table\" DROP COLUMN \"$column\";";
556 $this->currSchema = array();
558 $referencedSequencesInTableColumns = $this->
addTables();
559 $this->
addViews($viewowner = $SysConf[
'DBCONF'][
'user']);
560 $this->
addSequences($referencedSequencesInTableColumns);
563 unset($this->currSchema[
'TABLEID']);
572 $sql =
"SELECT class.relname AS \"table\", daddy.relname AS inherits_from
573 FROM pg_class AS class
574 INNER JOIN pg_catalog.pg_inherits ON pg_inherits.inhrelid = class.oid
575 INNER JOIN pg_class daddy ON pg_inherits.inhparent = daddy.oid";
576 $this->dbman->prepare($stmt=__METHOD__, $sql);
577 $res = $this->dbman->execute($stmt);
578 $relations = array();
579 while ($row=$this->dbman->fetchArray($res)) {
580 $relations[$row[
'table']] = $row[
'inherits_from'];
582 $this->dbman->freeResult($res);
583 $this->currSchema[
'INHERITS'] = $relations;
591 $referencedSequencesInTableColumns = array();
594 table_name AS \"table\", ordinal_position AS ordinal, column_name,
595 udt_name AS type, character_maximum_length AS modifier,
596 CASE is_nullable WHEN 'YES' THEN false WHEN 'NO' THEN true END AS \"notnull\",
597 column_default AS \"default\",
598 col_description(table_name::regclass, ordinal_position) AS description
599 FROM information_schema.columns
600 WHERE table_schema = 'public'
601 ORDER BY table_name, ordinal_position;";
603 $this->dbman->prepare($stmt, $sql);
604 $result = $this->dbman->execute($stmt);
605 while ($R = $this->dbman->fetchArray($result)) {
606 $Table = $R[
'table'];
607 $Column = $R[
'column_name'];
608 if (array_key_exists($Table, $this->currSchema[
'INHERITS'])) {
609 $this->currSchema[
'TABLEID'][$Table][$R[
'ordinal']] = $Column;
613 if ($Type ==
'bpchar') {
616 if ($R[
'modifier'] > 0) {
617 $Type .=
'(' . $R[
'modifier'] .
')';
619 if (!empty($R[
'description'])) {
620 $Desc = str_replace(
"'",
"''", $R[
'description']);
624 $this->currSchema[
'TABLEID'][$Table][$R[
'ordinal']] = $Column;
626 $this->currSchema[
'TABLE'][$Table][$Column][
'DESC'] =
"COMMENT ON COLUMN \"$Table\".\"$Column\" IS '$Desc'";
628 $this->currSchema[
'TABLE'][$Table][$Column][
'DESC'] =
"";
630 $this->currSchema[
'TABLE'][$Table][$Column][
'ADD'] =
"ALTER TABLE \"$Table\" ADD COLUMN \"$Column\" $Type";
631 $this->currSchema[
'TABLE'][$Table][$Column][
'ALTER'] =
"ALTER TABLE \"$Table\"";
632 $Alter =
"ALTER COLUMN \"$Column\"";
633 if ($R[
'notnull'] ==
't') {
634 $this->currSchema[
'TABLE'][$Table][$Column][
'ALTER'] .=
" $Alter SET NOT NULL";
636 $this->currSchema[
'TABLE'][$Table][$Column][
'ALTER'] .=
" $Alter DROP NOT NULL";
638 if ($R[
'default'] !=
'') {
639 $R[
'default'] = preg_replace(
"/::bpchar/",
"::char", $R[
'default']);
640 $R[
'default'] = str_replace(
"public.",
"", $R[
'default']);
641 $this->currSchema[
'TABLE'][$Table][$Column][
'ALTER'] .=
", $Alter SET DEFAULT " . $R[
'default'];
642 $this->currSchema[
'TABLE'][$Table][$Column][
'ADD'] .=
" DEFAULT " . $R[
'default'];
644 $rgx =
"/nextval\('([a-z_]*)'.*\)/";
646 if (preg_match($rgx, $R[
'default'], $matches)) {
647 $sequence = $matches[1];
648 $referencedSequencesInTableColumns[$sequence] = array(
"table" => $Table,
"column" => $Column);
652 $this->dbman->freeResult($result);
654 return $referencedSequencesInTableColumns;
663 $sql =
"SELECT viewname,definition FROM pg_views WHERE viewowner = $1";
665 $this->dbman->prepare($stmt, $sql);
666 $result = $this->dbman->execute($stmt, array($viewowner));
667 while ($row = $this->dbman->fetchArray($result)) {
668 $sql =
"CREATE VIEW \"" . $row[
'viewname'] .
"\" AS " . $row[
'definition'];
669 $this->currSchema[
'VIEW'][$row[
'viewname']] = $sql;
671 $this->dbman->freeResult($result);
680 $sql =
"SELECT relname
683 AND relnamespace IN (
684 SELECT oid FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'
688 $this->dbman->prepare($stmt, $sql);
689 $result = $this->dbman->execute($stmt);
691 while ($row = $this->dbman->fetchArray($result)) {
692 $sequence = $row[
'relname'];
693 if (empty($sequence)) {
697 $sqlCreate =
"CREATE SEQUENCE \"" . $sequence .
"\"";
698 $this->currSchema[
'SEQUENCE'][$sequence][
'CREATE'] = $sqlCreate;
700 if (array_key_exists($sequence, $referencedSequencesInTableColumns)) {
701 $table = $referencedSequencesInTableColumns[$sequence][
'table'];
702 $column = $referencedSequencesInTableColumns[$sequence][
'column'];
704 $sqlUpdate =
"SELECT setval('$sequence',(SELECT greatest(1,max($column)) val FROM $table))";
705 $this->currSchema[
'SEQUENCE'][$sequence][
'UPDATE'] = $sqlUpdate;
709 $this->dbman->freeResult($result);
717 $sql =
"SELECT c.conname AS constraint_name,
719 WHEN 'c' THEN 'CHECK'
720 WHEN 'f' THEN 'FOREIGN KEY'
721 WHEN 'p' THEN 'PRIMARY KEY'
722 WHEN 'u' THEN 'UNIQUE'
724 CASE WHEN c.condeferrable = 'f' THEN 0 ELSE 1 END AS is_deferrable,
725 CASE WHEN c.condeferred = 'f' THEN 0 ELSE 1 END AS is_deferred,
726 t.relname AS table_name, array_to_string(c.conkey, ' ') AS constraint_key,
728 WHEN 'a' THEN 'NO ACTION'
729 WHEN 'r' THEN 'RESTRICT'
730 WHEN 'c' THEN 'CASCADE'
731 WHEN 'n' THEN 'SET NULL'
732 WHEN 'd' THEN 'SET DEFAULT'
735 WHEN 'a' THEN 'NO ACTION'
736 WHEN 'r' THEN 'RESTRICT'
737 WHEN 'c' THEN 'CASCADE'
738 WHEN 'n' THEN 'SET NULL'
739 WHEN 'd' THEN 'SET DEFAULT' END AS on_delete,
741 WHEN 'u' THEN 'UNSPECIFIED'
743 WHEN 'p' THEN 'PARTIAL'
745 t2.relname AS references_table,
746 array_to_string(c.confkey, ' ') AS fk_constraint_key
747 FROM pg_constraint AS c
748 LEFT JOIN pg_class AS t ON c.conrelid = t.oid
749 INNER JOIN information_schema.tables AS tab ON t.relname = tab.table_name
750 LEFT JOIN pg_class AS t2 ON c.confrelid = t2.oid
751 ORDER BY constraint_name,table_name
754 $this->dbman->prepare($stmt, $sql);
755 $result = $this->dbman->execute($stmt);
756 $Results = $this->dbman->fetchAll($result);
757 $this->dbman->freeResult($result);
759 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
761 $Keys = explode(
" ", $Results[$i][
'constraint_key']);
762 foreach ($Keys as $K) {
769 if (!empty($this->currSchema[
'TABLEID'][$Results[$i][
'table_name']][$K])) {
770 $Key .=
'"' . $this->currSchema[
'TABLEID'][$Results[$i][
'table_name']][$K] .
'"';
773 $Results[$i][
'constraint_key'] = $Key;
775 if (!empty($Results[$i][
'fk_constraint_key'])) {
776 $Keys = explode(
" ", $Results[$i][
'fk_constraint_key']);
780 foreach ($Keys as $K) {
787 $Key .=
'"' . $this->currSchema[
'TABLEID'][$Results[$i][
'references_table']][$K] .
'"';
789 $Results[$i][
'fk_constraint_key'] = $Key;
794 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
795 if ($Results[$i][
'type'] !=
'PRIMARY KEY') {
798 $sql =
"ALTER TABLE \"" . $Results[$i][
'table_name'] .
"\"";
799 $sql .=
" ADD CONSTRAINT \"" . $Results[$i][
'constraint_name'] .
'"';
800 $sql .=
" " . $Results[$i][
'type'];
801 $sql .=
" (" . $Results[$i][
'constraint_key'] .
")";
802 if (!empty($Results[$i][
'references_table'])) {
803 $sql .=
" REFERENCES \"" . $Results[$i][
'references_table'] .
"\"";
804 $sql .=
" (" . $Results[$i][
'fk_constraint_key'] .
")";
807 $this->currSchema[
'CONSTRAINT'][$Results[$i][
'constraint_name']] = $sql;
808 $Results[$i][
'processed'] = 1;
811 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
812 if ($Results[$i][
'type'] !=
'UNIQUE') {
815 $sql =
"ALTER TABLE \"" . $Results[$i][
'table_name'] .
"\"";
816 $sql .=
" ADD CONSTRAINT \"" . $Results[$i][
'constraint_name'] .
'"';
817 $sql .=
" " . $Results[$i][
'type'];
818 $sql .=
" (" . $Results[$i][
'constraint_key'] .
")";
819 if (!empty($Results[$i][
'references_table'])) {
820 $sql .=
" REFERENCES \"" . $Results[$i][
'references_table'] .
"\"";
821 $sql .=
" (" . $Results[$i][
'fk_constraint_key'] .
")";
824 $this->currSchema[
'CONSTRAINT'][$Results[$i][
'constraint_name']] = $sql;
825 $Results[$i][
'processed'] = 1;
829 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
830 if ($Results[$i][
'type'] !=
'FOREIGN KEY') {
833 $sql =
"ALTER TABLE \"" . $Results[$i][
'table_name'] .
"\"";
834 $sql .=
" ADD CONSTRAINT \"" . $Results[$i][
'constraint_name'] .
'"';
835 $sql .=
" " . $Results[$i][
'type'];
836 $sql .=
" (" . $Results[$i][
'constraint_key'] .
")";
837 if (!empty($Results[$i][
'references_table'])) {
838 $sql .=
" REFERENCES \"" . $Results[$i][
'references_table'] .
"\"";
839 $sql .=
" (" . $Results[$i][
'fk_constraint_key'] .
")";
842 if (!empty($Results[$i][
'on_update'])) {
843 $sql .=
" ON UPDATE " . $Results[$i][
'on_update'];
845 if (!empty($Results[$i][
'on_delete'])) {
846 $sql .=
" ON DELETE " . $Results[$i][
'on_delete'];
850 $this->currSchema[
'CONSTRAINT'][$Results[$i][
'constraint_name']] = $sql;
851 $Results[$i][
'processed'] = 1;
855 for ($i = 0; !empty($Results[$i][
'constraint_name']); $i++) {
856 if (!empty($Results[$i][
'processed']) && $Results[$i][
'processed'] == 1) {
860 $sql =
"ALTER TABLE \"" . $Results[$i][
'table_name'] .
"\"";
861 $sql .=
" ADD CONSTRAINT \"" . $Results[$i][
'constraint_name'] .
'"';
862 $sql .=
" " . $Results[$i][
'type'];
863 $sql .=
" (" . $Results[$i][
'constraint_key'] .
")";
864 if (!empty($Results[$i][
'references_table'])) {
865 $sql .=
" REFERENCES \"" . $Results[$i][
'references_table'] .
"\"";
866 $sql .=
" (" . $Results[$i][
'fk_constraint_key'] .
")";
869 $this->currSchema[
'CONSTRAINT'][$Results[$i][
'constraint_name']] = $sql;
870 $Results[$i][
'processed'] = 1;
879 $sql =
"SELECT tablename AS \"table\", indexname AS index, indexdef AS define
881 INNER JOIN information_schema.tables ON table_name = tablename
882 AND table_type = 'BASE TABLE'
883 AND table_schema = 'public'
884 AND schemaname = 'public'
885 ORDER BY tablename,indexname;
888 $this->dbman->prepare($stmt, $sql);
889 $result = $this->dbman->execute($stmt);
890 while ($row = $this->dbman->fetchArray($result)) {
892 if (empty($this->currSchema[
'CONSTRAINT'][$row[
'index']])) {
893 $this->currSchema[
'INDEX'][$row[
'table']][$row[
'index']] = str_replace(
"public.",
"", $row[
'define']) .
";";
896 $this->dbman->freeResult($result);
908 $sql =
"SELECT proname AS name,
909 pronargs AS input_num,
910 proargnames AS input_names,
911 proargtypes AS input_type,
912 proargmodes AS input_modes,
914 prorettype AS output_type
916 INNER JOIN pg_language AS lang ON proc.prolang = lang.oid
917 WHERE lang.lanname = 'plpgsql'
920 $this->dbman->prepare($stmt, $sql);
921 $result = $this->dbman->execute($stmt);
922 while ($row = $this->dbman->fetchArray($result)) {
923 $sql =
"CREATE or REPLACE function " . $row[
'proname'] .
"()";
924 $sql .=
' RETURNS ' .
"TBD" .
' AS $$';
925 $sql .=
" " . $row[
'prosrc'];
926 $schema[
'FUNCTION'][$row[
'proname']] = $sql;
928 $this->dbman->freeResult($result);
941 $varname .=
'["' . str_replace(
'"',
'\"', $key) .
'"]';
942 if (!is_array($value)) {
943 $value = str_replace(
'"',
'\"', $value);
944 fwrite($fout,
"$varname = \"$value\";\n");
947 foreach ($value as $k => $v) {
966 $dbDriver = $this->dbman->getDriver();
967 if (empty($dbDriver)) {
969 $this->dbman->setDriver($pgDrive);
972 if (empty($filename)) {
973 $filename =
'php://stdout';
976 $fout = fopen($filename,
"w");
978 return (
"Failed to write to $filename\n");
981 fwrite($fout,
"<?php\n");
982 fwrite($fout,
"/* This file is generated by " . $Name .
" */\n");
983 fwrite($fout,
"/* Do not manually edit this file */\n\n");
984 fwrite($fout,
' $Schema=array();' .
"\n\n");
985 foreach ($Schema as $K1 => $V1) {
998 print
" Applying database functions\n";
1004 $sql =
'drop function if exists uploadtree2path(integer);';
1005 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
'.uploadtree2path.drop');
1008 CREATE function uploadtree2path(uploadtree_pk_in int) returns setof uploadtree as $$
1014 UTpk := uploadtree_pk_in;
1016 sql := ' .
"'" .
'select * from uploadtree where uploadtree_pk=' .
"'" .
' || UTpk;
1017 execute sql into UTrec;
1018 IF ((UTrec.ufile_mode & (1<<28)) = 0) THEN RETURN NEXT UTrec; END IF;
1019 UTpk := UTrec.parent;
1026 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
'.uploadtree2path.create');
1032 $sql =
'drop function if exists getItemParent(integer);';
1033 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
'.getItemParent.drop');
1036 CREATE OR REPLACE FUNCTION getItemParent(itemId Integer) RETURNS Integer AS $$
1037 WITH RECURSIVE file_tree(uploadtree_pk, parent, jump, path, cycle) AS (
1038 SELECT ut.uploadtree_pk, ut.parent,
1040 ARRAY[ut.uploadtree_pk],
1043 WHERE ut.uploadtree_pk = $1
1045 SELECT ut.uploadtree_pk, ut.parent,
1046 ut.ufile_mode & (1<<28) != 0,
1047 path || ut.uploadtree_pk,
1048 ut.uploadtree_pk = ANY(path)
1049 FROM uploadtree ut, file_tree ft
1050 WHERE ut.uploadtree_pk = ft.parent AND jump AND NOT cycle
1052 SELECT uploadtree_pk from file_tree ft WHERE NOT jump
1056 RETURNS NULL ON NULL INPUT
1058 $this->
applyOrEchoOnce($sql, $stmt = __METHOD__ .
'.getItemParent.create');
1067 if (empty($this->schema[
'INHERITS'])) {
1070 foreach ($this->schema[
'INHERITS'] as $table => $fromTable) {
1071 if (empty($table)) {
1074 if (!$this->dbman->existsTable($table) && $this->dbman->existsTable($fromTable)) {
1075 $sql =
"CREATE TABLE \"$table\" () INHERITS (\"$fromTable\")";
1084 if (empty($dbManager) || !($dbManager instanceof
DbManager)) {
1085 $logLevel = Logger::INFO;
1086 $logger =
new Logger(__FILE__);
1087 $logger->pushHandler(
new ErrorLogHandler(ErrorLogHandler::OPERATING_SYSTEM, $logLevel));
1089 $pgDriver =
new Postgres($GLOBALS[
'PG_CONN']);
1090 $dbManager->setDriver($pgDriver);
1101 function ApplySchema($Filename = NULL, $Debug =
false, $Catalog =
'fossology')
1104 return $libschema->applySchema($Filename, $Debug, $Catalog);
1113 return $libschema->getCurrSchema();
1125 return $libschema->exportSchema($filename);
1134 $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