Neevo Public API
  • Namespace
  • Class
  • Tree

Namespaces

  • Neevo
    • Cache
    • Drivers
    • Nette
  • PHP

Classes

  • MySQLDriver
  • MySQLiDriver
  • PDODriver
  • PgSQLDriver
  • SQLite2Driver
  • SQLite3Driver
  1 <?php
  2 /**
  3  * Neevo - Tiny database layer for PHP. (http://neevo.smasty.net)
  4  *
  5  * This source file is subject to the MIT license that is bundled
  6  * with this package in the file license.txt.
  7  *
  8  * Copyright (c) 2012 Smasty (http://smasty.net)
  9  *
 10  */
 11 
 12 namespace Neevo\Drivers;
 13 
 14 use DateTime;
 15 use InvalidArgumentException;
 16 use Neevo\BaseStatement;
 17 use Neevo\DriverException;
 18 use Neevo\DriverInterface;
 19 use Neevo\Manager;
 20 
 21 
 22 /**
 23  * Neevo PostgreSQL driver (PHP extension 'pgsql')
 24  *
 25  * Driver configuration:
 26  * - host, hostaddr, port, dbname, user, password, connect_timeout, options, sslmode, service => see pg_connect()
 27  * - string => Use connection string instead
 28  * - schema => Schema search path
 29  * - charset => Character encoding to set (defaults to utf-8)
 30  * - persistent (bool) => Try to find a persistent link
 31  *
 32  * - resource (type resource) => Existing SQLite link
 33  * - lazy, table_prefix... => see {@see Neevo\Connection}
 34  *
 35  * @author Smasty
 36  */
 37 class PgSQLDriver implements DriverInterface {
 38 
 39 
 40     /** @var resource */
 41     private $resource;
 42 
 43     /** @var int */
 44     private $affectedRows;
 45 
 46 
 47     /**
 48      * Checks for required PHP extension.
 49      * @throws DriverException
 50      */
 51     public function __construct(BaseStatement $statement = null){
 52         if(!extension_loaded("pgsql"))
 53             throw new DriverException("Cannot instantiate Neevo PgSQL driver - PHP extension 'pgsql' not loaded.");
 54         if($statement instanceof BaseStatement)
 55             parent::__construct($statement);
 56     }
 57 
 58 
 59     /**
 60      * Creates connection to database.
 61      * @param array $config Configuration options
 62      * @throws DriverException
 63      */
 64     public function connect(array $config){
 65 
 66         $defaults = array(
 67             'resource' => null,
 68             'persistent' => false,
 69             'charset' => 'utf8'
 70         );
 71 
 72         $config += $defaults;
 73 
 74         if(isset($config['string']))
 75             $string = $config['string'];
 76         else{
 77             // String generation
 78             $string = '';
 79             foreach(array('host', 'hostaddr', 'port', 'dbname', 'user', 'password', 'connect_timeout', 'options', 'sslmode', 'service') as $cfg){
 80                 if(isset($config[$cfg]))
 81                     $string .= "$cfg=$config[$cfg] ";
 82             }
 83         }
 84 
 85         // Connect
 86         if(is_resource($config['resource']))
 87             $connection = $config['resource'];
 88         elseif($config['persistent'])
 89             $connection = @pg_pconnect($string, PGSQL_CONNECT_FORCE_NEW);
 90         else
 91             $connection = @pg_connect($string, PGSQL_CONNECT_FORCE_NEW);
 92 
 93         if(!is_resource($connection))
 94             throw new DriverException("Connection to database failed.");
 95 
 96         $this->resource = $connection;
 97 
 98         // Encoding
 99         @pg_set_client_encoding($this->resource, $config['charset']);
100 
101         // Schema
102         if(isset($config['schema']))
103             $this->runQuery('SET search_path TO "' . $config['schema'] . '"');
104     }
105 
106 
107     /**
108      * Closes the connection.
109      */
110     public function closeConnection(){
111         @pg_close($this->resource);
112     }
113 
114 
115     /**
116      * Frees memory used by given result set.
117      * @param resource $resultSet
118      * @return bool
119      */
120     public function freeResultSet($resultSet){
121         @pg_free_result($resultSet);
122     }
123 
124 
125     /**
126      * Executes given SQL statement.
127      * @param string $queryString
128      * @return resource|bool
129      * @throws DriverException
130      */
131     public function runQuery($queryString){
132         $this->affectedRows = false;
133 
134         $result = @pg_query($this->resource, $queryString);
135         if($result === false)
136             throw new DriverException(pg_last_error($this->resource), null, $queryString);
137 
138         $this->affectedRows = @pg_affected_rows($result);
139         return $result;
140     }
141 
142 
143     /**
144      * Begins a transaction if supported.
145      * @param string $savepoint
146      */
147     public function beginTransaction($savepoint = null){
148         $this->runQuery($savepoint ? "SAVEPOINT $savepoint" : 'START TRANSACTION');
149     }
150 
151 
152     /**
153      * Commits statements in a transaction.
154      * @param string $savepoint
155      */
156     public function commit($savepoint = null){
157         $this->runQuery($savepoint ? "RELEASE SAVEPOINT $savepoint" : 'COMMIT');
158     }
159 
160 
161     /**
162      * Rollbacks changes in a transaction.
163      * @param string $savepoint
164      */
165     public function rollback($savepoint = null){
166         $this->runQuery($savepoint ? "ROLLBACK TO SAVEPOINT $savepoint" : 'ROLLBACK');
167     }
168 
169 
170     /**
171      * Fetches row from given result set as an associative array.
172      * @param resource $resultSet
173      * @return array
174      */
175     public function fetch($resultSet){
176         return @pg_fetch_assoc($resultSet);
177     }
178 
179 
180     /**
181      * Moves internal result pointer.
182      * @param resource $resultSet
183      * @param int $offset
184      * @return bool
185      */
186     public function seek($resultSet, $offset){
187         return @pg_result_seek($resultSet, $offset);
188     }
189 
190 
191     /**
192      * Returns the ID generated in the INSERT statement.
193      * @return int
194      */
195     public function getInsertId(){
196         $result = $this->runQuery("SELECT LASTVAL()");
197         if(!$result)
198             return false;
199 
200         $r = $this->fetch($result);
201         return is_array($r) ? reset($r) : false;
202     }
203 
204 
205     /**
206      * Randomizes result order.
207      * @param BaseStatement $statement
208      */
209     public function randomizeOrder(BaseStatement $statement){
210         $statement->order('RAND()');
211     }
212 
213 
214     /**
215      * Returns the number of rows in the given result set.
216      * @param resource $resultSet
217      * @return int|bool
218      */
219     public function getNumRows($resultSet){
220         return @pg_num_rows($resultSet);
221     }
222 
223 
224     /**
225      * Returns the number of affected rows in previous operation.
226      * @return int
227      */
228     public function getAffectedRows(){
229         return $this->affectedRows;
230     }
231 
232 
233     /**
234      * Escapes given value.
235      * @param mixed $value
236      * @param string $type
237      * @return mixed
238      * @throws InvalidArgumentException
239      */
240     public function escape($value, $type){
241         switch($type){
242             case Manager::BOOL:
243                 return $value ? 'TRUE' : 'FALSE';
244 
245             case Manager::TEXT:
246                 return "'" . pg_escape_string($this->resource, $value) . "'";
247 
248             case Manager::BINARY:
249                 return "'" . pg_escape_bytea($this->resource, $value) . "'";
250 
251             case Manager::IDENTIFIER:
252                 return '"' . str_replace('.', '"."', str_replace('"', '""', $value)) . '"';
253 
254             case Manager::DATETIME:
255                 return ($value instanceof DateTime) ? $value->format("'Y-m-d H:i:s'") : date("'Y-m-d H:i:s'", $value);
256 
257             default:
258                 throw new InvalidArgumentException('Unsupported data type.');
259                 break;
260         }
261     }
262 
263 
264     /**
265      * Decodes given value.
266      * @param mixed $value
267      * @param string $type
268      * @return mixed
269      * @throws InvalidArgumentException
270      */
271     public function unescape($value, $type){
272         if($type === Manager::BINARY)
273             return pg_unescape_bytea($value);
274         throw new InvalidArgumentException('Unsupported data type.');
275     }
276 
277 
278     /**
279      * Returns the PRIMARY KEY column for given table.
280      *
281      * Experimental implementation!
282      * @param string $table
283      * @return string
284      */
285     public function getPrimaryKey($table){
286         $def = $this->fetch($this->runQuery("SELECT indexdef FROM pg_indexes WHERE indexname = '{$table}_pkey'"));
287         if(!$def)
288             return false;
289         $def = reset($def);
290         if(preg_match("~{$table}_pkey\s+ON\s+{$table}.*\((\w+).*\)~i", $def, $matches))
291             return $matches[1];
292         return false;
293     }
294 
295 
296     /**
297      * Returns types of columns in given result set.
298      * @param resource $resultSet
299      * @param string $table
300      * @return array
301      */
302     public function getColumnTypes($resultSet, $table){
303         if($table === null)
304             return array();
305         $cols = pg_meta_data($this->resource, $table);
306         foreach($cols as $key => $value){
307             $cols[$key] = preg_replace('~[^a-z]~i', '', $value['type']);
308         }
309         return $cols;
310     }
311 
312 
313 }
314 
Neevo Public API API documentation generated by ApiGen 2.8.0