# Coverage for Doctrine_DataDict_Sqlite

Back to coverage report

1 | <?php
2 | /*
3 | * $Id: Sqlite.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_DataDict');
22 | /**
23 | * @package Doctrine
24 | * @subpackage DataDict
25 | * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
26 | * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
27 | * @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
28 | * @version $Revision: 2963 $
29 | * @link www.phpdoctrine.org
30 | * @since 1.0
31 | */
32 | class Doctrine_DataDict_Sqlite extends Doctrine_DataDict
33 | {
34 | /**
35 | * Obtain DBMS specific SQL code portion needed to declare an text type
36 | * field to be used in statements like CREATE TABLE.
37 | *
38 | * @param array $field associative array with the name of the properties
39 | * of the field being declared as array indexes. Currently, the types
40 | * of supported field properties are as follows:
41 | *
42 | * length
43 | * Integer value that determines the maximum length of the text
44 | * field. If this argument is missing the field should be
45 | * declared to have the longest length allowed by the DBMS.
46 | *
47 | * default
48 | * Text value to be used as default for this field.
49 | *
50 | * notnull
51 | * Boolean flag that indicates whether this field is constrained
52 | * to not be set to null.
53 | * @author Lukas Smith (PEAR MDB2 library)
54 | * @return string DBMS specific SQL code portion that should be used to
55 | * declare the specified field.
56 | */
57 | public function getNativeDeclaration(array $field)
58 | {
59 | if ( ! isset($field['type'])) {
60 | throw new Doctrine_DataDict_Exception('Missing column type.');
61 | }
62 | switch ($field['type']) {
63 | case 'text':
64 | case 'object':
65 | case 'array':
66 | case 'string':
67 | case 'char':
68 | case 'gzip':
69 | case 'varchar':
70 | $length = (isset($field['length']) && $field['length']) ? $field['length'] : null;
71 |
72 | $fixed = ((isset($field['fixed']) && $field['fixed']) || $field['type'] == 'char') ? true : false;
73 |
74 | return $fixed ? ($length ? 'CHAR('.$length.')' : 'CHAR('.$this->conn->getAttribute(Doctrine::ATTR_DEFAULT_TEXTFLD_LENGTH).')')
75 | : ($length ? 'VARCHAR('.$length.')' : 'TEXT');
76 | case 'clob':
77 | if ( ! empty($field['length'])) {
78 | $length = $field['length'];
79 | if ($length <= 255) {
80 | return 'TINYTEXT';
81 | } elseif ($length <= 65535) {
82 | return 'TEXT';
83 | } elseif ($length <= 16777215) {
84 | return 'MEDIUMTEXT';
85 | }
86 | }
87 | return 'LONGTEXT';
88 | case 'blob':
89 | if ( ! empty($field['length'])) {
90 | $length = $field['length'];
91 | if ($length <= 255) {
92 | return 'TINYBLOB';
93 | } elseif ($length <= 65535) {
94 | return 'BLOB';
95 | } elseif ($length <= 16777215) {
96 | return 'MEDIUMBLOB';
97 | }
98 | }
99 | return 'LONGBLOB';
100 | case 'enum':
101 | case 'integer':
102 | case 'boolean':
103 | case 'int':
104 | return 'INTEGER';
105 | case 'date':
106 | return 'DATE';
107 | case 'time':
108 | return 'TIME';
109 | case 'timestamp':
110 | return 'DATETIME';
111 | case 'float':
112 | case 'double':
113 | return 'DOUBLE';//($this->conn->options['fixed_float'] ? '('.
114 | //($this->conn->options['fixed_float']+2).','.$this->conn->options['fixed_float'].')' : '');
115 | case 'decimal':
116 | $length = !empty($field['length']) ? $field['length'] : 18;
117 | $scale = !empty($field['scale']) ? $field['scale'] : $this->conn->getAttribute(Doctrine::ATTR_DECIMAL_PLACES);
118 | return 'DECIMAL('.$length.','.$scale.')';
119 | }
120 | throw new Doctrine_DataDict_Exception('Unknown field type \'' . $field['type'] . '\'.');
121 | }
122 |
123 | /**
124 | * Maps a native array description of a field to Doctrine datatype and length
125 | *
126 | * @param array $field native field description
127 | * @return array containing the various possible types, length, sign, fixed
128 | */
129 | public function getPortableDeclaration(array $field)
130 | {
131 | $dbType = strtolower($field['type']);
132 | $length = (isset($field['length'])) ? $field['length'] : null;
133 | $unsigned = (isset($field['unsigned'])) ? $field['unsigned'] : null;
134 | $fixed = null;
135 | $type = array();
136 |
137 | if ( ! isset($field['name'])) {
138 | $field['name'] = '';
139 | }
140 |
141 | switch ($dbType) {
142 | case 'boolean':
143 | $type[] = 'boolean';
144 | break;
145 | case 'tinyint':
146 | $type[] = 'integer';
147 | $type[] = 'boolean';
148 | if (preg_match('/^(is|has)/', $field['name'])) {
149 | $type = array_reverse($type);
150 | }
151 | $unsigned = preg_match('/ unsigned/i', $field['type']);
152 | $length = 1;
153 | break;
154 | case 'smallint':
155 | $type[] = 'integer';
156 | $unsigned = preg_match('/ unsigned/i', $field['type']);
157 | $length = 2;
158 | break;
159 | case 'mediumint':
160 | $type[] = 'integer';
161 | $unsigned = preg_match('/ unsigned/i', $field['type']);
162 | $length = 3;
163 | break;
164 | case 'int':
165 | case 'integer':
166 | case 'serial':
167 | $type[] = 'integer';
168 | $unsigned = preg_match('/ unsigned/i', $field['type']);
169 | $length = 4;
170 | break;
171 | case 'bigint':
172 | case 'bigserial':
173 | $type[] = 'integer';
174 | $unsigned = preg_match('/ unsigned/i', $field['type']);
175 | $length = 8;
176 | break;
177 | case 'clob':
178 | case 'tinytext':
179 | case 'mediumtext':
180 | case 'longtext':
181 | case 'text':
182 | case 'varchar':
183 | case 'varchar2':
184 | $fixed = false;
185 | case 'char':
186 | $type[] = 'text';
187 | if ($length == '1') {
188 | $type[] = 'boolean';
189 | if (preg_match('/^(is|has)/', $field['name'])) {
190 | $type = array_reverse($type);
191 | }
192 | } elseif (strstr($dbType, 'text')) {
193 | $type[] = 'clob';
194 | }
195 | if ($fixed !== false) {
196 | $fixed = true;
197 | }
198 | break;
199 | case 'date':
200 | $type[] = 'date';
201 | $length = null;
202 | break;
203 | case 'datetime':
204 | case 'timestamp':
205 | $type[] = 'timestamp';
206 | $length = null;
207 | break;
208 | case 'time':
209 | $type[] = 'time';
210 | $length = null;
211 | break;
212 | case 'float':
213 | case 'double':
214 | case 'real':
215 | $type[] = 'float';
216 | $length = null;
217 | break;
218 | case 'decimal':
219 | case 'numeric':
220 | $type[] = 'decimal';
221 | $length = null;
222 | break;
223 | case 'tinyblob':
224 | case 'mediumblob':
225 | case 'longblob':
226 | case 'blob':
227 | $type[] = 'blob';
228 | $length = null;
229 | break;
230 | case 'year':
231 | $type[] = 'integer';
232 | $type[] = 'date';
233 | $length = null;
234 | break;
235 | default:
236 | throw new Doctrine_DataDict_Exception('unknown database attribute type: '.$dbType);
237 | }
238 |
239 | return array('type' => $type,
240 | 'length' => $length,
241 | 'unsigned' => $unsigned,
242 | 'fixed' => $fixed);
243 | }
244 |
245 | /**
246 | * Obtain DBMS specific SQL code portion needed to declare an integer type
247 | * field to be used in statements like CREATE TABLE.
248 | *
249 | * @param string $name name the field to be declared.
250 | * @param array $field associative array with the name of the properties
251 | * of the field being declared as array indexes.
252 | * Currently, the types of supported field
253 | * properties are as follows:
254 | *
255 | * unsigned
256 | * Boolean flag that indicates whether the field
257 | * should be declared as unsigned integer if
258 | * possible.
259 | *
260 | * default
261 | * Integer value to be used as default for this
262 | * field.
263 | *
264 | * notnull
265 | * Boolean flag that indicates whether this field is
266 | * constrained to not be set to null.
267 | * @return string DBMS specific SQL code portion that should be used to
268 | * declare the specified field.
269 | * @access protected
270 | */
271 | public function getIntegerDeclaration($name, array $field)
272 | {
273 | $default = $autoinc = '';
274 | $type = $this->getNativeDeclaration($field);
275 |
276 | $autoincrement = isset($field['autoincrement']) && $field['autoincrement'];
277 |
278 | if ($autoincrement) {
279 | $autoinc = ' PRIMARY KEY AUTOINCREMENT';
280 | $type = 'INTEGER';
281 | } elseif (array_key_exists('default', $field)) {
282 | if ($field['default'] === '') {
283 | $field['default'] = empty($field['notnull']) ? null : 0;
284 | }
285 | $default = ' DEFAULT ' . $this->conn->quote($field['default'], $field['type']);
286 | }/**
287 | elseif (empty($field['notnull'])) {
288 | $default = ' DEFAULT NULL';
289 | }
290 | */
291 |
292 | $notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : '';
293 |
294 | // sqlite does not support unsigned attribute for autoinremented fields
295 | $unsigned = (isset($field['unsigned']) && $field['unsigned'] && !$autoincrement) ? ' UNSIGNED' : '';
296 |
297 | $name = $this->conn->quoteIdentifier($name, true);
298 | return $name . ' ' . $type . $unsigned . $default . $notnull . $autoinc;
299 | }
300 | }