Passed
Push — develop ( ce7da4...69770d )
by Felipe
05:27
created

SequenceTrait::alterSequenceProps()   D

Complexity

Conditions 16
Paths 384

Size

Total Lines 50
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 50
rs 4
c 0
b 0
f 0
cc 16
eloc 21
nc 384
nop 8

How to fix   Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.40
5
 */
6
7
namespace PHPPgAdmin\Database;
8
9
/**
10
 * Common trait for sequence manipulation.
11
 */
12
trait SequenceTrait
13
{
14
15
    /**
16
     * Returns all sequences in the current database.
17
     *
18
     * @param bool $all
19
     *
20
     * @return \PHPPgAdmin\ADORecordSet A recordset
21
     */
22
    public function getSequences($all = false)
23
    {
24
        if ($all) {
25
            // Exclude pg_catalog and information_schema tables
26
            $sql = "SELECT n.nspname, c.relname AS seqname, u.usename AS seqowner
27
				FROM pg_catalog.pg_class c, pg_catalog.pg_user u, pg_catalog.pg_namespace n
28
				WHERE c.relowner=u.usesysid AND c.relnamespace=n.oid
29
				AND c.relkind = 'S'
30
				AND n.nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast')
31
				ORDER BY nspname, seqname";
32
        } else {
33
            $c_schema = $this->_schema;
34
            $this->clean($c_schema);
0 ignored issues
show
Bug introduced by
It seems like clean() 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

34
            $this->/** @scrutinizer ignore-call */ 
35
                   clean($c_schema);
Loading history...
35
            $sql = "SELECT c.relname AS seqname, u.usename AS seqowner, pg_catalog.obj_description(c.oid, 'pg_class') AS seqcomment,
36
				(SELECT spcname FROM pg_catalog.pg_tablespace pt WHERE pt.oid=c.reltablespace) AS tablespace
37
				FROM pg_catalog.pg_class c, pg_catalog.pg_user u, pg_catalog.pg_namespace n
38
				WHERE c.relowner=u.usesysid AND c.relnamespace=n.oid
39
				AND c.relkind = 'S' AND n.nspname='{$c_schema}' ORDER BY seqname";
40
        }
41
42
        return $this->selectSet($sql);
0 ignored issues
show
Bug introduced by
It seems like selectSet() 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

42
        return $this->/** @scrutinizer ignore-call */ selectSet($sql);
Loading history...
43
    }
44
45
    /**
46
     * Execute nextval on a given sequence.
47
     *
48
     * @param $sequence Sequence name
49
     *
50
     * @return int 0 if operation was successful
51
     */
52
    public function nextvalSequence($sequence)
53
    {
54
        /* This double-cleaning is deliberate */
55
        $f_schema = $this->_schema;
56
        $this->fieldClean($f_schema);
0 ignored issues
show
Bug introduced by
It seems like fieldClean() 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

56
        $this->/** @scrutinizer ignore-call */ 
57
               fieldClean($f_schema);
Loading history...
57
        $this->clean($f_schema);
58
        $this->fieldClean($sequence);
59
        $this->clean($sequence);
60
61
        $sql = "SELECT pg_catalog.NEXTVAL('\"{$f_schema}\".\"{$sequence}\"')";
62
63
        return $this->execute($sql);
0 ignored issues
show
Bug introduced by
It seems like execute() 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

63
        return $this->/** @scrutinizer ignore-call */ execute($sql);
Loading history...
64
    }
65
66
    /**
67
     * Execute setval on a given sequence.
68
     *
69
     * @param $sequence  Sequence name
70
     * @param $nextvalue The next value
0 ignored issues
show
Bug introduced by
The type PHPPgAdmin\Database\The was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
71
     *
72
     * @return int 0 if operation was successful
73
     */
74
    public function setvalSequence($sequence, $nextvalue)
75
    {
76
        /* This double-cleaning is deliberate */
77
        $f_schema = $this->_schema;
78
        $this->fieldClean($f_schema);
79
        $this->clean($f_schema);
80
        $this->fieldClean($sequence);
81
        $this->clean($sequence);
82
        $this->clean($nextvalue);
83
84
        $sql = "SELECT pg_catalog.SETVAL('\"{$f_schema}\".\"{$sequence}\"', '{$nextvalue}')";
85
86
        return $this->execute($sql);
87
    }
88
89
    /**
90
     * Restart a given sequence to its start value.
91
     *
92
     * @param $sequence Sequence name
93
     *
94
     * @return int 0 if operation was successful
95
     */
96
    public function restartSequence($sequence)
97
    {
98
        $f_schema = $this->_schema;
99
        $this->fieldClean($f_schema);
100
        $this->fieldClean($sequence);
101
102
        $sql = "ALTER SEQUENCE \"{$f_schema}\".\"{$sequence}\" RESTART;";
103
104
        return $this->execute($sql);
105
    }
106
107
    /**
108
     * Resets a given sequence to min value of sequence.
109
     *
110
     * @param $sequence Sequence name
111
     *
112
     * @return int 0 if operation was successful
113
     */
114
    public function resetSequence($sequence)
115
    {
116
        // Get the minimum value of the sequence
117
        $seq = $this->getSequence($sequence);
118
        if ($seq->recordCount() != 1) {
0 ignored issues
show
introduced by
The condition $seq->recordCount() != 1 is always true.
Loading history...
119
            return -1;
120
        }
121
122
        $minvalue = $seq->fields['min_value'];
123
124
        $f_schema = $this->_schema;
125
        $this->fieldClean($f_schema);
126
        /* This double-cleaning is deliberate */
127
        $this->fieldClean($sequence);
128
        $this->clean($sequence);
129
130
        $sql = "SELECT pg_catalog.SETVAL('\"{$f_schema}\".\"{$sequence}\"', {$minvalue})";
131
132
        return $this->execute($sql);
133
    }
134
135
    /**
136
     * Returns properties of a single sequence.
137
     *
138
     * @param $sequence Sequence name
139
     *
140
     * @return \PHPPgAdmin\ADORecordSet A recordset
141
     */
142
    public function getSequence($sequence)
143
    {
144
        $c_schema = $this->_schema;
145
        $this->clean($c_schema);
146
        $c_sequence = $sequence;
147
        $this->fieldClean($sequence);
148
        $this->clean($c_sequence);
149
150
        $sql = "
151
			SELECT c.relname AS seqname, s.*,
152
				pg_catalog.obj_description(s.tableoid, 'pg_class') AS seqcomment,
153
				u.usename AS seqowner, n.nspname
154
			FROM \"{$sequence}\" AS s, pg_catalog.pg_class c, pg_catalog.pg_user u, pg_catalog.pg_namespace n
155
			WHERE c.relowner=u.usesysid AND c.relnamespace=n.oid
156
				AND c.relname = '{$c_sequence}' AND c.relkind = 'S' AND n.nspname='{$c_schema}'
157
				AND n.oid = c.relnamespace";
158
159
        return $this->selectSet($sql);
160
    }
161
162
    /**
163
     * Creates a new sequence.
164
     *
165
     * @param $sequence    Sequence name
166
     * @param $increment   The increment
167
     * @param $minvalue    The min value
168
     * @param $maxvalue    The max value
169
     * @param $startvalue  The starting value
170
     * @param $cachevalue  The cache value
171
     * @param $cycledvalue True if cycled, false otherwise
172
     *
173
     * @return int 0 if operation was successful
174
     */
175
    public function createSequence(
176
        $sequence,
177
        $increment,
178
        $minvalue,
179
        $maxvalue,
180
        $startvalue,
181
        $cachevalue,
182
        $cycledvalue
183
    ) {
184
        $f_schema = $this->_schema;
185
        $this->fieldClean($f_schema);
186
        $this->fieldClean($sequence);
187
        $this->clean($increment);
188
        $this->clean($minvalue);
189
        $this->clean($maxvalue);
190
        $this->clean($startvalue);
191
        $this->clean($cachevalue);
192
193
        $sql = "CREATE SEQUENCE \"{$f_schema}\".\"{$sequence}\"";
194
        if ($increment != '') {
195
            $sql .= " INCREMENT {$increment}";
196
        }
197
198
        if ($minvalue != '') {
199
            $sql .= " MINVALUE {$minvalue}";
200
        }
201
202
        if ($maxvalue != '') {
203
            $sql .= " MAXVALUE {$maxvalue}";
204
        }
205
206
        if ($startvalue != '') {
207
            $sql .= " START {$startvalue}";
208
        }
209
210
        if ($cachevalue != '') {
211
            $sql .= " CACHE {$cachevalue}";
212
        }
213
214
        if ($cycledvalue) {
215
            $sql .= ' CYCLE';
216
        }
217
218
        return $this->execute($sql);
219
    }
220
221
    /**
222
     * Alters a sequence.
223
     *
224
     * @param $sequence     The name of the sequence
225
     * @param $name         The new name for the sequence
226
     * @param $comment      The comment on the sequence
227
     * @param $owner        The new owner for the sequence
228
     * @param $schema       The new schema for the sequence
229
     * @param $increment    The increment
230
     * @param $minvalue     The min value
231
     * @param $maxvalue     The max value
232
     * @param $restartvalue The starting value
233
     * @param $cachevalue   The cache value
234
     * @param $cycledvalue  True if cycled, false otherwise
235
     * @param $startvalue   The sequence start value when issueing a restart
236
     *
237
     * @return bool|int 0 success
238
     */
239
    public function alterSequence(
240
        $sequence,
241
        $name,
242
        $comment,
243
        $owner = null,
244
        $schema = null,
245
        $increment = null,
246
        $minvalue = null,
247
        $maxvalue = null,
248
        $restartvalue = null,
249
        $cachevalue = null,
250
        $cycledvalue = null,
251
        $startvalue = null
252
    ) {
253
        $this->fieldClean($sequence);
254
255
        $data = $this->getSequence($sequence);
256
257
        if ($data->recordCount() != 1) {
0 ignored issues
show
introduced by
The condition $data->recordCount() != 1 is always true.
Loading history...
258
            return -2;
259
        }
260
261
        $status = $this->beginTransaction();
262
        if ($status != 0) {
263
            $this->rollbackTransaction();
264
265
            return -1;
266
        }
267
268
        $status = $this->_alterSequence(
269
            $data,
270
            $name,
271
            $comment,
272
            $owner,
273
            $schema,
274
            $increment,
275
            $minvalue,
276
            $maxvalue,
277
            $restartvalue,
278
            $cachevalue,
279
            $cycledvalue,
280
            $startvalue
281
        );
282
283
        if ($status != 0) {
284
            $this->rollbackTransaction();
285
286
            return $status;
287
        }
288
289
        return $this->endTransaction();
290
    }
291
292
    /**
293
     * Protected method which alter a sequence
294
     * SHOULDN'T BE CALLED OUTSIDE OF A TRANSACTION.
295
     *
296
     * @param $seqrs        The sequence recordSet returned by getSequence()
297
     * @param $name         The new name for the sequence
298
     * @param $comment      The comment on the sequence
299
     * @param $owner        The new owner for the sequence
300
     * @param $schema       The new schema for the sequence
301
     * @param $increment    The increment
302
     * @param $minvalue     The min value
303
     * @param $maxvalue     The max value
304
     * @param $restartvalue The starting value
305
     * @param $cachevalue   The cache value
306
     * @param $cycledvalue  True if cycled, false otherwise
307
     * @param $startvalue   The sequence start value when issueing a restart
308
     *
309
     * @return int 0 success
310
     */
311
    protected function _alterSequence(
1 ignored issue
show
Coding Style introduced by
Protected method name "SequenceTrait::_alterSequence" must not be prefixed with an underscore
Loading history...
312
        $seqrs,
313
        $name,
314
        $comment,
315
        $owner,
316
        $schema,
317
        $increment,
318
        $minvalue,
319
        $maxvalue,
320
        $restartvalue,
321
        $cachevalue,
322
        $cycledvalue,
323
        $startvalue
324
    ) {
325
        $this->fieldArrayClean($seqrs->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

325
        $this->/** @scrutinizer ignore-call */ 
326
               fieldArrayClean($seqrs->fields);
Loading history...
326
327
        // Comment
328
        $status = $this->setComment('SEQUENCE', $seqrs->fields['seqname'], '', $comment);
0 ignored issues
show
Bug introduced by
It seems like setComment() 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

328
        /** @scrutinizer ignore-call */ 
329
        $status = $this->setComment('SEQUENCE', $seqrs->fields['seqname'], '', $comment);
Loading history...
329
        if ($status != 0) {
330
            return -4;
331
        }
332
333
        // Owner
334
        $this->fieldClean($owner);
335
        $status = $this->alterSequenceOwner($seqrs, $owner);
336
        if ($status != 0) {
337
            return -5;
338
        }
339
340
        // Props
341
        $this->clean($increment);
342
        $this->clean($minvalue);
343
        $this->clean($maxvalue);
344
        $this->clean($restartvalue);
345
        $this->clean($cachevalue);
346
        $this->clean($cycledvalue);
347
        $this->clean($startvalue);
348
        $status = $this->alterSequenceProps(
349
            $seqrs,
350
            $increment,
351
            $minvalue,
352
            $maxvalue,
353
            $restartvalue,
354
            $cachevalue,
355
            $cycledvalue,
356
            $startvalue
357
        );
358
        if ($status != 0) {
359
            return -6;
360
        }
361
362
        // Rename
363
        $this->fieldClean($name);
364
        $status = $this->alterSequenceName($seqrs, $name);
365
        if ($status != 0) {
366
            return -3;
367
        }
368
369
        // Schema
370
        $this->clean($schema);
371
        $status = $this->alterSequenceSchema($seqrs, $schema);
372
        if ($status != 0) {
373
            return -7;
374
        }
375
376
        return 0;
377
    }
378
379
    // Index functions
380
381
    /**
382
     * Alter a sequence's owner.
383
     *
384
     * @param $seqrs The sequence RecordSet returned by getSequence()
385
     * @param $owner
386
     *
387
     * @return int 0 if operation was successful
388
     *
389
     * @internal param \PHPPgAdmin\Database\The $name new owner for the sequence
390
     */
391
    public function alterSequenceOwner($seqrs, $owner)
392
    {
393
        // If owner has been changed, then do the alteration.  We are
394
        // careful to avoid this generally as changing owner is a
395
        // superuser only function.
396
        /* vars are cleaned in _alterSequence */
397
        if (!empty($owner) && ($seqrs->fields['seqowner'] != $owner)) {
398
            $f_schema = $this->_schema;
399
            $this->fieldClean($f_schema);
400
            $sql = "ALTER SEQUENCE \"{$f_schema}\".\"{$seqrs->fields['seqname']}\" OWNER TO \"{$owner}\"";
401
402
            return $this->execute($sql);
403
        }
404
405
        return 0;
406
    }
407
408
    /**
409
     * Alter a sequence's properties.
410
     *
411
     * @param $seqrs        The sequence RecordSet returned by getSequence()
412
     * @param $increment    The sequence incremental value
413
     * @param $minvalue     The sequence minimum value
414
     * @param $maxvalue     The sequence maximum value
415
     * @param $restartvalue The sequence current value
416
     * @param $cachevalue   The sequence cache value
417
     * @param $cycledvalue  Sequence can cycle ?
418
     * @param $startvalue   The sequence start value when issueing a restart
419
     *
420
     * @return int 0 if operation was successful
421
     */
422
    public function alterSequenceProps(
423
        $seqrs,
424
        $increment,
425
        $minvalue,
426
        $maxvalue,
427
        $restartvalue,
428
        $cachevalue,
429
        $cycledvalue,
430
        $startvalue
431
    ) {
432
        $sql = '';
433
        /* vars are cleaned in _alterSequence */
434
        if (!empty($increment) && ($increment != $seqrs->fields['increment_by'])) {
435
            $sql .= " INCREMENT {$increment}";
436
        }
437
438
        if (!empty($minvalue) && ($minvalue != $seqrs->fields['min_value'])) {
439
            $sql .= " MINVALUE {$minvalue}";
440
        }
441
442
        if (!empty($maxvalue) && ($maxvalue != $seqrs->fields['max_value'])) {
443
            $sql .= " MAXVALUE {$maxvalue}";
444
        }
445
446
        if (!empty($restartvalue) && ($restartvalue != $seqrs->fields['last_value'])) {
447
            $sql .= " RESTART {$restartvalue}";
448
        }
449
450
        if (!empty($cachevalue) && ($cachevalue != $seqrs->fields['cache_value'])) {
451
            $sql .= " CACHE {$cachevalue}";
452
        }
453
454
        if (!empty($startvalue) && ($startvalue != $seqrs->fields['start_value'])) {
455
            $sql .= " START {$startvalue}";
456
        }
457
458
        // toggle cycle yes/no
459
        if (!is_null($cycledvalue)) {
460
            $sql .= (!$cycledvalue ? ' NO ' : '') . ' CYCLE';
461
        }
462
463
        if ($sql != '') {
464
            $f_schema = $this->_schema;
465
            $this->fieldClean($f_schema);
466
            $sql = "ALTER SEQUENCE \"{$f_schema}\".\"{$seqrs->fields['seqname']}\" {$sql}";
467
468
            return $this->execute($sql);
469
        }
470
471
        return 0;
472
    }
473
474
    /**
475
     * Rename a sequence.
476
     *
477
     * @param $seqrs The sequence RecordSet returned by getSequence()
478
     * @param $name  The new name for the sequence
479
     *
480
     * @return int 0 if operation was successful
481
     */
482
    public function alterSequenceName($seqrs, $name)
483
    {
484
        /* vars are cleaned in _alterSequence */
485
        if (!empty($name) && ($seqrs->fields['seqname'] != $name)) {
486
            $f_schema = $this->_schema;
487
            $this->fieldClean($f_schema);
488
            $sql    = "ALTER SEQUENCE \"{$f_schema}\".\"{$seqrs->fields['seqname']}\" RENAME TO \"{$name}\"";
489
            $status = $this->execute($sql);
490
            if ($status == 0) {
491
                $seqrs->fields['seqname'] = $name;
492
            } else {
493
                return $status;
494
            }
495
        }
496
497
        return 0;
498
    }
499
500
    /**
501
     * Alter a sequence's schema.
502
     *
503
     * @param $seqrs The sequence RecordSet returned by getSequence()
504
     * @param $schema
505
     *
506
     * @return int 0 if operation was successful
507
     *
508
     * @internal param The $name new schema for the sequence
509
     */
510
    public function alterSequenceSchema($seqrs, $schema)
511
    {
512
        /* vars are cleaned in _alterSequence */
513
        if (!empty($schema) && ($seqrs->fields['nspname'] != $schema)) {
514
            $f_schema = $this->_schema;
515
            $this->fieldClean($f_schema);
516
            $sql = "ALTER SEQUENCE \"{$f_schema}\".\"{$seqrs->fields['seqname']}\" SET SCHEMA {$schema}";
517
518
            return $this->execute($sql);
519
        }
520
521
        return 0;
522
    }
523
524
    /**
525
     * Drops a given sequence.
526
     *
527
     * @param $sequence Sequence name
528
     * @param $cascade  True to cascade drop, false to restrict
529
     *
530
     * @return int 0 if operation was successful
531
     */
532
    public function dropSequence($sequence, $cascade)
533
    {
534
        $f_schema = $this->_schema;
535
        $this->fieldClean($f_schema);
536
        $this->fieldClean($sequence);
537
538
        $sql = "DROP SEQUENCE \"{$f_schema}\".\"{$sequence}\"";
539
        if ($cascade) {
540
            $sql .= ' CASCADE';
541
        }
542
543
        return $this->execute($sql);
544
    }
545
546
}
547