Neevo Public API
  • Namespace
  • Class
  • Tree

Namespaces

  • Neevo
    • Cache
    • Drivers
    • Nette
  • PHP

Classes

  • BaseStatement
  • Connection
  • Literal
  • Manager
  • Parser
  • Result
  • ResultIterator
  • Row
  • Statement

Interfaces

  • DriverInterface
  • ObservableInterface
  • ObserverInterface

Exceptions

  • DriverException
  • ImplementationException
  • NeevoException
  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;
 13 
 14 use ArrayAccess;
 15 use InvalidArgumentException;
 16 use Neevo\Cache\MemoryStorage;
 17 use Neevo\Cache\StorageInterface;
 18 use Neevo\DriverInterface;
 19 use PDO;
 20 use ReflectionClass;
 21 use ReflectionException;
 22 use SplObjectStorage;
 23 use Traversable;
 24 
 25 
 26 /**
 27  * Representation of database connection.
 28  *
 29  * Common configuration: (see also driver specific configuration)
 30  * - tablePrefix => prefix for table names
 31  * - lazy (bool) => If TRUE, connection will be established only when required.
 32  * - result
 33  *   - detectTypes (bool) => Detect column types automatically
 34  *   - formatDate => Date/time format (empty for DateTime instance).
 35  * - rowClass => Name of class to use as a row class.
 36  *
 37  * @author Smasty
 38  */
 39 class Connection implements ObservableInterface, ArrayAccess {
 40 
 41 
 42     /** @var array */
 43     private $config;
 44 
 45     /** @var bool */
 46     private $connected = false;
 47 
 48     /** @var DriverInterface */
 49     private $driver;
 50 
 51     /** @var string */
 52     private $parser = 'Neevo\\Parser';
 53 
 54     /** @var SplObjectStorage */
 55     private $observers;
 56 
 57     /** @var StorageInterface */
 58     private $cache;
 59 
 60 
 61     /**
 62      * Establishes a connection.
 63      * @param array|string|Traversable|PDO $config
 64      * @param StorageInterface $cache
 65      * @throws InvalidArgumentException
 66      */
 67     public function __construct($config, StorageInterface $cache = null){
 68         $this->observers = new SplObjectStorage;
 69 
 70         $this->cache = $cache !== null ? $cache : new MemoryStorage;
 71 
 72         // Parse config
 73         if(is_string($config)){
 74             parse_str($config, $config);
 75         } elseif($config instanceof Traversable){
 76             $tmp = array();
 77             foreach($config as $key => $val){
 78                 $tmp[$key] = $val instanceof Traversable ? iterator_to_array($val) : $val;
 79             }
 80             $config = $tmp;
 81         } elseif(class_exists('PDO') && $config instanceof PDO){
 82             $config = array(
 83                 'driver' => 'pdo',
 84                 'pdo' => $config
 85             );
 86         } elseif(!is_array($config)){
 87             throw new InvalidArgumentException('Configuration must be an array, string or Traversable.');
 88         }
 89 
 90         // Default values
 91         $defaults = array(
 92             'driver' => Manager::$defaultDriver,
 93             'lazy' => true,
 94             'rowClass' => 'Neevo\\Row',
 95             'tablePrefix' => '',
 96             'result' => array(
 97                 'detectTypes' => false,
 98                 'formatDate' => '',
 99             ),
100         );
101 
102         // Create aliases
103         self::alias($config, 'driver', 'extension');
104         self::alias($config, 'username', 'user');
105         self::alias($config, 'password', 'pass');
106         self::alias($config, 'password', 'pswd');
107         self::alias($config, 'host', 'hostname');
108         self::alias($config, 'host', 'server');
109         self::alias($config, 'database', 'db');
110         self::alias($config, 'database', 'dbname');
111         self::alias($config, 'tablePrefix', 'table_prefix');
112         self::alias($config, 'tablePrefix', 'prefix');
113         self::alias($config, 'charset', 'encoding');
114         self::alias($config, 'result.detectTypes', 'detectTypes');
115         self::alias($config, 'result.formatDate', 'formatDateTime');
116 
117         $config = array_replace_recursive($defaults, $config);
118 
119         $this->setDriver($config['driver']);
120 
121         $config['lazy'] = (bool) $config['lazy'] && strtolower($config['lazy']) !== 'false';
122         $this->config = $config;
123 
124         if($config['lazy'] === false)
125             $this->connect();
126     }
127 
128 
129     /**
130      * Closes database connection.
131      */
132     public function __destruct(){
133         try{
134             $this->driver->closeConnection();
135         } catch(ImplementationException $e){
136 
137         }
138 
139         $this->notifyObservers(ObserverInterface::DISCONNECT);
140     }
141 
142 
143     /**
144      * Opens database connection.
145      */
146     public function connect(){
147         if($this->connected !== false)
148             return;
149 
150         $this->driver->connect($this->config);
151         $this->connected = true;
152         $this->notifyObservers(ObserverInterface::CONNECT);
153     }
154 
155 
156     /**
157      * Returns configuration.
158      * @param string $key
159      * @return mixed
160      */
161     public function getConfig($key = null){
162         if($key === null)
163             return $this->config;
164         return isset($this->config[$key]) ? $this->config[$key] : null;
165     }
166 
167 
168     /**
169      * Returns defined table prefix.
170      * @return string
171      */
172     public function getPrefix(){
173         return isset($this->config['tablePrefix']) ? $this->config['tablePrefix'] : '';
174     }
175 
176 
177     /**
178      * Returns the current driver instance.
179      * @return DriverInterface
180      */
181     public function getDriver(){
182         return $this->driver;
183     }
184 
185 
186     /**
187      * Returns the current parser class name.
188      * @return string
189      */
190     public function getParser(){
191         return $this->parser;
192     }
193 
194 
195     /**
196      * Returns the current cache storage instance.
197      * @return StorageInterface
198      */
199     public function getCache(){
200         return $this->cache;
201     }
202 
203 
204     /**
205      * Sets the cache storage.
206      * @param StorageInterface $cache
207      */
208     public function setCache(StorageInterface $cache){
209         $this->cache = $cache;
210     }
211 
212 
213     /**
214      * Attaches given observer to given $event.
215      * @param ObserverInterface $observer
216      * @param int $event
217      */
218     public function attachObserver(ObserverInterface $observer, $event){
219         $this->observers->attach($observer, $event);
220     }
221 
222 
223     /**
224      * Detaches given observer.
225      * @param ObserverInterface $observer
226      */
227     public function detachObserver(ObserverInterface $observer){
228         $this->observers->detach($observer);
229     }
230 
231 
232     /**
233      * Notifies all observers attached to given event.
234      * @param int $event
235      */
236     public function notifyObservers($event){
237         foreach($this->observers as $observer){
238             if($event & $this->observers->getInfo())
239                 $observer->updateStatus($this, $event);
240         }
241     }
242 
243 
244     /**
245      * Returns configuration value.
246      * @param string $key
247      * @return mixed
248      */
249     public function offsetGet($key){
250         return $this->getConfig($key);
251     }
252 
253 
254     /**
255      * Checks if configuration value exists.
256      * @param mixed $key
257      * @return bool
258      */
259     public function offsetExists($key){
260         return isset($this->config[$key]);
261     }
262 
263 
264     /** @internal */
265     public function offsetSet($offset, $value){
266 
267     }
268 
269 
270     /** @internal */
271     public function offsetUnset($offset){
272 
273     }
274 
275 
276     /**
277      * Creates an alias for configuration value.
278      * @param array $config Passed by reference
279      * @param string $key
280      * @param string $alias Alias of $key
281      */
282     public static function alias(&$config, $key, $alias){
283         if(!isset($config[$alias]))
284             return;
285         $tmp = & $config;
286         foreach(explode('.', $key) as $key){
287             $tmp = & $tmp[$key];
288         }
289         if(!isset($tmp))
290             $tmp = $config[$alias];
291     }
292 
293 
294     /**
295      * Sets the driver and statement parser.
296      * @param string $driver
297      * @throws DriverException
298      */
299     protected function setDriver($driver){
300         if(strcasecmp($driver, 'sqlite') === 0) // Backward compatibility
301             $driver = 'SQLite2';
302 
303         $class = "Neevo\\Drivers\\{$driver}Driver";
304 
305         if(!class_exists($class)){
306             $file = __DIR__ . '/Drivers/' . strtolower($driver) . '.php';
307             if(!file_exists($file))
308                 throw new DriverException("$driver driver file ($file) does not exist.");
309             if(is_readable($file))
310                 include_once $file;
311             else
312                 throw new DriverException("$driver driver file ($file) is not readable.");
313         }
314         if(!$this->isDriver($class))
315             throw new DriverException("Class '$class' is not a valid Neevo driver class.");
316 
317         $this->driver = new $class;
318 
319         // Set statement parser
320         if($this->isParser($class))
321             $this->parser = $class;
322     }
323 
324 
325     /**
326      * Checks wether the given class is valid Neevo driver.
327      * @param string $class
328      * @return bool
329      */
330     protected function isDriver($class){
331         try{
332             $reflection = new ReflectionClass($class);
333             return $reflection->implementsInterface('Neevo\\DriverInterface');
334         } catch(ReflectionException $e){
335             return false;
336         }
337     }
338 
339 
340     /**
341      * Checks wether the given class is valid Neevo statement parser.
342      * @param string $class
343      * @return bool
344      */
345     protected function isParser($class){
346         try{
347             $reflection = new ReflectionClass($class);
348             return $reflection->isSubclassOf('Neevo\\Parser');
349         } catch(ReflectionException $e){
350             return false;
351         }
352     }
353 
354 
355 }
356 
Neevo Public API API documentation generated by ApiGen 2.8.0