Passed
Push — develop ( a33225...c5f03c )
by Felipe
09:45
created

ViewTrait::alterViewName()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 11
nc 6
nop 2
1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.47
5
 */
6
7
namespace PHPPgAdmin\DatabaseTraits;
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
     * @param bool   $materialized tells if it's a materialized view or not
61
     *
62
     * @return bool|int 0 success
63
     */
64
    public function setView($viewname, $definition, $comment, $materialized = false)
65
    {
66
        return $this->createView($viewname, $definition, true, $comment, $materialized);
67
    }
68
69
    /**
70
     * Creates a new view.
71
     *
72
     * @param string $viewname     The name of the view to create
73
     * @param string $definition   The definition for the new view
74
     * @param bool   $replace      True to replace the view, false otherwise
75
     * @param string $comment
76
     * @param bool   $materialized tells if it's a materialized view
77
     *
78
     * @return bool|int 0 success
79
     */
80
    public function createView($viewname, $definition, $replace, $comment, $materialized = false)
81
    {
82
        $status = $this->beginTransaction();
83
        if ($status != 0) {
84
            return -1;
85
        }
86
87
        $f_schema = $this->_schema;
88
        $this->fieldClean($f_schema);
89
        $this->fieldClean($viewname);
90
91
        // Note: $definition not cleaned
92
93
        $sql = 'CREATE ';
94
95
        $sql .= $replace ? ' OR REPLACE ' : ' ';
96
97
        $obj_type = $materialized ? ' MATERIALIZED VIEW ' : ' VIEW ';
98
99
        $sql .= $obj_type . " \"{$f_schema}\".\"{$viewname}\" AS {$definition}";
100
101
        $status = $this->execute($sql);
102
        if ($status) {
103
            $this->rollbackTransaction();
104
105
            return -1;
106
        }
107
108
        if ($comment != '') {
109
            $status = $this->setComment($obj_type, $viewname, '', $comment);
110
            if ($status) {
111
                $this->rollbackTransaction();
112
113
                return -1;
114
            }
115
        }
116
117
        return $this->endTransaction();
118
    }
119
120
    /**
121
     * Alter view properties.
122
     *
123
     * @param string $view    The name of the view
124
     * @param string $name    The new name for the view
125
     * @param string $owner   The new owner for the view
126
     * @param string $schema  The new schema for the view
127
     * @param string $comment The comment on the view
128
     *
129
     * @return bool|int 0 success
130
     */
131
    public function alterView($view, $name, $owner, $schema, $comment)
132
    {
133
        $data = $this->getView($view);
134
135
        if ($data->RecordCount() != 1) {
136
            return -2;
137
        }
138
139
        $status = $this->beginTransaction();
140
        if ($status != 0) {
141
            $this->rollbackTransaction();
142
143
            return -1;
144
        }
145
146
        $status = $this->_alterView($data, $name, $owner, $schema, $comment);
147
148
        if ($status != 0) {
149
            $this->rollbackTransaction();
150
151
            return $status;
152
        }
153
154
        return $this->endTransaction();
155
    }
156
157
    /**
158
     * Returns all details for a particular view or materialized view.
159
     *
160
     * @param string $view The name of the view or materialized to retrieve
161
     *
162
     * @return \PHPPgAdmin\ADORecordSet [Materialized] View info
163
     */
164
    public function getView($view)
165
    {
166
        $c_schema = $this->_schema;
167
        $this->clean($c_schema);
168
        $this->clean($view);
169
170
        $sql = "
171
			SELECT c.relname, n.nspname, pg_catalog.pg_get_userbyid(c.relowner) AS relowner,
172
				pg_catalog.pg_get_viewdef(c.oid, true) AS vwdefinition,
173
				pg_catalog.obj_description(c.oid, 'pg_class') AS relcomment,
174
                c.relkind
175
			FROM pg_catalog.pg_class c
176
				LEFT JOIN pg_catalog.pg_namespace n ON (n.oid = c.relnamespace)
177
			WHERE (c.relname = '{$view}') AND n.nspname='{$c_schema}'";
178
179
        return $this->selectSet($sql);
180
    }
181
182
    /**
183
     * Protected method which alter a view
184
     * SHOULDN'T BE CALLED OUTSIDE OF A TRANSACTION.
185
     *
186
     * @param \PHPPgAdmin\ADORecordSet $vwrs    The view recordSet returned by getView()
187
     * @param string                   $name    The new name for the view
188
     * @param string                   $owner   The new owner for the view
189
     * @param string                   $schema  Schema name
190
     * @param string                   $comment The comment on the view
191
     *
192
     * @return int 0 success
193
     */
