Coverage for Doctrine_Connection_Mssql

Back to coverage report

1 <?php
2 /*
3  *  $Id: Mssql.php 4050 2008-03-19 16:05:34Z romanb $
4  *
5  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16  *
17  * This software consists of voluntary contributions made by many individuals
18  * and is licensed under the LGPL. For more information, see
19  * <http://www.phpdoctrine.org>.
20  */
21 Doctrine::autoload('Doctrine_Connection');
22 /**
23  * Doctrine_Connection_Mssql
24  *
25  * @package     Doctrine
26  * @subpackage  Connection
27  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
28  * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
29  * @author      Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
30  * @version     $Revision: 4050 $
31  * @link        www.phpdoctrine.org
32  * @since       1.0
33  */
34 class Doctrine_Connection_Mssql extends Doctrine_Connection
35 {
36     /**
37      * @var string $driverName                  the name of this connection driver
38      */
39     protected $driverName = 'Mssql';
40
41     /**
42      * the constructor
43      *
44      * @param Doctrine_Manager $manager
45      * @param PDO $pdo                          database handle
46      */
47     public function __construct(Doctrine_Manager $manager, $adapter)
48     {
49         // initialize all driver options
50         $this->supported = array(
51                           'sequences'             => 'emulated',
52                           'indexes'               => true,
53                           'affected_rows'         => true,
54                           'transactions'          => true,
55                           'summary_functions'     => true,
56                           'order_by_text'         => true,
57                           'current_id'            => 'emulated',
58                           'limit_queries'         => 'emulated',
59                           'LOBs'                  => true,
60                           'replace'               => 'emulated',
61                           'sub_selects'           => true,
62                           'auto_increment'        => true,
63                           'primary_key'           => true,
64                           'result_introspection'  => true,
65                           'prepared_statements'   => 'emulated',
66                           );
67
68         parent::__construct($manager, $adapter);
69     }
70
71     /**
72      * quoteIdentifier
73      * Quote a string so it can be safely used as a table / column name
74      *
75      * Quoting style depends on which database driver is being used.
76      *
77      * @param string $identifier    identifier name to be quoted
78      * @param bool   $checkOption   check the 'quote_identifier' option
79      *
80      * @return string  quoted identifier string
81      */
82     public function quoteIdentifier($identifier, $checkOption = false)
83     {
84         if ($checkOption && ! $this->getAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER)) {
85             return $identifier;
86         }
87         
88         if (strpos($identifier, '.') !== false) { 
89             $parts = explode('.', $identifier); 
90             $quotedParts = array(); 
91             foreach ($parts as $p) { 
92                 $quotedParts[] = $this->quoteIdentifier($p); 
93             }
94             
95             return implode('.', $quotedParts); 
96         }
97         
98         return '[' . str_replace(']', ']]', $identifier) . ']';
99     }
100
101     /**
102      * Adds an adapter-specific LIMIT clause to the SELECT statement.
103      * [ borrowed from Zend Framework ]
104      *
105      * @param string $query
106      * @param mixed $limit
107      * @param mixed $offset
108      * @link http://lists.bestpractical.com/pipermail/rt-devel/2005-June/007339.html
109      * @return string
110      */
111     public function modifyLimitQuery($query, $limit = false, $offset = false, $isManip = false)
112     {
113         if ($limit > 0) {
114             $count = intval($limit);
115
116             $offset = intval($offset);
117             if ($offset < 0) {
118                 throw new Doctrine_Connection_Exception("LIMIT argument offset=$offset is not valid");
119             }
120     
121             $orderby = stristr($query, 'ORDER BY');
122             if ($orderby !== false) {
123                 $sort = (stripos($orderby, 'desc') !== false) ? 'desc' : 'asc';
124                 $order = str_ireplace('ORDER BY', '', $orderby);
125                 $order = trim(preg_replace('/ASC|DESC/i', '', $order));
126             }
127     
128             $query = preg_replace('/^SELECT\s/i', 'SELECT TOP ' . ($count+$offset) . ' ', $query);
129     
130             $query = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $query . ') AS inner_tbl';
131             if ($orderby !== false) {
132                 $query .= ' ORDER BY ' . $order . ' ';
133                 $query .= (stripos($sort, 'asc') !== false) ? 'DESC' : 'ASC';
134             }
135             $query .= ') AS outer_tbl';
136             if ($orderby !== false) {
137                 $query .= ' ORDER BY ' . $order . ' ' . $sort;
138             }
139     
140             return $query;
141
142         }
143
144         return $query;
145     }
146
147     /**
148      * return version information about the server
149      *
150      * @param bool   $native  determines if the raw version string should be returned
151      * @return mixed array/string with version information or MDB2 error object
152      */
153     public function getServerVersion($native = false)
154     {
155         if ($this->serverInfo) {
156             $serverInfo = $this->serverInfo;
157         } else {
158             $query      = 'SELECT @@VERSION';
159             $serverInfo = $this->fetchOne($query);
160         }
161         // cache server_info
162         $this->serverInfo = $serverInfo;
163         if ( ! $native) {
164             if (preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $serverInfo, $tmp)) {
165                 $serverInfo = array(
166                     'major' => $tmp[1],
167                     'minor' => $tmp[2],
168                     'patch' => $tmp[3],
169                     'extra' => null,
170                     'native' => $serverInfo,
171                 );
172             } else {
173                 $serverInfo = array(
174                     'major' => null,
175                     'minor' => null,
176                     'patch' => null,
177                     'extra' => null,
178                     'native' => $serverInfo,
179                 );
180             }
181         }
182         return $serverInfo;
183     }
184
185     /**
186      * Checks if there's a sequence that exists.
187      *
188      * @param  string $seq_name     The sequence name to verify.
189      * @return boolean              The value if the table exists or not
190      */
191     public function checkSequence($seqName)
192     {
193         $query = 'SELECT * FROM ' . $seqName;
194         try {
195             $this->exec($query);
196         } catch(Doctrine_Connection_Exception $e) {
197             if ($e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) {
198                 return false;
199             }
200
201             throw $e;
202         }
203         return true;
204     }
205 }