Coverage for Doctrine_Connection_Mssql

Back to coverage report

1 <?php
2 /*
3  *  $Id: Mssql.php 2963 2007-10-21 06:23:59Z Jonathan.Wage $
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: 2963 $
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         return '[' . str_replace(']', ']]', $identifier) . ']';
88     }
89
90     /**
91      * Adds an adapter-specific LIMIT clause to the SELECT statement.
92      * [ borrowed from Zend Framework ]
93      *
94      * @param string $query
95      * @param mixed $limit
96      * @param mixed $offset
97      * @link http://lists.bestpractical.com/pipermail/rt-devel/2005-June/007339.html
98      * @return string
99      */
100     public function modifyLimitQuery($query, $limit, $offset, $isManip = false)
101     {
102         if ($limit > 0) {
103             $count = intval($limit);
104
105             $offset = intval($offset);
106             if ($offset < 0) {
107                 throw new Doctrine_Connection_Exception("LIMIT argument offset=$offset is not valid");
108             }
109     
110             $orderby = stristr($query, 'ORDER BY');
111             if ($orderby !== false) {
112                 $sort = (stripos($orderby, 'desc') !== false) ? 'desc' : 'asc';
113                 $order = str_ireplace('ORDER BY', '', $orderby);
114                 $order = trim(preg_replace('/ASC|DESC/i', '', $order));
115             }
116     
117             $query = preg_replace('/^SELECT\s/i', 'SELECT TOP ' . ($count+$offset) . ' ', $query);
118     
119             $query = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $query . ') AS inner_tbl';
120             if ($orderby !== false) {
121                 $query .= ' ORDER BY ' . $order . ' ';
122                 $query .= (stripos($sort, 'asc') !== false) ? 'DESC' : 'ASC';
123             }
124             $query .= ') AS outer_tbl';
125             if ($orderby !== false) {
126                 $query .= ' ORDER BY ' . $order . ' ' . $sort;
127             }
128     
129             return $query;
130
131         }
132
133         return $query;
134     }
135
136     /**
137      * return version information about the server
138      *
139      * @param bool   $native  determines if the raw version string should be returned
140      * @return mixed array/string with version information or MDB2 error object
141      */
142     public function getServerVersion($native = false)
143     {
144         if ($this->serverInfo) {
145             $serverInfo = $this->serverInfo;
146         } else {
147             $query      = 'SELECT @@VERSION';
148             $serverInfo = $this->fetchOne($query);
149         }
150         // cache server_info
151         $this->serverInfo = $serverInfo;
152         if ( ! $native) {
153             if (preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $serverInfo, $tmp)) {
154                 $serverInfo = array(
155                     'major' => $tmp[1],
156                     'minor' => $tmp[2],
157                     'patch' => $tmp[3],
158                     'extra' => null,
159                     'native' => $serverInfo,
160                 );
161             } else {
162                 $serverInfo = array(
163                     'major' => null,
164                     'minor' => null,
165                     'patch' => null,
166                     'extra' => null,
167                     'native' => $serverInfo,
168                 );
169             }
170         }
171         return $serverInfo;
172     }
173
174     /**
175      * Checks if there's a sequence that exists.
176      *
177      * @param  string $seq_name     The sequence name to verify.
178      * @return boolean              The value if the table exists or not
179      */
180     public function checkSequence($seqName)
181     {
182         $query = 'SELECT * FROM ' . $seqName;
183         try {
184             $this->exec($query);
185         } catch(Doctrine_Connection_Exception $e) {
186             if ($e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) {
187                 return false;
188             }
189
190             throw $e;
191         }
192         return true;
193     }
194 }