SequenceTrait   C
last analyzed

Complexity

Total Complexity 53

Size/Duplication

Total Lines 559
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 180
c 0
b 0
f 0
dl 0
loc 559
rs 6.96
wmc 53

14 Methods

Rating   Name   Duplication   Size   Complexity  
A setvalSequence() 0 13 1
A restartSequence() 0 9 1
A getSequences() 0 21 2
A nextvalSequence() 0 12 1
A alterSequenceOwner() 0 15 3
A alterSequence() 0 52 4
B createSequence() 0 45 7
B _alterSequence() 0 71 6
A resetSequence() 0 20 2
A alterSequenceSchema() 0 12 3
A alterSequenceName() 0 17 4
A getSequence() 0 18 1
F alterSequenceProps() 0 50 16
A dropSequence() 0 13 2

How to fix   Complexity   

Complex Class

Complex classes like SequenceTrait often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SequenceTrait, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * PHPPgAdmin 6.1.3
5
 */
6
7
namespace PHPPgAdmin\Database\Traits;
8
9
/**
10
 * Common trait for sequence manipulation.
11
 */
12
trait SequenceTrait
13
{
14
    /**
15
     * Returns all sequences in the current database.
16
     *
17
     * @param bool $all true to get all sequences of all schemas
18
     *
19
     * @return \ADORecordSet|int
20
     */
21
    public function getSequences($all = false)
22
    {
23
        if ($all) {
24
            // Exclude pg_catalog and information_schema tables
25
            $sql = "SELECT n.nspname, c.relname AS seqname, u.usename AS seqowner
26
				FROM pg_catalog.pg_class c, pg_catalog.pg_user u, pg_catalog.pg_namespace n
27
				WHERE c.relowner=u.usesysid AND c.relnamespace=n.oid
28
				AND c.relkind = 'S'
29
				AND n.nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast')
30
				ORDER BY nspname, seqname";
31
        } else {
32
            $c_schema = $this->_schema;
33
            $this->clean($c_schema);
34
            $sql = "SELECT c.relname AS seqname, u.usename AS seqowner, pg_catalog.obj_description(c.oid, 'pg_class') AS seqcomment,
35
				(SELECT spcname FROM pg_catalog.pg_tablespace pt WHERE pt.oid=c.reltablespace) AS tablespace
36
				FROM pg_catalog.pg_class c, pg_catalog.pg_user u, pg_catalog.pg_namespace n
37
				WHERE c.relowner=u.usesysid AND c.relnamespace=n.oid
38
				AND c.relkind = 'S' AND n.nspname='{$c_schema}' ORDER BY seqname";
39
        }
40
41
        return $this->selectSet($sql);
42
    }
43
44
    /**
45
     * Execute nextval on a given sequence.
46
     *
47
     * @param string $sequence Sequence name
48
     *
49
     * @return \ADORecordSet|int
50
     */
51
    public function nextvalSequence($sequence)
52
    {
53
        /* This double-cleaning is deliberate */
54
        $f_schema = $this->_schema;
55
        $this->fieldClean($f_schema);
56
        $this->clean($f_schema);
57
        $this->fieldClean($sequence);
58
        $this->clean($sequence);
59
60
        $sql = "SELECT pg_catalog.NEXTVAL('\"{$f_schema}\".\"{$sequence}\"')";
61
62
        return $this->execute($sql);
63
    }
64
65
    /**
66
     * Execute setval on a given sequence.
67
     *
68
     * @param string $sequence  Sequence name
69
     * @param int    $nextvalue The next value
70
     *
71
     * @return \ADORecordSet|int
72
     */
73
    public function setvalSequence($sequence, $nextvalue)
74
    {
75
        /* This double-cleaning is deliberate */
76
        $f_schema = $this->_schema;
77
        $this->fieldClean($f_schema);
78
        $this->clean($f_schema);
79
        $this->fieldClean($sequence);
80
        $this->clean($sequence);
81
        $this->clean($nextvalue);
82
83
        $sql = "SELECT pg_catalog.SETVAL('\"{$f_schema}\".\"{$sequence}\"', '{$nextvalue}')";
84
85
        return $this->execute($sql);
86
    }
87
88
    /**
89
     * Restart a given sequence to its start value.
90
     *
91
     * @param string $sequence Sequence name
92
     *
93
     * @return \ADORecordSet|int
94
     */
95
    public function restartSequence($sequence)
96
    {
97
        $f_schema = $this->_schema;
98
        $this->fieldClean($f_schema);
99
        $this->fieldClean($sequence);
100
101
        $sql = "ALTER SEQUENCE \"{$f_schema}\".\"{$sequence}\" RESTART;";
102
103
        return $this->execute($sql);
104
    }
105
106
    /**
107
     * Resets a given sequence to min value of sequence.
108
     *
109
     * @param string $sequence Sequence name
110
     *
111
     * @return \ADORecordSet|int
112
     */
113
    public function resetSequence($sequence)
114
    {
115
        // Get the minimum value of the sequence
116
        $seq = $this->getSequence($sequence);
117
118
        if (1 !== $seq->recordCount()) {
0 ignored issues
show
introduced by
The condition 1 !== $seq->recordCount() 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 string $sequence Sequence name
139
     *
140
     * @return \ADORecordSet|int
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 string $sequence    Sequence name
166
     * @param int    $increment   The increment
167
     * @param int    $minvalue    The min value
168
     * @param int    $maxvalue    The max value
169
     * @param int    $startvalue  The starting value
170
     * @param int    $cachevalue  The cache value
171
     * @param bool   $cycledvalue True if cycled, false otherwise
172
     *
173
     * @return \ADORecordSet|int
174
     */
175
    public function createSequence(
176
        $sequence,
177
        $increment,
178
        $minvalue = null,
179
        $maxvalue = null,
180
        $startvalue = null,
181
        $cachevalue = null,
182
        $cycledvalue = false
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
195
        if ('' !== $increment) {
196
            $sql .= " INCREMENT {$increment}";
197
        }
198
199
        if ('' !== $minvalue) {
200
            $sql .= " MINVALUE {$minvalue}";
201
        }
202
203
        if ('' !== $maxvalue) {
204
            $sql .= " MAXVALUE {$maxvalue}";
205
        }
206
207
        if ('' !== $startvalue) {
208
            $sql .= " START {$startvalue}";
209
        }
210
211
        if ('' !== $cachevalue) {
212
            $sql .= " CACHE {$cachevalue}";
213
        }
214
215
        if ($cycledvalue) {
216
            $sql .= ' CYCLE';
217
        }
218
219
        return $this->execute($sql);
220
    }
221
222
    /**
223
     * Alters a sequence.
224
     *
225
     * @param string    $sequence     The name of the sequence
226
     * @param string    $name         The new name for the sequence
227
     * @param string    $comment      The comment on the sequence
228
     * @param string    $owner        The new owner for the sequence
229
     * @param string    $schema       The new schema for the sequence
230
     * @param string    $increment    The increment
231
     * @param int       $minvalue     The min value
232
     * @param int       $maxvalue     The max value
233
     * @param int       $restartvalue The starting value
234
     * @param int       $cachevalue   The cache value
235
     * @param null|bool $cycledvalue  True if cycled, false otherwise
236
     * @param int       $startvalue   The sequence start value when issueing a restart
237
     *
238
     * @return bool|int 0 success
239
     */
240
    public function alterSequence(
241
        $sequence,
242
        $name,
243
        $comment,
244
        $owner = null,
245
        $schema = null,
246
        $increment = null,
247
        $minvalue = null,
248
        $maxvalue = null,
249
        $restartvalue = null,
250
        $cachevalue = null,
251
        $cycledvalue = null,
252
        $startvalue = null
253
    ) {
254
        $this->fieldClean($sequence);
255
256
        $data = $this->getSequence($sequence);
257
258
        if (1 !== $data->recordCount()) {
0 ignored issues
show
introduced by
The condition 1 !== $data->recordCount() is always true.
Loading history...
259
            return -2;
260
        }
261
262
        $status = $this->beginTransaction();
263
264
        if (0 !== $status) {
265
            $this->rollbackTransaction();
266
267
            return -1;
268
        }
269
270
        $status = $this->_alterSequence(
271
            $data,
272
            $name,
273
            $comment,
274
            $owner,
275
            $schema,
276
            $increment,
277
            $minvalue,
278
            $maxvalue,
279
            $restartvalue,
280
            $cachevalue,
281
            $cycledvalue,
282
            $startvalue
283
        );
284
285
        if (0 !== $status) {
286
            $this->rollbackTransaction();
287
288
            return $status;
289
        }
290
291
        return $this->endTransaction();
292
    }
293
294
    // Index functions
295
296
    /**
297
     * Alter a sequence's owner.
298
     *
299
     * @param \ADORecordSet $seqrs The sequence RecordSet returned by getSequence()
300
     * @param string        $owner the new owner of the sequence
301
     *
302
     * @return \ADORecordSet|int
303
     *
304
     * @internal string $name new owner for the sequence
305
     */
306
    public function alterSequenceOwner($seqrs, $owner)
307
    {
308
        // If owner has been changed, then do the alteration.  We are
309
        // careful to avoid this generally as changing owner is a
310
        // superuser only function.
311
        /* vars are cleaned in _alterSequence */
312
        if (!empty($owner) && ($seqrs->fields['seqowner'] !== $owner)) {
313
            $f_schema = $this->_schema;
314
            $this->fieldClean($f_schema);
315
            $sql = "ALTER SEQUENCE \"{$f_schema}\".\"{$seqrs->fields['seqname']}\" OWNER TO \"{$owner}\"";
316
317
            return $this->execute($sql);
318
        }
319
320
        return 0;
321
    }
322
323
    /**
324
     * Alter a sequence's properties.
325
     *
326
     * @param \ADORecordSet $seqrs        The sequence RecordSet returned by getSequence()
327
     * @param int           $increment    The sequence incremental value
328
     * @param int           $minvalue     The sequence minimum value
329
     * @param int           $maxvalue     The sequence maximum value
330
     * @param int           $restartvalue The sequence current value
331
     * @param int           $cachevalue   The sequence cache value
332
     * @param null|bool     $cycledvalue  Sequence can cycle ?
333
     * @param int           $startvalue   The sequence start value when issueing a restart
334
     *
335
     * @return \ADORecordSet|int
336
     */
337
    public function alterSequenceProps(
338
        $seqrs,
339
        $increment,
340
        $minvalue,
341
        $maxvalue,
342
        $restartvalue,
343
        $cachevalue,
344
        $cycledvalue,
345
        $startvalue
346
    ) {
347
        $sql = '';
348
        /* vars are cleaned in _alterSequence */
349
        if (!empty($increment) && ($increment !== $seqrs->fields['increment_by'])) {
350
            $sql .= " INCREMENT {$increment}";
351
        }
352
353
        if (!empty($minvalue) && ($minvalue !== $seqrs->fields['min_value'])) {
354
            $sql .= " MINVALUE {$minvalue}";
355
        }
356
357
        if (!empty($maxvalue) && ($maxvalue !== $seqrs->fields['max_value'])) {
358
            $sql .= " MAXVALUE {$maxvalue}";
359
        }
360
361
        if (!empty($restartvalue) && ($restartvalue !== $seqrs->fields['last_value'])) {
362
            $sql .= " RESTART {$restartvalue}";
363
        }
364
365
        if (!empty($cachevalue) && ($cachevalue !== $seqrs->fields['cache_value'])) {
366
            $sql .= " CACHE {$cachevalue}";
367
        }
368
369
        if (!empty($startvalue) && ($startvalue !== $seqrs->fields['start_value'])) {
370
            $sql .= " START {$startvalue}";
371
        }
372
373
        // toggle cycle yes/no
374
        if (null !== $cycledvalue) {
375
            $sql .= (!$cycledvalue ? ' NO ' : '') . ' CYCLE';
376
        }
377
378
        if ('' !== $sql) {
379
            $f_schema = $this->_schema;
380
            $this->fieldClean($f_schema);
381
            $sql = "ALTER SEQUENCE \"{$f_schema}\".\"{$seqrs->fields['seqname']}\" {$sql}";
382
383
            return $this->execute($sql);
384
        }
385
386
        return 0;
387
    }
388
389
    /**
390
     * Rename a sequence.
391
     *
392
     * @param \ADORecordSet $seqrs The sequence RecordSet returned by getSequence()
393
     * @param string        $name  The new name for the sequence
394
     *
395
     * @return \ADORecordSet|int
396
     */
397
    public function alterSequenceName($seqrs, $name)
398
    {
399
        /* vars are cleaned in _alterSequence */
400
        if (!empty($name) && ($seqrs->fields['seqname'] !== $name)) {
401
            $f_schema = $this->_schema;
402
            $this->fieldClean($f_schema);
403
            $sql = "ALTER SEQUENCE \"{$f_schema}\".\"{$seqrs->fields['seqname']}\" RENAME TO \"{$name}\"";
404
            $status = $this->execute($sql);
405
406
            if (0 === $status) {
407
                $seqrs->fields['seqname'] = $name;
408
            } else {
409
                return $status;
410
            }
411
        }
412
413
        return 0;
414
    }
415
416
    /**
417
     * Alter a sequence's schema.
418
     *
419
     * @param \ADORecordSet $seqrs  The sequence RecordSet returned by getSequence()
420
     * @param string        $schema
421
     *
422
     * @return \ADORecordSet|int
423
     *
424
     * @internal param The $name new schema for the sequence
425
     */
426
    public function alterSequenceSchema($seqrs, $schema)
427
    {
428
        /* vars are cleaned in _alterSequence */
429
        if (!empty($schema) && ($seqrs->fields['nspname'] !== $schema)) {
430
            $f_schema = $this->_schema;
431
            $this->fieldClean($f_schema);
432
            $sql = "ALTER SEQUENCE \"{$f_schema}\".\"{$seqrs->fields['seqname']}\" SET SCHEMA {$schema}";
433
434
            return $this->execute($sql);
435
        }
436
437
        return 0;
438
    }
439
440
    /**
441
     * Drops a given sequence.
442
     *
443
     * @param string $sequence Sequence name
444
     * @param bool   $cascade  True to cascade drop, false to restrict
445
     *
446
     * @return \ADORecordSet|int
447
     */
448
    public function dropSequence($sequence, $cascade = false)
449
    {
450
        $f_schema = $this->_schema;
451
        $this->fieldClean($f_schema);
452
        $this->fieldClean($sequence);
453
454
        $sql = "DROP SEQUENCE \"{$f_schema}\".\"{$sequence}\"";
455
456
        if ($cascade) {
457
            $sql .= ' CASCADE';
458
        }
459
460
        return $this->execute($sql);
461
    }
462
463
    abstract public function fieldClean(&$str);
464
465
    abstract public function beginTransaction();
466
467
    abstract public function rollbackTransaction();
468
469
    abstract public function endTransaction();
470
471
    abstract public function execute($sql);
472
473
    abstract public function setComment($obj_type, $obj_name, $table, $comment, $basetype = null);
474
475
    abstract public function selectSet($sql);
476
477
    abstract public function clean(&$str);
478
479
    abstract public function fieldArrayClean(&$arr);
480
481
    /**
482
     * Protected method which alter a sequence
483
     * SHOULDN'T BE CALLED OUTSIDE OF A TRANSACTION.
484
     *
485
     * @param \ADORecordSet $seqrs        The sequence recordSet returned by getSequence()
486
     * @param string        $name         The new name for the sequence
487
     * @param string        $comment      The comment on the sequence
488
     * @param string        $owner        The new owner for the sequence
489
     * @param string        $schema       The new schema for the sequence
490
     * @param int           $increment    The increment
491
     * @param int           $minvalue     The min value
492
     * @param int           $maxvalue     The max value
493
     * @param int           $restartvalue The starting value
494
     * @param int           $cachevalue   The cache value
495
     * @param null|bool     $cycledvalue  True if cycled, false otherwise
496
     * @param int           $startvalue   The sequence start value when issueing a restart
497
     *
498
     * @return int 0 success
499
     */
500
    protected function _alterSequence(
501
        $seqrs,
502
        $name,
503
        $comment,
504
        $owner,
505
        $schema,
506
        $increment,
507
        $minvalue,
508
        $maxvalue,
509
        $restartvalue,
510
        $cachevalue,
511
        $cycledvalue,
512
        $startvalue
513
    ) {
514
        $this->fieldArrayClean($seqrs->fields);
515
516
        // Comment
517
        $status = $this->setComment('SEQUENCE', $seqrs->fields['seqname'], '', $comment);
518
519
        if (0 !== $status) {
520
            return -4;
521
        }
522
523
        // Owner
524
        $this->fieldClean($owner);
525
        $status = $this->alterSequenceOwner($seqrs, $owner);
526
527
        if (0 !== $status) {
528
            return -5;
529
        }
530
531
        // Props
532
        $this->clean($increment);
533
        $this->clean($minvalue);
534
        $this->clean($maxvalue);
535
        $this->clean($restartvalue);
536
        $this->clean($cachevalue);
537
        $this->clean($cycledvalue);
538
        $this->clean($startvalue);
539
        $status = $this->alterSequenceProps(
540
            $seqrs,
541
            $increment,
542
            $minvalue,
543
            $maxvalue,
544
            $restartvalue,
545
            $cachevalue,
546
            $cycledvalue,
547
            $startvalue
548
        );
549
550
        if (0 !== $status) {
551
            return -6;
552
        }
553
554
        // Rename
555
        $this->fieldClean($name);
556
        $status = $this->alterSequenceName($seqrs, $name);
557
558
        if (0 !== $status) {
559
            return -3;
560
        }
561
562
        // Schema
563
        $this->clean($schema);
564
        $status = $this->alterSequenceSchema($seqrs, $schema);
565
566
        if (0 !== $status) {
567
            return -7;
568
        }
569
570
        return 0;
571
    }
572
}
573