PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.2.0
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.2.0
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / libs / Zend / Db / Adapter / Pdo / Pgsql.php
matomo / app / libs / Zend / Db / Adapter / Pdo Last commit date
Ibm 2 years ago Abstract.php 2 years ago Ibm.php 2 years ago Mssql.php 2 years ago Mysql.php 1 year ago Oci.php 2 years ago Pgsql.php 2 years ago Sqlite.php 2 years ago
Pgsql.php
271 lines
1 <?php
2
3 namespace {
4 /**
5 * Zend Framework
6 *
7 * LICENSE
8 *
9 * This source file is subject to the new BSD license that is bundled
10 * with this package in the file LICENSE.txt.
11 * It is also available through the world-wide-web at this URL:
12 * http://framework.zend.com/license/new-bsd
13 * If you did not receive a copy of the license and are unable to
14 * obtain it through the world-wide-web, please send an email
15 * to license@zend.com so we can send you a copy immediately.
16 *
17 * @category Zend
18 * @package Zend_Db
19 * @subpackage Adapter
20 * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
21 * @license http://framework.zend.com/license/new-bsd New BSD License
22 * @version $Id: Pgsql.php 23775 2011-03-01 17:25:24Z ralph $
23 */
24 /**
25 * @see Zend_Db_Adapter_Pdo_Abstract
26 */
27 // require_once 'Zend/Db/Adapter/Pdo/Abstract.php';
28 /**
29 * Class for connecting to PostgreSQL databases and performing common operations.
30 *
31 * @category Zend
32 * @package Zend_Db
33 * @subpackage Adapter
34 * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
35 * @license http://framework.zend.com/license/new-bsd New BSD License
36 */
37 class Zend_Db_Adapter_Pdo_Pgsql extends \Zend_Db_Adapter_Pdo_Abstract
38 {
39 /**
40 * PDO type.
41 *
42 * @var string
43 */
44 protected $_pdoType = 'pgsql';
45 /**
46 * Keys are UPPERCASE SQL datatypes or the constants
47 * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
48 *
49 * Values are:
50 * 0 = 32-bit integer
51 * 1 = 64-bit integer
52 * 2 = float or decimal
53 *
54 * @var array Associative array of datatypes to values 0, 1, or 2.
55 */
56 protected $_numericDataTypes = array(\Zend_Db::INT_TYPE => \Zend_Db::INT_TYPE, \Zend_Db::BIGINT_TYPE => \Zend_Db::BIGINT_TYPE, \Zend_Db::FLOAT_TYPE => \Zend_Db::FLOAT_TYPE, 'INTEGER' => \Zend_Db::INT_TYPE, 'SERIAL' => \Zend_Db::INT_TYPE, 'SMALLINT' => \Zend_Db::INT_TYPE, 'BIGINT' => \Zend_Db::BIGINT_TYPE, 'BIGSERIAL' => \Zend_Db::BIGINT_TYPE, 'DECIMAL' => \Zend_Db::FLOAT_TYPE, 'DOUBLE PRECISION' => \Zend_Db::FLOAT_TYPE, 'NUMERIC' => \Zend_Db::FLOAT_TYPE, 'REAL' => \Zend_Db::FLOAT_TYPE);
57 /**
58 * Creates a PDO object and connects to the database.
59 *
60 * @return void
61 * @throws Zend_Db_Adapter_Exception
62 */
63 protected function _connect()
64 {
65 if ($this->_connection) {
66 return;
67 }
68 parent::_connect();
69 if (!empty($this->_config['charset'])) {
70 $sql = "SET NAMES '" . $this->_config['charset'] . "'";
71 $this->_connection->exec($sql);
72 }
73 }
74 /**
75 * Returns a list of the tables in the database.
76 *
77 * @return array
78 */
79 public function listTables()
80 {
81 // @todo use a better query with joins instead of subqueries
82 $sql = "SELECT c.relname AS table_name " . "FROM pg_class c, pg_user u " . "WHERE c.relowner = u.usesysid AND c.relkind = 'r' " . "AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname) " . "AND c.relname !~ '^(pg_|sql_)' " . "UNION " . "SELECT c.relname AS table_name " . "FROM pg_class c " . "WHERE c.relkind = 'r' " . "AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname) " . "AND NOT EXISTS (SELECT 1 FROM pg_user WHERE usesysid = c.relowner) " . "AND c.relname !~ '^pg_'";
83 return $this->fetchCol($sql);
84 }
85 /**
86 * Returns the column descriptions for a table.
87 *
88 * The return value is an associative array keyed by the column name,
89 * as returned by the RDBMS.
90 *
91 * The value of each array element is an associative array
92 * with the following keys:
93 *
94 * SCHEMA_NAME => string; name of database or schema
95 * TABLE_NAME => string;
96 * COLUMN_NAME => string; column name
97 * COLUMN_POSITION => number; ordinal position of column in table
98 * DATA_TYPE => string; SQL datatype name of column
99 * DEFAULT => string; default expression of column, null if none
100 * NULLABLE => boolean; true if column can have nulls
101 * LENGTH => number; length of CHAR/VARCHAR
102 * SCALE => number; scale of NUMERIC/DECIMAL
103 * PRECISION => number; precision of NUMERIC/DECIMAL
104 * UNSIGNED => boolean; unsigned property of an integer type
105 * PRIMARY => boolean; true if column is part of the primary key
106 * PRIMARY_POSITION => integer; position of column in primary key
107 * IDENTITY => integer; true if column is auto-generated with unique values
108 *
109 * @todo Discover integer unsigned property.
110 *
111 * @param string $tableName
112 * @param string $schemaName OPTIONAL
113 * @return array
114 */
115 public function describeTable($tableName, $schemaName = null)
116 {
117 $sql = "SELECT\n a.attnum,\n n.nspname,\n c.relname,\n a.attname AS colname,\n t.typname AS type,\n a.atttypmod,\n FORMAT_TYPE(a.atttypid, a.atttypmod) AS complete_type,\n d.adsrc AS default_value,\n a.attnotnull AS notnull,\n a.attlen AS length,\n co.contype,\n ARRAY_TO_STRING(co.conkey, ',') AS conkey\n FROM pg_attribute AS a\n JOIN pg_class AS c ON a.attrelid = c.oid\n JOIN pg_namespace AS n ON c.relnamespace = n.oid\n JOIN pg_type AS t ON a.atttypid = t.oid\n LEFT OUTER JOIN pg_constraint AS co ON (co.conrelid = c.oid\n AND a.attnum = ANY(co.conkey) AND co.contype = 'p')\n LEFT OUTER JOIN pg_attrdef AS d ON d.adrelid = c.oid AND d.adnum = a.attnum\n WHERE a.attnum > 0 AND c.relname = " . $this->quote($tableName);
118 if ($schemaName) {
119 $sql .= " AND n.nspname = " . $this->quote($schemaName);
120 }
121 $sql .= ' ORDER BY a.attnum';
122 $stmt = $this->query($sql);
123 // Use FETCH_NUM so we are not dependent on the CASE attribute of the PDO connection
124 $result = $stmt->fetchAll(\Zend_Db::FETCH_NUM);
125 $attnum = 0;
126 $nspname = 1;
127 $relname = 2;
128 $colname = 3;
129 $type = 4;
130 $atttypemod = 5;
131 $complete_type = 6;
132 $default_value = 7;
133 $notnull = 8;
134 $length = 9;
135 $contype = 10;
136 $conkey = 11;
137 $desc = array();
138 foreach ($result as $key => $row) {
139 $defaultValue = $row[$default_value];
140 if ($row[$type] == 'varchar' || $row[$type] == 'bpchar') {
141 if (\preg_match('/character(?: varying)?(?:\\((\\d+)\\))?/', $row[$complete_type], $matches)) {
142 if (isset($matches[1])) {
143 $row[$length] = $matches[1];
144 } else {
145 $row[$length] = null;
146 // unlimited
147 }
148 }
149 if (\preg_match("/^'(.*?)'::(?:character varying|bpchar)\$/", $defaultValue, $matches)) {
150 $defaultValue = $matches[1];
151 }
152 }
153 list($primary, $primaryPosition, $identity) = array(\false, null, \false);
154 if ($row[$contype] == 'p') {
155 $primary = \true;
156 $primaryPosition = \array_search($row[$attnum], \explode(',', $row[$conkey])) + 1;
157 $identity = (bool) \preg_match('/^nextval/', $row[$default_value]);
158 }
159 $desc[$this->foldCase($row[$colname])] = array(
160 'SCHEMA_NAME' => $this->foldCase($row[$nspname]),
161 'TABLE_NAME' => $this->foldCase($row[$relname]),
162 'COLUMN_NAME' => $this->foldCase($row[$colname]),
163 'COLUMN_POSITION' => $row[$attnum],
164 'DATA_TYPE' => $row[$type],
165 'DEFAULT' => $defaultValue,
166 'NULLABLE' => (bool) ($row[$notnull] != 't'),
167 'LENGTH' => $row[$length],
168 'SCALE' => null,
169 // @todo
170 'PRECISION' => null,
171 // @todo
172 'UNSIGNED' => null,
173 // @todo
174 'PRIMARY' => $primary,
175 'PRIMARY_POSITION' => $primaryPosition,
176 'IDENTITY' => $identity,
177 );
178 }
179 return $desc;
180 }
181 /**
182 * Adds an adapter-specific LIMIT clause to the SELECT statement.
183 *
184 * @param string $sql
185 * @param integer $count
186 * @param integer $offset OPTIONAL
187 * @return string
188 */
189 public function limit($sql, $count, $offset = 0)
190 {
191 $count = \intval($count);
192 if ($count <= 0) {
193 /**
194 * @see Zend_Db_Adapter_Exception
195 */
196 // require_once 'Zend/Db/Adapter/Exception.php';
197 throw new \Zend_Db_Adapter_Exception("LIMIT argument count={$count} is not valid");
198 }
199 $offset = \intval($offset);
200 if ($offset < 0) {
201 /**
202 * @see Zend_Db_Adapter_Exception
203 */
204 // require_once 'Zend/Db/Adapter/Exception.php';
205 throw new \Zend_Db_Adapter_Exception("LIMIT argument offset={$offset} is not valid");
206 }
207 $sql .= " LIMIT {$count}";
208 if ($offset > 0) {
209 $sql .= " OFFSET {$offset}";
210 }
211 return $sql;
212 }
213 /**
214 * Return the most recent value from the specified sequence in the database.
215 * This is supported only on RDBMS brands that support sequences
216 * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null.
217 *
218 * @param string $sequenceName
219 * @return string
220 */
221 public function lastSequenceId($sequenceName)
222 {
223 $this->_connect();
224 $sequenceName = \str_replace($this->getQuoteIdentifierSymbol(), '', (string) $sequenceName);
225 $value = $this->fetchOne("SELECT CURRVAL(" . $this->quote($this->quoteIdentifier($sequenceName, \true)) . ")");
226 return $value;
227 }
228 /**
229 * Generate a new value from the specified sequence in the database, and return it.
230 * This is supported only on RDBMS brands that support sequences
231 * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null.
232 *
233 * @param string $sequenceName
234 * @return string
235 */
236 public function nextSequenceId($sequenceName)
237 {
238 $this->_connect();
239 $sequenceName = \str_replace($this->getQuoteIdentifierSymbol(), '', (string) $sequenceName);
240 $value = $this->fetchOne("SELECT NEXTVAL(" . $this->quote($this->quoteIdentifier($sequenceName, \true)) . ")");
241 return $value;
242 }
243 /**
244 * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
245 *
246 * As a convention, on RDBMS brands that support sequences
247 * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
248 * from the arguments and returns the last id generated by that sequence.
249 * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
250 * returns the last value generated for such a column, and the table name
251 * argument is disregarded.
252 *
253 * @param string $tableName OPTIONAL Name of table.
254 * @param string $primaryKey OPTIONAL Name of primary key column.
255 * @return string
256 */
257 public function lastInsertId($tableName = null, $primaryKey = null)
258 {
259 if ($tableName !== null) {
260 $sequenceName = $tableName;
261 if ($primaryKey) {
262 $sequenceName .= "_{$primaryKey}";
263 }
264 $sequenceName .= '_seq';
265 return $this->lastSequenceId($sequenceName);
266 }
267 return $this->_connection->lastInsertId($tableName);
268 }
269 }
270 }
271