Completed
Push — master ( ead087...20edd5 )
by smiley
02:40
created

PostgreSQLDriver::getServerInfo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
/**
3
 * Class PostgreSQLDriver
4
 *
5
 * @filesource   PostgreSQLDriver.php
6
 * @created      21.02.2016
7
 * @package      chillerlan\Database\Drivers\PostgreSQL
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2016 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\Database\Drivers;
14
15
use chillerlan\Database\DBResult;
16
17
class PostgreSQLDriver extends DBDriverAbstract{
18
19
	protected $dialect = 'pgsql';
20
	protected $quotes = ['"', '"'];
21
22
	/**
23
	 * Holds the database resource object
24
	 *
25
	 * @var resource
26
	 */
27
	protected $db;
28
29
	/**
30
	 * Establishes a database connection and returns the connection object
31
	 *
32
	 * @return \chillerlan\Database\Drivers\DBDriverInterface
33
	 * @throws \chillerlan\Database\Drivers\DBDriverException
34
	 */
35
	public function connect():DBDriverInterface{
36
37
		if(gettype($this->db) === 'resource'){
38
			return $this;
39
		}
40
41
		// i am an ugly duckling. fix me please.
42
43
		$options = [
44
			'--client_encoding='.$this->options->pgsql_charset,
45
		];
46
47
		$conn_str = [
48
			'host=\''.$this->options->host.'\'',
49
			'port=\''.(int)$this->options->port.'\'',
50
			'dbname=\''.$this->options->database.'\'',
51
			'user=\''.$this->options->username.'\'',
52
			'password=\''.$this->options->password.'\'',
53
			'options=\''.implode(' ', $options).'\'',
54
		];
55
56
		try{
57
			$this->db = pg_connect(implode(' ', $conn_str));
58
59
			return $this;
60
		}
61
		catch(\Exception $e){
62
			throw new DBDriverException('db error: [PostgreSQLDriver]: '.$e->getMessage());
63
		}
64
65
	}
66
67
	/**
68
	 * Closes a database connection
69
	 *
70
	 * @return bool
71
	 */
72
	public function disconnect():bool{
73
		return pg_close($this->db);
74
	}
75
76
	/**
77
	 * Returns info about the used php client
78
	 *
79
	 * @return string php's database client string
80
	 */
81
	public function getClientInfo():string{
82
		$ver = pg_version($this->db);
83
84
		return 'PostgreSQL '.$ver['client'].' ('.$ver['client_encoding'].')';
85
	}
86
87
	/**
88
	 * Returns info about the database server
89
	 *
90
	 * @return string database's serverinfo string
91
	 */
92
	public function getServerInfo():string{
93
		$ver = pg_version($this->db);
94
95
		return 'PostgreSQL '.$ver['server'].' ('.$ver['server_encoding'].', date style: '.$ver['DateStyle'].', time zone: '.$ver['TimeZone'].')';
96
	}
97
98
	/**
99
	 * @param $data
100
	 *
101
	 * @return string
102
	 */
103
	public function escape($data){
104
		return pg_escape_string($this->db, $data);
105
	}
106
107
	/**
108
	 * @param             $result
109
	 * @param string|null $index
110
	 * @param bool        $assoc
111
	 *
112
	 * @return bool|\chillerlan\Database\DBResult
113
	 */
114
	protected function __getResult($result, string $index = null, bool $assoc = true){
115
116
		if(is_bool($result)){
117
			return $result; // @codeCoverageIgnore
118
		}
119
120
		$out = new DBResult(null, $this->source_encoding, $this->dest_encoding);
121
		$i   = 0;
122
123
		while($row = call_user_func_array($assoc ? 'pg_fetch_assoc' : 'pg_fetch_row', [$result])){
124
			$key = $i;
125
126
			$j = 0;
127
			foreach($row as $k => $item){
128
				// https://gitter.im/arenanet/api-cdi?at=594326ba31f589c64fafe554
129
				if(pg_field_type($result, $j) === 'boolean'){
130
					$row[$k] = $item === 't';
131
				}
132
133
				$j++;
134
			}
135
136
			if($assoc && !empty($index)){
137
				$key = $row[$index];
138
			}
139
140
			$out[$key] = $row;
141
			$i++;
142
		}
143
144
		$r = $i === 0 ? true : $out;
145
146
		pg_free_result($result);
147
148
		return $r;
149
	}
150
151
	/**
152
	 * @param string      $sql
153
	 * @param string|null $index
154
	 * @param bool        $assoc
155
	 *
156
	 * @return bool|\chillerlan\Database\DBResult
157
	 */
158
	protected function __raw(string $sql, string $index = null, bool $assoc = true){
159
		return $this->__getResult(pg_query($sql), $index, $assoc);
160
	}
161
162
	/**
163
	 * @param string      $sql
164
	 * @param array       $values
165
	 * @param string|null $index
166
	 * @param bool        $assoc
167
	 *
168
	 * @return bool|\chillerlan\Database\DBResult
169
	 */
170
	protected function __prepared(string $sql, array $values = [], string $index = null, bool $assoc = true){
171
		pg_prepare($this->db, '', $this->replaceParams($sql));
172
173
		return $this->__getResult(pg_execute($this->db, '', $values), $index, $assoc);
174
	}
175
176
	/**
177
	 * @param string $sql
178
	 * @param array  $values
179
	 *
180
	 * @return bool
181
	 */
182 View Code Duplication
	protected function __multi(string $sql, array $values){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
183
		pg_prepare($this->db, '', $this->replaceParams($sql));
184
185
		foreach($values as $row){
186
			pg_execute($this->db, '', $row);
187
		}
188
189
		return true;
190
	}
191
192
	/**
193
	 * @param string $sql
194
	 * @param array  $data
195
	 * @param        $callback
196
	 *
197
	 * @return bool
198
	 */
199 View Code Duplication
	protected function __multi_callback(string $sql, array $data, $callback){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
200
		pg_prepare($this->db, '', $this->replaceParams($sql));
201
202
		foreach($data as $row){
203
			pg_execute($this->db, '', call_user_func_array($callback, [$row]));
204
		}
205
206
		return true;
207
	}
208
209
	protected function replaceParams(string $sql):string{
210
		$i = 0;
211
212
		return preg_replace_callback('/(\?)/', function() use (&$i){
213
			return '$'.++$i;
214
		}, $sql);
215
	}
216
217
}
218