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

SequenceTrait::getSequence()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 9
nc 1
nop 1
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