Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402]
1 <?php 2 /** 3 * ADOdb PostgreSQL 7 driver 4 * 5 * This file is part of ADOdb, a Database Abstraction Layer library for PHP. 6 * 7 * @package ADOdb 8 * @link https://adodb.org Project's web site and documentation 9 * @link https://github.com/ADOdb/ADOdb Source code and issue tracker 10 * 11 * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause 12 * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, 13 * any later version. This means you can use it in proprietary products. 14 * See the LICENSE.md file distributed with this source code for details. 15 * @license BSD-3-Clause 16 * @license LGPL-2.1-or-later 17 * 18 * @copyright 2000-2013 John Lim 19 * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community 20 */ 21 22 // security - hide paths 23 if (!defined('ADODB_DIR')) die(); 24 25 include_once(ADODB_DIR."/drivers/adodb-postgres64.inc.php"); 26 27 class ADODB_postgres7 extends ADODB_postgres64 { 28 var $databaseType = 'postgres7'; 29 var $hasLimit = true; // set to true for pgsql 6.5+ only. support pgsql/mysql SELECT * FROM TABLE LIMIT 10 30 var $ansiOuter = true; 31 var $charSet = true; //set to true for Postgres 7 and above - PG client supports encodings 32 33 // Richard 3/18/2012 - Modified SQL to return SERIAL type correctly AS old driver no longer return SERIAL as data type. 34 var $metaColumnsSQL = " 35 SELECT 36 a.attname, 37 CASE 38 WHEN x.sequence_name != '' 39 THEN 'SERIAL' 40 ELSE t.typname 41 END AS typname, 42 a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum 43 FROM 44 pg_class c, 45 pg_attribute a 46 JOIN pg_type t ON a.atttypid = t.oid 47 LEFT JOIN ( 48 SELECT 49 c.relname as sequence_name, 50 c1.relname as related_table, 51 a.attname as related_column 52 FROM pg_class c 53 JOIN pg_depend d ON d.objid = c.oid 54 LEFT JOIN pg_class c1 ON d.refobjid = c1.oid 55 LEFT JOIN pg_attribute a ON (d.refobjid, d.refobjsubid) = (a.attrelid, a.attnum) 56 WHERE c.relkind = 'S' AND c1.relname = '%s' 57 ) x ON x.related_column= a.attname 58 WHERE 59 c.relkind in ('r','v') 60 AND (c.relname='%s' or c.relname = lower('%s')) 61 AND a.attname not like '....%%' 62 AND a.attnum > 0 63 AND a.attrelid = c.oid 64 ORDER BY 65 a.attnum"; 66 67 // used when schema defined 68 var $metaColumnsSQL1 = " 69 SELECT 70 a.attname, 71 CASE 72 WHEN x.sequence_name != '' 73 THEN 'SERIAL' 74 ELSE t.typname 75 END AS typname, 76 a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum 77 FROM 78 pg_class c, 79 pg_namespace n, 80 pg_attribute a 81 JOIN pg_type t ON a.atttypid = t.oid 82 LEFT JOIN ( 83 SELECT 84 c.relname as sequence_name, 85 c1.relname as related_table, 86 a.attname as related_column 87 FROM pg_class c 88 JOIN pg_depend d ON d.objid = c.oid 89 LEFT JOIN pg_class c1 ON d.refobjid = c1.oid 90 LEFT JOIN pg_attribute a ON (d.refobjid, d.refobjsubid) = (a.attrelid, a.attnum) 91 WHERE c.relkind = 'S' AND c1.relname = '%s' 92 ) x ON x.related_column= a.attname 93 WHERE 94 c.relkind in ('r','v') 95 AND (c.relname='%s' or c.relname = lower('%s')) 96 AND c.relnamespace=n.oid and n.nspname='%s' 97 AND a.attname not like '....%%' 98 AND a.attnum > 0 99 AND a.atttypid = t.oid 100 AND a.attrelid = c.oid 101 ORDER BY a.attnum"; 102 103 104 function __construct() 105 { 106 parent::__construct(); 107 if (ADODB_ASSOC_CASE !== ADODB_ASSOC_CASE_NATIVE) { 108 $this->rsPrefix .= 'assoc_'; 109 } 110 $this->_bindInputArray = true; 111 } 112 113 114 // the following should be compat with postgresql 7.2, 115 // which makes obsolete the LIMIT limit,offset syntax 116 function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 117 { 118 $nrows = (int) $nrows; 119 $offset = (int) $offset; 120 $offsetStr = ($offset >= 0) ? " OFFSET ".((integer)$offset) : ''; 121 $limitStr = ($nrows >= 0) ? " LIMIT ".((integer)$nrows) : ''; 122 if ($secs2cache) 123 $rs = $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr); 124 else 125 $rs = $this->Execute($sql."$limitStr$offsetStr",$inputarr); 126 127 return $rs; 128 } 129 130 /* 131 function Prepare($sql) 132 { 133 $info = $this->ServerInfo(); 134 if ($info['version']>=7.3) { 135 return array($sql,false); 136 } 137 return $sql; 138 } 139 */ 140 141 /** 142 * Generate the SQL to retrieve MetaColumns data 143 * @param string $table Table name 144 * @param string $schema Schema name (can be blank) 145 * @return string SQL statement to execute 146 */ 147 protected function _generateMetaColumnsSQL($table, $schema) 148 { 149 if ($schema) { 150 return sprintf($this->metaColumnsSQL1, $table, $table, $table, $schema); 151 } 152 else { 153 return sprintf($this->metaColumnsSQL, $table, $table, $schema); 154 } 155 } 156 157 public function metaForeignKeys($table, $owner = '', $upper = false, $associative = false) 158 { 159 # Regex isolates the 2 terms between parenthesis using subexpressions 160 $regex = '^.*\((.*)\).*\((.*)\).*$'; 161 $sql=" 162 SELECT 163 lookup_table, 164 regexp_replace(consrc, '$regex', '\\2') AS lookup_field, 165 dep_table, 166 regexp_replace(consrc, '$regex', '\\1') AS dep_field 167 FROM ( 168 SELECT 169 pg_get_constraintdef(c.oid) AS consrc, 170 t.relname AS dep_table, 171 ft.relname AS lookup_table 172 FROM pg_constraint c 173 JOIN pg_class t ON (t.oid = c.conrelid) 174 JOIN pg_class ft ON (ft.oid = c.confrelid) 175 JOIN pg_namespace nft ON (nft.oid = ft.relnamespace) 176 LEFT JOIN pg_description ds ON (ds.objoid = c.oid) 177 JOIN pg_namespace n ON (n.oid = t.relnamespace) 178 WHERE c.contype = 'f'::\"char\" 179 ORDER BY t.relname, n.nspname, c.conname, c.oid 180 ) constraints 181 WHERE 182 dep_table='".strtolower($table)."' 183 ORDER BY 184 lookup_table, 185 dep_table, 186 dep_field"; 187 $rs = $this->Execute($sql); 188 189 if (!$rs || $rs->EOF) return false; 190 191 $a = array(); 192 while (!$rs->EOF) { 193 $lookup_table = $rs->fields('lookup_table'); 194 $fields = $rs->fields('dep_field') . '=' . $rs->fields('lookup_field'); 195 if ($upper) { 196 $lookup_table = strtoupper($lookup_table); 197 $fields = strtoupper($fields); 198 } 199 $a[$lookup_table][] = str_replace('"','', $fields); 200 201 $rs->MoveNext(); 202 } 203 204 return $a; 205 } 206 207 function _query($sql,$inputarr=false) 208 { 209 if (! $this->_bindInputArray) { 210 // We don't have native support for parameterized queries, so let's emulate it at the parent 211 return ADODB_postgres64::_query($sql, $inputarr); 212 } 213 214 $this->_pnum = 0; 215 $this->_errorMsg = false; 216 // -- added Cristiano da Cunha Duarte 217 if ($inputarr) { 218 $sqlarr = explode('?',trim($sql)); 219 $sql = ''; 220 $i = 1; 221 $last = sizeof($sqlarr)-1; 222 foreach($sqlarr as $v) { 223 if ($last < $i) $sql .= $v; 224 else $sql .= $v.' $'.$i; 225 $i++; 226 } 227 228 $rez = pg_query_params($this->_connectionID,$sql, $inputarr); 229 } else { 230 $rez = pg_query($this->_connectionID,$sql); 231 } 232 // check if no data returned, then no need to create real recordset 233 if ($rez && pg_num_fields($rez) <= 0) { 234 if ($this->_resultid !== false) { 235 pg_free_result($this->_resultid); 236 } 237 $this->_resultid = $rez; 238 return true; 239 } 240 return $rez; 241 } 242 243 /** 244 * Retrieve the client connection's current character set. 245 246 * If no charsets were compiled into the server, the function will always 247 * return 'SQL_ASCII'. 248 * @see https://www.php.net/manual/en/function.pg-client-encoding.php 249 * 250 * @return string|false The character set, or false if it can't be determined. 251 */ 252 function getCharSet() 253 { 254 if (!$this->_connectionID) { 255 return false; 256 } 257 $this->charSet = pg_client_encoding($this->_connectionID); 258 return $this->charSet ?: false; 259 } 260 261 /** 262 * Sets the client-side character set (encoding). 263 * 264 * Allows managing client encoding - very important if the database and 265 * the output target (i.e. HTML) don't match; for instance, you may have a 266 * UNICODE database and server your pages as WIN1251, etc. 267 * 268 * Supported on PostgreSQL 7.0 and above. Available charsets depend on 269 * PostgreSQL version and the distribution's compile flags. 270 * 271 * @param string $charset The character set to switch to. 272 * 273 * @return bool True if the character set was changed successfully, false otherwise. 274 */ 275 function setCharSet($charset) 276 { 277 if ($this->charSet !== $charset) { 278 if (!$this->_connectionID || pg_set_client_encoding($this->_connectionID, $charset) != 0) { 279 return false; 280 } 281 $this->getCharSet(); 282 } 283 return true; 284 } 285 286 } 287 288 /*-------------------------------------------------------------------------------------- 289 Class Name: Recordset 290 --------------------------------------------------------------------------------------*/ 291 292 class ADORecordSet_postgres7 extends ADORecordSet_postgres64{ 293 294 var $databaseType = "postgres7"; 295 296 // 10% speedup to move MoveNext to child class 297 function MoveNext() 298 { 299 if (!$this->EOF) { 300 $this->_currentRow++; 301 if ($this->_numOfRows < 0 || $this->_numOfRows > $this->_currentRow) { 302 $this->_prepfields(); 303 if ($this->fields !== false) { 304 return true; 305 } 306 } 307 $this->fields = false; 308 $this->EOF = true; 309 } 310 return false; 311 } 312 313 } 314 315 class ADORecordSet_assoc_postgres7 extends ADORecordSet_postgres64{ 316 317 var $databaseType = "postgres7"; 318 319 320 function _fetch() 321 { 322 if ($this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0) { 323 return false; 324 } 325 326 $this->_prepfields(); 327 if ($this->fields !== false) { 328 $this->_updatefields(); 329 return true; 330 } 331 332 return false; 333 } 334 335 function MoveNext() 336 { 337 if (!$this->EOF) { 338 $this->_currentRow++; 339 if ($this->_numOfRows < 0 || $this->_numOfRows > $this->_currentRow) { 340 $this->_prepfields(); 341 if ($this->fields !== false) { 342 $this->_updatefields(); 343 return true; 344 } 345 } 346 347 $this->fields = false; 348 $this->EOF = true; 349 } 350 return false; 351 } 352 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body