]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - tests/PHPUnit/Util/PDO.php
Added unit tests.
[Github/sugarcrm.git] / tests / PHPUnit / Util / PDO.php
1 <?php
2 /**
3  * PHPUnit
4  *
5  * Copyright (c) 2002-2009, Sebastian Bergmann <sb@sebastian-bergmann.de>.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  *   * Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  *
15  *   * Redistributions in binary form must reproduce the above copyright
16  *     notice, this list of conditions and the following disclaimer in
17  *     the documentation and/or other materials provided with the
18  *     distribution.
19  *
20  *   * Neither the name of Sebastian Bergmann nor the names of his
21  *     contributors may be used to endorse or promote products derived
22  *     from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  *
37  * @category   Testing
38  * @package    PHPUnit
39  * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
40  * @copyright  2002-2009 Sebastian Bergmann <sb@sebastian-bergmann.de>
41  * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
42
43  * @link       http://www.phpunit.de/
44  * @since      File available since Release 3.1.4
45  */
46
47 require_once 'PHPUnit/Util/Filter.php';
48
49 PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
50
51 /**
52  * PDO helpers.
53  *
54  * @category   Testing
55  * @package    PHPUnit
56  * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
57  * @copyright  2002-2009 Sebastian Bergmann <sb@sebastian-bergmann.de>
58  * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
59  * @version    Release: 3.3.17
60  * @link       http://www.phpunit.de/
61  * @since      Class available since Release 3.1.4
62  */
63 class PHPUnit_Util_PDO
64 {
65     public static function factory($dsn)
66     {
67         $parsed = self::parseDSN($dsn);
68
69         switch ($parsed['phptype']) {
70             case 'mysql': {
71                 $database      = NULL;
72                 $charset       = NULL;
73                 $host          = NULL;
74                 $port          = NULL;
75                 $socket        = NULL;
76                 $user          = NULL;
77                 $pass          = NULL;
78                 $driverOptions = NULL;
79
80                 foreach ( $parsed as $key => $val )
81                 {
82                     switch ( $key )
83                     {
84                         case 'database':
85                         case 'dbname':
86                             $database = $val;
87                             break;
88
89                         case 'charset':
90                             $charset = $val;
91                             break;
92
93                         case 'host':
94                         case 'hostspec':
95                             $host = $val;
96                             break;
97
98                         case 'port':
99                             $port = $val;
100                             break;
101
102                         case 'socket':
103                             $socket = $val;
104                             break;
105
106                         case 'user':
107                         case 'username':
108                             $user = $val;
109                             break;
110
111                         case 'pass':
112                         case 'password':
113                             $pass = $val;
114                             break;
115
116                         case 'driver-opts':
117                             $driverOptions = $val;
118                             break;
119                     }
120                 }
121
122                 if ( !isset( $database ) )
123                 {
124                     throw new InvalidArgumentException('Invalid DSN.');
125                 }
126
127                 $dsn = "mysql:dbname=$database";
128
129                 if ( isset( $host ) && $host )
130                 {
131                     $dsn .= ";host=$host";
132                 }
133
134                 if ( isset( $port ) && $port )
135                 {
136                     $dsn .= ";port=$port";
137                 }
138
139                 if ( isset( $charset ) && $charset )
140                 {
141                     $dsn .= ";charset=$charset";
142                 }
143
144                 if ( isset( $socket ) && $socket )
145                 {
146                     $dsn .= ";unix_socket=$socket";
147                 }
148
149                 $dbh = new PDO($dsn, $user, $pass, $driverOptions);
150             }
151             break;
152
153             case 'sqlite': {
154                 $dbh = new PDO($dsn);
155             }
156             break;
157
158             default: {
159                 throw new InvalidArgumentException('Invalid DSN.');
160             }
161         }
162
163         $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
164
165         return $dbh;
166     }
167
168     /**
169      * Returns the Data Source Name as a structure containing the various parts of the DSN.
170      *
171      * Additional keys can be added by appending a URI query string to the
172      * end of the DSN.
173      *
174      * The format of the supplied DSN is in its fullest form:
175      * <code>
176      *  phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true
177      * </code>
178      *
179      * Most variations are allowed:
180      * <code>
181      *  phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644
182      *  phptype://username:password@hostspec/database_name
183      *  phptype://username:password@hostspec
184      *  phptype://username@hostspec
185      *  phptype://hostspec/database
186      *  phptype://hostspec
187      *  phptype(dbsyntax)
188      *  phptype
189      * </code>
190      *
191      * This function is 'borrowed' from PEAR /DB.php .
192      *
193      * @param string $dsn Data Source Name to be parsed
194      *
195      * @return array an associative array with the following keys:
196      *  + phptype:  Database backend used in PHP (mysql, odbc etc.)
197      *  + dbsyntax: Database used with regards to SQL syntax etc.
198      *  + protocol: Communication protocol to use (tcp, unix etc.)
199      *  + hostspec: Host specification (hostname[:port])
200      *  + database: Database to use on the DBMS server
201      *  + username: User name for login
202      *  + password: Password for login
203      */
204     public static function parseDSN( $dsn )
205     {
206         $parsed = array(
207             'phptype'  => FALSE,
208             'dbsyntax' => FALSE,
209             'username' => FALSE,
210             'password' => FALSE,
211             'protocol' => FALSE,
212             'hostspec' => FALSE,
213             'port'     => FALSE,
214             'socket'   => FALSE,
215             'database' => FALSE,
216         );
217
218         if ( is_array( $dsn ) )
219         {
220             $dsn = array_merge( $parsed, $dsn );
221             if ( !$dsn['dbsyntax'] )
222             {
223                 $dsn['dbsyntax'] = $dsn['phptype'];
224             }
225             return $dsn;
226         }
227
228         // Find phptype and dbsyntax
229         if ( ( $pos = strpos( $dsn, '://' ) ) !== FALSE )
230         {
231             $str = substr( $dsn, 0, $pos );
232             $dsn = substr( $dsn, $pos + 3 );
233         }
234         else
235         {
236             $str = $dsn;
237             $dsn = NULL;
238         }
239
240         // Get phptype and dbsyntax
241         // $str => phptype(dbsyntax)
242         if ( preg_match( '|^(.+?)\((.*?)\)$|', $str, $arr ) )
243         {
244             $parsed['phptype']  = $arr[1];
245             $parsed['dbsyntax'] = !$arr[2] ? $arr[1] : $arr[2];
246         }
247         else
248         {
249             $parsed['phptype']  = $str;
250             $parsed['dbsyntax'] = $str;
251         }
252
253         if ( !count( $dsn ) )
254         {
255             return $parsed;
256         }
257
258         // Get (if found): username and password
259         // $dsn => username:password@protocol+hostspec/database
260         if ( ( $at = strrpos( (string) $dsn, '@' ) ) !== FALSE )
261         {
262             $str = substr( $dsn, 0, $at );
263             $dsn = substr( $dsn, $at + 1 );
264             if ( ( $pos = strpos( $str, ':' ) ) !== FALSE )
265             {
266                 $parsed['username'] = rawurldecode( substr( $str, 0, $pos ) );
267                 $parsed['password'] = rawurldecode( substr( $str, $pos + 1 ) );
268             }
269             else
270             {
271                 $parsed['username'] = rawurldecode( $str );
272             }
273         }
274
275         // Find protocol and hostspec
276
277         if ( preg_match( '|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match ) )
278         {
279             // $dsn => proto(proto_opts)/database
280             $proto       = $match[1];
281             $proto_opts  = $match[2] ? $match[2] : FALSE;
282             $dsn         = $match[3];
283         }
284         else
285         {
286             // $dsn => protocol+hostspec/database (old format)
287             if ( strpos( $dsn, '+' ) !== FALSE )
288             {
289                 list( $proto, $dsn ) = explode( '+', $dsn, 2 );
290             }
291             if ( strpos( $dsn, '/' ) !== FALSE )
292             {
293                 list( $proto_opts, $dsn ) = explode( '/', $dsn, 2 );
294             }
295             else
296             {
297                 $proto_opts = $dsn;
298                 $dsn = NULL;
299             }
300         }
301
302         // process the different protocol options
303         $parsed['protocol'] = ( !empty( $proto ) ) ? $proto : 'tcp';
304         $proto_opts = rawurldecode( $proto_opts );
305         if ( $parsed['protocol'] == 'tcp' )
306         {
307             if ( strpos( $proto_opts, ':' ) !== FALSE )
308             {
309                 list( $parsed['hostspec'], $parsed['port'] ) = explode( ':', $proto_opts );
310             }
311             else
312             {
313                 $parsed['hostspec'] = $proto_opts;
314             }
315         }
316         elseif ( $parsed['protocol'] == 'unix' )
317         {
318             $parsed['socket'] = $proto_opts;
319         }
320
321         // Get dabase if any
322         // $dsn => database
323         if ( $dsn )
324         {
325             if ( ( $pos = strpos( $dsn, '?' ) ) === FALSE )
326             {
327                 // /database
328                 $parsed['database'] = rawurldecode( $dsn );
329             }
330             else
331             {
332                 // /database?param1=value1&param2=value2
333                 $parsed['database'] = rawurldecode( substr( $dsn, 0, $pos ) );
334                 $dsn = substr( $dsn, $pos + 1 );
335                 if ( strpos( $dsn, '&') !== FALSE )
336                 {
337                     $opts = explode( '&', $dsn );
338                 }
339                 else
340                 { // database?param1=value1
341                     $opts = array( $dsn );
342                 }
343                 foreach ( $opts as $opt )
344                 {
345                     list( $key, $value ) = explode( '=', $opt );
346                     if ( !isset( $parsed[$key] ) )
347                     {
348                         // don't allow params overwrite
349                         $parsed[$key] = rawurldecode( $value );
350                     }
351                 }
352             }
353         }
354         return $parsed;
355     }
356 }
357 ?>