Passed
Push — develop ( e54c4a...a6767a )
by Felipe
11:32 queued 05:47
created

ViewTrait::alterViewOwner()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 9.2
c 0
b 0
f 0
cc 4
eloc 9
nc 4
nop 2
1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.43
5
 */
6
7
namespace PHPPgAdmin\Traits;
8
9
/**
10
 * Common trait for views manipulation.
11
 */
12
trait ViewTrait
13
{
14
    /**
15
     * Returns a list of all views in the database.
16
     *
17
     * @return \PHPPgAdmin\ADORecordSet All views
18
     */
19
    public function getViews()
20
    {
21
        $c_schema = $this->_schema;
22
        $this->clean($c_schema);
23
        $sql = "
24
			SELECT c.relname, pg_catalog.pg_get_userbyid(c.relowner) AS relowner,
25
				pg_catalog.obj_description(c.oid, 'pg_class') AS relcomment
26
			FROM pg_catalog.pg_class c
27
				LEFT JOIN pg_catalog.pg_namespace n ON (n.oid = c.relnamespace)
28
			WHERE (n.nspname='{$c_schema}') AND (c.relkind = 'v'::\"char\")
29
			ORDER BY relname";
30
31
        return $this->selectSet($sql);
32
    }
33
34
    /**
35
     * Returns a list of all materialized views in the database.
36
     *
37
     * @return \PHPPgAdmin\ADORecordSet All materialized views
38
     */
39
    public function getMaterializedViews()
40
    {
41
        $c_schema = $this->_schema;
42
        $this->clean($c_schema);
43
        $sql = "
44
			SELECT c.relname, pg_catalog.pg_get_userbyid(c.relowner) AS relowner,
45
				pg_catalog.obj_description(c.oid, 'pg_class') AS relcomment
46
			FROM pg_catalog.pg_class c
47
				LEFT JOIN pg_catalog.pg_namespace n ON (n.oid = c.relnamespace)
48
			WHERE (n.nspname='{$c_schema}') AND (c.relkind = 'm'::\"char\")
49
			ORDER BY relname";
50
51
        return $this->selectSet($sql);
52
    }
53
54
    /**
55
     * Updates a view.
56
     *
57
     * @param string $viewname   The name fo the view to update
58
     * @param string $definition The new definition for the view
59
     * @param string $comment
60
     *
61
     * @return bool|int 0 success
62
     */
63
    public function setView($viewname, $definition, $comment)
64
    {
65
        return $this->createView($viewname, $definition, true, $comment);
66
    }
67
68
    /**
69
     * Creates a new view.
70
     *
71
     * @param string $viewname   The name of the view to create
72
     * @param string $definition The definition for the new view
73
     * @param bool   $replace    True to replace the view, false otherwise
74
     * @param string $comment
75
     *
76
     * @return bool|int 0 success
77
     */
78
    public function createView($viewname, $definition, $replace, $comment)
79
    {
80
        $status = $this->beginTransaction();
81
        if ($status != 0) {
82
            return -1;
83
        }
84
85
        $f_schema = $this->_schema;
86
        $this->fieldClean($f_schema);
87
        $this->fieldClean($viewname);
88
89
        // Note: $definition not cleaned
90
91
        $sql = 'CREATE ';
92
        if ($replace) {
93
            $sql .= 'OR REPLACE ';
94
        }
95
96
        $sql .= "VIEW \"{$f_schema}\".\"{$viewname}\" AS {$definition}";
97
98
        $status = $this->execute($sql);
99
        if ($status) {
100
            $this->rollbackTransaction();
101
102
            return -1;
103
        }
104
105
        if ($comment != '') {
106
            $status = $this->setComment('VIEW', $viewname, '', $comment);
107
            if ($status) {
108
                $this->rollbackTransaction();
109
110
                return -1;
111
            }
112
        }
113
114
        return $this->endTransaction();
115
    }
116
117
    /**
118
     * Alter view properties.
119
     *
120
     * @param string $view    The name of the view
121
     * @param string $name    The new name for the view
122
     * @param string $owner   The new owner for the view
123
     * @param string $schema  The new schema for the view
124
     * @param string $comment The comment on the view
125
     *
126
     * @return bool|int 0 success
127
     */
128
    public function alterView($view, $name, $owner, $schema, $comment)
129
    {
130
        $data = $this->getView($view);
131
132
        if ($data->recordCount() != 1) {
0 ignored issues
show
introduced by
The condition $data->recordCount() != 1 is always true.
Loading history...
133
            return -2;
134
        }
135
136
        $status = $this->beginTransaction();
137
        if ($status != 0) {
138
            $this->rollbackTransaction();
139
140
            return -1;
141
        }
142
143
        $status = $this->_alterView($data, $name, $owner, $schema, $comment);
144
145
        if ($status != 0) {
146
            $this->rollbackTransaction();
147
148
            return $status;
149
        }
150
151
        return $this->endTransaction();
152
    }
153
154
    /**
155
     * Returns all details for a particular view or materialized view.
156
     *
157
     * @param string $view The name of the view or materialized to retrieve
158
     *
159
     * @return \PHPPgAdmin\ADORecordSet [Materialized] View info
160
     */
161
    public function getView($view)
162
    {
163
        $c_schema = $this->_schema;
164
        $this->clean($c_schema);
165
        $this->clean($view);
166
167
        $sql = "
168
			SELECT c.relname, n.nspname, pg_catalog.pg_get_userbyid(c.relowner) AS relowner,
169
				pg_catalog.pg_get_viewdef(c.oid, true) AS vwdefinition,
170
				pg_catalog.obj_description(c.oid, 'pg_class') AS relcomment,
171
                c.relkind
172
			FROM pg_catalog.pg_class c
173
				LEFT JOIN pg_catalog.pg_namespace n ON (n.oid = c.relnamespace)
174
			WHERE (c.relname = '{$view}') AND n.nspname='{$c_schema}'";
175
176
        return $this->selectSet($sql);
177
    }
178
179
    /**
180
     * Protected method which alter a view
181
     * SHOULDN'T BE CALLED OUTSIDE OF A TRANSACTION.
182
     *
183
     * @param \PHPPgAdmin\ADORecordSet $vwrs    The view recordSet returned by getView()
184
     * @param string                   $name    The new name for the view
185
     * @param string                   $owner   The new owner for the view
186
     * @param string                   $schema  Schema name
187
     * @param string                   $comment The comment on the view
188
     *
189
     * @return int 0 success
190
     */
191
    protected function _alterView($vwrs, $name, $owner, $schema, $comment)
1 ignored issue
show
Coding Style introduced by
Protected method name "ViewTrait::_alterView" must not be prefixed with an underscore
Loading history...
192
    {
193
        $this->fieldArrayClean($vwrs->fields);
0 ignored issues
show
Bug introduced by
It seems like fieldArrayClean() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

193
        $this->/** @scrutinizer ignore-call */ 
194
               fieldArrayClean($vwrs->fields);
Loading history...
194
195
        $type = 'VIEW';
196
        if ($vwrs->fields['relkind'] === 'm') {
197
            $type = 'MATERIALIZED VIEW';
198
        }
199
        // Comment
200
201
        if ($this->setComment($type, $vwrs->fields['relname'], '', $comment) != 0) {
202
            return -4;
203
        }
204
205
        // Owner
206
        $this->fieldClean($owner);
207
        $status = $this->alterViewOwner($vwrs, $owner);
208
        if ($status != 0) {
209
            return -5;
210
        }
211
212
        // Rename
213
        $this->fieldClean($name);
214
        $status = $this->alterViewName($vwrs, $name);
215
        if ($status != 0) {
216
            return -3;
217
        }
218
219
        // Schema
220
        $this->fieldClean($schema);
221
        $status = $this->alterViewSchema($vwrs, $schema);
222
        if ($status != 0) {
223
            return -6;
224
        }
225
226
        return 0;
227
    }
228
229
    /**
230
     * Alter a view's owner.
231
     *
232
     * @param \PHPPgAdmin\ADORecordSet $vwrs  The view recordSet returned by getView()
233
     * @param null|string              $owner
234
     *
235
     * @return int 0 if operation was successful
236
     *
237
     * @internal param  $name new view's owner
238
     */
239
    public function alterViewOwner($vwrs, $owner = null)
240
    {
241
        $type = 'VIEW';
242
        if ($vwrs->fields['relkind'] === 'm') {
243
            $type = 'MATERIALIZED VIEW';
244
        }
245
        /* $vwrs and $owner are cleaned in _alterView */
246
        if ((!empty($owner)) && ($vwrs->fields['relowner'] != $owner)) {
247
            $f_schema = $this->_schema;
248
            $this->fieldClean($f_schema);
249
            // If owner has been changed, then do the alteration.  We are
250
            // careful to avoid this generally as changing owner is a
251
            // superuser only function.
252
            $sql = "ALTER ${type} \"{$f_schema}\".\"{$vwrs->fields['relname']}\" OWNER TO \"{$owner}\"";
253
254
            return $this->execute($sql);
255
        }
256
257
        return 0;
258
    }
259
260
    /**
261
     * Rename a view.
262
     *
263
     * @param \PHPPgAdmin\ADORecordSet $vwrs The view recordSet returned by getView()
264
     * @param string                   $name The new view's name
265
     *
266
     * @return int 0 if operation was successful
267
     */
268
    public function alterViewName($vwrs, $name)
269
    {
270
        $type = 'VIEW';
271
        if ($vwrs->fields['relkind'] === 'm') {
272
            $type = 'MATERIALIZED VIEW';
273
        }
274
        // Rename (only if name has changed)
275
        /* $vwrs and $name are cleaned in _alterView */
276
        if (!empty($name) && ($name != $vwrs->fields['relname'])) {
277
            $f_schema = $this->_schema;
278
            $this->fieldClean($f_schema);
279
            $sql    = "ALTER $type \"{$f_schema}\".\"{$vwrs->fields['relname']}\" RENAME TO \"{$name}\"";
280
            $status = $this->execute($sql);
281
            if ($status == 0) {
282
                $vwrs->fields['relname'] = $name;
283
            } else {
284
                return $status;
285
            }
286
        }
287
288
        return 0;
289
    }
290
291
    /**
292
     * Alter a view's schema.
293
     *
294
     * @param \PHPPgAdmin\ADORecordSet $vwrs   The view recordSet returned by getView()
295
     * @param string                   $schema
296
     *
297
     * @return int 0 if operation was successful
298
     *
299
     * @internal param The $name new view's schema
300
     */
301
    public function alterViewSchema($vwrs, $schema)
302
    {
303
        $type = 'VIEW';
304
        if ($vwrs->fields['relkind'] === 'm') {
305
            $type = 'MATERIALIZED VIEW';
306
        }
307
        /* $vwrs and $schema are cleaned in _alterView */
308
        if (!empty($schema) && ($vwrs->fields['nspname'] != $schema)) {
309
            $f_schema = $this->_schema;
310
            $this->fieldClean($f_schema);
311
            // If tablespace has been changed, then do the alteration.  We
312
            // don't want to do this unnecessarily.
313
            $sql = "ALTER $type \"{$f_schema}\".\"{$vwrs->fields['relname']}\" SET SCHEMA \"{$schema}\"";
314
315
            return $this->execute($sql);
316
        }
317
318
        return 0;
319
    }
320
321
    /**
322
     * Drops a view.
323
     *
324
     * @param string $viewname The name of the view to drop
325
     * @param string $cascade  True to cascade drop, false to restrict
326
     *
327
     * @return int 0 if operation was successful
328
     */
329
    public function dropView($viewname, $cascade)
330
    {
331
        $type = 'VIEW';
332
        if ($vwrs->fields['relkind'] === 'm') {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $vwrs seems to be never defined.
Loading history...
333
            $type = 'MATERIALIZED VIEW';
334
        }
335
        $f_schema = $this->_schema;
336
        $this->fieldClean($f_schema);
337
        $this->fieldClean($viewname);
338
339
        $sql = "DROP $type \"{$f_schema}\".\"{$viewname}\"";
340
        if ($cascade) {
341
            $sql .= ' CASCADE';
342
        }
343
344
        return $this->execute($sql);
345
    }
346
347
    abstract public function fieldClean(&$str);
348
349
    abstract public function beginTransaction();
350
351
    abstract public function rollbackTransaction();
352
353
    abstract public function endTransaction();
354
355
    abstract public function execute($sql);
356
357
    abstract public function setComment($obj_type, $obj_name, $table, $comment, $basetype = null);
358
359
    abstract public function selectSet($sql);
360
361
    abstract public function clean(&$str);
362
}
363