root/trunk/src/main/php/net/stubbles/rdbms/pdo/stubDatabasePDOConnection.php

Revision 1281, 9.7 kB (checked in by mikey, 6 months ago)

code nazi :)

Line 
1 <?php
2 /**
3  * wrapper around the pdo connection
4  *
5  * @author      Frank Kleine <mikey@stubbles.net>
6  * @package     stubbles
7  * @subpackage  rdbms_pdo
8  */
9 stubClassLoader::load('net::stubbles::rdbms::stubDatabaseConnection',
10                       'net::stubbles::rdbms::pdo::stubDatabasePDOStatement'
11 );
12 /**
13  * wrapper around the pdo connection
14  *
15  * @package     stubbles
16  * @subpackage  rdbms_pdo
17  * @see         http://php.net/pdo
18  */
19 class stubDatabasePDOConnection extends stubBaseObject implements stubDatabaseConnection
20 {
21     /**
22      * container that contains the data required to establish the connection
23      *
24      * @var  stubDatabaseConnectionData
25      */
26     protected $connectionData;
27     /**
28      * instance of pdo
29      *
30      * @var  PDO
31      */
32     protected  $pdo           = null;
33
34     /**
35      * constructor
36      *
37      * @param   stubDatabaseConnectionData  $connectionData  container that contains the data required to establish the connection
38      * @throws  stubRuntimeException
39      */
40     public function __construct(stubDatabaseConnectionData $connectionData)
41     {
42         if (extension_loaded('pdo') == false) {
43             throw new stubRuntimeException('Can not create ' . __CLASS__ . ', requires PHP-extension "pdo".');
44         }
45         
46         $this->connectionData = $connectionData;
47     }
48
49     /**
50      * destructor
51      */
52     public function __destruct()
53     {
54         $this->disconnect();
55     }
56
57     /**
58      * establishes the connection
59      *
60      * @throws  stubDatabaseException
61      */
62     public function connect()
63     {
64         if (null !== $this->pdo) {
65             throw new stubDatabaseException('Already connected, can not connect twice.');
66         }
67         
68         try {
69             $this->createPDO();
70             $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
71         } catch (PDOException $pdoe) {
72             throw new stubDatabaseException($pdoe->getMessage(), $pdoe);
73         }
74     }
75
76     /**
77      * tries to create a new pdo instance
78      *
79      * @throws  PDOException
80      */
81     protected function createPDO()
82     {
83         $this->pdo = new PDO($this->connectionData->getDSN(),
84                              $this->connectionData->getUserName(),
85                              $this->connectionData->getPassword(),
86                              $this->connectionData->getDriverOptions()
87                      );
88     }
89
90     /**
91      * disconnects the database
92      */
93     public function disconnect()
94     {
95         $this->pdo = null;
96     }
97
98     /**
99      * returns the connection data used for the connection
100      *
101      * @return  stubDatabaseConnectionData
102      */
103     public function getConnectionData()
104     {
105         return $this->connectionData;
106     }
107
108     /**
109      * redirects calls on non-existing methods to the pdo object
110      *
111      * @param   string  $method     name of the method to call
112      * @param   array   $arguments  list of arguments for the method call
113      * @return  mixed
114      * @throws  stubDatabaseException
115      */
116     public function __call($method, $arguments)
117     {
118         if (null === $this->pdo) {
119             $this->connect();
120         }
121         
122         if (method_exists($this->pdo, $method) == false) {
123             throw new stubDatabaseException('Call to undefined method ' . $this->getClassName() . '::' . $method . '().');
124         }
125         
126         try {
127             return call_user_func_array(array($this->pdo, $method), $arguments);
128         } catch (PDOException $pdoe) {
129             throw new stubDatabaseException($pdoe->getMessage(), $pdoe);
130         }
131     }
132
133     /**
134      * start a transaction
135      *
136      * @return  bool
137      * @throws  stubDatabaseException
138      */
139     public function beginTransaction()
140     {
141         return $this->__call('beginTransaction', array());
142     }
143
144     /**
145      * commit a transaction
146      *
147      * @return  bool
148      * @throws  stubDatabaseException
149      */
150     public function commit()
151     {
152         return $this->__call('commit', array());
153     }
154
155     /**
156      * rollback a transaction
157      *
158      * @return  bool
159      * @throws  stubDatabaseException
160      */
161     public function rollback()
162     {
163         return $this->__call('rollBack', array());
164     }
165
166     /**
167      * creates a prepared statement
168      *
169      * @param   string  $statement      SQL statement
170      * @param   array   $driverOptions  optional  one or more key=>value pairs to set attribute values for the Statement object
171      * @return  stubDatabasePDOStatement
172      * @throws  stubDatabaseException
173      * @see     http://php.net/pdo-prepare
174      */
175     public function prepare($statement, array $driverOptions = array())
176     {
177         if (null === $this->pdo) {
178             $this->connect();
179         }
180         
181         try {
182             $statement = new stubDatabasePDOStatement($this->pdo->prepare($statement, $driverOptions));
183             return $statement;
184         } catch (PDOException $pdoe) {
185             throw new stubDatabaseException($pdoe->getMessage(), $pdoe);
186         }
187     }
188
189     /**
190      * executes a SQL statement
191      *
192      * The driver options can be:
193      * <code>
194      * fetchMode => one of the PDO::FETCH_* constants
195      * colNo     => if fetchMode == PDO::FETCH_COLUMN this denotes the column number to fetch
196      * object    => if fetchMode == PDO::FETCH_INTO this denotes the object to fetch the data into
197      * classname => if fetchMode == PDO::FETCH_CLASS this denotes the class to create and fetch the data into
198      * ctorargs  => (optional) if fetchMode == PDO::FETCH_CLASS this denotes the list of arguments for the constructor of the class to create and fetch the data into
199      * </code>
200      *
201      * @param   string  $sql            the sql query to use
202      * @param   array   $driverOptions  optional  how to fetch the data
203      * @return  stubDatabasePDOStatement
204      * @throws  stubDatabaseException
205      * @see     http://php.net/pdo-query
206      * @see     http://php.net/pdostatement-setfetchmode for the details on the fetch mode options
207      */
208     public function query($sql, array $driverOptions = array())
209     {
210         if (null === $this->pdo) {
211             $this->connect();
212         }
213         
214         try {
215             if (isset($driverOptions['fetchMode']) == true) {
216                 switch ($driverOptions['fetchMode']) {
217                     case PDO::FETCH_COLUMN:
218                         if (isset($driverOptions['colNo']) == false) {
219                             throw new stubDatabaseException('Fetch mode COLUMN requires driver option ŽcolNoŽ.');
220                         }
221                         
222                         $pdoStatement = $this->pdo->query($sql, $driverOptions['fetchMode'], $driverOptions['colNo']);
223                         break;
224                     
225                     case PDO::FETCH_INTO:
226                         if (isset($driverOptions['object']) == false) {
227                             throw new stubDatabaseException('Fetch mode INTO requires driver option ŽobjectŽ.');
228                         }
229                         
230                         $pdoStatement = $this->pdo->query($sql, $driverOptions['fetchMode'], $driverOptions['object']);
231                         break;
232                     
233                     case PDO::FETCH_CLASS:
234                         if (isset($driverOptions['classname']) == false) {
235                             throw new stubDatabaseException('Fetch mode CLASS requires driver option ŽclassnameŽ.');
236                         }
237                         
238                         if (isset($driverOptions['ctorargs']) == false) {
239                             $driverOptions['ctorargs'] = array();
240                         }
241                         
242                         $pdoStatement = $this->pdo->query($sql, $driverOptions['fetchMode'], $driverOptions['classname'], $driverOptions['ctorargs']);
243                         break;
244                     
245                     default:
246                         $pdoStatement = $this->pdo->query($sql, $driverOptions['fetchMode']);
247                 }
248             } else {
249                 $pdoStatement = $this->pdo->query($sql);
250             }
251         } catch (PDOException $pdoe) {
252             throw new stubDatabaseException($pdoe->getMessage(), $pdoe);
253         }
254         
255         $statement = new stubDatabasePDOStatement($pdoStatement);
256         return $statement;
257     }
258
259     /**
260      * execute an SQL statement and return the number of affected rows
261      *
262      * @param   string  $statement      the sql statement to execute
263      * @param   array   $driverOptions  optional  one or more driver specific options for the call to query()
264      * @return  int     number of effected rows
265      * @throws  stubDatabaseException
266      */
267     public function exec($statement, array $driverOptions = array())
268     {
269         if (null === $this->pdo) {
270             $this->connect();
271         }
272         
273         try {
274             return $this->pdo->exec($statement);
275         } catch (PDOException $pdoe) {
276             throw new stubDatabaseException($pdoe->getMessage(), $pdoe);
277         }
278     }
279
280     /**
281      * returns the last insert id
282      *
283      * @param   string  $name  optional  name of the sequence object from which the ID should be returned.
284      * @return  int
285      * @throws  stubDatabaseException
286      */
287     public function getLastInsertId($name = null)
288     {
289         if (null === $this->pdo) {
290             throw new stubDatabaseException('Not connected: can not retrieve last insert id.');
291         }
292         
293         try {
294             return $this->pdo->lastInsertId($name);
295         } catch (PDOException $pdoe) {
296             throw new stubDatabaseException($pdoe->getMessage(), $pdoe);
297         }
298     }
299
300     /**
301      * returns the database name (e.g. MySQL or PostgreSQL)
302      *
303      * @return  string
304      */
305     public function getDatabase()
306     {
307         $dsnParts = explode(':', $this->connectionData->getDSN());
308         return $dsnParts[0];
309     }
310 }
311 ?>
Note: See TracBrowser for help on using the browser.