Coverage for Doctrine_Connection_Mysql

Back to coverage report

1 <?php
2 /*
3  *  $Id: Mysql.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_Common');
22 /**
23  * Doctrine_Connection_Mysql
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_Mysql extends Doctrine_Connection_Common
35 {
36     /**
37      * @var string $driverName                  the name of this connection driver
38      */
39     protected $driverName = 'Mysql';
40     /**
41      * the constructor
42      *
43      * @param Doctrine_Manager $manager
44      * @param PDO|Doctrine_Adapter $adapter     database handler
45      */
46     public function __construct(Doctrine_Manager $manager, $adapter)
47     {
48         $this->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
49         $this->setAttribute(Doctrine::ATTR_DEFAULT_TABLE_TYPE, 'INNODB');
50
51         $this->supported = array(
52                           'sequences'            => 'emulated',
53                           'indexes'              => true,
54                           'affected_rows'        => true,
55                           'transactions'         => true,
56                           'savepoints'           => false,
57                           'summary_functions'    => true,
58                           'order_by_text'        => true,
59                           'current_id'           => 'emulated',
60                           'limit_queries'        => true,
61                           'LOBs'                 => true,
62                           'replace'              => true,
63                           'sub_selects'          => true,
64                           'auto_increment'       => true,
65                           'primary_key'          => true,
66                           'result_introspection' => true,
67                           'prepared_statements'  => 'emulated',
68                           'identifier_quoting'   => true,
69                           'pattern_escaping'     => true
70                           );
71
72         $this->properties['string_quoting'] = array('start' => "'",
73                                                     'end' => "'",
74                                                     'escape' => '\\',
75                                                     'escape_pattern' => '\\');
76
77         $this->properties['identifier_quoting'] = array('start' => '`',
78                                                         'end' => '`',
79                                                         'escape' => '`');
80
81         $this->properties['sql_comments'] = array(
82                                             array('start' => '-- ', 'end' => "\n", 'escape' => false),
83                                             array('start' => '#', 'end' => "\n", 'escape' => false),
84                                             array('start' => '/*', 'end' => '*/', 'escape' => false),
85                                             );
86
87         $this->properties['varchar_max_length'] = 255;
88
89         parent::__construct($manager, $adapter);
90     }
91     /**
92      * Set the charset on the current connection
93      *
94      * @param string    charset
95      *
96      * @return void
97      */
98     public function setCharset($charset)
99     {
100         $query = 'SET NAMES '.$this->dbh->quote($charset);
101         $this->exec($query);
102     }
103     /**
104      * Execute a SQL REPLACE query. A REPLACE query is identical to a INSERT
105      * query, except that if there is already a row in the table with the same
106      * key field values, the REPLACE query just updates its values instead of
107      * inserting a new row.
108      *
109      * The REPLACE type of query does not make part of the SQL standards. Since
110      * practically only MySQL implements it natively, this type of query is
111      * emulated through this method for other DBMS using standard types of
112      * queries inside a transaction to assure the atomicity of the operation.
113      *
114      * @access public
115      *
116      * @param string $table name of the table on which the REPLACE query will
117      *  be executed.
118      * @param array $fields associative array that describes the fields and the
119      *  values that will be inserted or updated in the specified table. The
120      *  indexes of the array are the names of all the fields of the table. The
121      *  values of the array are also associative arrays that describe the
122      *  values and other properties of the table fields.
123      *
124      *  Here follows a list of field properties that need to be specified:
125      *
126      *    value:
127      *          Value to be assigned to the specified field. This value may be
128      *          of specified in database independent type format as this
129      *          function can perform the necessary datatype conversions.
130      *
131      *    Default:
132      *          this property is required unless the Null property
133      *          is set to 1.
134      *
135      *    type
136      *          Name of the type of the field. Currently, all types Metabase
137      *          are supported except for clob and blob.
138      *
139      *    Default: no type conversion
140      *
141      *    null
142      *          Boolean property that indicates that the value for this field
143      *          should be set to null.
144      *
145      *          The default value for fields missing in INSERT queries may be
146      *          specified the definition of a table. Often, the default value
147      *          is already null, but since the REPLACE may be emulated using
148      *          an UPDATE query, make sure that all fields of the table are
149      *          listed in this function argument array.
150      *
151      *    Default: 0
152      *
153      *    key
154      *          Boolean property that indicates that this field should be
155      *          handled as a primary key or at least as part of the compound
156      *          unique index of the table that will determine the row that will
157      *          updated if it exists or inserted a new row otherwise.
158      *
159      *          This function will fail if no key field is specified or if the
160      *          value of a key field is set to null because fields that are
161      *          part of unique index they may not be null.
162      *
163      *    Default: 0
164      *
165      * @return integer      the number of affected rows
166      */
167     public function replace($table, array $fields, array $keys)
168     {
169         $count = count($fields);
170         $query = $values = '';
171         $keys = $colnum = 0;
172
173         for (reset($fields); $colnum < $count; next($fields), $colnum++) {
174             $name = key($fields);
175
176             if ($colnum > 0) {
177                 $query .= ',';
178                 $values.= ',';
179             }
180
181             $query .= $name;
182
183             if (isset($fields[$name]['null']) && $fields[$name]['null']) {
184                 $value = 'NULL';
185             } else {
186                 $type = isset($fields[$name]['type']) ? $fields[$name]['type'] : null;
187                 $value = $this->quote($fields[$name]['value'], $type);
188             }
189
190             $values .= $value;
191
192             if (isset($fields[$name]['key']) && $fields[$name]['key']) {
193                 if ($value === 'NULL') {
194                     throw new Doctrine_Connection_Mysql_Exception('key value '.$name.' may not be NULL');
195                 }
196                 $keys++;
197             }
198         }
199
200         if ($keys == 0) {
201             throw new Doctrine_Connection_Mysql_Exception('not specified which fields are keys');
202         }
203         $query = 'REPLACE INTO ' . $table . ' (' . $query . ') VALUES (' . $values . ')';
204
205         return $this->exec($query);
206     }
207 }