Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/HuasoFoundries/phpPgAdmin6.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/Database/Traits/ViewTrait.php')
-rw-r--r--src/Database/Traits/ViewTrait.php368
1 files changed, 368 insertions, 0 deletions
diff --git a/src/Database/Traits/ViewTrait.php b/src/Database/Traits/ViewTrait.php
new file mode 100644
index 00000000..b58409f1
--- /dev/null
+++ b/src/Database/Traits/ViewTrait.php
@@ -0,0 +1,368 @@
+<?php
+
+/**
+ * PHPPgAdmin6
+ */
+
+namespace PHPPgAdmin\Database\Traits;
+
+/**
+ * Common trait for views manipulation.
+ */
+trait ViewTrait
+{
+ /**
+ * Returns a list of all views in the database.
+ *
+ * @return \ADORecordSet|bool|int|string
+ */
+ public function getViews()
+ {
+ $c_schema = $this->_schema;
+ $this->clean($c_schema);
+ $sql = \sprintf('
+ SELECT c.relname, pg_catalog.pg_get_userbyid(c.relowner) AS relowner,
+ pg_catalog.obj_description(c.oid, \'pg_class\') AS relcomment
+ FROM pg_catalog.pg_class c
+ LEFT JOIN pg_catalog.pg_namespace n ON (n.oid = c.relnamespace)
+ WHERE (n.nspname=\'%s\') AND (c.relkind = \'v\'::"char")
+ ORDER BY relname', $c_schema);
+
+ return $this->selectSet($sql);
+ }
+
+ /**
+ * Returns a list of all materialized views in the database.
+ *
+ * @return \ADORecordSet|bool|int|string
+ */
+ public function getMaterializedViews()
+ {
+ $c_schema = $this->_schema;
+ $this->clean($c_schema);
+ $sql = \sprintf('
+ SELECT c.relname, pg_catalog.pg_get_userbyid(c.relowner) AS relowner,
+ pg_catalog.obj_description(c.oid, \'pg_class\') AS relcomment
+ FROM pg_catalog.pg_class c
+ LEFT JOIN pg_catalog.pg_namespace n ON (n.oid = c.relnamespace)
+ WHERE (n.nspname=\'%s\') AND (c.relkind = \'m\'::"char")
+ ORDER BY relname', $c_schema);
+
+ return $this->selectSet($sql);
+ }
+
+ /**
+ * Updates a view.
+ *
+ * @param string $viewname The name fo the view to update
+ * @param string $definition The new definition for the view
+ * @param string $comment
+ * @param bool $materialized tells if it's a materialized view or not
+ *
+ * @return int 0 success
+ */
+ public function setView($viewname, $definition, $comment, $materialized = false)
+ {
+ return $this->createView($viewname, $definition, true, $comment, $materialized);
+ }
+
+ /**
+ * Creates a new view.
+ *
+ * @param string $viewname The name of the view to create
+ * @param string $definition The definition for the new view
+ * @param bool $replace True to replace the view, false otherwise
+ * @param string $comment
+ * @param bool $materialized tells if it's a materialized view
+ *
+ * @return int
+ *
+ * @psalm-return -1|0|1
+ */
+ public function createView($viewname, $definition, $replace, $comment, $materialized = false)
+ {
+ $status = $this->beginTransaction();
+
+ if (0 !== $status) {
+ return -1;
+ }
+
+ $f_schema = $this->_schema;
+ $this->fieldClean($f_schema);
+ $this->fieldClean($viewname);
+
+ // Note: $definition not cleaned
+
+ $sql = 'CREATE ';
+
+ $sql .= $replace ? ' OR REPLACE ' : ' ';
+
+ $obj_type = $materialized ? ' MATERIALIZED VIEW ' : ' VIEW ';
+
+ $sql .= $obj_type . \sprintf(' "%s"."%s" AS %s', $f_schema, $viewname, $definition);
+
+ $status = $this->execute($sql);
+
+ if ($status) {
+ $this->rollbackTransaction();
+
+ return -1;
+ }
+
+ if ('' !== $comment) {
+ $status = $this->setComment($obj_type, $viewname, '', $comment);
+
+ if ($status) {
+ $this->rollbackTransaction();
+
+ return -1;
+ }
+ }
+
+ return $this->endTransaction();
+ }
+
+ /**
+ * Alter view properties.
+ *
+ * @param string $view The name of the view
+ * @param string $name The new name for the view
+ * @param string $owner The new owner for the view
+ * @param string $schema The new schema for the view
+ * @param string $comment The comment on the view
+ *
+ * @return int 0 success
+ */
+ public function alterView($view, $name, $owner, $schema, $comment)
+ {
+ $data = $this->getView($view);
+
+ if (1 !== $data->RecordCount()) {
+ return -2;
+ }
+
+ $status = $this->beginTransaction();
+
+ if (0 !== $status || !($data instanceof \PHPPgAdmin\Core\ADORecordSet)) {
+ $this->rollbackTransaction();
+
+ return -1;
+ }
+
+ $status = $this->_alterView($data, $name, $owner, $schema, $comment);
+
+ if (0 !== $status) {
+ $this->rollbackTransaction();
+
+ return $status;
+ }
+
+ return $this->endTransaction();
+ }
+
+ /**
+ * Returns all details for a particular view or materialized view.
+ *
+ * @param string $view The name of the view or materialized to retrieve
+ *
+ * @return \ADORecordSet|bool|int|string
+ */
+ public function getView($view)
+ {
+ $c_schema = $this->_schema;
+ $this->clean($c_schema);
+ $this->clean($view);
+
+ $sql = \sprintf('
+ SELECT c.relname, n.nspname, pg_catalog.pg_get_userbyid(c.relowner) AS relowner,
+ pg_catalog.pg_get_viewdef(c.oid, true) AS vwdefinition,
+ pg_catalog.obj_description(c.oid, \'pg_class\') AS relcomment,
+ c.relkind
+ FROM pg_catalog.pg_class c
+ LEFT JOIN pg_catalog.pg_namespace n ON (n.oid = c.relnamespace)
+ WHERE (c.relname = \'%s\') AND n.nspname=\'%s\'', $view, $c_schema);
+
+ return $this->selectSet($sql);
+ }
+
+ /**
+ * Alter a view's owner.
+ *
+ * @param \PHPPgAdmin\Core\ADORecordSet $vwrs The view recordSet returned by getView()
+ * @param null|string $owner
+ *
+ * @return int|string
+ *
+ * @internal param $name new view's owner
+ */
+ public function alterViewOwner($vwrs, $owner = null)
+ {
+ $type = ('m' === $vwrs->fields['relkind']) ? 'MATERIALIZED VIEW' : 'VIEW';
+ /* $vwrs and $owner are cleaned in _alterView */
+ if ((!empty($owner)) && ($vwrs->fields['relowner'] !== $owner)) {
+ $f_schema = $this->_schema;
+ $this->fieldClean($f_schema);
+ // If owner has been changed, then do the alteration. We are
+ // careful to avoid this generally as changing owner is a
+ // superuser only function.
+ $sql = \sprintf('ALTER %s "%s"."%s" OWNER TO "%s"', $type, $f_schema, $vwrs->fields['relname'], $owner);
+
+ return $this->execute($sql);
+ }
+
+ return 0;
+ }
+
+ /**
+ * Rename a view.
+ *
+ * @param \PHPPgAdmin\Core\ADORecordSet $vwrs The view recordSet returned by getView()
+ * @param string $name The new view's name
+ *
+ * @return int|string
+ */
+ public function alterViewName($vwrs, $name)
+ {
+ $type = ('m' === $vwrs->fields['relkind']) ? 'MATERIALIZED VIEW' : 'VIEW';
+ // Rename (only if name has changed)
+ /* $vwrs and $name are cleaned in _alterView */
+ if (!empty($name) && ($name !== $vwrs->fields['relname'])) {
+ $f_schema = $this->_schema;
+ $this->fieldClean($f_schema);
+ $sql = \sprintf('ALTER %s "%s"."%s" RENAME TO "%s"', $type, $f_schema, $vwrs->fields['relname'], $name);
+ $status = $this->execute($sql);
+
+ if (0 === $status) {
+ $vwrs->fields['relname'] = $name;
+ } else {
+ return $status;
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ * Alter a view's schema.
+ *
+ * @param \PHPPgAdmin\Core\ADORecordSet $vwrs The view recordSet returned by getView()
+ * @param string $schema
+ *
+ * @return int|string
+ *
+ * @internal param The $name new view's schema
+ */
+ public function alterViewSchema($vwrs, $schema)
+ {
+ $type = ('m' === $vwrs->fields['relkind']) ? 'MATERIALIZED VIEW' : 'VIEW';
+
+ /* $vwrs and $schema are cleaned in _alterView */
+ if (!empty($schema) && ($vwrs->fields['nspname'] !== $schema)) {
+ $f_schema = $this->_schema;
+ $this->fieldClean($f_schema);
+ // If tablespace has been changed, then do the alteration. We
+ // don't want to do this unnecessarily.
+ $sql = \sprintf('ALTER %s "%s"."%s" SET SCHEMA "%s"', $type, $f_schema, $vwrs->fields['relname'], $schema);
+
+ return $this->execute($sql);
+ }
+
+ return 0;
+ }
+
+ /**
+ * Drops a view.
+ *
+ * @param string $viewname The name of the view to drop
+ * @param string $cascade True to cascade drop, false to restrict
+ *
+ * @return int|string
+ */
+ public function dropView($viewname, $cascade)
+ {
+ $vwrs = $this->getView($viewname);
+ $type = ('m' === $vwrs->fields['relkind']) ? 'MATERIALIZED VIEW' : 'VIEW';
+
+ $f_schema = $this->_schema;
+ $this->fieldClean($f_schema);
+ $this->fieldClean($viewname);
+
+ $sql = \sprintf('DROP %s "%s"."%s"', $type, $f_schema, $viewname);
+
+ if ($cascade) {
+ $sql .= ' CASCADE';
+ }
+
+ return $this->execute($sql);
+ }
+
+ abstract public function fieldClean(&$str);
+
+ abstract public function beginTransaction();
+
+ abstract public function rollbackTransaction();
+
+ abstract public function endTransaction();
+
+ abstract public function execute($sql);
+
+ abstract public function setComment($obj_type, $obj_name, $table, $comment, $basetype = null);
+
+ abstract public function selectSet($sql);
+
+ abstract public function clean(&$str);
+
+ abstract public function fieldArrayClean(&$arr);
+
+ /**
+ * Protected method which alter a view
+ * SHOULDN'T BE CALLED OUTSIDE OF A TRANSACTION.
+ *
+ * @param \PHPPgAdmin\Core\ADORecordSet $vwrs The view recordSet returned by getView()
+ * @param string $name The new name for the view
+ * @param string $owner The new owner for the view
+ * @param string $schema Schema name
+ * @param string $comment The comment on the view
+ *
+ * @return int
+ *
+ * @psalm-return -6|-5|-4|-3|0
+ */
+ protected function _alterView($vwrs, $name, $owner, $schema, $comment)
+ {
+ $this->fieldArrayClean($vwrs->fields);
+
+ $type = ('m' === $vwrs->fields['relkind']) ? 'MATERIALIZED VIEW' : 'VIEW';
+ // Comment
+
+ if (0 !== $this->setComment($type, $vwrs->fields['relname'], '', $comment)) {
+ return -4;
+ }
+
+ // Owner
+ $this->fieldClean($owner);
+ $status = $this->alterViewOwner($vwrs, $owner);
+
+ if (0 !== $status) {
+ return -5;
+ }
+
+ // Rename
+ $this->fieldClean($name);
+ $status = $this->alterViewName($vwrs, $name);
+
+ if (0 !== $status) {
+ return -3;
+ }
+
+ // Schema
+ $this->fieldClean($schema);
+ $status = $this->alterViewSchema($vwrs, $schema);
+
+ if (0 !== $status) {
+ return -6;
+ }
+
+ return 0;
+ }
+}