Coverage for Doctrine_Connection_Mssql

Back to coverage report

1 <?php
2 /*
3  *  $Id: Mssql.php 2702 2007-10-03 21:43:22Z 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.com>.
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: 2702 $
31  * @link        www.phpdoctrine.com
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      * the constructor
42      *
43      * @param Doctrine_Manager $manager
44      * @param PDO $pdo                          database handle
45      */
46     public function __construct(Doctrine_Manager $manager, $adapter)
47     {
48         // initialize all driver options
49         $this->supported = array(
50                           'sequences'             => 'emulated',
51                           'indexes'               => true,
52                           'affected_rows'         => true,
53                           'transactions'          => true,
54                           'summary_functions'     => true,
55                           'order_by_text'         => true,
56                           'current_id'            => 'emulated',
57                           'limit_queries'         => 'emulated',
58                           'LOBs'                  => true,
59                           'replace'               => 'emulated',
60                           'sub_selects'           => true,
61                           'auto_increment'        => true,
62                           'primary_key'           => true,
63                           'result_introspection'  => true,
64                           'prepared_statements'   => 'emulated',
65                           );
66
67         parent::__construct($manager, $adapter);
68     }
69     /**
70      * quoteIdentifier
71      * Quote a string so it can be safely used as a table / column name
72      *
73      * Quoting style depends on which database driver is being used.
74      *
75      * @param string $identifier    identifier name to be quoted
76      * @param bool   $checkOption   check the 'quote_identifier' option
77      *
78      * @return string  quoted identifier string
79      */
80     public function quoteIdentifier($identifier, $checkOption = false)
81     {
82         if ($checkOption && ! $this->getAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER)) {
83             return $identifier;
84         }
85         return '[' . str_replace(']', ']]', $identifier) . ']';
86     }
87     /**
88      * Adds an adapter-specific LIMIT clause to the SELECT statement.
89      * [ borrowed from Zend Framework ]
90      *
91      * @param string $query
92      * @param mixed $limit
93      * @param mixed $offset
94      * @link http://lists.bestpractical.com/pipermail/rt-devel/2005-June/007339.html
95      * @return string
96      */
97     public function modifyLimitQuery($query, $limit, $offset, $isManip = false)
98     {
99         if ($limit > 0) {
100             $count = intval($limit);
101
102             $offset = intval($offset);
103             if ($offset < 0) {
104                 throw new Doctrine_Connection_Exception("LIMIT argument offset=$offset is not valid");
105             }
106     
107             $orderby = stristr($query, 'ORDER BY');
108             if ($orderby !== false) {
109                 $sort = (stripos($orderby, 'desc') !== false) ? 'desc' : 'asc';
110                 $order = str_ireplace('ORDER BY', '', $orderby);
111                 $order = trim(preg_replace('/ASC|DESC/i', '', $order));
112             }
113     
114             $query = preg_replace('/^SELECT\s/i', 'SELECT TOP ' . ($count+$offset) . ' ', $query);
115     
116             $query = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $query . ') AS inner_tbl';
117             if ($orderby !== false) {
118                 $query .= ' ORDER BY ' . $order . ' ';
119                 $query .= (stripos($sort, 'asc') !== false) ? 'DESC' : 'ASC';
120             }
121             $query .= ') AS outer_tbl';
122             if ($orderby !== false) {
123                 $query .= ' ORDER BY ' . $order . ' ' . $sort;
124             }
125     
126             return $query;
127
128         }
129
130         return $query;
131     }
132     /**
133      * return version information about the server
134      *
135      * @param bool   $native  determines if the raw version string should be returned
136      * @return mixed array/string with version information or MDB2 error object
137      */
138     public function getServerVersion($native = false)
139     {
140         if ($this->serverInfo) {
141             $serverInfo = $this->serverInfo;
142         } else {
143             $query      = 'SELECT @@VERSION';
144             $serverInfo = $this->fetchOne($query);
145         }
146         // cache server_info
147         $this->serverInfo = $serverInfo;
148         if ( ! $native) {
149             if (preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $serverInfo, $tmp)) {
150                 $serverInfo = array(
151                     'major' => $tmp[1],
152                     'minor' => $tmp[2],
153                     'patch' => $tmp[3],
154                     'extra' => null,
155                     'native' => $serverInfo,
156                 );
157             } else {
158                 $serverInfo = array(
159                     'major' => null,
160                     'minor' => null,
161                     'patch' => null,
162                     'extra' => null,
163                     'native' => $serverInfo,
164                 );
165             }
166         }
167         return $serverInfo;
168     }
169     /**
170      * Checks if there's a sequence that exists.
171      *
172      * @param  string $seq_name     The sequence name to verify.
173      * @return boolean              The value if the table exists or not
174      */
175     public function checkSequence($seqName)
176     {
177         $query = 'SELECT * FROM ' . $seqName;
178         try {
179             $this->exec($query);
180         } catch(Doctrine_Connection_Exception $e) {
181             if ($e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) {
182                 return false;
183             }
184
185             throw $e;
186         }
187         return true;
188     }
189 }