Completed
Push — master ( d508c6...ead087 )
by smiley
02:37
created

CreateTable::sql()   B

Complexity

Conditions 6
Paths 13

Size

Total Lines 29
Code Lines 16

Duplication

Lines 9
Ratio 31.03 %

Importance

Changes 0
Metric Value
dl 9
loc 29
c 0
b 0
f 0
rs 8.439
cc 6
eloc 16
nc 13
nop 0
1
<?php
2
/**
3
 * Class CreateTable
4
 *
5
 * @filesource   CreateTable.php
6
 * @created      03.06.2017
7
 * @package      chillerlan\Database\Query\Dialects\Postgres
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2017 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\Database\Query\Dialects\Postgres;
14
15
use chillerlan\Database\Query\CreateTableAbstract;
16
use chillerlan\Database\Query\QueryException;
17
18
/**
19
 * @link https://www.postgresql.org/docs/current/static/sql-createtable.html
20
 */
21
class CreateTable extends CreateTableAbstract{
22
23
	public function sql():string{
24
25
		if(empty($this->name)){
26
			throw new QueryException('no name specified');
27
		}
28
29
		$sql = 'CREATE ';
30
		$sql .= $this->temp ? ' TEMPORARY ' : '';
31
		$sql .= 'TABLE ';
32
		$sql .= $this->ifNotExists ? 'IF NOT EXISTS ' : '';
33
34
		$n = explode('.', $this->name);
35
36
		$sql .= $this->quote($n[count($n)-1]);
37
38 View Code Duplication
		if(!empty($this->cols)){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
39
			$sql .= ' ('.PHP_EOL."\t".implode(','.PHP_EOL."\t", $this->cols);
40
41
			if($this->primaryKey){
42
				$sql .=','.PHP_EOL."\t".'PRIMARY KEY ('.$this->quote($this->primaryKey).')';
43
			}
44
45
			$sql .= PHP_EOL.')';
46
		}
47
48
		$sql .= '';
49
50
		return $sql;
51
	}
52
53
	protected function fieldspec(
54
		string $name,
55
		string $type,
56
		$length = null,
57
		string $attribute = null,
58
		string $collation = null,
59
		bool $isNull = null,
60
		string $defaultType = null,
61
		$defaultValue = null,
62
		string $extra = null
63
	){
64
		$name = trim($name);
65
		$type = strtoupper(trim($type));
66
67
		$field = ['"'.$name.'"'];
68
69
70
		$type_translation = [
71
			'TINYINT'    => 'SMALLINT',
72
			'MEDIUMINT'  => 'INT',
73
			'DOUBLE'     => 'DOUBLE PRECISION',
74
			'TINYTEXT'   => 'VARCHAR(255)',
75
			'DATETIME'   => 'TIMESTAMP',
76
			'IMAGE'      => 'BLOB',
77
			'MEDIUMTEXT' => 'TEXT',
78
			'LONGTEXT'   => 'TEXT',
79
		][$type] ?? $type;
80
81
#		$f = array_key_exists($type, $type_translation) ? $type_translation[$type] : $type;
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
82
83
84
		if((is_int($length) || is_string($length) && count(explode(',', $length)) === 2)
85
		   && in_array($type, ['BIT', 'VARBIT', 'CHAR', 'VARCHAR', 'DECIMAL', 'NUMERIC', 'TIME', 'TIMESTAMP', 'INTERVAL'])){
86
			$field[] = $type_translation.'('. $length . ')';
87
		}
88
		else{
89
			$field[] = $type_translation;
90
		}
91
92
93
		if($collation && in_array($type, ['TINYTEXT', 'TEXT', 'MEDIUMTEXT', 'LONGTEXT', 'VARCHAR', 'CHAR'])
0 ignored issues
show
Bug Best Practice introduced by
The expression $collation of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
94
			&& !in_array(strtolower($collation), ['utf8'])){
95
			$field[] = 'COLLATE '.$collation;
96
		}
97
98
		if(is_bool($isNull)){
99
			$field[] = $isNull ? 'NULL' : 'NOT NULL';
100
		}
101
102
103
		if($attribute){
0 ignored issues
show
Bug Best Practice introduced by
The expression $attribute of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
104
			$field[] = strtoupper($attribute);
105
		}
106
107
		$defaultType = strtoupper($defaultType);
108
109
		if($defaultType === 'USER_DEFINED'){
110
111
			switch(true){
112
				case $type === 'TIMESTAMP' && intval($defaultValue) === 0:
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
113
					$field[] = 'DEFAULT 0';
114
					break;
115 View Code Duplication
				case $type === 'BIT' || $type === 'VARBIT':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
116
					$field[] = 'DEFAULT b\''.preg_replace('/[^01]/', '0', $defaultValue).'\'';
117
					break;
118 View Code Duplication
				case $type === 'BOOLEAN':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
119
					$field[] = 'DEFAULT '.preg_match('/^1|T|TRUE|YES$/i', $defaultValue) ? 'TRUE' : 'FALSE';
120
					break;
121 View Code Duplication
				case strtoupper($defaultValue) === 'NULL' && $isNull === true:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
122
					$field[] = 'DEFAULT NULL';
123
					break;
124
				default:
125
					$field[] = 'DEFAULT \''.$defaultValue.'\'';
126
			}
127
128
		}
129 View Code Duplication
		else if($defaultType === 'CURRENT_TIMESTAMP'){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
130
			$field[] = 'DEFAULT CURRENT_TIMESTAMP';
131
		}
132
		else if($defaultType === 'NULL' && $isNull === true){
133
			$field[] = 'DEFAULT NULL';
134
		}
135
136
137
		if($extra){
0 ignored issues
show
Bug Best Practice introduced by
The expression $extra of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
138
			$field[] = $extra;
139
		}
140
141
		return implode(' ', $field);
142
	}
143
144
}
145