194
    protected function _alterView($vwrs, $name, $owner, $schema, $comment)
195
    {
196
        $this->fieldArrayClean($vwrs->fields);
197
198
        $type = ($vwrs->fields['relkind'] === 'm') ? 'MATERIALIZED VIEW' : 'VIEW';
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 = ($vwrs->fields['relkind'] === 'm') ? 'MATERIALIZED VIEW' : 'VIEW';
242
        /* $vwrs and $owner are cleaned in _alterView */
243
        if ((!empty($owner)) && ($vwrs->fields['relowner'] != $owner)) {
244
            $f_schema = $this->_schema;
245
            $this->fieldClean($f_schema);
246
            // If owner has been changed, then do the alteration.  We are
247
            // careful to avoid this generally as changing owner is a
248
            // superuser only function.
249
            $sql = "ALTER ${type} \"{$f_schema}\".\"{$vwrs->fields['relname']}\" OWNER TO \"{$owner}\"";
250
251
            return $this->execute($sql);
252
        }
253
254
        return 0;
255
    }
256
257
    /**
258
     * Rename a view.
259
     *
260
     * @param \PHPPgAdmin\ADORecordSet $vwrs The view recordSet returned by getView()
261
     * @param string                   $name The new view's name
262
     *
263
     * @return int 0 if operation was successful
264
     */
265
    public function alterViewName($vwrs, $name)
266
    {
267
        $type = ($vwrs->fields['relkind'] === 'm') ? 'MATERIALIZED VIEW' : 'VIEW';
268
        // Rename (only if name has changed)
269
        /* $vwrs and $name are cleaned in _alterView */
270
        if (!empty($name) && ($name != $vwrs->fields['relname'])) {
271
            $f_schema = $this->_schema;
272
            $this->fieldClean($f_schema);
273
            $sql    = "ALTER ${type} \"{$f_schema}\".\"{$vwrs->fields['relname']}\" RENAME TO \"{$name}\"";
274
            $status = $this->execute($sql);
275
            if ($status == 0) {
276
                $vwrs->fields['relname'] = $name;
277
            } else {
278
                return $status;
279
            }
280
        }
281
282
        return 0;
283
    }
284
285
    /**
286
     * Alter a view's schema.
287
     *
288
     * @param \PHPPgAdmin\ADORecordSet $vwrs   The view recordSet returned by getView()
289
     * @param string                   $schema
290
     *
291
     * @return int 0 if operation was successful
292
     *
293
     * @internal param The $name new view's schema
294
     */
295
    public function alterViewSchema($vwrs, $schema)
296
    {
297
        $type = ($vwrs->fields['relkind'] === 'm') ? 'MATERIALIZED VIEW' : 'VIEW';
298
299
        /* $vwrs and $schema are cleaned in _alterView */
300
        if (!empty($schema) && ($vwrs->fields['nspname'] != $schema)) {
301
            $f_schema = $this->_schema;
302
            $this->fieldClean($f_schema);
303
            // If tablespace has been changed, then do the alteration.  We
304
            // don't want to do this unnecessarily.
305
            $sql = "ALTER ${type} \"{$f_schema}\".\"{$vwrs->fields['relname']}\" SET SCHEMA \"{$schema}\"";
306
307
            return $this->execute($sql);
308
        }
309
310
        return 0;
311
    }
312
313
    /**
314
     * Drops a view.
315
     *
316
     * @param string $viewname The name of the view to drop
317
     * @param string $cascade  True to cascade drop, false to restrict
318
     *
319
     * @return int 0 if operation was successful
320
     */
321
    public function dropView($viewname, $cascade)
322
    {
323
        $vwrs = $this->getView($viewname);
324
        $type = ($vwrs->fields['relkind'] === 'm') ? 'MATERIALIZED VIEW' : 'VIEW';
325
326
        $f_schema = $this->_schema;
327
        $this->fieldClean($f_schema);
328
        $this->fieldClean($viewname);
329
330
        $sql = "DROP ${type} \"{$f_schema}\".\"{$viewname}\"";
331
        if ($cascade) {
332
            $sql .= ' CASCADE';
333
        }
334
335
        return $this->execute($sql);
336
    }
337
338
    abstract public function fieldClean(&$str);
339
340
    abstract public function beginTransaction();
341
342
    abstract public function rollbackTransaction();
343
344
    abstract public function endTransaction();
345
346
    abstract public function execute($sql);
347
348
    abstract public function setComment($obj_type, $obj_name, $table, $comment, $basetype = null);
349
350
    abstract public function selectSet($sql);
351
352
    abstract public function clean(&$str);
353
354
    abstract public function fieldArrayClean(&$arr);
355
}
356